Skip to content

Commit

Permalink
feat: move key-related classes into a separate SPI and Lib module (#4038
Browse files Browse the repository at this point in the history
)

* Move key-related classes into a separate SPI and Lib module

* Move resources

* Add test resource

* Move key classes to dedicated SPI
  • Loading branch information
jimmarino authored Mar 22, 2024
1 parent 7493208 commit b6e26c1
Show file tree
Hide file tree
Showing 87 changed files with 245 additions and 141 deletions.
2 changes: 2 additions & 0 deletions core/common/connector-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ plugins {
dependencies {
api(project(":spi:common:core-spi"))
api(project(":spi:common:http-spi"))
api(project(":spi:common:keys-spi"))
api(project(":spi:common:policy-engine-spi"))
api(project(":spi:common:transaction-spi"))
api(project(":spi:common:transaction-datasource-spi"))
Expand All @@ -34,6 +35,7 @@ dependencies {
implementation(project(":core:common:validator-core"))
implementation(project(":core:common:lib:boot-lib"))
implementation(project(":core:common:lib:http-lib"))
implementation(project(":core:common:lib:keys-lib"))

implementation(libs.bouncyCastle.bcpkixJdk18on)
implementation(libs.nimbus.jwt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

package org.eclipse.edc.connector.core;

import org.eclipse.edc.connector.core.security.LocalPublicKeyServiceImpl;
import org.eclipse.edc.keys.LocalPublicKeyServiceImpl;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.keys.spi.LocalPublicKeyService;
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.Provides;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.iam.LocalPublicKeyService;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParserRegistry;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@

package org.eclipse.edc.connector.core;

import org.eclipse.edc.connector.core.security.KeyParserRegistryImpl;
import org.eclipse.edc.connector.core.security.keyparsers.JwkParser;
import org.eclipse.edc.connector.core.security.keyparsers.PemParser;
import org.eclipse.edc.keys.KeyParserRegistryImpl;
import org.eclipse.edc.keys.VaultCertificateResolver;
import org.eclipse.edc.keys.VaultPrivateKeyResolver;
import org.eclipse.edc.keys.keyparsers.JwkParser;
import org.eclipse.edc.keys.keyparsers.PemParser;
import org.eclipse.edc.keys.spi.CertificateResolver;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
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.spi.security.CertificateResolver;
import org.eclipse.edc.spi.security.KeyParserRegistry;
import org.eclipse.edc.spi.security.PrivateKeyResolver;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.security.VaultCertificateResolver;
import org.eclipse.edc.spi.security.VaultPrivateKeyResolver;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import org.eclipse.edc.connector.core.event.EventExecutorServiceContainer;
import org.eclipse.edc.junit.extensions.DependencyInjectionExtension;
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
import org.eclipse.edc.policy.model.PolicyRegistrationTypes;
import org.eclipse.edc.spi.security.PrivateKeyResolver;
import org.eclipse.edc.spi.system.ExecutorInstrumentation;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.injection.ObjectFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

package org.eclipse.edc.connector.core;

import org.eclipse.edc.connector.core.security.LocalPublicKeyServiceImpl;
import org.eclipse.edc.junit.extensions.DependencyInjectionExtension;
import org.eclipse.edc.junit.testfixtures.TestUtils;
import org.eclipse.edc.keys.LocalPublicKeyServiceImpl;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParserRegistry;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.configuration.ConfigFactory;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -92,7 +92,7 @@ void localPublicKeyService_shouldRaiseException_withoutValueOrPath(LocalPublicKe
when(context.getConfig(EDC_PUBLIC_KEYS_PREFIX)).thenReturn(ConfigFactory.fromMap(keys));
extension.initialize(context);

assertThatThrownBy(() -> extension.prepare()).isInstanceOf(EdcException.class);
assertThatThrownBy(extension::prepare).isInstanceOf(EdcException.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
package org.eclipse.edc.connector.core;

import org.eclipse.edc.junit.extensions.DependencyInjectionExtension;
import org.eclipse.edc.spi.security.CertificateResolver;
import org.eclipse.edc.spi.security.VaultPrivateKeyResolver;
import org.eclipse.edc.keys.VaultPrivateKeyResolver;
import org.eclipse.edc.keys.spi.CertificateResolver;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down
32 changes: 32 additions & 0 deletions core/common/lib/keys-lib/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

plugins {
`java-library`
`java-test-fixtures`
`maven-publish`
}

dependencies {
api(project(":spi:common:keys-spi"))
api(project(":spi:common:core-spi"))
implementation(libs.bouncyCastle.bcpkixJdk18on)
implementation(libs.nimbus.jwt)
implementation(libs.tink)

testImplementation(project(":core:common:junit"));

}


Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
*
*/

package org.eclipse.edc.spi.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.system.configuration.Config;
import org.jetbrains.annotations.NotNull;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
*
*/

package org.eclipse.edc.spi.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.spi.iam.PublicKeyResolver;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.keys.spi.PublicKeyResolver;
import org.eclipse.edc.spi.result.Result;

import java.security.PublicKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
*
*/

package org.eclipse.edc.connector.core.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.keys.spi.KeyParser;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParser;
import org.eclipse.edc.spi.security.KeyParserRegistry;

import java.security.Key;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
*
*/

package org.eclipse.edc.connector.core.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.spi.iam.LocalPublicKeyService;
import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.keys.spi.LocalPublicKeyService;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParserRegistry;
import org.eclipse.edc.spi.security.Vault;

import java.security.PublicKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
*
*/

package org.eclipse.edc.spi.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.keys.spi.CertificateResolver;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.security.Vault;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
*
*/

package org.eclipse.edc.spi.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.keys.spi.KeyParserRegistry;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.system.configuration.Config;
import org.jetbrains.annotations.NotNull;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
*/

package org.eclipse.edc.connector.core.security.keyparsers;
package org.eclipse.edc.keys.keyparsers;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.jwk.Curve;
Expand All @@ -24,9 +24,9 @@
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.eclipse.edc.keys.spi.KeyParser;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParser;

import java.io.IOException;
import java.security.Key;
Expand All @@ -40,8 +40,6 @@
import java.text.ParseException;
import java.util.List;

import static org.eclipse.edc.spi.result.Result.failure;

/**
* KeyParser that can parse a private key represented in JWK format. Specifically, it can handle the following keys:
* <ul>
Expand Down Expand Up @@ -102,10 +100,10 @@ public Result<Key> parse(String encoded) {
.findFirst()
.or(() -> list.stream().filter(k -> k instanceof PublicKey).findFirst())
.map(Result::success)
.orElse(failure(ERROR_NO_KEY));
.orElse(Result.failure(ERROR_NO_KEY));
} catch (ParseException | NoSuchAlgorithmException | IOException | InvalidKeySpecException e) {
monitor.warning("Parser error", e);
return failure("Parser error: " + e.getMessage());
return Result.failure("Parser error: " + e.getMessage());
}
}

Expand All @@ -114,7 +112,7 @@ private Result<? extends Key> parseOctetKeyPair(OctetKeyPair okp) throws NoSuchA
var x = okp.getDecodedX();

if (d == null && x == null) {
return failure(ERROR_NO_KEY);
return Result.failure(ERROR_NO_KEY);
}

// if the JWK contains a private key, return that, otherwise return just the public key
Expand All @@ -138,7 +136,7 @@ private Result<PrivateKey> readPrivateKey(Curve curve, byte[] decodedD) throws I
keyFactory = KeyFactory.getInstance(Curve.X25519.getName());
privKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), new DEROctetString(decodedD));
} else {
return failure("Cannot parse an OctetKeyPair with Curve %s".formatted(curve));
return Result.failure("Cannot parse an OctetKeyPair with Curve %s".formatted(curve));
}

var pkcs8KeySpec = new PKCS8EncodedKeySpec(privKeyInfo.getEncoded());
Expand All @@ -160,7 +158,7 @@ private Result<PublicKey> readPublicKey(Curve curve, byte[] decodedX) throws Inv
var publicKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), decodedX);
x509KeySpec = new X509EncodedKeySpec(publicKeyInfo.getEncoded());
} else {
return failure("Cannot parse an OctetKeyPair with Curve %s".formatted(curve));
return Result.failure("Cannot parse an OctetKeyPair with Curve %s".formatted(curve));

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
*/

package org.eclipse.edc.connector.core.security.keyparsers;
package org.eclipse.edc.keys.keyparsers;

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
Expand All @@ -21,9 +21,9 @@
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.eclipse.edc.keys.spi.KeyParser;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParser;

import java.io.IOException;
import java.io.StringReader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@
*
*/

package org.eclipse.edc.connector.core.security;
package org.eclipse.edc.keys;

import org.eclipse.edc.junit.assertions.AbstractResultAssert;
import org.eclipse.edc.keys.spi.KeyParser;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.KeyParser;
import org.junit.jupiter.api.Test;

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;

import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat;
import static org.eclipse.edc.spi.result.Result.failure;
import static org.eclipse.edc.spi.result.Result.success;

class KeyParserRegistryImplTest {

private final KeyParserRegistryImpl registry = new KeyParserRegistryImpl();
Expand All @@ -42,16 +39,16 @@ public boolean canHandle(String encoded) {

@Override
public Result<Key> parse(String encoded) {
return success(rsaKey().getPrivate());
return Result.success(rsaKey().getPrivate());
}
});

assertThat(registry.parse(encoded)).isSucceeded();
AbstractResultAssert.assertThat(registry.parse(encoded)).isSucceeded();
}

@Test
void parse_noParser() {
assertThat(registry.parse("test-private-key")).isFailed()
AbstractResultAssert.assertThat(registry.parse("test-private-key")).isFailed()
.detail().isEqualTo("No parser found that can handle that format.");
}

Expand All @@ -65,11 +62,11 @@ public boolean canHandle(String encoded) {

@Override
public Result<Key> parse(String encoded) {
return failure("test-failure");
return Result.failure("test-failure");
}
});

assertThat(registry.parse("test-private-key"))
AbstractResultAssert.assertThat(registry.parse("test-private-key"))
.isFailed()
.detail()
.isEqualTo("test-failure");
Expand Down
Loading

0 comments on commit b6e26c1

Please sign in to comment.