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