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