Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use the new JwsSignerProvider interface #419

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ maven/mavencentral/org.eclipse.edc/json-lib/0.8.2-SNAPSHOT, Apache-2.0, approved
maven/mavencentral/org.eclipse.edc/junit-base/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/junit/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/jws2020-lib/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/jwt-signer-spi/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/jwt-spi/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/jwt-verifiable-credentials/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/keys-lib/0.8.2-SNAPSHOT, Apache-2.0, approved, technology.edc
Expand Down
1 change: 1 addition & 0 deletions core/identity-hub-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies {
implementation(libs.edc.lib.jsonld)
implementation(libs.edc.lib.query)
implementation(libs.edc.lib.jws2020)
implementation(libs.edc.lib.common.crypto)
implementation(libs.edc.spi.token)
implementation(libs.edc.spi.identity.did)
implementation(libs.edc.vc.ldp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@
import org.eclipse.edc.identityhub.spi.store.CredentialStore;
import org.eclipse.edc.identityhub.spi.store.KeyPairResourceStore;
import org.eclipse.edc.identityhub.spi.store.ParticipantContextStore;
import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider;
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;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.security.token.jwt.CryptoConverter;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
Expand All @@ -54,6 +58,8 @@ public class DefaultServicesExtension implements ServiceExtension {
@Inject
private TypeManager typeManager;
private RevocationListService revocationService;
@Inject
private PrivateKeyResolver privateKeyResolver;

@Override
public String name() {
Expand Down Expand Up @@ -105,4 +111,11 @@ public RevocationListService createRevocationListService(ServiceExtensionContext
public SignatureSuiteRegistry createSignatureSuiteRegistry() {
return new InMemorySignatureSuiteRegistry();
}

@Provider(isDefault = true)
public JwsSignerProvider defaultSignerProvider() {
// default implementation: resolve the private key (from vault of config) and create a JWSSigner based on its algorithm
return privateKeyId -> privateKeyResolver.resolvePrivateKey(privateKeyId)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also duplicated in the connector, maybe it could be extracted in a class and put in the crypto-common-lib module

Copy link
Member Author

@paullatzelsperger paullatzelsperger Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to merge eclipse-edc/Connector#4403 first

.compose(pk -> Result.ofThrowable(() -> CryptoConverter.createSignerFor(pk)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.eclipse.edc.identityhub.spi.verification.AccessTokenVerifier;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.jsonld.util.JacksonJsonLd;
import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.keys.spi.LocalPublicKeyService;
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
Expand Down Expand Up @@ -120,6 +121,8 @@ public class CoreServicesExtension implements ServiceExtension {
private LocalPublicKeyService fallbackService;
@Inject
private ParticipantContextService participantContextService;
@Inject
private JwsSignerProvider jwsSignerProvider;

@Override
public String name() {
Expand Down Expand Up @@ -148,7 +151,7 @@ public CredentialQueryResolver createCredentialQueryResolver(ServiceExtensionCon
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(clock, new JwtGenerationService(jwsSignerProvider)), 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)),
Expand Down
2 changes: 1 addition & 1 deletion core/identity-hub-did/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies {
implementation(project(":spi:keypair-spi"))
implementation(project(":spi:participant-context-spi"))
implementation(libs.edc.core.connector) // for the reflection-based query resolver
implementation(libs.edc.common.crypto)
implementation(libs.edc.lib.common.crypto)
implementation(libs.edc.lib.store)
implementation(libs.edc.lib.query)

Expand Down
2 changes: 1 addition & 1 deletion core/identity-hub-keypairs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies {
api(project(":spi:identity-hub-store-spi"))
api(libs.edc.spi.transaction)
implementation(project(":core:lib:keypair-lib"))
implementation(libs.edc.common.crypto)
implementation(libs.edc.lib.common.crypto)
implementation(libs.edc.core.connector)
testImplementation(libs.edc.junit)
}
2 changes: 1 addition & 1 deletion core/identity-hub-participants/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dependencies {
api(project(":spi:identity-hub-store-spi"))
api(libs.edc.spi.transaction)
implementation(project(":core:lib:keypair-lib"))
implementation(libs.edc.common.crypto)
implementation(libs.edc.lib.common.crypto)
implementation(libs.edc.core.connector)

testImplementation(libs.edc.lib.keys)
Expand Down
2 changes: 1 addition & 1 deletion core/lib/verifiable-presentation-lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies {
implementation(libs.edc.spi.vc)
implementation(libs.edc.spi.jsonld)
implementation(libs.edc.core.token) // for Jwt generation service, token validation service and rule registry impl
implementation(libs.edc.common.crypto) // for the CryptoConverter
implementation(libs.edc.lib.common.crypto) // for the CryptoConverter
implementation(libs.edc.lib.jws2020)
implementation(libs.edc.vc.ldp)
implementation(libs.edc.verifiablecredentials)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,18 @@
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.stream.Collectors;

import static org.eclipse.edc.identithub.verifiablepresentation.generators.PresentationGeneratorConstants.CONTROLLER_ADDITIONAL_DATA;
Expand All @@ -47,19 +44,17 @@
*/
public class JwtPresentationGenerator implements PresentationGenerator<String> {
public static final String VERIFIABLE_PRESENTATION_CLAIM = "vp";
private final PrivateKeyResolver privateKeyResolver;
private final Clock clock;

private final TokenGenerationService tokenGenerationService;

/**
* 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 clock The clock used for generating timestamps.
* @param clock The clock used for generating timestamps.
* @param tokenGenerationService service to generate (JWT) tokens
*/
public JwtPresentationGenerator(PrivateKeyResolver privateKeyResolver, Clock clock, TokenGenerationService tokenGenerationService) {
this.privateKeyResolver = privateKeyResolver;
public JwtPresentationGenerator(Clock clock, TokenGenerationService tokenGenerationService) {
this.clock = clock;
this.tokenGenerationService = tokenGenerationService;
}
Expand Down Expand Up @@ -107,8 +102,7 @@ public String generatePresentation(List<VerifiableCredentialContainer> credentia
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 -> {
var tokenResult = tokenGenerationService.generate(privateKeyAlias, vpDecorator(rawVcs, issuerId), tp -> {
additionalData.forEach(tp::claims);
return tp;
}, new KeyIdDecorator(composedKeyId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialFormat;
import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredentialContainer;
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.token.JwtGenerationService;
import org.eclipse.edc.token.spi.TokenGenerationService;
Expand All @@ -42,7 +44,7 @@
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.edc.identithub.verifiablepresentation.generators.JwtPresentationGenerator.VERIFIABLE_PRESENTATION_CLAIM;
import static org.eclipse.edc.identithub.verifiablepresentation.generators.PresentationGeneratorConstants.VERIFIABLE_CREDENTIAL_PROPERTY;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand All @@ -53,16 +55,17 @@ class JwtPresentationGeneratorTest extends PresentationGeneratorTest {
"aud", "did:web:test-audience",
"controller", "did:web:test"
);
private final PrivateKeyResolver privateKeyResolver = mock();
private final TokenGenerationService tokenGenerationService = new JwtGenerationService();
private final JwsSignerProvider signerProvider = mock();
private final TokenGenerationService tokenGenerationService = new JwtGenerationService(signerProvider);
private JwtPresentationGenerator creator;

@BeforeEach
void setup() throws JOSEException {
var vpSigningKey = createKey(Curve.P_384, "vp-key");
when(privateKeyResolver.resolvePrivateKey(any())).thenReturn(Result.failure("not found"));
when(privateKeyResolver.resolvePrivateKey(eq(PRIVATE_KEY_ALIAS))).thenReturn(Result.success(vpSigningKey.toPrivateKey()));
creator = new JwtPresentationGenerator(privateKeyResolver, Clock.systemUTC(), tokenGenerationService);
when(signerProvider.createJwsSigner(anyString())).thenReturn(Result.failure("not found"));
when(signerProvider.createJwsSigner(eq(PRIVATE_KEY_ALIAS))).thenReturn(Result.success(new ECDSASigner(vpSigningKey)));

creator = new JwtPresentationGenerator(Clock.systemUTC(), tokenGenerationService);
}

@Test
Expand Down Expand Up @@ -121,7 +124,9 @@ void create_whenVcsEmpty_shouldReturnEmptyVp() {
@DisplayName("Should throw an exception if no private key is found for a key-id")
void create_whenPrivateKeyNotFound() {
var vcc = new VerifiableCredentialContainer("foobar", CredentialFormat.JWT, createDummyCredential());
assertThatThrownBy(() -> creator.generatePresentation(List.of(vcc), "not-exist", PUBLIC_KEY_ID, issuerId, ADDITIONAL_DATA)).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> creator.generatePresentation(List.of(vcc), "not-exist", PUBLIC_KEY_ID, issuerId, ADDITIONAL_DATA))
.isInstanceOf(EdcException.class)
.hasMessage("JWSSigner cannot be generated for private key 'not-exist': not found");
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ edc-lib-store = { "module" = "org.eclipse.edc:store-lib", version.ref = "edc" }
edc-lib-transform = { module = "org.eclipse.edc:transform-lib", version.ref = "edc" }
edc-lib-util = { module = "org.eclipse.edc:util-lib", version.ref = "edc" }
edc-lib-json = { module = "org.eclipse.edc:json-lib", version.ref = "edc" }
edc-common-crypto = { module = "org.eclipse.edc:crypto-common-lib", version.ref = "edc" }
edc-lib-common-crypto = { module = "org.eclipse.edc:crypto-common-lib", version.ref = "edc" }
edc-core-jerseyproviders = { module = "org.eclipse.edc:jersey-providers-lib", version.ref = "edc" }


Expand Down
2 changes: 1 addition & 1 deletion spi/verifiable-credential-spi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ dependencies {
testImplementation(libs.edc.lib.json)
testFixturesImplementation(libs.nimbus.jwt)
testFixturesImplementation(libs.edc.spi.identity.did)
testFixturesImplementation(libs.edc.common.crypto)
testFixturesImplementation(libs.edc.lib.common.crypto)
}
Loading