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 2021-10-01 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 JWE algorithm. 139 */ 140 private final JWEAlgorithm alg; 141 142 143 /** 144 * The encryption method. 145 */ 146 private final EncryptionMethod enc; 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 * JWK Set URL. 169 */ 170 private URI jku; 171 172 173 /** 174 * 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 with the parameters from 302 * the specified header. 303 * 304 * @param jweHeader The JWE header to use. Must not be 305 * {@code null}. 306 */ 307 public Builder(final JWEHeader jweHeader) { 308 309 this(jweHeader.getAlgorithm(), jweHeader.getEncryptionMethod()); 310 311 typ = jweHeader.getType(); 312 cty = jweHeader.getContentType(); 313 crit = jweHeader.getCriticalParams(); 314 customParams = jweHeader.getCustomParams(); 315 316 jku = jweHeader.getJWKURL(); 317 jwk = jweHeader.getJWK(); 318 x5u = jweHeader.getX509CertURL(); 319 x5t = jweHeader.getX509CertThumbprint(); 320 x5t256 = jweHeader.getX509CertSHA256Thumbprint(); 321 x5c = jweHeader.getX509CertChain(); 322 kid = jweHeader.getKeyID(); 323 324 epk = jweHeader.getEphemeralPublicKey(); 325 zip = jweHeader.getCompressionAlgorithm(); 326 apu = jweHeader.getAgreementPartyUInfo(); 327 apv = jweHeader.getAgreementPartyVInfo(); 328 p2s = jweHeader.getPBES2Salt(); 329 p2c = jweHeader.getPBES2Count(); 330 iv = jweHeader.getIV(); 331 tag = jweHeader.getAuthTag(); 332 333 skid = jweHeader.getSenderKeyID(); 334 335 customParams = jweHeader.getCustomParams(); 336 } 337 338 339 /** 340 * Sets the type ({@code typ}) parameter. 341 * 342 * @param typ The type parameter, {@code null} if not 343 * specified. 344 * 345 * @return This builder. 346 */ 347 public Builder type(final JOSEObjectType typ) { 348 349 this.typ = typ; 350 return this; 351 } 352 353 354 /** 355 * Sets the content type ({@code cty}) parameter. 356 * 357 * @param cty The content type parameter, {@code null} if not 358 * specified. 359 * 360 * @return This builder. 361 */ 362 public Builder contentType(final String cty) { 363 364 this.cty = cty; 365 return this; 366 } 367 368 369 /** 370 * Sets the critical header parameters ({@code crit}) 371 * parameter. 372 * 373 * @param crit The names of the critical header parameters, 374 * empty set or {@code null} if none. 375 * 376 * @return This builder. 377 */ 378 public Builder criticalParams(final Set<String> crit) { 379 380 this.crit = crit; 381 return this; 382 } 383 384 385 /** 386 * Sets the JSON Web Key (JWK) Set URL ({@code jku}) parameter. 387 * 388 * @param jku The JSON Web Key (JWK) Set URL parameter, 389 * {@code null} if not specified. 390 * 391 * @return This builder. 392 */ 393 public Builder jwkURL(final URI jku) { 394 395 this.jku = jku; 396 return this; 397 } 398 399 400 /** 401 * Sets the JSON Web Key (JWK) ({@code jwk}) parameter. 402 * 403 * @param jwk The JSON Web Key (JWK) ({@code jwk}) parameter, 404 * {@code null} if not specified. 405 * 406 * @return This builder. 407 */ 408 public Builder jwk(final JWK jwk) { 409 410 this.jwk = jwk; 411 return this; 412 } 413 414 415 /** 416 * Sets the X.509 certificate URL ({@code x5u}) parameter. 417 * 418 * @param x5u The X.509 certificate URL parameter, {@code null} 419 * if not specified. 420 * 421 * @return This builder. 422 */ 423 public Builder x509CertURL(final URI x5u) { 424 425 this.x5u = x5u; 426 return this; 427 } 428 429 430 /** 431 * Sets the X.509 certificate SHA-1 thumbprint ({@code x5t}) 432 * parameter. 433 * 434 * @param x5t The X.509 certificate SHA-1 thumbprint parameter, 435 * {@code null} if not specified. 436 * 437 * @return This builder. 438 */ 439 @Deprecated 440 public Builder x509CertThumbprint(final Base64URL x5t) { 441 442 this.x5t = x5t; 443 return this; 444 } 445 446 447 /** 448 * Sets the X.509 certificate SHA-256 thumbprint 449 * ({@code x5t#s256}) parameter. 450 * 451 * @param x5t256 The X.509 certificate SHA-256 thumbprint 452 * parameter, {@code null} if not specified. 453 * 454 * @return This builder. 455 */ 456 public Builder x509CertSHA256Thumbprint(final Base64URL x5t256) { 457 458 this.x5t256 = x5t256; 459 return this; 460 } 461 462 463 /** 464 * Sets the X.509 certificate chain parameter ({@code x5c}) 465 * corresponding to the key used to sign the JWS object. 466 * 467 * @param x5c The X.509 certificate chain parameter, 468 * {@code null} if not specified. 469 * 470 * @return This builder. 471 */ 472 public Builder x509CertChain(final List<Base64> x5c) { 473 474 this.x5c = x5c; 475 return this; 476 } 477 478 479 /** 480 * Sets the key ID ({@code kid}) parameter. 481 * 482 * @param kid The key ID parameter, {@code null} if not 483 * specified. 484 * 485 * @return This builder. 486 */ 487 public Builder keyID(final String kid) { 488 489 this.kid = kid; 490 return this; 491 } 492 493 494 /** 495 * Sets the Ephemeral Public Key ({@code epk}) parameter. 496 * 497 * @param epk The Ephemeral Public Key parameter, {@code null} 498 * if not specified. 499 * 500 * @return This builder. 501 */ 502 public Builder ephemeralPublicKey(final JWK epk) { 503 504 this.epk = epk; 505 return this; 506 } 507 508 509 /** 510 * Sets the compression algorithm ({@code zip}) parameter. 511 * 512 * @param zip The compression algorithm parameter, {@code null} 513 * if not specified. 514 * 515 * @return This builder. 516 */ 517 public Builder compressionAlgorithm(final CompressionAlgorithm zip) { 518 519 this.zip = zip; 520 return this; 521 } 522 523 524 /** 525 * Sets the agreement PartyUInfo ({@code apu}) parameter. 526 * 527 * @param apu The agreement PartyUInfo parameter, {@code null} 528 * if not specified. 529 * 530 * @return This builder. 531 */ 532 public Builder agreementPartyUInfo(final Base64URL apu) { 533 534 this.apu = apu; 535 return this; 536 } 537 538 539 /** 540 * Sets the agreement PartyVInfo ({@code apv}) parameter. 541 * 542 * @param apv The agreement PartyVInfo parameter, {@code null} 543 * if not specified. 544 * 545 * @return This builder. 546 */ 547 public Builder agreementPartyVInfo(final Base64URL apv) { 548 549 this.apv = apv; 550 return this; 551 } 552 553 554 /** 555 * Sets the PBES2 salt ({@code p2s}) parameter. 556 * 557 * @param p2s The PBES2 salt parameter, {@code null} if not 558 * specified. 559 * 560 * @return This builder. 561 */ 562 public Builder pbes2Salt(final Base64URL p2s) { 563 564 this.p2s = p2s; 565 return this; 566 } 567 568 569 /** 570 * Sets the PBES2 count ({@code p2c}) parameter. 571 * 572 * @param p2c The PBES2 count parameter, zero if not specified. 573 * Must not be negative. 574 * 575 * @return This builder. 576 */ 577 public Builder pbes2Count(final int p2c) { 578 579 if (p2c < 0) 580 throw new IllegalArgumentException("The PBES2 count parameter must not be negative"); 581 582 this.p2c = p2c; 583 return this; 584 } 585 586 587 /** 588 * Sets the initialisation vector ({@code iv}) parameter. 589 * 590 * @param iv The initialisation vector, {@code null} if not 591 * specified. 592 * 593 * @return This builder. 594 */ 595 public Builder iv(final Base64URL iv) { 596 597 this.iv = iv; 598 return this; 599 } 600 601 602 /** 603 * Sets the authentication tag ({@code tag}) parameter. 604 * 605 * @param tag The authentication tag, {@code null} if not 606 * specified. 607 * 608 * @return This builder. 609 */ 610 public Builder authTag(final Base64URL tag) { 611 612 this.tag = tag; 613 return this; 614 } 615 616 617 /** 618 * Sets the sender key ID ({@code skid}) parameter. 619 * 620 * @param skid The sender Key ID parameter, {@code null} if not 621 * specified. 622 * 623 * @return This builder. 624 */ 625 public Builder senderKeyID(final String skid) { 626 627 this.skid = skid; 628 return this; 629 } 630 631 632 /** 633 * Sets a custom (non-registered) parameter. 634 * 635 * @param name The name of the custom parameter. Must not 636 * match a registered parameter name and must not 637 * be {@code null}. 638 * @param value The value of the custom parameter, should map 639 * to a valid JSON entity, {@code null} if not 640 * specified. 641 * 642 * @return This builder. 643 * 644 * @throws IllegalArgumentException If the specified parameter 645 * name matches a registered 646 * parameter name. 647 */ 648 public Builder customParam(final String name, final Object value) { 649 650 if (getRegisteredParameterNames().contains(name)) { 651 throw new IllegalArgumentException("The parameter name \"" + name + "\" matches a registered name"); 652 } 653 654 if (customParams == null) { 655 customParams = new HashMap<>(); 656 } 657 658 customParams.put(name, value); 659 660 return this; 661 } 662 663 664 /** 665 * Sets the custom (non-registered) parameters. The values must 666 * be serialisable to a JSON entity, otherwise will be ignored. 667 * 668 * @param customParameters The custom parameters, empty map or 669 * {@code null} if none. 670 * 671 * @return This builder. 672 */ 673 public Builder customParams(final Map<String, Object> customParameters) { 674 675 this.customParams = customParameters; 676 return this; 677 } 678 679 680 /** 681 * Sets the parsed Base64URL. 682 * 683 * @param base64URL The parsed Base64URL, {@code null} if the 684 * header is created from scratch. 685 * 686 * @return This builder. 687 */ 688 public Builder parsedBase64URL(final Base64URL base64URL) { 689 690 this.parsedBase64URL = base64URL; 691 return this; 692 } 693 694 695 /** 696 * Builds a new JWE header. 697 * 698 * @return The JWE header. 699 */ 700 public JWEHeader build() { 701 702 return new JWEHeader( 703 alg, enc, typ, cty, crit, 704 jku, jwk, x5u, x5t, x5t256, x5c, kid, 705 epk, zip, apu, apv, p2s, p2c, 706 iv, tag, skid, 707 customParams, parsedBase64URL); 708 } 709 } 710 711 712 /** 713 * The encryption method ({@code enc}) parameter. 714 */ 715 private final EncryptionMethod enc; 716 717 718 /** 719 * The ephemeral public key ({@code epk}) parameter. 720 */ 721 private final JWK epk; 722 723 724 /** 725 * The compression algorithm ({@code zip}) parameter. 726 */ 727 private final CompressionAlgorithm zip; 728 729 730 /** 731 * The agreement PartyUInfo ({@code apu}) parameter. 732 */ 733 private final Base64URL apu; 734 735 736 /** 737 * The agreement PartyVInfo ({@code apv}) parameter. 738 */ 739 private final Base64URL apv; 740 741 742 /** 743 * The PBES2 salt ({@code p2s}) parameter. 744 */ 745 private final Base64URL p2s; 746 747 748 /** 749 * The PBES2 count ({@code p2c}) parameter. 750 */ 751 private final int p2c; 752 753 754 /** 755 * The initialisation vector ({@code iv}) parameter. 756 */ 757 private final Base64URL iv; 758 759 760 /** 761 * The authentication tag ({@code tag}) parameter. 762 */ 763 private final Base64URL tag; 764 765 766 /** 767 * The sender key ID ({@code skid}) parameter. 768 */ 769 private final String skid; 770 771 772 /** 773 * Creates a new minimal JSON Web Encryption (JWE) header. 774 * 775 * <p>Note: Use {@link PlainHeader} to create a header with algorithm 776 * {@link Algorithm#NONE none}. 777 * 778 * @param alg The JWE algorithm parameter. Must not be "none" or 779 * {@code null}. 780 * @param enc The encryption method parameter. Must not be 781 * {@code null}. 782 */ 783 public JWEHeader(final JWEAlgorithm alg, final EncryptionMethod enc) { 784 785 this( 786 alg, enc, 787 null, null, null, null, null, null, null, null, null, null, 788 null, null, null, null, null, 0, 789 null, null, 790 null, null, null); 791 } 792 793 794 /** 795 * Creates a new JSON Web Encryption (JWE) header. 796 * 797 * <p>Note: Use {@link PlainHeader} to create a header with algorithm 798 * {@link Algorithm#NONE none}. 799 * 800 * @param alg The JWE algorithm ({@code alg}) parameter. 801 * Must not be "none" or {@code null}. 802 * @param enc The encryption method parameter. Must not be 803 * {@code null}. 804 * @param typ The type ({@code typ}) parameter, 805 * {@code null} if not specified. 806 * @param cty The content type ({@code cty}) parameter, 807 * {@code null} if not specified. 808 * @param crit The names of the critical header 809 * ({@code crit}) parameters, empty set or 810 * {@code null} if none. 811 * @param jku The JSON Web Key (JWK) Set URL ({@code jku}) 812 * parameter, {@code null} if not specified. 813 * @param jwk The X.509 certificate URL ({@code jwk}) 814 * parameter, {@code null} if not specified. 815 * @param x5u The X.509 certificate URL parameter 816 * ({@code x5u}), {@code null} if not specified. 817 * @param x5t The X.509 certificate SHA-1 thumbprint 818 * ({@code x5t}) parameter, {@code null} if not 819 * specified. 820 * @param x5t256 The X.509 certificate SHA-256 thumbprint 821 * ({@code x5t#S256}) parameter, {@code null} if 822 * not specified. 823 * @param x5c The X.509 certificate chain ({@code x5c}) 824 * parameter, {@code null} if not specified. 825 * @param kid The key ID ({@code kid}) parameter, 826 * {@code null} if not specified. 827 * @param epk The Ephemeral Public Key ({@code epk}) 828 * parameter, {@code null} if not specified. 829 * @param zip The compression algorithm ({@code zip}) 830 * parameter, {@code null} if not specified. 831 * @param apu The agreement PartyUInfo ({@code apu}) 832 * parameter, {@code null} if not specified. 833 * @param apv The agreement PartyVInfo ({@code apv}) 834 * parameter, {@code null} if not specified. 835 * @param p2s The PBES2 salt ({@code p2s}) parameter, 836 * {@code null} if not specified. 837 * @param p2c The PBES2 count ({@code p2c}) parameter, zero 838 * if not specified. Must not be negative. 839 * @param iv The initialisation vector ({@code iv}) 840 * parameter, {@code null} if not specified. 841 * @param tag The authentication tag ({@code tag}) 842 * parameter, {@code null} if not specified. 843 * @param skid The sender key ID ({@code skid}) parameter, 844 * {@code null} if not specified. 845 * @param customParams The custom parameters, empty map or 846 * {@code null} if none. 847 * @param parsedBase64URL The parsed Base64URL, {@code null} if the 848 * header is created from scratch. 849 */ 850 public JWEHeader(final Algorithm alg, 851 final EncryptionMethod enc, 852 final JOSEObjectType typ, 853 final String cty, 854 final Set<String> crit, 855 final URI jku, 856 final JWK jwk, 857 final URI x5u, 858 final Base64URL x5t, 859 final Base64URL x5t256, 860 final List<Base64> x5c, 861 final String kid, 862 final JWK epk, 863 final CompressionAlgorithm zip, 864 final Base64URL apu, 865 final Base64URL apv, 866 final Base64URL p2s, 867 final int p2c, 868 final Base64URL iv, 869 final Base64URL tag, 870 final String skid, 871 final Map<String,Object> customParams, 872 final Base64URL parsedBase64URL) { 873 874 super(alg, typ, cty, crit, jku, jwk, x5u, x5t, x5t256, x5c, kid, customParams, parsedBase64URL); 875 876 if (alg.getName().equals(Algorithm.NONE.getName())) { 877 throw new IllegalArgumentException("The JWE algorithm cannot be \"none\""); 878 } 879 880 if (enc == null) { 881 throw new IllegalArgumentException("The encryption method \"enc\" parameter must not be null"); 882 } 883 884 if (epk != null && epk.isPrivate()) { 885 throw new IllegalArgumentException("Ephemeral public key should not be a private key"); 886 } 887 888 this.enc = enc; 889 890 this.epk = epk; 891 this.zip = zip; 892 this.apu = apu; 893 this.apv = apv; 894 this.p2s = p2s; 895 this.p2c = p2c; 896 this.iv = iv; 897 this.tag = tag; 898 this.skid = skid; 899 } 900 901 902 /** 903 * Deep copy constructor. 904 * 905 * @param jweHeader The JWE header to copy. Must not be {@code null}. 906 */ 907 public JWEHeader(final JWEHeader jweHeader) { 908 909 this( 910 jweHeader.getAlgorithm(), 911 jweHeader.getEncryptionMethod(), 912 jweHeader.getType(), 913 jweHeader.getContentType(), 914 jweHeader.getCriticalParams(), 915 jweHeader.getJWKURL(), 916 jweHeader.getJWK(), 917 jweHeader.getX509CertURL(), 918 jweHeader.getX509CertThumbprint(), 919 jweHeader.getX509CertSHA256Thumbprint(), 920 jweHeader.getX509CertChain(), 921 jweHeader.getKeyID(), 922 jweHeader.getEphemeralPublicKey(), 923 jweHeader.getCompressionAlgorithm(), 924 jweHeader.getAgreementPartyUInfo(), 925 jweHeader.getAgreementPartyVInfo(), 926 jweHeader.getPBES2Salt(), 927 jweHeader.getPBES2Count(), 928 jweHeader.getIV(), 929 jweHeader.getAuthTag(), 930 jweHeader.getSenderKeyID(), 931 jweHeader.getCustomParams(), 932 jweHeader.getParsedBase64URL() 933 ); 934 } 935 936 937 /** 938 * Gets the registered parameter names for JWE headers. 939 * 940 * @return The registered parameter names, as an unmodifiable set. 941 */ 942 public static Set<String> getRegisteredParameterNames() { 943 944 return REGISTERED_PARAMETER_NAMES; 945 } 946 947 948 /** 949 * Gets the algorithm ({@code alg}) parameter. 950 * 951 * @return The algorithm parameter. 952 */ 953 @Override 954 public JWEAlgorithm getAlgorithm() { 955 956 return (JWEAlgorithm)super.getAlgorithm(); 957 } 958 959 960 /** 961 * Gets the encryption method ({@code enc}) parameter. 962 * 963 * @return The encryption method parameter. 964 */ 965 public EncryptionMethod getEncryptionMethod() { 966 967 return enc; 968 } 969 970 971 /** 972 * Gets the Ephemeral Public Key ({@code epk}) parameter. 973 * 974 * @return The Ephemeral Public Key parameter, {@code null} if not 975 * specified. 976 */ 977 public JWK getEphemeralPublicKey() { 978 979 return epk; 980 } 981 982 983 /** 984 * Gets the compression algorithm ({@code zip}) parameter. 985 * 986 * @return The compression algorithm parameter, {@code null} if not 987 * specified. 988 */ 989 public CompressionAlgorithm getCompressionAlgorithm() { 990 991 return zip; 992 } 993 994 995 /** 996 * Gets the agreement PartyUInfo ({@code apu}) parameter. 997 * 998 * @return The agreement PartyUInfo parameter, {@code null} if not 999 * specified. 1000 */ 1001 public Base64URL getAgreementPartyUInfo() { 1002 1003 return apu; 1004 } 1005 1006 1007 /** 1008 * Gets the agreement PartyVInfo ({@code apv}) parameter. 1009 * 1010 * @return The agreement PartyVInfo parameter, {@code null} if not 1011 * specified. 1012 */ 1013 public Base64URL getAgreementPartyVInfo() { 1014 1015 return apv; 1016 } 1017 1018 1019 /** 1020 * Gets the PBES2 salt ({@code p2s}) parameter. 1021 * 1022 * @return The PBES2 salt parameter, {@code null} if not specified. 1023 */ 1024 public Base64URL getPBES2Salt() { 1025 1026 return p2s; 1027 } 1028 1029 1030 /** 1031 * Gets the PBES2 count ({@code p2c}) parameter. 1032 * 1033 * @return The PBES2 count parameter, zero if not specified. 1034 */ 1035 public int getPBES2Count() { 1036 1037 return p2c; 1038 } 1039 1040 1041 /** 1042 * Gets the initialisation vector ({@code iv}) parameter. 1043 * 1044 * @return The initialisation vector, {@code null} if not specified. 1045 */ 1046 public Base64URL getIV() { 1047 1048 return iv; 1049 } 1050 1051 1052 /** 1053 * Gets the authentication tag ({@code tag}) parameter. 1054 * 1055 * @return The authentication tag, {@code null} if not specified. 1056 */ 1057 public Base64URL getAuthTag() { 1058 1059 return tag; 1060 } 1061 1062 1063 /** 1064 * Gets the sender key ID ({@code skid}) parameter. 1065 * 1066 * @return The sender key ID, {@code null} if not specified. 1067 */ 1068 public String getSenderKeyID() { 1069 1070 return skid; 1071 } 1072 1073 1074 @Override 1075 public Set<String> getIncludedParams() { 1076 1077 Set<String> includedParameters = super.getIncludedParams(); 1078 1079 if (enc != null) { 1080 includedParameters.add(HeaderParameterNames.ENCRYPTION_ALGORITHM); 1081 } 1082 1083 if (epk != null) { 1084 includedParameters.add(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY); 1085 } 1086 1087 if (zip != null) { 1088 includedParameters.add(HeaderParameterNames.COMPRESSION_ALGORITHM); 1089 } 1090 1091 if (apu != null) { 1092 includedParameters.add(HeaderParameterNames.AGREEMENT_PARTY_U_INFO); 1093 } 1094 1095 if (apv != null) { 1096 includedParameters.add(HeaderParameterNames.AGREEMENT_PARTY_V_INFO); 1097 } 1098 1099 if (p2s != null) { 1100 includedParameters.add(HeaderParameterNames.PBES2_SALT_INPUT); 1101 } 1102 1103 if (p2c > 0) { 1104 includedParameters.add(HeaderParameterNames.PBES2_COUNT); 1105 } 1106 1107 if (iv != null) { 1108 includedParameters.add(HeaderParameterNames.INITIALIZATION_VECTOR); 1109 } 1110 1111 if (tag != null) { 1112 includedParameters.add(HeaderParameterNames.AUTHENTICATION_TAG); 1113 } 1114 1115 if (skid != null) { 1116 includedParameters.add(HeaderParameterNames.SENDER_KEY_ID); 1117 } 1118 1119 return includedParameters; 1120 } 1121 1122 1123 @Override 1124 public Map<String, Object> toJSONObject() { 1125 1126 Map<String, Object> o = super.toJSONObject(); 1127 1128 if (enc != null) { 1129 o.put(HeaderParameterNames.ENCRYPTION_ALGORITHM, enc.toString()); 1130 } 1131 1132 if (epk != null) { 1133 o.put(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY, epk.toJSONObject()); 1134 } 1135 1136 if (zip != null) { 1137 o.put(HeaderParameterNames.COMPRESSION_ALGORITHM, zip.toString()); 1138 } 1139 1140 if (apu != null) { 1141 o.put(HeaderParameterNames.AGREEMENT_PARTY_U_INFO, apu.toString()); 1142 } 1143 1144 if (apv != null) { 1145 o.put(HeaderParameterNames.AGREEMENT_PARTY_V_INFO, apv.toString()); 1146 } 1147 1148 if (p2s != null) { 1149 o.put(HeaderParameterNames.PBES2_SALT_INPUT, p2s.toString()); 1150 } 1151 1152 if (p2c > 0) { 1153 o.put(HeaderParameterNames.PBES2_COUNT, p2c); 1154 } 1155 1156 if (iv != null) { 1157 o.put(HeaderParameterNames.INITIALIZATION_VECTOR, iv.toString()); 1158 } 1159 1160 if (tag != null) { 1161 o.put(HeaderParameterNames.AUTHENTICATION_TAG, tag.toString()); 1162 } 1163 1164 if (skid != null) { 1165 o.put(HeaderParameterNames.SENDER_KEY_ID, skid); 1166 } 1167 1168 return o; 1169 } 1170 1171 1172 /** 1173 * Parses an encryption method ({@code enc}) parameter from the 1174 * specified JWE header JSON object. 1175 * 1176 * @param json The JSON object to parse. Must not be {@code null}. 1177 * 1178 * @return The encryption method. 1179 * 1180 * @throws ParseException If the {@code enc} parameter couldn't be 1181 * parsed. 1182 */ 1183 private static EncryptionMethod parseEncryptionMethod(final Map<String, Object> json) 1184 throws ParseException { 1185 1186 return EncryptionMethod.parse(JSONObjectUtils.getString(json, HeaderParameterNames.ENCRYPTION_ALGORITHM)); 1187 } 1188 1189 1190 /** 1191 * Parses a JWE header from the specified JSON object. 1192 * 1193 * @param jsonObject The JSON object to parse. Must not be 1194 * {@code null}. 1195 * 1196 * @return The JWE header. 1197 * 1198 * @throws ParseException If the specified JSON object doesn't 1199 * represent a valid JWE header. 1200 */ 1201 public static JWEHeader parse(final Map<String, Object> jsonObject) 1202 throws ParseException { 1203 1204 return parse(jsonObject, null); 1205 } 1206 1207 1208 /** 1209 * Parses a JWE header from the specified JSON object. 1210 * 1211 * @param jsonObject The JSON object to parse. Must not be 1212 * {@code null}. 1213 * @param parsedBase64URL The original parsed Base64URL, {@code null} 1214 * if not applicable. 1215 * 1216 * @return The JWE header. 1217 * 1218 * @throws ParseException If the specified JSON object doesn't 1219 * represent a valid JWE header. 1220 */ 1221 public static JWEHeader parse(final Map<String, Object> jsonObject, 1222 final Base64URL parsedBase64URL) 1223 throws ParseException { 1224 1225 // Get the "alg" parameter 1226 Algorithm alg = Header.parseAlgorithm(jsonObject); 1227 1228 if (! (alg instanceof JWEAlgorithm)) { 1229 throw new ParseException("The algorithm \"alg\" header parameter must be for encryption", 0); 1230 } 1231 1232 // Get the "enc" parameter 1233 EncryptionMethod enc = parseEncryptionMethod(jsonObject); 1234 1235 JWEHeader.Builder header = new Builder((JWEAlgorithm)alg, enc).parsedBase64URL(parsedBase64URL); 1236 1237 // Parse optional + custom parameters 1238 for(final String name: jsonObject.keySet()) { 1239 1240 if(HeaderParameterNames.ALGORITHM.equals(name)) { 1241 // skip 1242 } else if(HeaderParameterNames.ENCRYPTION_ALGORITHM.equals(name)) { 1243 // skip 1244 } else if(HeaderParameterNames.TYPE.equals(name)) { 1245 String typValue = JSONObjectUtils.getString(jsonObject, name); 1246 if (typValue != null) { 1247 header = header.type(new JOSEObjectType(typValue)); 1248 } 1249 } else if(HeaderParameterNames.CONTENT_TYPE.equals(name)) { 1250 header = header.contentType(JSONObjectUtils.getString(jsonObject, name)); 1251 } else if(HeaderParameterNames.CRITICAL.equals(name)) { 1252 List<String> critValues = JSONObjectUtils.getStringList(jsonObject, name); 1253 if (critValues != null) { 1254 header = header.criticalParams(new HashSet<>(critValues)); 1255 } 1256 } else if(HeaderParameterNames.JWK_SET_URL.equals(name)) { 1257 header = header.jwkURL(JSONObjectUtils.getURI(jsonObject, name)); 1258 } else if(HeaderParameterNames.JWK.equals(name)) { 1259 Map<String, Object> jwkObject = JSONObjectUtils.getJSONObject(jsonObject, name); 1260 if (jwkObject != null) { 1261 header = header.jwk(JWK.parse(jwkObject)); 1262 } 1263 } else if(HeaderParameterNames.X_509_CERT_URL.equals(name)) { 1264 header = header.x509CertURL(JSONObjectUtils.getURI(jsonObject, name)); 1265 } else if(HeaderParameterNames.X_509_CERT_SHA_1_THUMBPRINT.equals(name)) { 1266 header = header.x509CertThumbprint(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1267 } else if(HeaderParameterNames.X_509_CERT_SHA_256_THUMBPRINT.equals(name)) { 1268 header = header.x509CertSHA256Thumbprint(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1269 } else if(HeaderParameterNames.X_509_CERT_CHAIN.equals(name)) { 1270 header = header.x509CertChain(X509CertChainUtils.toBase64List(JSONObjectUtils.getJSONArray(jsonObject, name))); 1271 } else if(HeaderParameterNames.KEY_ID.equals(name)) { 1272 header = header.keyID(JSONObjectUtils.getString(jsonObject, name)); 1273 } else if(HeaderParameterNames.EPHEMERAL_PUBLIC_KEY.equals(name)) { 1274 header = header.ephemeralPublicKey(JWK.parse(JSONObjectUtils.getJSONObject(jsonObject, name))); 1275 } else if(HeaderParameterNames.COMPRESSION_ALGORITHM.equals(name)) { 1276 String zipValue = JSONObjectUtils.getString(jsonObject, name); 1277 if (zipValue != null) { 1278 header = header.compressionAlgorithm(new CompressionAlgorithm(zipValue)); 1279 } 1280 } else if(HeaderParameterNames.AGREEMENT_PARTY_U_INFO.equals(name)) { 1281 header = header.agreementPartyUInfo(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1282 } else if(HeaderParameterNames.AGREEMENT_PARTY_V_INFO.equals(name)) { 1283 header = header.agreementPartyVInfo(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1284 } else if(HeaderParameterNames.PBES2_SALT_INPUT.equals(name)) { 1285 header = header.pbes2Salt(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1286 } else if(HeaderParameterNames.PBES2_COUNT.equals(name)) { 1287 header = header.pbes2Count(JSONObjectUtils.getInt(jsonObject, name)); 1288 } else if(HeaderParameterNames.INITIALIZATION_VECTOR.equals(name)) { 1289 header = header.iv(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1290 } else if(HeaderParameterNames.AUTHENTICATION_TAG.equals(name)) { 1291 header = header.authTag(Base64URL.from(JSONObjectUtils.getString(jsonObject, name))); 1292 } else if(HeaderParameterNames.SENDER_KEY_ID.equals(name)) { 1293 header = header.senderKeyID(JSONObjectUtils.getString(jsonObject, name)); 1294 } else { 1295 header = header.customParam(name, jsonObject.get(name)); 1296 } 1297 } 1298 1299 return header.build(); 1300 } 1301 1302 1303 /** 1304 * Parses a JWE header from the specified JSON object string. 1305 * 1306 * @param jsonString The JSON object string to parse. Must not be {@code null}. 1307 * 1308 * @return The JWE header. 1309 * 1310 * @throws ParseException If the specified JSON object string doesn't 1311 * represent a valid JWE header. 1312 */ 1313 public static JWEHeader parse(final String jsonString) 1314 throws ParseException { 1315 1316 return parse(JSONObjectUtils.parse(jsonString), null); 1317 } 1318 1319 1320 /** 1321 * Parses a JWE header from the specified JSON object string. 1322 * 1323 * @param jsonString The JSON string to parse. Must not be 1324 * {@code null}. 1325 * @param parsedBase64URL The original parsed Base64URL, {@code null} 1326 * if not applicable. 1327 * 1328 * @return The JWE header. 1329 * 1330 * @throws ParseException If the specified JSON object string doesn't 1331 * represent a valid JWE header. 1332 */ 1333 public static JWEHeader parse(final String jsonString, 1334 final Base64URL parsedBase64URL) 1335 throws ParseException { 1336 1337 return parse(JSONObjectUtils.parse(jsonString, MAX_HEADER_STRING_LENGTH), parsedBase64URL); 1338 } 1339 1340 1341 /** 1342 * Parses a JWE header from the specified Base64URL. 1343 * 1344 * @param base64URL The Base64URL to parse. Must not be {@code null}. 1345 * 1346 * @return The JWE header. 1347 * 1348 * @throws ParseException If the specified Base64URL doesn't represent 1349 * a valid JWE header. 1350 */ 1351 public static JWEHeader parse(final Base64URL base64URL) 1352 throws ParseException { 1353 1354 return parse(base64URL.decodeToString(), base64URL); 1355 } 1356}