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