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 public void setTrustMarkIssuerMetadata(final TrustMarkIssuerMetadata trustMarkIssuerMetadata) { 538 539 JSONObject o = trustMarkIssuerMetadata != null ? trustMarkIssuerMetadata.toJSONObject() : null; 540 setMetadata(EntityType.TRUST_MARK_ISSUER, o); 541 } 542 543 544 /** 545 * Gets the complete metadata policy JSON object. Corresponds to the 546 * {@code metadata_policy} claim. 547 * 548 * @return The metadata policy JSON object, {@code null} if not 549 * specified or if parsing failed. 550 */ 551 public JSONObject getMetadataPolicyJSONObject() { 552 553 return getJSONObjectClaim(METADATA_POLICY_CLAIM_NAME); 554 } 555 556 557 /** 558 * Sets the complete metadata policy JSON object. Corresponds to the 559 * {@code metadata_policy} claim. 560 * 561 * @param metadataPolicy The metadata policy JSON object, {@code null} 562 * if not specified. 563 */ 564 public void setMetadataPolicyJSONObject(final JSONObject metadataPolicy) { 565 566 setClaim(METADATA_POLICY_CLAIM_NAME, metadataPolicy); 567 } 568 569 570 /** 571 * Gets the metadata policy for the specified type. Corresponds to the 572 * {@code metadata_policy} claim. 573 * 574 * @param type The entity type. Must not be {@code null}. 575 * 576 * @return The metadata policy, {@code null} or if JSON parsing failed. 577 * 578 * @throws PolicyViolationException On a policy violation. 579 */ 580 public MetadataPolicy getMetadataPolicy(final EntityType type) 581 throws PolicyViolationException { 582 583 JSONObject o = getMetadataPolicyJSONObject(); 584 585 if (o == null) { 586 return null; 587 } 588 589 try { 590 JSONObject policyJSONObject = JSONObjectUtils.getJSONObject(o, type.getValue(), null); 591 if (policyJSONObject == null) { 592 return null; 593 } 594 return MetadataPolicy.parse(policyJSONObject); 595 } catch (ParseException e) { 596 return null; 597 } 598 } 599 600 601 /** 602 * Sets the metadata policy for the specified type. Corresponds to the 603 * {@code metadata_policy} claim. 604 * 605 * @param type The entity type. Must not be {@code null}. 606 * @param metadataPolicy The metadata policy, {@code null} if not 607 * specified. 608 */ 609 public void setMetadataPolicy(final EntityType type, final MetadataPolicy metadataPolicy) { 610 611 JSONObject o = getMetadataPolicyJSONObject(); 612 613 if (o == null) { 614 if (metadataPolicy == null) { 615 return; // nothing to clear 616 } 617 o = new JSONObject(); 618 } 619 620 if (metadataPolicy != null) { 621 o.put(type.getValue(), metadataPolicy.toJSONObject()); 622 } else { 623 o.remove(type.getValue()); 624 } 625 626 if (o.isEmpty()) { 627 o = null; 628 } 629 setMetadataPolicyJSONObject(o); 630 } 631 632 633 /** 634 * Gets the used trust anchor in a explicit client registration in 635 * OpenID Connect Federation 1.0. Intended for entity statements issued 636 * by an OpenID provider for a Relying party performing explicit client 637 * registration only. Corresponds to the {@code trust_anchor_id} claim. 638 * 639 * @return The trust anchor ID, {@code null} if not specified. 640 */ 641 public EntityID getTrustAnchorID() { 642 643 String value = getStringClaim(TRUST_ANCHOR_ID_CLAIM_NAME); 644 645 try { 646 return EntityID.parse(value); 647 } catch (ParseException e) { 648 return null; 649 } 650 } 651 652 653 /** 654 * Sets the used trust anchor in a explicit client registration in 655 * OpenID Connect Federation 1.0. Intended for entity statements issued 656 * by an OpenID provider for a Relying party performing explicit client 657 * registration only. Corresponds to the {@code trust_anchor_id} claim. 658 * 659 * @param trustAnchorID The trust anchor ID, {@code null} if not 660 * specified. 661 */ 662 public void setTrustAnchorID(final EntityID trustAnchorID) { 663 664 if (trustAnchorID != null) { 665 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, trustAnchorID.getValue()); 666 } else { 667 setClaim(TRUST_ANCHOR_ID_CLAIM_NAME, null); 668 } 669 } 670 671 672 /** 673 * Gets the trust chain constraints for subordinate entities. 674 * Corresponds to the {@code constraints} claim. 675 * 676 * @return The trust chain constraints, {@code null} if not specified 677 * or if parsing failed. 678 */ 679 public TrustChainConstraints getConstraints() { 680 681 JSONObject o = getJSONObjectClaim(CONSTRAINTS_CLAIM_NAME); 682 683 if (o == null) { 684 return null; 685 } 686 687 try { 688 return TrustChainConstraints.parse(o); 689 } catch (ParseException e) { 690 return null; 691 } 692 } 693 694 695 /** 696 * Sets the trust chain constraint for subordinate entities. 697 * Corresponds to the {@code constraints} claim. 698 * 699 * @param constraints The trust chain constraints, {@code null} if not 700 * specified. 701 */ 702 public void setConstraints(final TrustChainConstraints constraints) { 703 704 if (constraints != null) { 705 setClaim(CONSTRAINTS_CLAIM_NAME, constraints.toJSONObject()); 706 } else { 707 setClaim(CONSTRAINTS_CLAIM_NAME, null); 708 } 709 } 710 711 712 /** 713 * Sets the trust marks. Corresponds to the {@code trust_marks} claim. 714 * 715 * @param marks The trust marks, {@code null} if not specified. 716 */ 717 public void setTrustMarks(final List<TrustMarkEntry> marks) { 718 719 if (marks != null) { 720 JSONArray array = new JSONArray(); 721 for (TrustMarkEntry en: marks) { 722 array.add(en.toJSONObject()); 723 } 724 setClaim(TRUST_MARKS_CLAIM_NAME, array); 725 } else { 726 setClaim(TRUST_MARKS_CLAIM_NAME, null); 727 } 728 } 729 730 731 /** 732 * Gets the trust marks issuers. Corresponds to the 733 * {@code trust_marks_issuers} claim. 734 * 735 * @return The trust marks issuers, {@code null} if not specified or 736 * parsing failed. 737 */ 738 public Map<Identifier, List<Issuer>> getTrustMarksIssuers() { 739 740 JSONObject o = getJSONObjectClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME); 741 742 if (o == null) { 743 return null; 744 } 745 746 Map<Identifier, List<Issuer>> issuers = new HashMap<>(); 747 748 for (String id: o.keySet()) { 749 try { 750 List<Issuer> issuerList = new LinkedList<>(); 751 for (String issuerString: JSONObjectUtils.getStringList(o, id)) { 752 issuerList.add(new Issuer(issuerString)); 753 } 754 issuers.put(new Identifier(id), issuerList); 755 } catch (ParseException e) { 756 return null; 757 } 758 } 759 760 return issuers; 761 } 762 763 764 /** 765 * Sets the trust marks issuers. Corresponds to the 766 * {@code trust_marks_issuers} claim. 767 * 768 * @param issuers The trust marks issuers, {@code null} if not 769 * specified. 770 */ 771 public void setTrustMarksIssuers(final Map<Identifier, List<Issuer>> issuers) { 772 773 if (issuers != null) { 774 JSONObject issuersObject = new JSONObject(); 775 for (Map.Entry<Identifier, List<Issuer>> en: issuers.entrySet()) { 776 issuersObject.put(en.getKey().getValue(), Issuer.toStringList(en.getValue())); 777 setClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME, issuersObject); 778 } 779 } else { 780 setClaim(TRUST_MARKS_ISSUERS_CLAIM_NAME, null); 781 } 782 } 783 784 785 /** 786 * Gets the names of the critical extension claims. Corresponds to the 787 * {@code crit} claim. 788 * 789 * @return The names of the critical extension claims, {@code null} if 790 * not specified or if parsing failed. 791 */ 792 public List<String> getCriticalExtensionClaims() { 793 794 return getStringListClaim(CRITICAL_CLAIM_NAME); 795 } 796 797 798 /** 799 * Sets the names of the critical extension claims. Corresponds to the 800 * {@code crit} claim. 801 * 802 * @param claimNames The names of the critical extension claims, 803 * {@code null} if not specified. Must not be an 804 * empty list. 805 */ 806 public void setCriticalExtensionClaims(final List<String> claimNames) { 807 808 if (claimNames != null && claimNames.isEmpty()) { 809 throw new IllegalArgumentException("The critical extension claim names must not be empty"); 810 } 811 812 setClaim(CRITICAL_CLAIM_NAME, claimNames); 813 } 814 815 816 /** 817 * Gets the names of the critical policy extensions. Corresponds to the 818 * {@code policy_language_crit} claim. 819 * 820 * @return The names of the critical policy extensions or if parsing 821 * failed. 822 */ 823 public List<String> getCriticalPolicyExtensions() { 824 825 return getStringListClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME); 826 } 827 828 829 /** 830 * Sets the names of the critical policy extensions. Corresponds to the 831 * {@code policy_language_crit} claim. 832 * 833 * @param extNames The names of the critical policy extensions, 834 * {@code null} if not specified. Must not be an empty 835 * list. 836 */ 837 public void setCriticalPolicyExtensions(final List<String> extNames) { 838 839 if (extNames != null && extNames.isEmpty()) { 840 throw new IllegalArgumentException("The critical policy extension names must not be empty"); 841 } 842 843 setClaim(POLICY_LANGUAGE_CRITICAL_CLAIM_NAME, extNames); 844 } 845}