001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose; 019 020 021import java.net.URI; 022import java.text.ParseException; 023import java.util.*; 024 025import net.jcip.annotations.Immutable; 026 027import com.nimbusds.jose.jwk.JWK; 028import com.nimbusds.jose.util.Base64; 029import com.nimbusds.jose.util.Base64URL; 030import com.nimbusds.jose.util.JSONObjectUtils; 031import com.nimbusds.jose.util.X509CertChainUtils; 032 033 034/** 035 * JSON Web Encryption (JWE) header. This class is immutable. 036 * 037 * <p>Supports the following {@link #getRegisteredParameterNames registered 038 * header parameters}: 039 * 040 * <ul> 041 * <li>alg 042 * <li>enc 043 * <li>epk 044 * <li>zip 045 * <li>jku 046 * <li>jwk 047 * <li>x5u 048 * <li>x5t 049 * <li>x5t#S256 050 * <li>x5c 051 * <li>kid 052 * <li>typ 053 * <li>cty 054 * <li>crit 055 * <li>apu 056 * <li>apv 057 * <li>p2s 058 * <li>p2c 059 * <li>iv 060 * <li>skid 061 * <li>authTag 062 * </ul> 063 * 064 * <p>The header may also include {@link #getCustomParams custom 065 * parameters}; these will be serialised and parsed along the registered ones. 066 * 067 * <p>Example header: 068 * 069 * <pre> 070 * { 071 * "alg" : "RSA1_5", 072 * "enc" : "A128CBC-HS256" 073 * } 074 * </pre> 075 * 076 * @author Vladimir Dzhuvinov 077 * @version 2022-03-07 078 */ 079@Immutable 080public final class JWEHeader extends CommonSEHeader { 081 082 083 private static final long serialVersionUID = 1L; 084 085 086 /** 087 * The registered parameter names. 088 */ 089 private static final Set<String> REGISTERED_PARAMETER_NAMES; 090 091 092 static { 093 Set<String> p = new HashSet<>(); 094 095 p.add(HeaderParameterNames.ALGORITHM); 096 p.add(HeaderParameterNames.ENCRYPTION_ALGORITHM); 097 p.add(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY); 098 p.add(HeaderParameterNames.COMPRESSION_ALGORITHM); 099 p.add(HeaderParameterNames.JWK_SET_URL); 100 p.add(HeaderParameterNames.JWK); 101 p.add(HeaderParameterNames.X_509_CERT_URL); 102 p.add(HeaderParameterNames.X_509_CERT_SHA_1_THUMBPRINT); 103 p.add(HeaderParameterNames.X_509_CERT_SHA_256_THUMBPRINT); 104 p.add(HeaderParameterNames.X_509_CERT_CHAIN); 105 p.add(HeaderParameterNames.KEY_ID); 106 p.add(HeaderParameterNames.TYPE); 107 p.add(HeaderParameterNames.CONTENT_TYPE); 108 p.add(HeaderParameterNames.CRITICAL); 109 p.add(HeaderParameterNames.AGREEMENT_PARTY_U_INFO); 110 p.add(HeaderParameterNames.AGREEMENT_PARTY_V_INFO); 111 p.add(HeaderParameterNames.PBES2_SALT_INPUT); 112 p.add(HeaderParameterNames.PBES2_COUNT); 113 p.add(HeaderParameterNames.INITIALIZATION_VECTOR); 114 p.add(HeaderParameterNames.AUTHENTICATION_TAG); 115 p.add(HeaderParameterNames.SENDER_KEY_ID); 116 p.add("authTag"); // this is a non-standard header, but we should leave it for backwards compatibility 117 118 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 119 } 120 121 122 /** 123 * Builder for constructing JSON Web Encryption (JWE) headers. 124 * 125 * <p>Example usage: 126 * 127 * <pre> 128 * JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.RSA1_5, EncryptionMethod.A128GCM) 129 * .contentType("text/plain") 130 * .customParam("exp", new Date().getTime()) 131 * .build(); 132 * </pre> 133 */ 134 public static class Builder { 135 136 137 /** 138 * The encryption method. 139 */ 140 private final EncryptionMethod enc; 141 142 143 /** 144 * The JWE algorithm. 145 */ 146 private JWEAlgorithm alg; 147 148 149 /** 150 * The JOSE object type. 151 */ 152 private JOSEObjectType typ; 153 154 155 /** 156 * The content type. 157 */ 158 private String cty; 159 160 161 /** 162 * The critical headers. 163 */ 164 private Set<String> crit; 165 166 167 /** 168 * Public JWK Set URL. 169 */ 170 private URI jku; 171 172 173 /** 174 * Public JWK. 175 */ 176 private JWK jwk; 177 178 179 /** 180 * X.509 certificate URL. 181 */ 182 private URI x5u; 183 184 185 /** 186 * X.509 certificate SHA-1 thumbprint. 187 */ 188 @Deprecated 189 private Base64URL x5t; 190 191 192 /** 193 * X.509 certificate SHA-256 thumbprint. 194 */ 195 private Base64URL x5t256; 196 197 198 /** 199 * The X.509 certificate chain corresponding to the key used to 200 * sign the JWS object. 201 */ 202 private List<Base64> x5c; 203 204 205 /** 206 * Key ID. 207 */ 208 private String kid; 209 210 211 /** 212 * The ephemeral public key. 213 */ 214 private JWK epk; 215 216 217 /** 218 * The compression algorithm. 219 */ 220 private CompressionAlgorithm zip; 221 222 223 /** 224 * The agreement PartyUInfo. 225 */ 226 private Base64URL apu; 227 228 229 /** 230 * The agreement PartyVInfo. 231 */ 232 private Base64URL apv; 233 234 235 /** 236 * The PBES2 salt. 237 */ 238 private Base64URL p2s; 239 240 241 /** 242 * The PBES2 count. 243 */ 244 private int p2c; 245 246 247 /** 248 * The initialisation vector. 249 */ 250 private Base64URL iv; 251 252 253 /** 254 * The authentication authTag. 255 */ 256 private Base64URL tag; 257 258 259 /** 260 * Sender key ID. 261 */ 262 private String skid; 263 264 265 /** 266 * Custom header parameters. 267 */ 268 private Map<String,Object> customParams; 269 270 271 /** 272 * The parsed Base64URL. 273 */ 274 private Base64URL parsedBase64URL; 275 276 277 /** 278 * Creates a new JWE header builder. 279 * 280 * @param alg The JWE algorithm ({@code alg}) parameter. Must 281 * not be "none" or {@code null}. 282 * @param enc The encryption method. Must not be {@code null}. 283 */ 284 public Builder(final JWEAlgorithm alg, final EncryptionMethod enc) { 285 286 if (alg.getName().equals(Algorithm.NONE.getName())) { 287 throw new IllegalArgumentException("The JWE algorithm \"alg\" cannot be \"none\""); 288 } 289 290 this.alg = alg; 291 292 if (enc == null) { 293 throw new IllegalArgumentException("The encryption method \"enc\" parameter must not be null"); 294 } 295 296 this.enc = enc; 297 } 298 299 300 /** 301 * Creates a new JWE header builder. This builder is intended 302 * for {@link JWEObjectJSON multi-recipient JWE}. 303 * 304 * @param enc The encryption method. Must not be {@code null}. 305 */ 306 public Builder(final EncryptionMethod enc) { 307 308 if (enc == null) { 309 throw new IllegalArgumentException("The encryption method \"enc\" parameter must not be null"); 310 } 311 312 this.enc = enc; 313 } 314 315 316 /** 317 * Creates a new JWE header builder with the parameters from 318 * the specified header. 319 * 320 * @param jweHeader The JWE header to use. Must not be 321 * {@code null}. 322 */ 323 public Builder(final JWEHeader jweHeader) { 324 325 this(jweHeader.getEncryptionMethod()); 326 327 alg = jweHeader.getAlgorithm(); 328 typ = jweHeader.getType(); 329 cty = jweHeader.getContentType(); 330 crit = jweHeader.getCriticalParams(); 331 customParams = jweHeader.getCustomParams(); 332 333 jku = jweHeader.getJWKURL(); 334 jwk = jweHeader.getJWK(); 335 x5u = jweHeader.getX509CertURL(); 336 x5t = jweHeader.getX509CertThumbprint(); 337 x5t256 = jweHeader.getX509CertSHA256Thumbprint(); 338 x5c = jweHeader.getX509CertChain(); 339 kid = jweHeader.getKeyID(); 340 341 epk = jweHeader.getEphemeralPublicKey(); 342 zip = jweHeader.getCompressionAlgorithm(); 343 apu = jweHeader.getAgreementPartyUInfo(); 344 apv = jweHeader.getAgreementPartyVInfo(); 345 p2s = jweHeader.getPBES2Salt(); 346 p2c = jweHeader.getPBES2Count(); 347 iv = jweHeader.getIV(); 348 tag = jweHeader.getAuthTag(); 349 350 skid = jweHeader.getSenderKeyID(); 351 352 customParams = jweHeader.getCustomParams(); 353 } 354 355 356 357 /** 358 * Sets the algorithm ({@code alg}) parameter. 359 * 360 * @param alg The alg parameter, {@code null} if not 361 * specified. 362 * 363 * @return This builder. 364 */ 365 public Builder alg(final JWEAlgorithm alg) { 366 367 this.alg = alg; 368 return this; 369 } 370 371 372 /** 373 * Sets the type ({@code typ}) parameter. 374 * 375 * @param typ The type parameter, {@code null} if not 376 * specified. 377 * 378 * @return This builder. 379 */ 380 public Builder type(final JOSEObjectType typ) { 381 382 this.typ = typ; 383 return this; 384 } 385 386 387 /** 388 * Sets the content type ({@code cty}) parameter. 389 * 390 * @param cty The content type parameter, {@code null} if not 391 * specified. 392 * 393 * @return This builder. 394 */ 395 public Builder contentType(final String cty) { 396 397 this.cty = cty; 398 return this; 399 } 400 401 402 /** 403 * Sets the critical header parameters ({@code crit}) 404 * parameter. 405 * 406 * @param crit The names of the critical header parameters, 407 * empty set or {@code null} if none. 408 * 409 * @return This builder. 410 */ 411 public Builder criticalParams(final Set<String> crit) { 412 413 this.crit = crit; 414 return this; 415 } 416 417 418 /** 419 * Sets the public JSON Web Key (JWK) Set URL ({@code jku}) 420 * parameter. 421 * 422 * @param jku The public JSON Web Key (JWK) Set URL parameter, 423 * {@code null} if not specified. 424 * 425 * @return This builder. 426 */ 427 public Builder jwkURL(final URI jku) { 428 429 this.jku = jku; 430 return this; 431 } 432 433 434 /** 435 * Sets the public JSON Web Key (JWK) ({@code jwk}) parameter. 436 * 437 * @param jwk The public JSON Web Key (JWK) ({@code jwk}) 438 * parameter, {@code null} if not specified. 439 * 440 * @return This builder. 441 */ 442 public Builder jwk(final JWK jwk) { 443 444 if (jwk != null && jwk.isPrivate()) { 445 throw new IllegalArgumentException("The JWK must be public"); 446 } 447 448 this.jwk = jwk; 449 return this; 450 } 451 452 453 /** 454 * Sets the X.509 certificate URL ({@code x5u}) parameter. 455 * 456 * @param x5u The X.509 certificate URL parameter, {@code null} 457 * if not specified. 458 * 459 * @return This builder. 460 */ 461 public Builder x509CertURL(final URI x5u) { 462 463 this.x5u = x5u; 464 return this; 465 } 466 467 468 /** 469 * Sets the X.509 certificate SHA-1 thumbprint ({@code x5t}) 470 * parameter. 471 * 472 * @param x5t The X.509 certificate SHA-1 thumbprint parameter, 473 * {@code null} if not specified. 474 * 475 * @return This builder. 476 */ 477 @Deprecated 478 public Builder x509CertThumbprint(final Base64URL x5t) { 479 480 this.x5t = x5t; 481 return this; 482 } 483 484 485 /** 486 * Sets the X.509 certificate SHA-256 thumbprint 487 * ({@code x5t#s256}) parameter. 488 * 489 * @param x5t256 The X.509 certificate SHA-256 thumbprint 490 * parameter, {@code null} if not specified. 491 * 492 * @return This builder. 493 */ 494 public Builder x509CertSHA256Thumbprint(final Base64URL x5t256) { 495 496 this.x5t256 = x5t256; 497 return this; 498 } 499 500 501 /** 502 * Sets the X.509 certificate chain parameter ({@code x5c}) 503 * corresponding to the key used to sign the JWS object. 504 * 505 * @param x5c The X.509 certificate chain parameter, 506 * {@code null} if not specified. 507 * 508 * @return This builder. 509 */ 510 public Builder x509CertChain(final List<Base64> x5c) { 511 512 this.x5c = x5c; 513 return this; 514 } 515 516 517 /** 518 * Sets the key ID ({@code kid}) parameter. 519 * 520 * @param kid The key ID parameter, {@code null} if not 521 * specified. 522 * 523 * @return This builder. 524 */ 525 public Builder keyID(final String kid) { 526 527 this.kid = kid; 528 return this; 529 } 530 531 532 /** 533 * Sets the Ephemeral Public Key ({@code epk}) parameter. 534 * 535 * @param epk The Ephemeral Public Key parameter, {@code null} 536 * if not specified. 537 * 538 * @return This builder. 539 */ 540 public Builder ephemeralPublicKey(final JWK epk) { 541 542 this.epk = epk; 543 return this; 544 } 545 546 547 /** 548 * Sets the compression algorithm ({@code zip}) parameter. 549 * 550 * @param zip The compression algorithm parameter, {@code null} 551 * if not specified. 552 * 553 * @return This builder. 554 */ 555 public Builder compressionAlgorithm(final CompressionAlgorithm zip) { 556 557 this.zip = zip; 558 return this; 559 } 560 561 562 /** 563 * Sets the agreement PartyUInfo ({@code apu}) parameter. 564 * 565 * @param apu The agreement PartyUInfo parameter, {@code null} 566 * if not specified. 567 * 568 * @return This builder. 569 */ 570 public Builder agreementPartyUInfo(final Base64URL apu) { 571 572 this.apu = apu; 573 return this; 574 } 575 576 577 /** 578 * Sets the agreement PartyVInfo ({@code apv}) parameter. 579 * 580 * @param apv The agreement PartyVInfo parameter, {@code null} 581 * if not specified. 582 * 583 * @return This builder. 584 */ 585 public Builder agreementPartyVInfo(final Base64URL apv) { 586 587 this.apv = apv; 588 return this; 589 } 590 591 592 /** 593 * Sets the PBES2 salt ({@code p2s}) parameter. 594 * 595 * @param p2s The PBES2 salt parameter, {@code null} if not 596 * specified. 597 * 598 * @return This builder. 599 */ 600 public Builder pbes2Salt(final Base64URL p2s) { 601 602 this.p2s = p2s; 603 return this; 604 } 605 606 607 /** 608 * Sets the PBES2 count ({@code p2c}) parameter. 609 * 610 * @param p2c The PBES2 count parameter, zero if not specified. 611 * Must not be negative. 612 * 613 * @return This builder. 614 */ 615 public Builder pbes2Count(final int p2c) { 616 617 if (p2c < 0) 618 throw new IllegalArgumentException("The PBES2 count parameter must not be negative"); 619 620 this.p2c = p2c; 621 return this; 622 } 623 624 625 /** 626 * Sets the initialisation vector ({@code iv}) parameter. 627 * 628 * @param iv The initialisation vector, {@code null} if not 629 * specified. 630 * 631 * @return This builder. 632 */ 633 public Builder iv(final Base64URL iv) { 634 635 this.iv = iv; 636 return this; 637 } 638 639 640 /** 641 * Sets the authentication tag ({@code tag}) parameter. 642 * 643 * @param tag The authentication tag, {@code null} if not 644 * specified. 645 * 646 * @return This builder. 647 */ 648 public Builder authTag(final Base64URL tag) { 649 650 this.tag = tag; 651 return this; 652 } 653 654 655 /** 656 * Sets the sender key ID ({@code skid}) parameter. 657 * 658 * @param skid The sender Key ID parameter, {@code null} if not 659 * specified. 660 * 661 * @return This builder. 662 */ 663 public Builder senderKeyID(final String skid) { 664 665 this.skid = skid; 666 return this; 667 } 668 669 670 /** 671 * Sets a custom (non-registered) parameter. 672 * 673 * @param name The name of the custom parameter. Must not 674 * match a registered parameter name and must not 675 * be {@code null}. 676 * @param value The value of the custom parameter, should map 677 * to a valid JSON entity, {@code null} if not 678 * specified. 679 * 680 * @return This builder. 681 * 682 * @throws IllegalArgumentException If the specified parameter 683 * name matches a registered 684 * parameter name. 685 */ 686 public Builder customParam(final String name, final Object value) { 687 688 if (getRegisteredParameterNames().contains(name)) { 689 throw new IllegalArgumentException("The parameter name \"" + name + "\" matches a registered name"); 690 } 691 692 if (customParams == null) { 693 customParams = new HashMap<>(); 694 } 695 696 customParams.put(name, value); 697 698 return this; 699 } 700 701 702 /** 703 * Sets the custom (non-registered) parameters. The values must 704 * be serialisable to a JSON entity, otherwise will be ignored. 705 * 706 * @param customParameters The custom parameters, empty map or 707 * {@code null} if none. 708 * 709 * @return This builder. 710 */ 711 public Builder customParams(final Map<String, Object> customParameters) { 712 713 this.customParams = customParameters; 714 return this; 715 } 716 717 718 /** 719 * Sets the parsed Base64URL. 720 * 721 * @param base64URL The parsed Base64URL, {@code null} if the 722 * header is created from scratch. 723 * 724 * @return This builder. 725 */ 726 public Builder parsedBase64URL(final Base64URL base64URL) { 727 728 this.parsedBase64URL = base64URL; 729 return this; 730 } 731 732 733 /** 734 * Builds a new JWE header. 735 * 736 * @return The JWE header. 737 */ 738 public JWEHeader build() { 739 740 return new JWEHeader( 741 alg, enc, typ, cty, crit, 742 jku, jwk, x5u, x5t, x5t256, x5c, kid, 743 epk, zip, apu, apv, p2s, p2c, 744 iv, tag, skid, 745 customParams, parsedBase64URL); 746 } 747 } 748 749 750 /** 751 * The encryption method ({@code enc}) parameter. 752 */ 753 private final EncryptionMethod enc; 754 755 756 /** 757 * The ephemeral public key ({@code epk}) parameter. 758 */ 759 private final JWK epk; 760 761 762 /** 763 * The compression algorithm ({@code zip}) parameter. 764 */ 765 private final CompressionAlgorithm zip; 766 767 768 /** 769 * The agreement PartyUInfo ({@code apu}) parameter. 770 */ 771 private final Base64URL apu; 772 773 774 /** 775 * The agreement PartyVInfo ({@code apv}) parameter. 776 */ 777 private final Base64URL apv; 778 779 780 /** 781 * The PBES2 salt ({@code p2s}) parameter. 782 */ 783 private final Base64URL p2s; 784 785 786 /** 787 * The PBES2 count ({@code p2c}) parameter. 788 */ 789 private final int p2c; 790 791 792 /** 793 * The initialisation vector ({@code iv}) parameter. 794 */ 795 private final Base64URL iv; 796 797 798 /** 799 * The authentication tag ({@code tag}) parameter. 800 */ 801 private final Base64URL tag; 802 803 804 /** 805 * The sender key ID ({@code skid}) parameter. 806 */ 807 private final String skid; 808 809 810 /** 811 * Creates a new minimal JSON Web Encryption (JWE) header. 812 * 813 * @param enc The encryption method parameter. Must not be 814 * {@code null}. 815 */ 816 public JWEHeader(final EncryptionMethod enc) { 817 818 this( 819 null, enc, 820 null, null, null, null, null, null, null, null, null, null, 821 null, null, null, null, null, 0, 822 null, null, 823 null, null, null); 824 } 825 826 827 /** 828 * Creates a new minimal JSON Web Encryption (JWE) header. 829 * 830 * <p>Note: Use {@link PlainHeader} to create a header with algorithm 831 * {@link Algorithm#NONE none}. 832 * 833 * @param alg The JWE algorithm parameter. Must not be "none" or 834 * {@code null}. 835 * @param enc The encryption method parameter. Must not be 836 * {@code null}. 837 */ 838 public JWEHeader(final JWEAlgorithm alg, final EncryptionMethod enc) { 839 840 this( 841 alg, enc, 842 null, null, null, null, null, null, null, null, null, null, 843 null, null, null, null, null, 0, 844 null, null, 845 null, null, null); 846 } 847 848 849 /** 850 * Creates a new JSON Web Encryption (JWE) header. 851 * 852 * <p>Note: Use {@link PlainHeader} to create a header with algorithm 853 * {@link Algorithm#NONE none}. 854 * 855 * @param alg The JWE algorithm ({@code alg}) parameter. 856 * {@code null} if not specified. 857 * @param enc The encryption method parameter. Must not be 858 * {@code null}. 859 * @param typ The type ({@code typ}) parameter, 860 * {@code null} if not specified. 861 * @param cty The content type ({@code cty}) parameter, 862 * {@code null} if not specified. 863 * @param crit The names of the critical header 864 * ({@code crit}) parameters, empty set or 865 * {@code null} if none. 866 * @param jku The JSON Web Key (JWK) Set URL ({@code jku}) 867 * parameter, {@code null} if not specified. 868 * @param jwk The X.509 certificate URL ({@code jwk}) 869 * parameter, {@code null} if not specified. 870 * @param x5u The X.509 certificate URL parameter 871 * ({@code x5u}), {@code null} if not specified. 872 * @param x5t The X.509 certificate SHA-1 thumbprint 873 * ({@code x5t}) parameter, {@code null} if not 874 * specified. 875 * @param x5t256 The X.509 certificate SHA-256 thumbprint 876 * ({@code x5t#S256}) parameter, {@code null} if 877 * not specified. 878 * @param x5c The X.509 certificate chain ({@code x5c}) 879 * parameter, {@code null} if not specified. 880 * @param kid The key ID ({@code kid}) parameter, 881 * {@code null} if not specified. 882 * @param epk The Ephemeral Public Key ({@code epk}) 883 * parameter, {@code null} if not specified. 884 * @param zip The compression algorithm ({@code zip}) 885 * parameter, {@code null} if not specified. 886 * @param apu The agreement PartyUInfo ({@code apu}) 887 * parameter, {@code null} if not specified. 888 * @param apv The agreement PartyVInfo ({@code apv}) 889 * parameter, {@code null} if not specified. 890 * @param p2s The PBES2 salt ({@code p2s}) parameter, 891 * {@code null} if not specified. 892 * @param p2c The PBES2 count ({@code p2c}) parameter, zero 893 * if not specified. Must not be negative. 894 * @param iv The initialisation vector ({@code iv}) 895 * parameter, {@code null} if not specified. 896 * @param tag The authentication tag ({@code tag}) 897 * parameter, {@code null} if not specified. 898 * @param skid The sender key ID ({@code skid}) parameter, 899 * {@code null} if not specified. 900 * @param customParams The custom parameters, empty map or 901 * {@code null} if none. 902 * @param parsedBase64URL The parsed Base64URL, {@code null} if the 903 * header is created from scratch. 904 */ 905 public JWEHeader(final Algorithm alg, 906 final EncryptionMethod enc, 907 final JOSEObjectType typ, 908 final String cty, 909 final Set<String> crit, 910 final URI jku, 911 final JWK jwk, 912 final URI x5u, 913 final Base64URL x5t, 914 final Base64URL x5t256, 915 final List<Base64> x5c, 916 final String kid, 917 final JWK epk, 918 final CompressionAlgorithm zip, 919 final Base64URL apu, 920 final Base64URL apv, 921 final Base64URL p2s, 922 final int p2c, 923 final Base64URL iv, 924 final Base64URL tag, 925 final String skid, 926 final Map<String,Object> customParams, 927 final Base64URL parsedBase64URL) { 928 929 super(alg, typ, cty, crit, jku, jwk, x5u, x5t, x5t256, x5c, kid, customParams, parsedBase64URL); 930 931 if (alg != null && alg.getName().equals(Algorithm.NONE.getName())) { 932 throw new IllegalArgumentException("The JWE algorithm cannot be \"none\""); 933 } 934 935 if (enc == null) { 936 throw new IllegalArgumentException("The encryption method \"enc\" parameter must not be null"); 937 } 938 939 if (epk != null && epk.isPrivate()) { 940 throw new IllegalArgumentException("Ephemeral public key should not be a private key"); 941 } 942 943 this.enc = enc; 944 945 this.epk = epk; 946 this.zip = zip; 947 this.apu = apu; 948 this.apv = apv; 949 this.p2s = p2s; 950 this.p2c = p2c; 951 this.iv = iv; 952 this.tag = tag; 953 this.skid = skid; 954 } 955 956 957 /** 958 * Deep copy constructor. 959 * 960 * @param jweHeader The JWE header to copy. Must not be {@code null}. 961 */ 962 public JWEHeader(final JWEHeader jweHeader) { 963 964 this( 965 jweHeader.getAlgorithm(), 966 jweHeader.getEncryptionMethod(), 967 jweHeader.getType(), 968 jweHeader.getContentType(), 969 jweHeader.getCriticalParams(), 970 jweHeader.getJWKURL(), 971 jweHeader.getJWK(), 972 jweHeader.getX509CertURL(), 973 jweHeader.getX509CertThumbprint(), 974 jweHeader.getX509CertSHA256Thumbprint(), 975 jweHeader.getX509CertChain(), 976 jweHeader.getKeyID(), 977 jweHeader.getEphemeralPublicKey(), 978 jweHeader.getCompressionAlgorithm(), 979 jweHeader.getAgreementPartyUInfo(), 980 jweHeader.getAgreementPartyVInfo(), 981 jweHeader.getPBES2Salt(), 982 jweHeader.getPBES2Count(), 983 jweHeader.getIV(), 984 jweHeader.getAuthTag(), 985 jweHeader.getSenderKeyID(), 986 jweHeader.getCustomParams(), 987 jweHeader.getParsedBase64URL() 988 ); 989 } 990 991 992 /** 993 * Gets the registered parameter names for JWE headers. 994 * 995 * @return The registered parameter names, as an unmodifiable set. 996 */ 997 public static Set<String> getRegisteredParameterNames() { 998 999 return REGISTERED_PARAMETER_NAMES; 1000 } 1001 1002 1003 /** 1004 * Gets the algorithm ({@code alg}) parameter. 1005 * 1006 * @return The algorithm parameter. 1007 */ 1008 @Override 1009 public JWEAlgorithm getAlgorithm() { 1010 1011 return (JWEAlgorithm)super.getAlgorithm(); 1012 } 1013 1014 1015 /** 1016 * Gets the encryption method ({@code enc}) parameter. 1017 * 1018 * @return The encryption method parameter. 1019 */ 1020 public EncryptionMethod getEncryptionMethod() { 1021 1022 return enc; 1023 } 1024 1025 1026 /** 1027 * Gets the Ephemeral Public Key ({@code epk}) parameter. 1028 * 1029 * @return The Ephemeral Public Key parameter, {@code null} if not 1030 * specified. 1031 */ 1032 public JWK getEphemeralPublicKey() { 1033 1034 return epk; 1035 } 1036 1037 1038 /** 1039 * Gets the compression algorithm ({@code zip}) parameter. 1040 * 1041 * @return The compression algorithm parameter, {@code null} if not 1042 * specified. 1043 */ 1044 public CompressionAlgorithm getCompressionAlgorithm() { 1045 1046 return zip; 1047 } 1048 1049 1050 /** 1051 * Gets the agreement PartyUInfo ({@code apu}) parameter. 1052 * 1053 * @return The agreement PartyUInfo parameter, {@code null} if not 1054 * specified. 1055 */ 1056 public Base64URL getAgreementPartyUInfo() { 1057 1058 return apu; 1059 } 1060 1061 1062 /** 1063 * Gets the agreement PartyVInfo ({@code apv}) parameter. 1064 * 1065 * @return The agreement PartyVInfo parameter, {@code null} if not 1066 * specified. 1067 */ 1068 public Base64URL getAgreementPartyVInfo() { 1069 1070 return apv; 1071 } 1072 1073 1074 /** 1075 * Gets the PBES2 salt ({@code p2s}) parameter. 1076 * 1077 * @return The PBES2 salt parameter, {@code null} if not specified. 1078 */ 1079 public Base64URL getPBES2Salt() { 1080 1081 return p2s; 1082 } 1083 1084 1085 /** 1086 * Gets the PBES2 count ({@code p2c}) parameter. 1087 * 1088 * @return The PBES2 count parameter, zero if not specified. 1089 */ 1090 public int getPBES2Count() { 1091 1092 return p2c; 1093 } 1094 1095 1096 /** 1097 * Gets the initialisation vector ({@code iv}) parameter. 1098 * 1099 * @return The initialisation vector, {@code null} if not specified. 1100 */ 1101 public Base64URL getIV() { 1102 1103 return iv; 1104 } 1105 1106 1107 /** 1108 * Gets the authentication tag ({@code tag}) parameter. 1109 * 1110 * @return The authentication tag, {@code null} if not specified. 1111 */ 1112 public Base64URL getAuthTag() { 1113 1114 return tag; 1115 } 1116 1117 1118 /** 1119 * Gets the sender key ID ({@code skid}) parameter. 1120 * 1121 * @return The sender key ID, {@code null} if not specified. 1122 */ 1123 public String getSenderKeyID() { 1124 1125 return skid; 1126 } 1127 1128 1129 @Override 1130 public Set<String> getIncludedParams() { 1131 1132 Set<String> includedParameters = super.getIncludedParams(); 1133 1134 if (enc != null) { 1135 includedParameters.add(HeaderParameterNames.ENCRYPTION_ALGORITHM); 1136 } 1137 1138 if (epk != null) { 1139 includedParameters.add(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY); 1140 } 1141 1142 if (zip != null) { 1143 includedParameters.add(HeaderParameterNames.COMPRESSION_ALGORITHM); 1144 } 1145 1146 if (apu != null) { 1147 includedParameters.add(HeaderParameterNames.AGREEMENT_PARTY_U_INFO); 1148 } 1149 1150 if (apv != null) { 1151 includedParameters.add(HeaderParameterNames.AGREEMENT_PARTY_V_INFO); 1152 } 1153 1154 if (p2s != null) { 1155 includedParameters.add(HeaderParameterNames.PBES2_SALT_INPUT); 1156 } 1157 1158 if (p2c > 0) { 1159 includedParameters.add(HeaderParameterNames.PBES2_COUNT); 1160 } 1161 1162 if (iv != null) { 1163 includedParameters.add(HeaderParameterNames.INITIALIZATION_VECTOR); 1164 } 1165 1166 if (tag != null) { 1167 includedParameters.add(HeaderParameterNames.AUTHENTICATION_TAG); 1168 } 1169 1170 if (skid != null) { 1171 includedParameters.add(HeaderParameterNames.SENDER_KEY_ID); 1172 } 1173 1174 return includedParameters; 1175 } 1176 1177 1178 @Override 1179 public Map<String, Object> toJSONObject() { 1180 1181 Map<String, Object> o = super.toJSONObject(); 1182 1183 if (enc != null) { 1184 o.put(HeaderParameterNames.ENCRYPTION_ALGORITHM, enc.toString()); 1185 } 1186 1187 if (epk != null) { 1188 o.put(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY, epk.toJSONObject()); 1189 } 1190 1191 if (zip != null) { 1192 o.put(HeaderParameterNames.COMPRESSION_ALGORITHM, zip.toString()); 1193 } 1194 1195 if (apu != null) { 1196 o.put(HeaderParameterNames.AGREEMENT_PARTY_U_INFO, apu.toString()); 1197 } 1198 1199 if (apv != null) { 1200 o.put(HeaderParameterNames.AGREEMENT_PARTY_V_INFO, apv.toString()); 1201 } 1202 1203 if (p2s != null) { 1204 o.put(HeaderParameterNames.PBES2_SALT_INPUT, p2s.toString()); 1205 } 1206 1207 if (p2c > 0) { 1208 o.put(HeaderParameterNames.PBES2_COUNT, p2c); 1209 } 1210 1211 if (iv != null) { 1212 o.put(HeaderParameterNames.INITIALIZATION_VECTOR, iv.toString()); 1213 } 1214 1215 if (tag != null) { 1216 o.put(HeaderParameterNames.AUTHENTICATION_TAG, tag.toString()); 1217 } 1218 1219 if (skid != null) { 1220 o.put(HeaderParameterNames.SENDER_KEY_ID, skid); 1221 } 1222 1223 return o; 1224 } 1225 1226 1227 /** 1228 * Parses an encryption method ({@code enc}) parameter from the 1229 * specified JWE header JSON object. 1230 * 1231 * @param json The JSON object to parse. Must not be {@code null}. 1232 * 1233 * @return The encryption method. 1234 * 1235 * @throws ParseException If the {@code enc} parameter couldn't be 1236 * parsed. 1237 */ 1238 private static EncryptionMethod parseEncryptionMethod(final Map<String, Object> json) 1239 throws ParseException { 1240 1241 return EncryptionMethod.parse(JSONObjectUtils.getString(json, HeaderParameterNames.ENCRYPTION_ALGORITHM)); 1242 } 1243 1244 1245 /** 1246 * Parses a JWE header from the specified JSON object. 1247 * 1248 * @param jsonObject The JSON object to parse. Must not be 1249 * {@code null}. 1250 * 1251 * @return The JWE header. 1252 * 1253 * @throws ParseException If the specified JSON object doesn't 1254 * represent a valid JWE header. 1255 */ 1256 public static JWEHeader parse(final Map<String, Object> jsonObject) 1257 throws ParseException { 1258 1259 return parse(jsonObject, null); 1260 } 1261 1262 1263 /** 1264 * Parses a JWE header from the specified JSON object. 1265 * 1266 * @param jsonObject The JSON object to parse. Must not be 1267 * {@code null}. 1268 * @param parsedBase64URL The original parsed Base64URL, {@code null} 1269 * if not applicable. 1270 * 1271 * @return The JWE header. 1272 * 1273 * @throws ParseException If the specified JSON object doesn't 1274 * represent a valid JWE header. 1275 */ 1276 public static JWEHeader parse(final Map<String, Object> jsonObject, 1277 final Base64URL parsedBase64URL) 1278 throws ParseException { 1279 1280 // Get the "enc" parameter 1281 EncryptionMethod enc = parseEncryptionMethod(jsonObject); 1282 1283 JWEHeader.Builder header = new Builder(enc).parsedBase64URL(parsedBase64URL); 1284 1285 // Parse optional + custom parameters 1286 for(final String name: jsonObject.keySet()) { 1287 1288 if(HeaderParameterNames.ALGORITHM.equals(name)) { 1289 header = header.alg(JWEAlgorithm.parse(JSONObjectUtils.getString(jsonObject, name))); 1290 } else if(HeaderParameterNames.ENCRYPTION_ALGORITHM.equals(name)) { 1291 // skip 1292 } else if(HeaderParameterNames.TYPE.equals(name)) { 1293 String typValue = JSONObjectUtils.getString(jsonObject, name); 1294 if (typValue != null) { 1295 header = header.type(new JOSEObjectType(typValue)); 1296 } 1297 } else if(HeaderParameterNames.CONTENT_TYPE.equals(name)) { 1298 header = header.contentType(JSONObjectUtils.getString(jsonObject, name)); 1299 } else if(HeaderParameterNames.CRITICAL.equals(name)) { 1300 List<String> critValues = JSONObjectUtils.getStringList(jsonObject, name); 1301 if (critValues != null) { 1302 header = header.criticalParams(new HashSet<>(critValues)); 1303 } 1304 } else if(HeaderParameterNames.JWK_SET_URL.equals(name)) { 1305 header = header.jwkURL(JSONObjectUtils.getURI(jsonObject, name)); 1306 } else if(HeaderParameterNames.JWK.equals(name)) { 1307 header = header.jwk(CommonSEHeader.parsePublicJWK(JSONObjectUtils.getJSONObject(jsonObject, name))); 1308 } else if(HeaderParameterNames.X_509_CERT_URL.equals(name)) { 1309 header = header.x509CertURL(JSONObjectUtils.getURI(jsonObject, name)); 1310 } else if(HeaderParameterNames.X_509_CERT_SHA_1_THUMBPRINT.equals(name)) { 1311 header = header.x509CertThumbprint(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1312 } else if(HeaderParameterNames.X_509_CERT_SHA_256_THUMBPRINT.equals(name)) { 1313 header = header.x509CertSHA256Thumbprint(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1314 } else if(HeaderParameterNames.X_509_CERT_CHAIN.equals(name)) { 1315 header = header.x509CertChain(X509CertChainUtils.toBase64List(JSONObjectUtils.getJSONArray(jsonObject, name))); 1316 } else if(HeaderParameterNames.KEY_ID.equals(name)) { 1317 header = header.keyID(JSONObjectUtils.getString(jsonObject, name)); 1318 } else if(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY.equals(name)) { 1319 header = header.ephemeralPublicKey(JWK.parse(JSONObjectUtils.getJSONObject(jsonObject, name))); 1320 } else if(HeaderParameterNames.COMPRESSION_ALGORITHM.equals(name)) { 1321 String zipValue = JSONObjectUtils.getString(jsonObject, name); 1322 if (zipValue != null) { 1323 header = header.compressionAlgorithm(new CompressionAlgorithm(zipValue)); 1324 } 1325 } else if(HeaderParameterNames.AGREEMENT_PARTY_U_INFO.equals(name)) { 1326 header = header.agreementPartyUInfo(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1327 } else if(HeaderParameterNames.AGREEMENT_PARTY_V_INFO.equals(name)) { 1328 header = header.agreementPartyVInfo(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1329 } else if(HeaderParameterNames.PBES2_SALT_INPUT.equals(name)) { 1330 header = header.pbes2Salt(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1331 } else if(HeaderParameterNames.PBES2_COUNT.equals(name)) { 1332 header = header.pbes2Count(JSONObjectUtils.getInt(jsonObject, name)); 1333 } else if(HeaderParameterNames.INITIALIZATION_VECTOR.equals(name)) { 1334 header = header.iv(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1335 } else if(HeaderParameterNames.AUTHENTICATION_TAG.equals(name)) { 1336 header = header.authTag(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1337 } else if(HeaderParameterNames.SENDER_KEY_ID.equals(name)) { 1338 header = header.senderKeyID(JSONObjectUtils.getString(jsonObject, name)); 1339 } else { 1340 header = header.customParam(name, jsonObject.get(name)); 1341 } 1342 } 1343 1344 return header.build(); 1345 } 1346 1347 1348 /** 1349 * Parses a JWE header from the specified JSON object string. 1350 * 1351 * @param jsonString The JSON object string to parse. Must not be {@code null}. 1352 * 1353 * @return The JWE header. 1354 * 1355 * @throws ParseException If the specified JSON object string doesn't 1356 * represent a valid JWE header. 1357 */ 1358 public static JWEHeader parse(final String jsonString) 1359 throws ParseException { 1360 1361 return parse(JSONObjectUtils.parse(jsonString), null); 1362 } 1363 1364 1365 /** 1366 * Parses a JWE header from the specified JSON object string. 1367 * 1368 * @param jsonString The JSON string to parse. Must not be 1369 * {@code null}. 1370 * @param parsedBase64URL The original parsed Base64URL, {@code null} 1371 * if not applicable. 1372 * 1373 * @return The JWE header. 1374 * 1375 * @throws ParseException If the specified JSON object string doesn't 1376 * represent a valid JWE header. 1377 */ 1378 public static JWEHeader parse(final String jsonString, 1379 final Base64URL parsedBase64URL) 1380 throws ParseException { 1381 1382 return parse(JSONObjectUtils.parse(jsonString, MAX_HEADER_STRING_LENGTH), parsedBase64URL); 1383 } 1384 1385 1386 /** 1387 * Parses a JWE header from the specified Base64URL. 1388 * 1389 * @param base64URL The Base64URL to parse. Must not be {@code null}. 1390 * 1391 * @return The JWE header. 1392 * 1393 * @throws ParseException If the specified Base64URL doesn't represent 1394 * a valid JWE header. 1395 */ 1396 public static JWEHeader parse(final Base64URL base64URL) 1397 throws ParseException { 1398 1399 return parse(base64URL.decodeToString(), base64URL); 1400 } 1401}