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