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