-
-
Save andresrosenthal/0f833f71b6d33805c20dca03c9e45796 to your computer and use it in GitHub Desktop.
Extensible JWSSigner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/CoreServicesExtension.java core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/CoreServicesExtension.java | |
index e8d9f43..7ba49ed 100644 | |
--- core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/CoreServicesExtension.java | |
+++ core/identity-hub-core/src/main/java/org/eclipse/edc/identityhub/core/CoreServicesExtension.java | |
@@ -14,6 +14,7 @@ | |
package org.eclipse.edc.identityhub.core; | |
+import com.nimbusds.jose.JWSSigner; | |
import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver; | |
import org.eclipse.edc.iam.identitytrust.spi.verification.SignatureSuiteRegistry; | |
import org.eclipse.edc.iam.verifiablecredentials.spi.RevocationListService; | |
@@ -41,7 +42,6 @@ import org.eclipse.edc.jsonld.spi.JsonLd; | |
import org.eclipse.edc.jsonld.util.JacksonJsonLd; | |
import org.eclipse.edc.keys.spi.KeyParserRegistry; | |
import org.eclipse.edc.keys.spi.LocalPublicKeyService; | |
-import org.eclipse.edc.keys.spi.PrivateKeyResolver; | |
import org.eclipse.edc.runtime.metamodel.annotation.Extension; | |
import org.eclipse.edc.runtime.metamodel.annotation.Inject; | |
import org.eclipse.edc.runtime.metamodel.annotation.Provider; | |
@@ -57,6 +57,7 @@ import org.eclipse.edc.verifiablecredentials.linkeddata.LdpIssuer; | |
import java.net.URISyntaxException; | |
import java.time.Clock; | |
+import java.util.function.Function; | |
import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DCP_CONTEXT_URL; | |
import static org.eclipse.edc.identityhub.core.CoreServicesExtension.NAME; | |
@@ -92,7 +93,7 @@ public class CoreServicesExtension implements ServiceExtension { | |
@Inject | |
private ScopeToCriterionTransformer transformer; | |
@Inject | |
- private PrivateKeyResolver privateKeyResolver; | |
+ private Function<String, JWSSigner> jwsSignerResolver; | |
@Inject | |
private Clock clock; | |
@Inject | |
@@ -148,10 +149,10 @@ public class CoreServicesExtension implements ServiceExtension { | |
public PresentationCreatorRegistry presentationCreatorRegistry(ServiceExtensionContext context) { | |
if (presentationCreatorRegistry == null) { | |
presentationCreatorRegistry = new PresentationCreatorRegistryImpl(keyPairService, participantContextService); | |
- presentationCreatorRegistry.addCreator(new JwtPresentationGenerator(privateKeyResolver, clock, new JwtGenerationService()), CredentialFormat.JWT); | |
+ presentationCreatorRegistry.addCreator(new JwtPresentationGenerator(jwsSignerResolver, clock, new JwtGenerationService()), CredentialFormat.JWT); | |
var ldpIssuer = LdpIssuer.Builder.newInstance().jsonLd(jsonLd).monitor(context.getMonitor()).build(); | |
- presentationCreatorRegistry.addCreator(new LdpPresentationGenerator(privateKeyResolver, signatureSuiteRegistry, IdentityHubConstants.JWS_2020_SIGNATURE_SUITE, ldpIssuer, typeManager.getMapper(JSON_LD)), | |
+ presentationCreatorRegistry.addCreator(new LdpPresentationGenerator(jwsSignerResolver, signatureSuiteRegistry, IdentityHubConstants.JWS_2020_SIGNATURE_SUITE, ldpIssuer, typeManager.getMapper(JSON_LD)), | |
CredentialFormat.JSON_LD); | |
} | |
return presentationCreatorRegistry; | |
diff --git core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/JwtPresentationGenerator.java core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/JwtPresentationGenerator.java | |
index 1eb8896..b6d1a0f 100644 | |
--- core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/JwtPresentationGenerator.java | |
+++ core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/JwtPresentationGenerator.java | |
@@ -14,27 +14,26 @@ | |
package org.eclipse.edc.identithub.verifiablepresentation.generators; | |
+import com.nimbusds.jose.JWSSigner; | |
import org.eclipse.edc.iam.identitytrust.spi.DcpConstants; | |
import org.eclipse.edc.iam.verifiablecredentials.spi.VcConstants; | |
import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredentialContainer; | |
import org.eclipse.edc.identityhub.spi.verifiablecredentials.generator.PresentationGenerator; | |
import org.eclipse.edc.jsonld.spi.JsonLdKeywords; | |
import org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames; | |
-import org.eclipse.edc.keys.spi.PrivateKeyResolver; | |
import org.eclipse.edc.spi.EdcException; | |
import org.eclipse.edc.spi.iam.TokenRepresentation; | |
import org.eclipse.edc.token.spi.KeyIdDecorator; | |
import org.eclipse.edc.token.spi.TokenDecorator; | |
import org.eclipse.edc.token.spi.TokenGenerationService; | |
-import java.security.PrivateKey; | |
import java.time.Clock; | |
import java.time.Instant; | |
import java.util.Date; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.UUID; | |
-import java.util.function.Supplier; | |
+import java.util.function.Function; | |
import java.util.stream.Collectors; | |
import static org.eclipse.edc.identithub.verifiablepresentation.generators.PresentationGeneratorConstants.CONTROLLER_ADDITIONAL_DATA; | |
@@ -47,7 +46,7 @@ import static org.eclipse.edc.identithub.verifiablepresentation.generators.Prese | |
*/ | |
public class JwtPresentationGenerator implements PresentationGenerator<String> { | |
public static final String VERIFIABLE_PRESENTATION_CLAIM = "vp"; | |
- private final PrivateKeyResolver privateKeyResolver; | |
+ private final Function<String, JWSSigner> jwsSignerResolver; | |
private final Clock clock; | |
private final TokenGenerationService tokenGenerationService; | |
@@ -55,11 +54,11 @@ public class JwtPresentationGenerator implements PresentationGenerator<String> { | |
/** | |
* Creates a JWT presentation based on a list of Verifiable Credential Containers. | |
* | |
- * @param privateKeyResolver The resolver for private keys used for signing the presentation. | |
+ * @param jwsSignerResolver The resolver used for signing the presentation. | |
* @param clock The clock used for generating timestamps. | |
*/ | |
- public JwtPresentationGenerator(PrivateKeyResolver privateKeyResolver, Clock clock, TokenGenerationService tokenGenerationService) { | |
- this.privateKeyResolver = privateKeyResolver; | |
+ public JwtPresentationGenerator(Function<String, JWSSigner> jwsSignerResolver, Clock clock, TokenGenerationService tokenGenerationService) { | |
+ this.jwsSignerResolver = jwsSignerResolver; | |
this.clock = clock; | |
this.tokenGenerationService = tokenGenerationService; | |
} | |
@@ -107,8 +106,8 @@ public class JwtPresentationGenerator implements PresentationGenerator<String> { | |
var rawVcs = credentials.stream() | |
.map(VerifiableCredentialContainer::rawVc) | |
.collect(Collectors.toList()); | |
- Supplier<PrivateKey> privateKeySupplier = () -> privateKeyResolver.resolvePrivateKey(privateKeyAlias).orElseThrow(f -> new IllegalArgumentException(f.getFailureDetail())); | |
- var tokenResult = tokenGenerationService.generate(privateKeySupplier, vpDecorator(rawVcs, issuerId), tp -> { | |
+ JWSSigner jwsSigner = jwsSignerResolver.apply(privateKeyAlias); | |
+ var tokenResult = tokenGenerationService.generate(jwsSigner, vpDecorator(rawVcs, issuerId), tp -> { | |
additionalData.forEach(tp::claims); | |
return tp; | |
}, new KeyIdDecorator(composedKeyId)); | |
diff --git core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/LdpPresentationGenerator.java core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/LdpPresentationGenerator.java | |
index c59db4a..49ac2a8 100644 | |
--- core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/LdpPresentationGenerator.java | |
+++ core/lib/verifiable-presentation-lib/src/main/java/org/eclipse/edc/identithub/verifiablepresentation/generators/LdpPresentationGenerator.java | |
@@ -14,9 +14,11 @@ | |
package org.eclipse.edc.identithub.verifiablepresentation.generators; | |
+import com.apicatalog.ld.signature.key.KeyPair; | |
import com.apicatalog.vc.suite.SignatureSuite; | |
import com.fasterxml.jackson.core.JsonProcessingException; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
+import com.nimbusds.jose.JWSSigner; | |
import jakarta.json.Json; | |
import jakarta.json.JsonArray; | |
import jakarta.json.JsonArrayBuilder; | |
@@ -28,22 +30,19 @@ import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialFormat; | |
import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredentialContainer; | |
import org.eclipse.edc.identityhub.spi.verifiablecredentials.generator.PresentationGenerator; | |
import org.eclipse.edc.jsonld.spi.JsonLdKeywords; | |
-import org.eclipse.edc.keys.spi.PrivateKeyResolver; | |
import org.eclipse.edc.security.signature.jws2020.JsonWebKeyPair; | |
import org.eclipse.edc.security.signature.jws2020.Jws2020ProofDraft; | |
-import org.eclipse.edc.security.token.jwt.CryptoConverter; | |
import org.eclipse.edc.spi.EdcException; | |
import org.eclipse.edc.verifiablecredentials.linkeddata.LdpIssuer; | |
import org.jetbrains.annotations.NotNull; | |
import java.net.URI; | |
-import java.security.KeyPair; | |
-import java.security.PrivateKey; | |
import java.time.Instant; | |
import java.util.Collection; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.UUID; | |
+import java.util.function.Function; | |
import static org.eclipse.edc.identithub.verifiablepresentation.generators.PresentationGeneratorConstants.CONTROLLER_ADDITIONAL_DATA; | |
import static org.eclipse.edc.identithub.verifiablepresentation.generators.PresentationGeneratorConstants.VERIFIABLE_CREDENTIAL_PROPERTY; | |
@@ -60,15 +59,15 @@ public class LdpPresentationGenerator implements PresentationGenerator<JsonObjec | |
public static final String TYPE_ADDITIONAL_DATA = "types"; | |
public static final String HOLDER_PROPERTY = "holder"; | |
public static final URI ASSERTION_METHOD = URI.create("https://w3id.org/security#assertionMethod"); | |
- private final PrivateKeyResolver privateKeyResolver; | |
+ private final Function<String, JWSSigner> jwsSignerResolver; | |
private final SignatureSuiteRegistry signatureSuiteRegistry; | |
private final String defaultSignatureSuite; | |
private final LdpIssuer ldpIssuer; | |
private final ObjectMapper mapper; | |
- public LdpPresentationGenerator(PrivateKeyResolver privateKeyResolver, | |
+ public LdpPresentationGenerator(Function<String, JWSSigner> jwsSignerResolver, | |
SignatureSuiteRegistry signatureSuiteRegistry, String defaultSignatureSuite, LdpIssuer ldpIssuer, ObjectMapper mapper) { | |
- this.privateKeyResolver = privateKeyResolver; | |
+ this.jwsSignerResolver = jwsSignerResolver; | |
this.signatureSuiteRegistry = signatureSuiteRegistry; | |
this.defaultSignatureSuite = defaultSignatureSuite; | |
this.ldpIssuer = ldpIssuer; | |
@@ -121,9 +120,6 @@ public class LdpPresentationGenerator implements PresentationGenerator<JsonObjec | |
throw new IllegalArgumentException("One or more VerifiableCredentials cannot be represented in the desired format " + CredentialFormat.JSON_LD); | |
} | |
- // check if private key can be resolved | |
- var pk = privateKeyResolver.resolvePrivateKey(privateKeyAlias) | |
- .orElseThrow(f -> new IllegalArgumentException(f.getFailureDetail())); | |
var types = (List) additionalData.get(TYPE_ADDITIONAL_DATA); | |
var presentationObject = Json.createObjectBuilder() | |
@@ -134,7 +130,9 @@ public class LdpPresentationGenerator implements PresentationGenerator<JsonObjec | |
.add(VERIFIABLE_CREDENTIAL_PROPERTY, toJsonArray(credentials)) | |
.build(); | |
- return signPresentation(presentationObject, suite, suiteIdentifier, pk, publicKeyId, additionalData.get(CONTROLLER_ADDITIONAL_DATA).toString()); | |
+ JWSSigner jwsSigner = jwsSignerResolver.apply(privateKeyAlias); | |
+ return signPresentation(presentationObject, suite, suiteIdentifier, jwsSigner, publicKeyId, | |
+ additionalData.get(CONTROLLER_ADDITIONAL_DATA).toString()); | |
} | |
@NotNull | |
@@ -153,26 +151,57 @@ public class LdpPresentationGenerator implements PresentationGenerator<JsonObjec | |
return array.build(); | |
} | |
- private JsonObject signPresentation(JsonObject presentationObject, SignatureSuite suite, String suiteIdentifier, PrivateKey pk, String publicKeyId, String controller) { | |
- var keyIdUri = URI.create(publicKeyId); | |
+ private JsonObject signPresentation(JsonObject presentationObject, SignatureSuite suite, String suiteIdentifier, | |
+ JWSSigner jwsSigner, String publicKeyId, String controller) { | |
var controllerUri = URI.create(controller); | |
var verificationMethodType = URI.create(suiteIdentifier); | |
- var jwk = CryptoConverter.createJwk(new KeyPair(null, pk)); | |
- | |
- var keypair = new JsonWebKeyPair(keyIdUri, verificationMethodType, controllerUri, jwk); | |
- | |
var proofDraft = Jws2020ProofDraft.Builder.newInstance() | |
+ .jwsSigner(jwsSigner) | |
.proofPurpose(ASSERTION_METHOD) | |
.verificationMethod(new JsonWebKeyPair(URI.create(controller + "#" + publicKeyId), verificationMethodType, controllerUri, null)) | |
.created(Instant.now()) | |
.mapper(mapper) | |
.build(); | |
- return ldpIssuer.signDocument(suite, presentationObject, keypair, proofDraft) | |
+ return ldpIssuer.signDocument(suite, presentationObject, keyPairMock(), proofDraft) | |
.orElseThrow(f -> new EdcException(f.getFailureDetail())); | |
} | |
+ KeyPair keyPairMock() { | |
+ return new KeyPair() { | |
+ @Override | |
+ public byte[] privateKey() { | |
+ return new byte[0]; | |
+ } | |
+ | |
+ @Override | |
+ public String algorithm() { | |
+ return null; | |
+ } | |
+ | |
+ @Override | |
+ public byte[] publicKey() { | |
+ return new byte[0]; | |
+ } | |
+ | |
+ @Override | |
+ public URI id() { | |
+ return null; | |
+ } | |
+ | |
+ @Override | |
+ public URI type() { | |
+ return null; | |
+ } | |
+ | |
+ @Override | |
+ public URI controller() { | |
+ return null; | |
+ } | |
+ }; | |
+ } | |
+ | |
private JsonArrayBuilder stringArray(Collection<?> values) { | |
var ja = Json.createArrayBuilder(); | |
values.forEach(s -> ja.add(s.toString())); | |
diff --git spi/verifiable-credential-spi/build.gradle.kts spi/verifiable-credential-spi/build.gradle.kts | |
index 75fb756..456534f 100644 | |
--- spi/verifiable-credential-spi/build.gradle.kts | |
+++ spi/verifiable-credential-spi/build.gradle.kts | |
@@ -24,9 +24,9 @@ dependencies { | |
api(project(":spi:participant-context-spi")) | |
api(libs.edc.spi.dcp) | |
+ implementation(libs.nimbus.jwt) | |
testImplementation(libs.edc.lib.json) | |
- testFixturesImplementation(libs.nimbus.jwt) | |
testFixturesImplementation(libs.edc.spi.identity.did) | |
testFixturesImplementation(libs.edc.common.crypto) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment