diff --git a/extensions/common/iam/identity-trust/identity-trust-core/src/main/java/org/eclipse/edc/iam/identitytrust/core/IdentityAndTrustExtension.java b/extensions/common/iam/identity-trust/identity-trust-core/src/main/java/org/eclipse/edc/iam/identitytrust/core/IdentityAndTrustExtension.java index 7b8b4628f71..b2e62164ddc 100644 --- a/extensions/common/iam/identity-trust/identity-trust-core/src/main/java/org/eclipse/edc/iam/identitytrust/core/IdentityAndTrustExtension.java +++ b/extensions/common/iam/identity-trust/identity-trust-core/src/main/java/org/eclipse/edc/iam/identitytrust/core/IdentityAndTrustExtension.java @@ -16,9 +16,9 @@ import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.iam.identitytrust.IdentityAndTrustService; -import org.eclipse.edc.iam.identitytrust.validation.JwtValidatorImpl; -import org.eclipse.edc.iam.identitytrust.verification.JwtVerifierImpl; +import org.eclipse.edc.iam.identitytrust.validation.SelfIssuedIdTokenValidator; import org.eclipse.edc.iam.identitytrust.verification.MultiFormatPresentationVerifier; +import org.eclipse.edc.iam.identitytrust.verification.SelfIssuedIdTokenVerifier; import org.eclipse.edc.identitytrust.CredentialServiceClient; import org.eclipse.edc.identitytrust.SecureTokenService; import org.eclipse.edc.identitytrust.validation.JwtValidator; @@ -62,7 +62,7 @@ public IdentityService createIdentityService(ServiceExtensionContext context) { @Provider public JwtValidator getJwtValidator() { if (jwtValidator == null) { - jwtValidator = new JwtValidatorImpl(); + jwtValidator = new SelfIssuedIdTokenValidator(); } return jwtValidator; } @@ -75,7 +75,7 @@ public PresentationVerifier createPresentationVerifier() { @Provider private JwtVerifier getJwtVerifier() { if (jwtVerifier == null) { - jwtVerifier = new JwtVerifierImpl(resolverRegistry); + jwtVerifier = new SelfIssuedIdTokenVerifier(resolverRegistry); } return jwtVerifier; } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/IdentityAndTrustService.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/IdentityAndTrustService.java index a6649330c51..bb5f77014fa 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/IdentityAndTrustService.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/IdentityAndTrustService.java @@ -20,8 +20,8 @@ import org.eclipse.edc.identitytrust.CredentialServiceClient; import org.eclipse.edc.identitytrust.SecureTokenService; import org.eclipse.edc.identitytrust.model.VerifiableCredential; +import org.eclipse.edc.identitytrust.validation.CredentialValidationRule; import org.eclipse.edc.identitytrust.validation.JwtValidator; -import org.eclipse.edc.identitytrust.validation.VcValidationRule; import org.eclipse.edc.identitytrust.verification.JwtVerifier; import org.eclipse.edc.identitytrust.verification.PresentationVerifier; import org.eclipse.edc.spi.iam.ClaimToken; @@ -123,7 +123,7 @@ public Result verifyJwtToken(TokenRepresentation tokenRepresentation new HasValidIssuer(getAllowedIssuers()))); filters.addAll(getAdditionalValidations()); - var results = credentials.stream().map(c -> filters.stream().reduce(t -> Result.success(), VcValidationRule::and).apply(c)).reduce(Result::merge); + var results = credentials.stream().map(c -> filters.stream().reduce(t -> Result.success(), CredentialValidationRule::and).apply(c)).reduce(Result::merge); return results.orElseGet(() -> failure("Could not determine the status of the VC validation")); }); @@ -135,7 +135,7 @@ private ClaimToken extractClaimToken(List credentials) { return null; } - private Collection getAdditionalValidations() { + private Collection getAdditionalValidations() { return List.of(); } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidIssuer.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidIssuer.java index 41c457879a0..f690ddaeb07 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidIssuer.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidIssuer.java @@ -15,7 +15,7 @@ package org.eclipse.edc.iam.identitytrust.validation; import org.eclipse.edc.identitytrust.model.VerifiableCredential; -import org.eclipse.edc.identitytrust.validation.VcValidationRule; +import org.eclipse.edc.identitytrust.validation.CredentialValidationRule; import org.eclipse.edc.spi.result.Result; import java.util.List; @@ -24,7 +24,13 @@ import static org.eclipse.edc.spi.result.Result.failure; import static org.eclipse.edc.spi.result.Result.success; -public class HasValidIssuer implements VcValidationRule { +/** + * A class that implements the {@link CredentialValidationRule} interface and checks if a {@link VerifiableCredential} has a valid issuer. + * Valid issuers are stored in a global list. + *

+ * If the issuer object is neither a string nor an object containing an "id" field, a failure is returned. + */ +public class HasValidIssuer implements CredentialValidationRule { private final List allowedIssuers; public HasValidIssuer(List allowedIssuers) { @@ -41,6 +47,9 @@ public Result apply(VerifiableCredential credential) { issuer = issuerObject.toString(); } else if (issuerObject instanceof Map) { issuer = ((Map) issuerObject).get("id").toString(); + if (issuer == null) { + return failure("Issuer was an object, but did not contain an 'id' field"); + } } else { return failure("VC Issuer must either be a String or an Object but was %s.".formatted(issuerObject.getClass())); } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidSubjectIds.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidSubjectIds.java index b8aefade982..ba83fff3f52 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidSubjectIds.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/HasValidSubjectIds.java @@ -15,13 +15,17 @@ package org.eclipse.edc.iam.identitytrust.validation; import org.eclipse.edc.identitytrust.model.VerifiableCredential; -import org.eclipse.edc.identitytrust.validation.VcValidationRule; +import org.eclipse.edc.identitytrust.validation.CredentialValidationRule; import org.eclipse.edc.spi.result.Result; import static org.eclipse.edc.spi.result.Result.failure; import static org.eclipse.edc.spi.result.Result.success; -public class HasValidSubjectIds implements VcValidationRule { +/** + * This class implements the CredentialValidationRule interface and checks if all subject IDs in a + * VerifiableCredential match an expected subject ID, which in practice is the DID of the holder of a VP. + */ +public class HasValidSubjectIds implements CredentialValidationRule { private final String expectedSubjectId; diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/IsRevoked.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/IsRevoked.java index 6ff14c95483..0fec7686fa7 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/IsRevoked.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/IsRevoked.java @@ -15,12 +15,15 @@ package org.eclipse.edc.iam.identitytrust.validation; import org.eclipse.edc.identitytrust.model.VerifiableCredential; -import org.eclipse.edc.identitytrust.validation.VcValidationRule; +import org.eclipse.edc.identitytrust.validation.CredentialValidationRule; import org.eclipse.edc.spi.result.Result; import static org.eclipse.edc.spi.result.Result.success; -public class IsRevoked implements VcValidationRule { +/** + * This class represents a rule that checks if a given VerifiableCredential is revoked based on a StatusList2021 credential. + */ +public class IsRevoked implements CredentialValidationRule { private final VerifiableCredential statusList2021; public IsRevoked(VerifiableCredential statusList2021) { diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImpl.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidator.java similarity index 77% rename from extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImpl.java rename to extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidator.java index 7115a98072f..f4fe86a7499 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImpl.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidator.java @@ -28,9 +28,22 @@ import static org.eclipse.edc.spi.result.Result.success; /** - * Default implementation for JWT validation in the context of IATP. + * Performs structural validation a Self-Issued ID Token. It asserts that: + *

+ *

+ * Please note that the signature of the JWT is not verified, that is done by the {@link org.eclipse.edc.iam.identitytrust.verification.SelfIssuedIdTokenVerifier}. + * + * @see org.eclipse.edc.iam.identitytrust.verification.SelfIssuedIdTokenVerifier SI Token signature verification */ -public class JwtValidatorImpl implements JwtValidator { +public class SelfIssuedIdTokenValidator implements JwtValidator { private static final long EPSILON = 60; diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JsonLdPresentationVerifier.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JsonLdPresentationVerifier.java index e50d4691109..acdc61d14ed 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JsonLdPresentationVerifier.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JsonLdPresentationVerifier.java @@ -16,11 +16,16 @@ import org.eclipse.edc.spi.result.Result; +/** + * Verifies the cryptographic integrity of a VerifiablePresentation that is presented as a JSON-LD. + */ class JsonLdPresentationVerifier { - JsonLdPresentationVerifier() { - } - + /** + * Computes the cryptographic integrity of a VerifiablePresentation + * + * @param rawVp The unaltered JSON-LD string, as it was received from the holder. + */ public Result verifyPresentation(String rawVp) { throw new UnsupportedOperationException("not yet implemented!"); } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtPresentationVerifier.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtPresentationVerifier.java index 888fa937ac2..5b35065f410 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtPresentationVerifier.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtPresentationVerifier.java @@ -16,8 +16,16 @@ import org.eclipse.edc.spi.result.Result; +/** + * Verifies VerifiablePresentations, which are present in JWT format. Only the cryptographic integrity is asserted + */ class JwtPresentationVerifier { + /** + * Computes the cryptographic integrity of a VerifiablePresentation + * + * @param rawVp The base64-encoded JWT string + */ public Result verifyPresentation(String rawVp) { - return null; + throw new UnsupportedOperationException("not yet implemented!"); } } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImpl.java b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifier.java similarity index 74% rename from extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImpl.java rename to extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifier.java index 04a1a7a2c5c..bc5308b5327 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImpl.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/main/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifier.java @@ -30,12 +30,24 @@ import java.util.Optional; /** - * This implementation + * Performs cryptographic (and some structural) verification of a self-issued ID token. To that end, the issuer of the token + * ({@code iss} claim) is presumed to be a Decentralized Identifier (DID). + *

+ * If the JWT contains in its header a {@code kid} field identifying the public key that was used for signing, the DID is + * expected to have a verificationMethod + * with that same ID. If no such verification method is found, {@link Result#failure(String)} is returned. + *

+ * If no such {@code kid} header is present, then the first verification method is used. + *

+ * Please note that no structural validation is done beyond the very basics (must have iss and aud claim). + * This is done by the {@link org.eclipse.edc.iam.identitytrust.validation.SelfIssuedIdTokenValidator}. + * + * @see org.eclipse.edc.iam.identitytrust.validation.SelfIssuedIdTokenValidator For SI Token validation. */ -public class JwtVerifierImpl implements JwtVerifier { +public class SelfIssuedIdTokenVerifier implements JwtVerifier { private final DidResolverRegistry resolverRegistry; - public JwtVerifierImpl(DidResolverRegistry resolverRegistry) { + public SelfIssuedIdTokenVerifier(DidResolverRegistry resolverRegistry) { this.resolverRegistry = resolverRegistry; } diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImplTest.java b/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidatorTest.java similarity index 97% rename from extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImplTest.java rename to extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidatorTest.java index 4346287781b..7aae06de5bc 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/JwtValidatorImplTest.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/validation/SelfIssuedIdTokenValidatorTest.java @@ -26,11 +26,11 @@ import static org.eclipse.edc.identitytrust.TestFunctions.createJwt; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -class JwtValidatorImplTest { +class SelfIssuedIdTokenValidatorTest { private static final String EXPECTED_OWN_DID = "did:web:provider"; private static final String CONSUMER_DID = "did:web:consumer"; - private final JwtValidatorImpl validator = new JwtValidatorImpl(); + private final SelfIssuedIdTokenValidator validator = new SelfIssuedIdTokenValidator(); @BeforeEach void setUp() { diff --git a/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImplTest.java b/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifierTest.java similarity index 97% rename from extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImplTest.java rename to extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifierTest.java index 4e70f96fa2c..d2afc7a85c3 100644 --- a/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/JwtVerifierImplTest.java +++ b/extensions/common/iam/identity-trust/identity-trust-service/src/test/java/org/eclipse/edc/iam/identitytrust/verification/SelfIssuedIdTokenVerifierTest.java @@ -38,10 +38,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -class JwtVerifierImplTest { +class SelfIssuedIdTokenVerifierTest { private final DidResolverRegistry didResolverRegistry = mock(); - private final JwtVerifierImpl verifier = new JwtVerifierImpl(didResolverRegistry); + private final SelfIssuedIdTokenVerifier verifier = new SelfIssuedIdTokenVerifier(didResolverRegistry); private ECKey didVerificationMethod; @BeforeEach diff --git a/spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/VcValidationRule.java b/spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/CredentialValidationRule.java similarity index 80% rename from spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/VcValidationRule.java rename to spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/CredentialValidationRule.java index c45df68a4aa..303b2e74e3d 100644 --- a/spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/VcValidationRule.java +++ b/spi/common/identity-trust-spi/src/main/java/org/eclipse/edc/identitytrust/validation/CredentialValidationRule.java @@ -21,8 +21,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -public interface VcValidationRule extends Function> { - default VcValidationRule and(VcValidationRule other) { +/** + * Interface for a rule that is being applied to a {@link VerifiableCredential}, and returns {@link Result#success()} or {@link Result#failure(String)}. + */ +public interface CredentialValidationRule extends Function> { + default CredentialValidationRule and(CredentialValidationRule other) { return t -> { var thisResult = this.apply(t); var otherResult = other.apply(t);