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