001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 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.openid.connect.sdk.federation.entities; 019 020 021import java.util.*; 022 023import net.minidev.json.JSONArray; 024import net.minidev.json.JSONObject; 025 026import com.nimbusds.jose.jwk.JWKSet; 027import com.nimbusds.jwt.JWTClaimsSet; 028import com.nimbusds.oauth2.sdk.ParseException; 029import com.nimbusds.oauth2.sdk.as.AuthorizationServerMetadata; 030import com.nimbusds.oauth2.sdk.client.ClientMetadata; 031import com.nimbusds.oauth2.sdk.id.Identifier; 032import com.nimbusds.oauth2.sdk.id.Issuer; 033import com.nimbusds.oauth2.sdk.id.Subject; 034import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 035import com.nimbusds.oauth2.sdk.util.MapUtils; 036import com.nimbusds.openid.connect.sdk.federation.policy.MetadataPolicy; 037import com.nimbusds.openid.connect.sdk.federation.policy.language.PolicyViolationException; 038import com.nimbusds.openid.connect.sdk.federation.trust.constraints.TrustChainConstraints; 039import com.nimbusds.openid.connect.sdk.federation.trust.marks.TrustMarkEntry; 040import com.nimbusds.openid.connect.sdk.federation.trust.marks.TrustMarkIssuerMetadata; 041import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata; 042import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata; 043 044 045/** 046 * Federation entity statement claims set, serialisable to a JSON object. 047 * 048 * <p>Example claims set: 049 * 050 * <pre> 051 * { 052 * "iss": "https://feide.no", 053 * "sub": "https://ntnu.no", 054 * "iat": 1516239022, 055 * "exp": 1516298022, 056 * "crit": ["jti"], 057 * "jti": "7l2lncFdY6SlhNia", 058 * "policy_language_crit": ["regexp"], 059 * "metadata": { 060 * "openid_provider": { 061 * "issuer": "https://ntnu.no", 062 * "organization_name": "NTNU", 063 * }, 064 * "oauth_client": { 065 * "organization_name": "NTNU" 066 * } 067 * }, 068 * "metadata_policy": { 069 * "openid_provider": { 070 * "id_token_signing_alg_values_supported": { 071 * "subset_of": ["RS256", "RS384", "RS512"] 072 * }, 073 * "op_policy_uri": { 074 * "regexp": "^https:\/\/[\\w-]+\\.example\\.com\/[\\w-]+\\.html"} 075 * }, 076 * "oauth_client": { 077 * "grant_types": { 078 * "subset_of": ["authorization_code", "client_credentials"]}, 079 * "scope": { 080 * "subset_of": ["openid", "profile", "email", "phone"]} 081 * } 082 * }, 083 * "constraints": { 084 * "max_path_length": 2 085 * }, 086 * "jwks": { 087 * "keys": [ 088 * { 089 * "alg": "RS256", 090 * "e": "AQAB", 091 * "key_ops": ["verify"], 092 * "kid": "key1", 093 * "kty": "RSA", 094 * "n": "pnXBOusEANuug6ewezb9J_...", 095 * "use": "sig" 096 * } 097 * ] 098 * } 099 * } 100 * </pre> 101 * 102 * <p>Related specifications: 103 * 104 * <ul> 105 * <li>OpenID Connect Federation 1.0, section 3.1. 106 * </ul> 107 */ 108public class EntityStatementClaimsSet extends CommonFederationClaimsSet { 109 110 111 /** 112 * The JWK set claim name. 113 */ 114 public static final String JWKS_CLAIM_NAME = "jwks"; 115 116 117 /** 118 * The authority hints claim name. 119 */ 120 public static final String AUTHORITY_HINTS_CLAIM_NAME = "authority_hints"; 121 122 123 /** 124 * The metadata policy claim name. 125 */ 126 public static final String METADATA_POLICY_CLAIM_NAME = "metadata_policy"; 127 128 129 /** 130 * The assumed trust anchor in a explicit client registration. Intended 131 * for entity statements issued by an OP for RP performing explicit 132 * client registration only. 133 */ 134 public static final String TRUST_ANCHOR_ID_CLAIM_NAME = "trust_anchor_id"; 135 136 137 /** 138 * The constraints claim name. 139 */ 140 public static final String CONSTRAINTS_CLAIM_NAME = "constraints"; 141 142 143 /** 144 * The trust marks issuers claim name. 145 */ 146 public static final String TRUST_MARKS_ISSUERS_CLAIM_NAME = "trust_marks_issuers"; 147 148 149 /** 150 * The critical claim name. 151 */ 152 public static final String CRITICAL_CLAIM_NAME = "crit"; 153 154 155 /** 156 * The policy critical claim name. 157 */ 158 public static final String POLICY_LANGUAGE_CRITICAL_CLAIM_NAME = "policy_language_crit"; 159 160 161 /** 162 * The names of the standard top-level claims. 163 */ 164 private static final Set<String> STD_CLAIM_NAMES; 165 166 static { 167 Set<String> claimNames = new HashSet<>(); 168 claimNames.add(ISS_CLAIM_NAME); 169 claimNames.add(SUB_CLAIM_NAME); 170 claimNames.add(IAT_CLAIM_NAME); 171 claimNames.add(EXP_CLAIM_NAME); 172 claimNames.add(JWKS_CLAIM_NAME); 173 claimNames.add(AUD_CLAIM_NAME); 174 claimNames.add(AUTHORITY_HINTS_CLAIM_NAME); 175 claimNames.add(METADATA_CLAIM_NAME); 176 claimNames.add(METADATA_POLICY_CLAIM_NAME); 177 claimNames.add(CONSTRAINTS_CLAIM_NAME); 178 claimNames.add(CRITICAL_CLAIM_NAME); 179 claimNames.add(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME); 180 claimNames.add(TRUST_MARKS_CLAIM_NAME); 181 claimNames.add(TRUST_MARKS_ISSUERS_CLAIM_NAME); 182 claimNames.add(TRUST_ANCHOR_ID_CLAIM_NAME); 183 STD_CLAIM_NAMES = Collections.unmodifiableSet(claimNames); 184 } 185 186 187 /** 188 * Gets the names of the standard top-level claims. 189 * 190 * @return The names of the standard top-level claims (read-only set). 191 */ 192 public static Set<String> getStandardClaimNames() { 193 194 return STD_CLAIM_NAMES; 195 } 196 197 198 /** 199 * Creates a new federation entity statement claims set with the 200 * minimum required claims. 201 * 202 * @param iss The issuer. Must not be {@code null}. 203 * @param sub The subject. Must not be {@code null}. 204 * @param iat The issue time. Must not be {@code null}. 205 * @param exp The expiration time. Must not be {@code null}. 206 * @param jwks The entity public JWK set, {@code null} if not required. 207 */ 208 public EntityStatementClaimsSet(final Issuer iss, 209 final Subject sub, 210 final Date iat, 211 final Date exp, 212 final JWKSet jwks) { 213 214 this(new EntityID(iss.getValue()), new EntityID(sub.getValue()), iat, exp, jwks); 215 } 216 217 218 /** 219 * Creates a new federation entity statement claims set with the 220 * minimum required claims. 221 * 222 * @param iss The issuer. Must not be {@code null}. 223 * @param sub The subject. Must not be {@code null}. 224 * @param iat The issue time. Must not be {@code null}. 225 * @param exp The expiration time. Must not be {@code null}. 226 * @param jwks The entity public JWK set, {@code null} if not required. 227 */ 228 public EntityStatementClaimsSet(final EntityID iss, 229 final EntityID sub, 230 final Date iat, 231 final Date exp, 232 final JWKSet jwks) { 233 234 setClaim(ISS_CLAIM_NAME, iss.getValue()); 235 setClaim(SUB_CLAIM_NAME, sub.getValue()); 236 237 if (iat == null) { 238 throw new IllegalArgumentException("The iat (issued-at) claim must not be null"); 239 } 240 setDateClaim(IAT_CLAIM_NAME, iat); 241 242 if (exp == null) { 243 throw new IllegalArgumentException("The exp (expiration) claim must not be null"); 244 } 245 setDateClaim(EXP_CLAIM_NAME, exp); 246 247 if (jwks != null) { 248 setClaim(JWKS_CLAIM_NAME, new JSONObject(jwks.toJSONObject(true))); // public JWKs only 249 } 250 } 251 252 253 /** 254 * Creates a new federation entity statement claims set from the 255 * specified JWT claims set. 256 * 257 * @param jwtClaimsSet The JWT claims set. Must not be {@code null}. 258 * 259 * @throws ParseException If the JWT claims set doesn't represent a 260 * valid federation entity statement claims set. 261 */ 262 public EntityStatementClaimsSet(final JWTClaimsSet jwtClaimsSet) 263 throws ParseException { 264 265 super(JSONObjectUtils.toJSONObject(jwtClaimsSet)); 266 267 validateRequiredClaimsPresence(); 268 } 269 270 271 /** 272 * Validates this claims set for having all minimum required claims for 273 * an entity statement. If a {@link #isSelfStatement() selt-statement} 274 * check for the {@link #hasMetadata() presence of metadata}. If 275 * {@link #getCriticalExtensionClaims() critical extension claims} are 276 * listed their presence is also checked. 277 * 278 * @throws ParseException If the validation failed and a required claim 279 * is missing. 280 */ 281 public void validateRequiredClaimsPresence() 282 throws ParseException { 283 284 super.validateRequiredClaimsPresence(); 285 286 // jwks always required for self-statements 287 if (isSelfStatement() && getJWKSet() == null) { 288 throw new ParseException("Missing jwks (JWK set) claim"); 289 } 290 291 if (isSelfStatement() && ! hasMetadata()) { 292 throw new ParseException("Missing required metadata claim for self-statement"); 293 } 294 295 List<String> crit = getCriticalExtensionClaims(); 296 297 if (crit != null) { 298 for (String claimName: crit) { 299 if (getClaim(claimName) == null) { 300 throw new ParseException("Missing critical " + claimName + " claim"); 301 } 302 } 303 } 304 } 305 306 307 /** 308 * Returns {@code true} if this is a self-statement (issuer and subject 309 * match). 310 * 311 * @return {@code true} for a self-statement, {@code false} if not. 312 */ 313 public boolean isSelfStatement() { 314 315 Issuer issuer = getIssuer(); 316 Subject subject = getSubject(); 317 318 return issuer != null && subject != null && issuer.getValue().equals(subject.getValue()); 319 } 320 321 322 /** 323 * Gets the entity JWK set. Corresponds to the {@code jwks} claim. 324 * 325 * @return The entity JWK set, {@code null} if not specified or parsing 326 * failed. 327 */ 328 public JWKSet getJWKSet() { 329 330 JSONObject jwkSetJSONObject = getJSONObjectClaim(JWKS_CLAIM_NAME); 331 if (jwkSetJSONObject == null) { 332 return null; 333 } 334 try { 335 return JWKSet.parse(jwkSetJSONObject); 336 } catch (java.text.ParseException e) { 337 return null; 338 } 339 } 340 341 342 /** 343 * Gets the entity IDs of the intermediate entities or trust anchors. 344 * Corresponds to the {@code authority_hints} claim. 345 * 346 * @return The entity IDs, {@code null} or empty list for a trust 347 * anchor, or if parsing failed. 348 */ 349 public List<EntityID> getAuthorityHints() { 350 351 List<String> strings = getStringListClaim(AUTHORITY_HINTS_CLAIM_NAME); 352 353 if (strings == null) { 354 return null; 355 } 356 357 List<EntityID> trustChain = new LinkedList<>(); 358 for (String s: strings) { 359 trustChain.add(new EntityID(s)); 360 } 361 return trustChain; 362 } 363 364 365 /** 366 * Sets the entity IDs of the intermediate entities or trust anchors. 367 * Corresponds to the {@code authority_hints} claim. 368 * 369 * @param trustChain The entity IDs, {@code null} or empty list for a 370 * trust anchor. 371 */ 372 public void setAuthorityHints(final List<EntityID> trustChain) { 373 374 if (trustChain != null) { 375 setClaim(AUTHORITY_HINTS_CLAIM_NAME, Identifier.toStringList(trustChain)); 376 } else { 377 setClaim(AUTHORITY_HINTS_CLAIM_NAME, null); 378 } 379 } 380 381 382 /** 383 * Returns {@code true} if a metadata field is present. Corresponds to 384 * the {@code metadata} claim. 385 * 386 * @return {@code true} if a metadata field for an OpenID relying 387 * party, an OpenID provider, an OAuth authorisation server, an 388 * OAuth client, an OAuth protected resource, a federation 389 * entity, or a trust mark issuer is present. 390 */ 391 public boolean hasMetadata() { 392 393 JSONObject metadataObject = getJSONObjectClaim(METADATA_CLAIM_NAME); 394 395 if (MapUtils.isEmpty(metadataObject)) { 396 return false; 397 } 398 399 if (metadataObject.get(EntityType.OPENID_RELYING_PARTY.getValue()) != null) return true; 400 if (metadataObject.get(EntityType.OPENID_PROVIDER.getValue()) != null) return true; 401 if (metadataObject.get(EntityType.OAUTH_AUTHORIZATION_SERVER.getValue()) != null) return true; 402 if (metadataObject.get(EntityType.OAUTH_CLIENT.getValue()) != null) return true; 403 if (metadataObject.get(EntityType.OAUTH_RESOURCE.getValue()) != null) return true; 404 if (metadataObject.get(EntityType.FEDERATION_ENTITY.getValue()) != null) return true; 405 if (metadataObject.get(EntityType.TRUST_MARK_ISSUER.getValue()) != null) return true; 406 407 return false; 408 } 409 410 411 /** 412 * Gets the metadata for the specified entity type. Use a typed getter, 413 * such as {@link #getRPMetadata}, when available. Corresponds to the 414 * {@code metadata} claim. 415 * 416 * @param type The entity type. Must not be {@code null}. 417 * 418 * @return The metadata, {@code null} if not specified or if parsing 419 * failed. 420 */ 421 public JSONObject getMetadata(final EntityType type) { 422 423 JSONObject o = getJSONObjectClaim(METADATA_CLAIM_NAME); 424 425 if (o == null) { 426 return null; 427 } 428 429 try { 430 return JSONObjectUtils.getJSONObject(o, type.getValue(), null); 431 } catch (ParseException e) { 432 return null; 433 } 434 } 435 436 437 /** 438 * Sets the metadata for the specified entity type. Use a typed setter, 439 * such as {@link #setRPMetadata}, when available. Corresponds to the 440 * {@code metadata} claim. 441 * 442 * @param type The type. Must not be {@code null}. 443 * @param metadata The metadata, {@code null} if not specified. 444 */ 445 public void setMetadata(final EntityType type, final JSONObject metadata) { 446 447 JSONObject o = getJSONObjectClaim(METADATA_CLAIM_NAME); 448 449 if (o == null) { 450 if (metadata == null) { 451 return; // nothing to clear 452 } 453 o = new JSONObject(); 454 } 455 456 o.put(type.getValue(), metadata); 457 458 setClaim(METADATA_CLAIM_NAME, o); 459 } 460 461 462 /** 463 * Sets the OpenID relying party metadata if present for this entity. 464 * Corresponds to the {@code metadata.openid_relying_party} claim. 465 * 466 * @param rpMetadata The RP metadata, {@code null} if not specified. 467 */ 468 public void setRPMetadata(final OIDCClientMetadata rpMetadata) { 469 470 JSONObject o = rpMetadata != null ? rpMetadata.toJSONObject() : null; 471 setMetadata(EntityType.OPENID_RELYING_PARTY, o); 472 } 473 474 475 /** 476 * Gets the OpenID provider metadata if present for this entity. 477 * Corresponds to the {@code metadata.openid_provider} claim. 478 * 479 * @param opMetadata The OP metadata, {@code null} if not specified. 480 */ 481 public void setOPMetadata(final OIDCProviderMetadata opMetadata) { 482 483 JSONObject o = opMetadata != null ? opMetadata.toJSONObject() : null; 484 setMetadata(EntityType.OPENID_PROVIDER, o); 485 } 486 487 488 /** 489 * Sets the OAuth 2.0 client metadata if present for this entity. 490 * Corresponds to the {@code metadata.oauth_client} claim. 491 * 492 * @param clientMetadata The client metadata, {@code null} if not 493 * specified. 494 */ 495 public void setOAuthClientMetadata(final ClientMetadata clientMetadata) { 496 497 JSONObject o = clientMetadata != null ? clientMetadata.toJSONObject() : null; 498 setMetadata(EntityType.OAUTH_CLIENT, o); 499 } 500 501 502 /** 503 * Sets the OAuth 2.0 authorisation server metadata if present for this 504 * entity. Corresponds to the 505 * {@code metadata.oauth_authorization_server} claim. 506 * 507 * @param asMetadata The AS metadata, {@code null} if not specified. 508 */ 509 public void setASMetadata(final AuthorizationServerMetadata asMetadata) { 510 511 JSONObject o = asMetadata != null ? asMetadata.toJSONObject() : null; 512 setMetadata(EntityType.OAUTH_AUTHORIZATION_SERVER, o); 513 } 514 515 516 /** 517 * Sets the federation entity metadata if present for this entity. 518 * Corresponds to the {@code metadata.federation_entity} claim. 519 * 520 * @param entityMetadata The federation entity metadata, {@code null} 521 * if not specified. 522 */ 523 public void setFederationEntityMetadata(final FederationEntityMetadata entityMetadata) { 524 525 JSONObject o = entityMetadata != null ? entityMetadata.toJSONObject() : null; 526 setMetadata(EntityType.FEDERATION_ENTITY, o); 527 } 528 529 530 /** 531 * Sets the trust mark issuer metadata for this entity. 532 * Corresponds to the {@code metadata.trust_mark_issuer} claim. 533 * 534 * @param trustMarkIssuerMetadata The trust mark issuer metadata, 535 * {@code null} if not specified. 536 */ 537 @Deprecated 538 public void setTrustMarkIssuerMetadata(final TrustMarkIssuerMetadata trustMarkIssuerMetadata) { 539 540 JSONObject o = trustMarkIssuerMetadata != null ? trustMarkIssuerMetadata.toJSONObject() : null; 541 setMetadata(EntityType.TRUST_MARK_ISSUER, o); 542 } 543 544 545 /** 546 * Gets the complete metadata policy JSON object. Corresponds to the 547 * {@code metadata_policy} claim. 548 * 549 * @return The metadata policy JSON object, {@code null} if not 550 * specified or if parsing failed. 551 */ 552 public JSONObject getMetadataPolicyJSONObject() { 553 554 return getJSONObjectClaim(METADATA_POLICY_CLAIM_NAME); 555 } 556 557 558 /** 559 * Sets the complete metadata policy JSON object. Corresponds to the 560 * {@code metadata_policy} claim. 561 * 562 * @param metadataPolicy The metadata policy JSON object, {@code null} 563 * if not specified. 564 */ 565 public void setMetadataPolicyJSONObject(final JSONObject metadataPolicy) { 566 567 setClaim(METADATA_POLICY_CLAIM_NAME, metadataPolicy); 568 } 569 570 571 /** 572 * Gets the metadata policy for the specified type. Corresponds to the 573 * {@code metadata_policy} claim. 574 * 575 * @param type The entity type. Must not be {@code null}. 576 * 577 * @return The metadata policy, {@code null} or if JSON parsing failed. 578 * 579 * @throws PolicyViolationException On a policy violation. 580 */ 581 public MetadataPolicy getMetadataPolicy(final EntityType type) 582 throws PolicyViolationException { 583 584 JSONObject o = getMetadataPolicyJSONObject(); 585 586 if (o == null) { 587 return null; 588 } 589 590 try { 591 JSONObject policyJSONObject = JSONObjectUtils.getJSONObject(o, type.getValue(), null); 592 if (policyJSONObject == null) { 593 return null; 594 } 595 return MetadataPolicy.parse(policyJSONObject); 596 } catch (ParseException e) { 597 return null; 598 } 599 } 600 601 602 /** 603 * Sets the metadata policy for the specified type. Corresponds to the 604 * {@code metadata_policy} claim. 605 * 606 * @param type The entity type. Must not be {@code null}. 607 * @param metadataPolicy The metadata policy, {@code null} if not 608 * specified. 609 */ 610 public void setMetadataPolicy(final EntityType type, final MetadataPolicy metadataPolicy) { 611 612 JSONObject o = getMetadataPolicyJSONObject(); 613 614 if (o == null) { 615 if (metadataPolicy == null) { 616 return; // nothing to clear 617 } 618 o = new JSONObject(); 619 } 620 621 if (metadataPolicy != null) { 622 o.put(type.getValue(), metadataPolicy.toJSONObject()); 623 } else { 624 o.remove(type.getValue()); 625 } 626 627 if (o.isEmpty()) { 628 o = null; 629 } 630 setMetadataPolicyJSONObject(o); 631 } 632 633 634 /** 635 * Gets the used trust anchor in a explicit client registration in 636 * OpenID Connect Federation 1.0. Intended for entity statements issued 637 * by an OpenID provider for a Relying party performing explicit client 638 * registration only. Corresponds to the {@code trust_anchor_id} claim. 639 * 640 * @return The trust anchor ID, {@code null} if not specified. 641 */ 642 public EntityID getTrustAnchorID() { 643 644 String value = getStringClaim(TRUST_ANCHOR_ID_CLAIM_NAME); 645 646 try { 647 return EntityID.parse(value); 648 } catch (ParseException e) { 649 return null; 650 } 651 } 652 653 654 /** 655 * Sets the used trust anchor in a explicit client registration in 656 * OpenID Connect Federation 1.0. Intended for entity statements issued 657 * by an OpenID provider for a Relying party performing explicit client 658 * registration only. Corresponds to the {@code trust_anchor_id} claim. 659 * 660 * @param trustAnchorID The trust anchor ID, {@code null} if not 661 * specified. 662 */ 663 public void setTrustAnchorID(final EntityID trustAnchorID) { 664 665 if (trustAnchorID != null) { 666 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, trustAnchorID.getValue()); 667 } else { 668 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, null); 669 } 670 } 671 672 673 /** 674 * Gets the trust chain constraints for subordinate entities. 675 * Corresponds to the {@code constraints} claim. 676 * 677 * @return The trust chain constraints, {@code null} if not specified 678 * or if parsing failed. 679 */ 680 public TrustChainConstraints getConstraints() { 681 682 JSONObject o = getJSONObjectClaim(CONSTRAINTS_CLAIM_NAME); 683 684 if (o == null) { 685 return null; 686 } 687 688 try { 689 return TrustChainConstraints.parse(o); 690 } catch (ParseException e) { 691 return null; 692 } 693 } 694 695 696 /** 697 * Sets the trust chain constraint for subordinate entities. 698 * Corresponds to the {@code constraints} claim. 699 * 700 * @param constraints The trust chain constraints, {@code null} if not 701 * specified. 702 */ 703 public void setConstraints(final TrustChainConstraints constraints) { 704 705 if (constraints != null) { 706 setClaim(CONSTRAINTS_CLAIM_NAME, constraints.toJSONObject()); 707 } else { 708 setClaim(CONSTRAINTS_CLAIM_NAME, null); 709 } 710 } 711 712 713 /** 714 * Sets the trust marks. Corresponds to the {@code trust_marks} claim. 715 * 716 * @param marks The trust marks, {@code null} if not specified. 717 */ 718 public void setTrustMarks(final List<TrustMarkEntry> marks) { 719 720 if (marks != null) { 721 JSONArray array = new JSONArray(); 722 for (TrustMarkEntry en: marks) { 723 array.add(en.toJSONObject()); 724 } 725 setClaim(TRUST_MARKS_CLAIM_NAME, array); 726 } else { 727 setClaim(TRUST_MARKS_CLAIM_NAME, null); 728 } 729 } 730 731 732 /** 733 * Gets the trust marks issuers. Corresponds to the 734 * {@code trust_marks_issuers} claim. 735 * 736 * @return The trust marks issuers, {@code null} if not specified or 737 * parsing failed. 738 */ 739 public Map<Identifier, List<Issuer>> getTrustMarksIssuers() { 740 741 JSONObject o = getJSONObjectClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME); 742 743 if (o == null) { 744 return null; 745 } 746 747 Map<Identifier, List<Issuer>> issuers = new HashMap<>(); 748 749 for (String id: o.keySet()) { 750 try { 751 List<Issuer> issuerList = new LinkedList<>(); 752 for (String issuerString: JSONObjectUtils.getStringList(o, id)) { 753 issuerList.add(new Issuer(issuerString)); 754 } 755 issuers.put(new Identifier(id), issuerList); 756 } catch (ParseException e) { 757 return null; 758 } 759 } 760 761 return issuers; 762 } 763 764 765 /** 766 * Sets the trust marks issuers. Corresponds to the 767 * {@code trust_marks_issuers} claim. 768 * 769 * @param issuers The trust marks issuers, {@code null} if not 770 * specified. 771 */ 772 public void setTrustMarksIssuers(final Map<Identifier, List<Issuer>> issuers) { 773 774 if (issuers != null) { 775 JSONObject issuersObject = new JSONObject(); 776 for (Map.Entry<Identifier, List<Issuer>> en: issuers.entrySet()) { 777 issuersObject.put(en.getKey().getValue(), Issuer.toStringList(en.getValue())); 778 setClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME, issuersObject); 779 } 780 } else { 781 setClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME, null); 782 } 783 } 784 785 786 /** 787 * Gets the names of the critical extension claims. Corresponds to the 788 * {@code crit} claim. 789 * 790 * @return The names of the critical extension claims, {@code null} if 791 * not specified or if parsing failed. 792 */ 793 public List<String> getCriticalExtensionClaims() { 794 795 return getStringListClaim(CRITICAL_CLAIM_NAME); 796 } 797 798 799 /** 800 * Sets the names of the critical extension claims. Corresponds to the 801 * {@code crit} claim. 802 * 803 * @param claimNames The names of the critical extension claims, 804 * {@code null} if not specified. Must not be an 805 * empty list. 806 */ 807 public void setCriticalExtensionClaims(final List<String> claimNames) { 808 809 if (claimNames != null && claimNames.isEmpty()) { 810 throw new IllegalArgumentException("The critical extension claim names must not be empty"); 811 } 812 813 setClaim(CRITICAL_CLAIM_NAME, claimNames); 814 } 815 816 817 /** 818 * Gets the names of the critical policy extensions. Corresponds to the 819 * {@code policy_language_crit} claim. 820 * 821 * @return The names of the critical policy extensions or if parsing 822 * failed. 823 */ 824 public List<String> getCriticalPolicyExtensions() { 825 826 return getStringListClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME); 827 } 828 829 830 /** 831 * Sets the names of the critical policy extensions. Corresponds to the 832 * {@code policy_language_crit} claim. 833 * 834 * @param extNames The names of the critical policy extensions, 835 * {@code null} if not specified. Must not be an empty 836 * list. 837 */ 838 public void setCriticalPolicyExtensions(final List<String> extNames) { 839 840 if (extNames != null && extNames.isEmpty()) { 841 throw new IllegalArgumentException("The critical policy extension names must not be empty"); 842 } 843 844 setClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME, extNames); 845 } 846}