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.jwk; 019 020 021import java.util.*; 022 023import com.nimbusds.jose.Algorithm; 024import com.nimbusds.jose.util.Base64URL; 025import net.jcip.annotations.Immutable; 026 027 028/** 029 * JSON Web Key (JWK) matcher. May be used to ensure a JWK matches a set of 030 * application-specific criteria. 031 * 032 * <p>Supported key matching criteria: 033 * 034 * <ul> 035 * <li>Any, unspecified, one or more key types (typ). 036 * <li>Any, unspecified, one or more key uses (use). 037 * <li>Any, unspecified, one or more key operations (key_ops). 038 * <li>Any, unspecified, one or more key algorithms (alg). 039 * <li>Any, unspecified, one or more key identifiers (kid). 040 * <li>Private only key. 041 * <li>Public only key. 042 * <li>Minimum, maximum or exact key sizes. 043 * <li>Any, unspecified, one or more curves for EC and OKP keys (crv). 044 * <li>X.509 certificate SHA-256 thumbprint. 045 * </ul> 046 * 047 * <p>Matching by JWK thumbprint (RFC 7638), X.509 certificate URL and X.509 048 * certificate chain is not supported. 049 * 050 * @author Vladimir Dzhuvinov 051 * @author Josh Cummings 052 * @version 2018-06-13 053 */ 054@Immutable 055public class JWKMatcher { 056 057 058 /** 059 * The key types to match. 060 */ 061 private final Set<KeyType> types; 062 063 064 /** 065 * The public key uses to match. 066 */ 067 private final Set<KeyUse> uses; 068 069 070 /** 071 * The key operations to match. 072 */ 073 private final Set<KeyOperation> ops; 074 075 076 /** 077 * The algorithms to match. 078 */ 079 private final Set<Algorithm> algs; 080 081 082 /** 083 * The key IDs to match. 084 */ 085 private final Set<String> ids; 086 087 088 /** 089 * {@code true} to match a key with a set use. 090 */ 091 private final boolean hasUse; 092 093 094 /** 095 * {@code true} to match a key with a set ID. 096 */ 097 private final boolean hasID; 098 099 100 /** 101 * {@code true} to match a private key. 102 */ 103 private final boolean privateOnly; 104 105 106 /** 107 * {@code true} to match a public only key. 108 */ 109 private final boolean publicOnly; 110 111 112 /** 113 * The minimum key size in bits, zero implies no minimum size limit. 114 */ 115 private final int minSizeBits; 116 117 118 /** 119 * The maximum key size in bits, zero implies no maximum size limit. 120 */ 121 private final int maxSizeBits; 122 123 124 /** 125 * The key sizes in bits. 126 */ 127 private final Set<Integer> sizesBits; 128 129 130 /** 131 * The curves to match (for EC and OKP keys). 132 */ 133 private final Set<Curve> curves; 134 135 136 /** 137 * The X.509 certificate SHA-256 thumbprints to match. 138 */ 139 private final Set<Base64URL> x5tS256s; 140 141 142 /** 143 * Builder for constructing JWK matchers. 144 * 145 * <p>Example usage: 146 * 147 * <pre> 148 * JWKMatcher matcher = new JWKMatcher().keyID("123").build(); 149 * </pre> 150 */ 151 public static class Builder { 152 153 154 /** 155 * The key types to match. 156 */ 157 private Set<KeyType> types; 158 159 160 /** 161 * The public key uses to match. 162 */ 163 private Set<KeyUse> uses; 164 165 166 /** 167 * The key operations to match. 168 */ 169 private Set<KeyOperation> ops; 170 171 172 /** 173 * The algorithms to match. 174 */ 175 private Set<Algorithm> algs; 176 177 178 /** 179 * The key IDs to match. 180 */ 181 private Set<String> ids; 182 183 184 /** 185 * {@code true} to match a key with a set use. 186 */ 187 private boolean hasUse = false; 188 189 190 /** 191 * {@code true} to match a key with a set ID. 192 */ 193 private boolean hasID = false; 194 195 196 /** 197 * {@code true} to match a private key. 198 */ 199 private boolean privateOnly = false; 200 201 202 /** 203 * {@code true} to match a public only key. 204 */ 205 private boolean publicOnly = false; 206 207 208 /** 209 * The minimum key size in bits, zero implies no minimum size 210 * limit. 211 */ 212 private int minSizeBits = 0; 213 214 215 /** 216 * The maximum key size in bits, zero implies no maximum size 217 * limit. 218 */ 219 private int maxSizeBits = 0; 220 221 222 /** 223 * The key sizes in bits. 224 */ 225 private Set<Integer> sizesBits; 226 227 228 /** 229 * The curves to match (for EC and OKP keys). 230 */ 231 private Set<Curve> curves; 232 233 234 /** 235 * The X.509 certificate SHA-256 thumbprints to match. 236 */ 237 private Set<Base64URL> x5tS256s; 238 239 240 /** 241 * Sets a single key type to match. 242 * 243 * @param kty The key type, {@code null} if not specified. 244 * 245 * @return This builder. 246 */ 247 public Builder keyType(final KeyType kty) { 248 249 if (kty == null) { 250 types = null; 251 } else { 252 types = new HashSet<>(Collections.singletonList(kty)); 253 } 254 255 return this; 256 } 257 258 259 /** 260 * Sets multiple key types to match. 261 * 262 * @param types The key types. 263 * 264 * @return This builder. 265 */ 266 public Builder keyTypes(final KeyType ... types) { 267 268 keyTypes(new LinkedHashSet<>(Arrays.asList(types))); 269 return this; 270 } 271 272 273 /** 274 * Sets multiple key types to match. 275 * 276 * @param types The key types, {@code null} if not specified. 277 * 278 * @return This builder. 279 */ 280 public Builder keyTypes(final Set<KeyType> types) { 281 282 this.types = types; 283 return this; 284 } 285 286 287 /** 288 * Sets a single public key use to match. 289 * 290 * @param use The public key use, {@code null} if not 291 * specified. 292 * 293 * @return This builder. 294 */ 295 public Builder keyUse(final KeyUse use) { 296 297 if (use == null) { 298 uses = null; 299 } else { 300 uses = new HashSet<>(Collections.singletonList(use)); 301 } 302 return this; 303 } 304 305 306 /** 307 * Sets multiple public key uses to match. 308 * 309 * @param uses The public key uses. 310 * 311 * @return This builder. 312 */ 313 public Builder keyUses(final KeyUse... uses) { 314 315 keyUses(new LinkedHashSet<>(Arrays.asList(uses))); 316 return this; 317 } 318 319 320 /** 321 * Sets multiple public key uses to match. 322 * 323 * @param uses The public key uses, {@code null} if not 324 * specified. 325 * 326 * @return This builder. 327 */ 328 public Builder keyUses(final Set<KeyUse> uses) { 329 330 this.uses = uses; 331 return this; 332 } 333 334 335 /** 336 * Sets a single key operation to match. 337 * 338 * @param op The key operation, {@code null} if not specified. 339 * 340 * @return This builder. 341 */ 342 public Builder keyOperation(final KeyOperation op) { 343 344 if (op == null) { 345 ops = null; 346 } else { 347 ops = new HashSet<>(Collections.singletonList(op)); 348 } 349 return this; 350 } 351 352 353 /** 354 * Sets multiple key operations to match. 355 * 356 * @param ops The key operations. 357 * 358 * @return This builder. 359 */ 360 public Builder keyOperations(final KeyOperation... ops) { 361 362 keyOperations(new LinkedHashSet<>(Arrays.asList(ops))); 363 return this; 364 } 365 366 367 /** 368 * Sets multiple key operations to match. 369 * 370 * @param ops The key operations, {@code null} if not 371 * specified. 372 * 373 * @return This builder. 374 */ 375 public Builder keyOperations(final Set<KeyOperation> ops) { 376 377 this.ops = ops; 378 return this; 379 } 380 381 382 /** 383 * Sets a single JOSE algorithm to match. 384 * 385 * @param alg The JOSE algorithm, {@code null} if not 386 * specified. 387 * 388 * @return This builder. 389 */ 390 public Builder algorithm(final Algorithm alg) { 391 392 if (alg == null) { 393 algs = null; 394 } else { 395 algs = new HashSet<>(Collections.singletonList(alg)); 396 } 397 return this; 398 } 399 400 401 /** 402 * Sets multiple JOSE algorithms to match. 403 * 404 * @param algs The JOSE algorithms. 405 * 406 * @return This builder. 407 */ 408 public Builder algorithms(final Algorithm ... algs) { 409 410 algorithms(new LinkedHashSet<>(Arrays.asList(algs))); 411 return this; 412 } 413 414 415 /** 416 * Sets multiple JOSE algorithms to match. 417 * 418 * @param algs The JOSE algorithms, {@code null} if not 419 * specified. 420 * 421 * @return This builder. 422 */ 423 public Builder algorithms(final Set<Algorithm> algs) { 424 425 this.algs = algs; 426 return this; 427 } 428 429 430 /** 431 * Sets a single key ID to match. 432 * 433 * @param id The key ID, {@code null} if not specified. 434 * 435 * @return This builder. 436 */ 437 public Builder keyID(final String id) { 438 439 if (id == null) { 440 ids = null; 441 } else { 442 ids = new HashSet<>(Collections.singletonList(id)); 443 } 444 return this; 445 } 446 447 448 /** 449 * Sets multiple key IDs to match. 450 * 451 * @param ids The key IDs. 452 * 453 * @return This builder. 454 */ 455 public Builder keyIDs(final String ... ids) { 456 457 keyIDs(new LinkedHashSet<>(Arrays.asList(ids))); 458 return this; 459 } 460 461 462 /** 463 * Sets multiple key IDs to match. 464 * 465 * @param ids The key IDs, {@code null} if not specified. 466 * 467 * @return This builder. 468 */ 469 public Builder keyIDs(final Set<String> ids) { 470 471 this.ids = ids; 472 return this; 473 } 474 475 476 /** 477 * Sets key use presence matching. 478 * 479 * @param hasUse {@code true} to match a key with a set use. 480 * 481 * @return This builder. 482 */ 483 public Builder hasKeyUse(final boolean hasUse) { 484 485 this.hasUse = hasUse; 486 return this; 487 } 488 489 490 /** 491 * Sets key ID presence matching. 492 * 493 * @param hasID {@code true} to match a key with a set ID. 494 * 495 * @return This builder. 496 */ 497 public Builder hasKeyID(final boolean hasID) { 498 499 this.hasID = hasID; 500 return this; 501 } 502 503 504 /** 505 * Sets the private key matching policy. 506 * 507 * @param privateOnly {@code true} to match a private key. 508 * 509 * @return This builder. 510 */ 511 public Builder privateOnly(final boolean privateOnly) { 512 513 this.privateOnly = privateOnly; 514 return this; 515 } 516 517 518 /** 519 * Sets the public key matching policy. 520 * 521 * @param publicOnly {@code true} to match a public only key. 522 * 523 * @return This builder. 524 */ 525 public Builder publicOnly(final boolean publicOnly) { 526 527 this.publicOnly = publicOnly; 528 return this; 529 } 530 531 532 /** 533 * Sets the minimal key size. 534 * 535 * @param minSizeBits The minimum key size in bits, zero 536 * implies no minimum key size limit. 537 * 538 * @return This builder. 539 */ 540 public Builder minKeySize(final int minSizeBits) { 541 542 this.minSizeBits = minSizeBits; 543 return this; 544 } 545 546 547 /** 548 * Sets the maximum key size. 549 * 550 * @param maxSizeBits The maximum key size in bits, zero 551 * implies no maximum key size limit. 552 * 553 * @return This builder. 554 */ 555 public Builder maxKeySize(final int maxSizeBits) { 556 557 this.maxSizeBits = maxSizeBits; 558 return this; 559 } 560 561 562 /** 563 * Sets the key size. 564 * 565 * @param keySizeBits The key size in bits, zero if not 566 * specified. 567 * 568 * @return This builder. 569 */ 570 public Builder keySize(final int keySizeBits) { 571 if (keySizeBits <= 0) { 572 sizesBits = null; 573 } else { 574 sizesBits = Collections.singleton(keySizeBits); 575 } 576 return this; 577 } 578 579 580 /** 581 * Sets the key sizes. 582 * 583 * @param keySizesBits The key sizes in bits. 584 * 585 * @return This builder. 586 */ 587 public Builder keySizes(final int... keySizesBits) { 588 Set<Integer> sizesSet = new LinkedHashSet<>(); 589 for (int keySize: keySizesBits) { 590 sizesSet.add(keySize); 591 } 592 keySizes(sizesSet); 593 return this; 594 } 595 596 597 /** 598 * Sets the key sizes. 599 * 600 * @param keySizesBits The key sizes in bits. 601 * 602 * @return This builder. 603 */ 604 public Builder keySizes(final Set<Integer> keySizesBits) { 605 606 this.sizesBits = keySizesBits; 607 return this; 608 } 609 610 611 /** 612 * Sets a single curve to match (for EC and OKP keys). 613 * 614 * @param curve The curve, {@code null} if not specified. 615 * 616 * @return This builder. 617 */ 618 public Builder curve(final Curve curve) { 619 620 if (curve == null) { 621 curves = null; 622 } else { 623 curves = new HashSet<>(Collections.singletonList(curve)); 624 } 625 return this; 626 } 627 628 629 /** 630 * Sets multiple curves to match (for EC and OKP keys). 631 * 632 * @param curves The curves. 633 * 634 * @return This builder. 635 */ 636 public Builder curves(final Curve... curves) { 637 638 curves(new LinkedHashSet<>(Arrays.asList(curves))); 639 return this; 640 } 641 642 643 /** 644 * Sets multiple curves to match (for EC and OKP keys). 645 * 646 * @param curves The curves, {@code null} if not specified. 647 * 648 * @return This builder. 649 */ 650 public Builder curves(final Set<Curve> curves) { 651 652 this.curves = curves; 653 return this; 654 } 655 656 657 /** 658 * Sets a single X.509 certificate SHA-256 thumbprint to match. 659 * 660 * @param x5tS256 The thumbprint, {@code null} if not 661 * specified. 662 * 663 * @return This builder. 664 */ 665 public Builder x509CertSHA256Thumbprint(final Base64URL x5tS256) { 666 667 if (x5tS256 == null) { 668 x5tS256s = null; 669 } else { 670 x5tS256s = Collections.singleton(x5tS256); 671 } 672 return this; 673 } 674 675 /** 676 * Sets multiple X.509 certificate SHA-256 thumbprints to 677 * match. 678 * 679 * @param x5tS256s The thumbprints. 680 * 681 * @return This builder. 682 */ 683 public Builder x509CertSHA256Thumbprints(final Base64URL... x5tS256s) { 684 return x509CertSHA256Thumbprints(new LinkedHashSet<>(Arrays.asList(x5tS256s))); 685 } 686 687 688 /** 689 * Sets multiple X.509 certificate SHA-256 thumbprints to 690 * match. 691 * 692 * @param x5tS256s The thumbprints, {@code null} if not 693 * specified. 694 * 695 * @return This builder. 696 */ 697 public Builder x509CertSHA256Thumbprints(final Set<Base64URL> x5tS256s) { 698 this.x5tS256s = x5tS256s; 699 return this; 700 } 701 702 /** 703 * Builds a new JWK matcher. 704 * 705 * @return The JWK matcher. 706 */ 707 public JWKMatcher build() { 708 709 return new JWKMatcher(types, uses, ops, algs, ids, hasUse, hasID, privateOnly, publicOnly, minSizeBits, maxSizeBits, sizesBits, curves, x5tS256s); 710 } 711 } 712 713 714 /** 715 * Creates a new JSON Web Key (JWK) matcher. 716 * 717 * @param types The key types to match, {@code null} if not 718 * specified. 719 * @param uses The public key uses to match, {@code null} if not 720 * specified. 721 * @param ops The key operations to match, {@code null} if not 722 * specified. 723 * @param algs The JOSE algorithms to match, {@code null} if not 724 * specified. 725 * @param ids The key IDs to match, {@code null} if not 726 * specified. 727 * @param privateOnly {@code true} to match a private key. 728 * @param publicOnly {@code true} to match a public only key. 729 */ 730 @Deprecated 731 public JWKMatcher(final Set<KeyType> types, 732 final Set<KeyUse> uses, 733 final Set<KeyOperation> ops, 734 final Set<Algorithm> algs, 735 final Set<String> ids, 736 final boolean privateOnly, 737 final boolean publicOnly) { 738 739 this(types, uses, ops, algs, ids, privateOnly, publicOnly, 0, 0); 740 } 741 742 743 /** 744 * Creates a new JSON Web Key (JWK) matcher. 745 * 746 * @param types The key types to match, {@code null} if not 747 * specified. 748 * @param uses The public key uses to match, {@code null} if not 749 * specified. 750 * @param ops The key operations to match, {@code null} if not 751 * specified. 752 * @param algs The JOSE algorithms to match, {@code null} if not 753 * specified. 754 * @param ids The key IDs to match, {@code null} if not 755 * specified. 756 * @param privateOnly {@code true} to match a private key. 757 * @param publicOnly {@code true} to match a public only key. 758 * @param minSizeBits The minimum key size in bits, zero implies no 759 * minimum size limit. 760 * @param maxSizeBits The maximum key size in bits, zero implies no 761 * maximum size limit. 762 */ 763 @Deprecated 764 public JWKMatcher(final Set<KeyType> types, 765 final Set<KeyUse> uses, 766 final Set<KeyOperation> ops, 767 final Set<Algorithm> algs, 768 final Set<String> ids, 769 final boolean privateOnly, 770 final boolean publicOnly, 771 final int minSizeBits, 772 final int maxSizeBits) { 773 774 this(types, uses, ops, algs, ids, privateOnly, publicOnly, minSizeBits, maxSizeBits, null); 775 } 776 777 778 /** 779 * Creates a new JSON Web Key (JWK) matcher. 780 * 781 * @param types The key types to match, {@code null} if not 782 * specified. 783 * @param uses The public key uses to match, {@code null} if not 784 * specified. 785 * @param ops The key operations to match, {@code null} if not 786 * specified. 787 * @param algs The JOSE algorithms to match, {@code null} if not 788 * specified. 789 * @param ids The key IDs to match, {@code null} if not 790 * specified. 791 * @param privateOnly {@code true} to match a private key. 792 * @param publicOnly {@code true} to match a public only key. 793 * @param minSizeBits The minimum key size in bits, zero implies no 794 * minimum size limit. 795 * @param maxSizeBits The maximum key size in bits, zero implies no 796 * maximum size limit. 797 * @param curves The curves to match (for EC keys), {@code null} 798 * if not specified. 799 */ 800 @Deprecated 801 public JWKMatcher(final Set<KeyType> types, 802 final Set<KeyUse> uses, 803 final Set<KeyOperation> ops, 804 final Set<Algorithm> algs, 805 final Set<String> ids, 806 final boolean privateOnly, 807 final boolean publicOnly, 808 final int minSizeBits, 809 final int maxSizeBits, 810 final Set<Curve> curves) { 811 812 this(types, uses, ops, algs, ids, privateOnly, publicOnly, minSizeBits, maxSizeBits, null, curves); 813 } 814 815 816 /** 817 * Creates a new JSON Web Key (JWK) matcher. 818 * 819 * @param types The key types to match, {@code null} if not 820 * specified. 821 * @param uses The public key uses to match, {@code null} if not 822 * specified. 823 * @param ops The key operations to match, {@code null} if not 824 * specified. 825 * @param algs The JOSE algorithms to match, {@code null} if not 826 * specified. 827 * @param ids The key IDs to match, {@code null} if not 828 * specified. 829 * @param privateOnly {@code true} to match a private key. 830 * @param publicOnly {@code true} to match a public only key. 831 * @param minSizeBits The minimum key size in bits, zero implies no 832 * minimum size limit. 833 * @param maxSizeBits The maximum key size in bits, zero implies no 834 * maximum size limit. 835 * @param sizesBits The key sizes in bits, {@code null} if not 836 * specified. 837 * @param curves The curves to match (for EC and OKP keys), 838 * {@code null} if not specified. 839 */ 840 @Deprecated 841 public JWKMatcher(final Set<KeyType> types, 842 final Set<KeyUse> uses, 843 final Set<KeyOperation> ops, 844 final Set<Algorithm> algs, 845 final Set<String> ids, 846 final boolean privateOnly, 847 final boolean publicOnly, 848 final int minSizeBits, 849 final int maxSizeBits, 850 final Set<Integer> sizesBits, 851 final Set<Curve> curves) { 852 853 this(types, uses, ops, algs, ids, false, false, privateOnly, publicOnly, minSizeBits, maxSizeBits, sizesBits, curves); 854 } 855 856 857 /** 858 * Creates a new JSON Web Key (JWK) matcher. 859 * 860 * @param types The key types to match, {@code null} if not 861 * specified. 862 * @param uses The public key uses to match, {@code null} if not 863 * specified. 864 * @param ops The key operations to match, {@code null} if not 865 * specified. 866 * @param algs The JOSE algorithms to match, {@code null} if not 867 * specified. 868 * @param ids The key IDs to match, {@code null} if not 869 * specified. 870 * @param hasUse {@code true} to match a key with a set use. 871 * @param hasID {@code true} to match a key with a set ID. 872 * @param privateOnly {@code true} to match a private key. 873 * @param publicOnly {@code true} to match a public only key. 874 * @param minSizeBits The minimum key size in bits, zero implies no 875 * minimum size limit. 876 * @param maxSizeBits The maximum key size in bits, zero implies no 877 * maximum size limit. 878 * @param sizesBits The key sizes in bits, {@code null} if not 879 * specified. 880 * @param curves The curves to match (for EC and OKP keys), 881 * {@code null} if not specified. 882 */ 883 @Deprecated 884 public JWKMatcher(final Set<KeyType> types, 885 final Set<KeyUse> uses, 886 final Set<KeyOperation> ops, 887 final Set<Algorithm> algs, 888 final Set<String> ids, 889 final boolean hasUse, 890 final boolean hasID, 891 final boolean privateOnly, 892 final boolean publicOnly, 893 final int minSizeBits, 894 final int maxSizeBits, 895 final Set<Integer> sizesBits, 896 final Set<Curve> curves) { 897 898 this(types, uses, ops, algs, ids, hasUse, hasID, privateOnly, publicOnly, minSizeBits, maxSizeBits, sizesBits, curves, null); 899 } 900 901 /** 902 * Creates a new JSON Web Key (JWK) matcher. 903 * 904 * @param types The key types to match, {@code null} if not 905 * specified. 906 * @param uses The public key uses to match, {@code null} if not 907 * specified. 908 * @param ops The key operations to match, {@code null} if not 909 * specified. 910 * @param algs The JOSE algorithms to match, {@code null} if not 911 * specified. 912 * @param ids The key IDs to match, {@code null} if not 913 * specified. 914 * @param hasUse {@code true} to match a key with a set use. 915 * @param hasID {@code true} to match a key with a set ID. 916 * @param privateOnly {@code true} to match a private key. 917 * @param publicOnly {@code true} to match a public only key. 918 * @param minSizeBits The minimum key size in bits, zero implies no 919 * minimum size limit. 920 * @param maxSizeBits The maximum key size in bits, zero implies no 921 * maximum size limit. 922 * @param sizesBits The key sizes in bits, {@code null} if not 923 * specified. 924 * @param curves The curves to match (for EC and OKP keys), 925 * {@code null} if not specified. 926 * @param x5tS256s The X.509 certificate thumbprints to match, 927 * {@code null} if not specified. 928 */ 929 public JWKMatcher(final Set<KeyType> types, 930 final Set<KeyUse> uses, 931 final Set<KeyOperation> ops, 932 final Set<Algorithm> algs, 933 final Set<String> ids, 934 final boolean hasUse, 935 final boolean hasID, 936 final boolean privateOnly, 937 final boolean publicOnly, 938 final int minSizeBits, 939 final int maxSizeBits, 940 final Set<Integer> sizesBits, 941 final Set<Curve> curves, 942 final Set<Base64URL> x5tS256s) { 943 944 this.types = types; 945 this.uses = uses; 946 this.ops = ops; 947 this.algs = algs; 948 this.ids = ids; 949 this.hasUse = hasUse; 950 this.hasID = hasID; 951 this.privateOnly = privateOnly; 952 this.publicOnly = publicOnly; 953 this.minSizeBits = minSizeBits; 954 this.maxSizeBits = maxSizeBits; 955 this.sizesBits = sizesBits; 956 this.curves = curves; 957 this.x5tS256s = x5tS256s; 958 } 959 960 961 /** 962 * Returns the key types to match. 963 * 964 * @return The key types, {@code null} if not specified. 965 */ 966 public Set<KeyType> getKeyTypes() { 967 968 return types; 969 } 970 971 972 /** 973 * Returns the public key uses to match. 974 * 975 * @return The public key uses, {@code null} if not specified. 976 */ 977 public Set<KeyUse> getKeyUses() { 978 979 return uses; 980 } 981 982 983 /** 984 * Returns the key operations to match. 985 * 986 * @return The key operations, {@code null} if not specified. 987 */ 988 public Set<KeyOperation> getKeyOperations() { 989 990 return ops; 991 } 992 993 994 /** 995 * Returns the JOSE algorithms to match. 996 * 997 * @return The JOSE algorithms, {@code null} if not specified. 998 */ 999 public Set<Algorithm> getAlgorithms() { 1000 1001 return algs; 1002 } 1003 1004 1005 /** 1006 * Returns the key IDs to match. 1007 * 1008 * @return The key IDs, {@code null} if not specified. 1009 */ 1010 public Set<String> getKeyIDs() { 1011 1012 return ids; 1013 } 1014 1015 1016 /** 1017 * Returns {@code true} if keys with a set use are matched. 1018 * 1019 * @return {@code true} if keys with a set use are matched, else 1020 * {@code false}. 1021 */ 1022 public boolean hasKeyUse() { 1023 1024 return hasUse; 1025 } 1026 1027 1028 /** 1029 * Returns {@code true} if keys with a set use are matched. 1030 * 1031 * @return {@code true} if keys with a set ID are matched, else 1032 * {@code false}. 1033 */ 1034 public boolean hasKeyID() { 1035 1036 return hasID; 1037 } 1038 1039 1040 /** 1041 * Returns {@code true} if only private keys are matched. 1042 * 1043 * @return {@code true} if only private keys are matched, else 1044 * {@code false}. 1045 */ 1046 public boolean isPrivateOnly() { 1047 1048 return privateOnly; 1049 } 1050 1051 1052 /** 1053 * Returns {@code true} if only public keys are matched. 1054 * 1055 * @return {@code true} if only public keys are selected, else 1056 * {@code false}. 1057 */ 1058 public boolean isPublicOnly() { 1059 1060 return publicOnly; 1061 } 1062 1063 1064 /** 1065 * Returns the minimum key size. Use {@link #getMinKeySize()} instead. 1066 * 1067 * @return The minimum key size in bits, zero implies no minimum size 1068 * limit. 1069 */ 1070 @Deprecated 1071 public int getMinSize() { 1072 1073 return getMinKeySize(); 1074 } 1075 1076 1077 /** 1078 * Returns the minimum key size. 1079 * 1080 * @return The minimum key size in bits, zero implies no minimum size 1081 * limit. 1082 */ 1083 public int getMinKeySize() { 1084 1085 return minSizeBits; 1086 } 1087 1088 1089 /** 1090 * Returns the maximum key size. Use {@link #getMaxKeySize()} instead. 1091 * 1092 * @return The maximum key size in bits, zero implies no maximum size 1093 * limit. 1094 */ 1095 @Deprecated 1096 public int getMaxSize() { 1097 1098 return getMaxKeySize(); 1099 } 1100 1101 1102 /** 1103 * Returns the maximum key size. 1104 * 1105 * @return The maximum key size in bits, zero implies no maximum size 1106 * limit. 1107 */ 1108 public int getMaxKeySize() { 1109 1110 return maxSizeBits; 1111 } 1112 1113 1114 /** 1115 * Returns the key sizes. 1116 * 1117 * @return The key sizes in bits, {@code null} if not specified. 1118 */ 1119 public Set<Integer> getKeySizes() { 1120 1121 return sizesBits; 1122 } 1123 1124 1125 /** 1126 * Returns the curves to match (for EC and OKP keys). 1127 * 1128 * @return The curves, {@code null} if not specified. 1129 */ 1130 public Set<Curve> getCurves() { 1131 1132 return curves; 1133 } 1134 1135 /** 1136 * Returns the X.509 certificate SHA-256 thumbprints to match. 1137 * 1138 * @return The thumbprints, {@code null} if not specified. 1139 */ 1140 public Set<Base64URL> getX509CertSHA256Thumbprints() { 1141 1142 return x5tS256s; 1143 } 1144 1145 /** 1146 * Returns {@code true} if the specified JWK matches. 1147 * 1148 * @param key The JSON Web Key (JWK). Must not be {@code null}. 1149 * 1150 * @return {@code true} if the JWK matches, else {@code false}. 1151 */ 1152 public boolean matches(final JWK key) { 1153 1154 if (hasUse && key.getKeyUse() == null) 1155 return false; 1156 1157 if (hasID && (key.getKeyID() == null || key.getKeyID().trim().isEmpty())) 1158 return false; 1159 1160 if (privateOnly && ! key.isPrivate()) 1161 return false; 1162 1163 if (publicOnly && key.isPrivate()) 1164 return false; 1165 1166 if (types != null && ! types.contains(key.getKeyType())) 1167 return false; 1168 1169 if (uses != null && ! uses.contains(key.getKeyUse())) 1170 return false; 1171 1172 if (ops != null) { 1173 1174 if (ops.contains(null) && key.getKeyOperations() == null) { 1175 // pass 1176 } else if (key.getKeyOperations() != null && ops.containsAll(key.getKeyOperations())) { 1177 // pass 1178 } else { 1179 return false; 1180 } 1181 } 1182 1183 if (algs != null && ! algs.contains(key.getAlgorithm())) 1184 return false; 1185 1186 if (ids != null && ! ids.contains(key.getKeyID())) 1187 return false; 1188 1189 if (minSizeBits > 0) { 1190 1191 if (key.size() < minSizeBits) 1192 return false; 1193 } 1194 1195 if (maxSizeBits > 0) { 1196 1197 if (key.size() > maxSizeBits) 1198 return false; 1199 } 1200 1201 if (sizesBits != null) { 1202 if (! sizesBits.contains(key.size())) 1203 return false; 1204 } 1205 1206 if (curves != null) { 1207 1208 if (! (key instanceof CurveBasedJWK)) 1209 return false; 1210 1211 CurveBasedJWK curveBasedJWK = (CurveBasedJWK) key; 1212 1213 if (! curves.contains(curveBasedJWK.getCurve())) 1214 return false; 1215 } 1216 1217 if (x5tS256s != null) { 1218 if (! x5tS256s.contains(key.getX509CertSHA256Thumbprint()) ) 1219 return false; 1220 } 1221 1222 return true; 1223 } 1224 1225 @Override 1226 public String toString() { 1227 StringBuilder sb = new StringBuilder(); 1228 1229 append(sb, "kty", types); 1230 append(sb, "use", uses); 1231 append(sb, "key_ops", ops); 1232 append(sb, "alg", algs); 1233 append(sb, "kid", ids); 1234 1235 if (hasUse) { 1236 sb.append("has_use=true "); 1237 } 1238 1239 if (hasID) { 1240 sb.append("has_id=true "); 1241 } 1242 1243 if (privateOnly) { 1244 sb.append("private_only=true "); 1245 } 1246 1247 if (publicOnly) { 1248 sb.append("public_only=true "); 1249 } 1250 1251 if (minSizeBits > 0) { 1252 sb.append("min_size=" + minSizeBits + " "); 1253 } 1254 1255 if (maxSizeBits > 0) { 1256 sb.append("max_size=" + maxSizeBits + " "); 1257 } 1258 1259 append(sb, "size", sizesBits); 1260 append(sb, "crv", curves); 1261 append(sb, "x5t#S256", x5tS256s); 1262 1263 return sb.toString().trim(); 1264 } 1265 1266 1267 /** 1268 * Appends the specified JWK matcher parameter to a string builder. 1269 * 1270 * @param sb The string builder. Must not be {@code null}. 1271 * @param key The parameter key. Must not be {@code null}. 1272 * @param values The parameter value, {@code null} if not specified. 1273 */ 1274 private static void append(final StringBuilder sb, final String key, final Set<?> values) { 1275 1276 if (values != null) { 1277 1278 sb.append(key); 1279 sb.append('='); 1280 if (values.size() == 1) { 1281 Object value = values.iterator().next(); 1282 if (value == null) { 1283 sb.append("ANY"); 1284 } else { 1285 sb.append(value.toString().trim()); 1286 } 1287 } else { 1288 sb.append(values.toString().trim()); 1289 } 1290 1291 sb.append(' '); 1292 } 1293 } 1294}