summaryrefslogtreecommitdiffstats
path: root/vespa-athenz
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-05-14 16:58:07 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-05-18 13:21:38 +0200
commitcf8af6d6ce0be3dd565b1f7a14f0648d482b3e42 (patch)
treec2ee7c98daf6f35a988f9e45cb48b78f84b761f9 /vespa-athenz
parent73fa58e682c278b190ad89f7c74919b5e70b1d24 (diff)
Expose underlying certificate and private key from SiaIdentityProvider
Extend ServiceIdentityProvider interface with new methods. Add class that bundles certificate with private key. Use Path instead of File for better compatibility with mocked file system in unit tests.
Diffstat (limited to 'vespa-athenz')
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/ServiceIdentityProvider.java10
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java32
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java17
-rw-r--r--vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identity/SiaIdentityProviderTest.java12
4 files changed, 48 insertions, 23 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/ServiceIdentityProvider.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/ServiceIdentityProvider.java
index e5ed885b316..180d052c8dc 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/ServiceIdentityProvider.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/ServiceIdentityProvider.java
@@ -2,18 +2,22 @@
package com.yahoo.vespa.athenz.identity;
import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider;
+import com.yahoo.security.X509CertificateWithKey;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzService;
import javax.net.ssl.SSLContext;
+import java.nio.file.Path;
/**
- * A interface for types that provides a service identity.
- * Some similarities to {@link AthenzIdentityProvider}, but this type is not public api and intended for internal use.
+ * A interface for types that provides the Athenz service identity (SIA) from the environment.
+ * Some similarities to {@link AthenzIdentityProvider}, but this type is not public API and intended for internal use.
*
* @author bjorncs
*/
public interface ServiceIdentityProvider {
AthenzIdentity identity();
SSLContext getIdentitySslContext();
+ X509CertificateWithKey getIdentityCertificateWithKey();
+ Path certificatePath();
+ Path privateKeyPath();
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java
index 4981b80998f..082925048cb 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java
@@ -5,13 +5,13 @@ import com.google.inject.Inject;
import com.yahoo.component.AbstractComponent;
import com.yahoo.security.KeyStoreType;
import com.yahoo.security.SslContextBuilder;
+import com.yahoo.security.X509CertificateWithKey;
import com.yahoo.security.tls.AutoReloadingX509KeyManager;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.utils.SiaUtils;
import javax.net.ssl.SSLContext;
-import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -26,34 +26,38 @@ public class SiaIdentityProvider extends AbstractComponent implements ServiceIde
private final AutoReloadingX509KeyManager keyManager;
private final SSLContext sslContext;
private final AthenzIdentity service;
+ private final Path certificateFile;
+ private final Path privateKeyFile;
@Inject
public SiaIdentityProvider(SiaProviderConfig config) {
this(new AthenzService(config.athenzDomain(), config.athenzService()),
- SiaUtils.getPrivateKeyFile(Paths.get(config.keyPathPrefix()), new AthenzService(config.athenzDomain(), config.athenzService())).toFile(),
- SiaUtils.getCertificateFile(Paths.get(config.keyPathPrefix()), new AthenzService(config.athenzDomain(), config.athenzService())).toFile(),
- new File(config.trustStorePath()),
+ SiaUtils.getPrivateKeyFile(Paths.get(config.keyPathPrefix()), new AthenzService(config.athenzDomain(), config.athenzService())),
+ SiaUtils.getCertificateFile(Paths.get(config.keyPathPrefix()), new AthenzService(config.athenzDomain(), config.athenzService())),
+ Paths.get(config.trustStorePath()),
config.trustStoreType());
}
public SiaIdentityProvider(AthenzIdentity service,
Path siaPath,
- File trustStoreFile) {
+ Path trustStoreFile) {
this(service,
- SiaUtils.getPrivateKeyFile(siaPath, service).toFile(),
- SiaUtils.getCertificateFile(siaPath, service).toFile(),
+ SiaUtils.getPrivateKeyFile(siaPath, service),
+ SiaUtils.getCertificateFile(siaPath, service),
trustStoreFile,
SiaProviderConfig.TrustStoreType.Enum.jks);
}
public SiaIdentityProvider(AthenzIdentity service,
- File privateKeyFile,
- File certificateFile,
- File trustStoreFile,
+ Path privateKeyFile,
+ Path certificateFile,
+ Path trustStoreFile,
SiaProviderConfig.TrustStoreType.Enum trustStoreType) {
this.service = service;
- this.keyManager = AutoReloadingX509KeyManager.fromPemFiles(privateKeyFile.toPath(), certificateFile.toPath());
- this.sslContext = createIdentitySslContext(keyManager, trustStoreFile.toPath(), trustStoreType);
+ this.keyManager = AutoReloadingX509KeyManager.fromPemFiles(privateKeyFile, certificateFile);
+ this.sslContext = createIdentitySslContext(keyManager, trustStoreFile, trustStoreType);
+ this.certificateFile = certificateFile;
+ this.privateKeyFile = privateKeyFile;
}
@Override
@@ -66,6 +70,10 @@ public class SiaIdentityProvider extends AbstractComponent implements ServiceIde
return sslContext;
}
+ @Override public X509CertificateWithKey getIdentityCertificateWithKey() { return keyManager.getCurrentCertificateWithKey(); }
+ @Override public Path certificatePath() { return certificateFile; }
+ @Override public Path privateKeyPath() { return privateKeyFile; }
+
private static SSLContext createIdentitySslContext(AutoReloadingX509KeyManager keyManager, Path trustStoreFile,
SiaProviderConfig.TrustStoreType.Enum trustStoreType) {
var builder = new SslContextBuilder();
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
index 71a4c1a9954..a52ad159fdc 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
@@ -10,11 +10,11 @@ import com.yahoo.container.core.identity.IdentityConfig;
import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider;
import com.yahoo.container.jdisc.athenz.AthenzIdentityProviderException;
import com.yahoo.jdisc.Metric;
-import java.util.logging.Level;
import com.yahoo.security.KeyStoreBuilder;
import com.yahoo.security.KeyStoreType;
import com.yahoo.security.Pkcs10Csr;
import com.yahoo.security.SslContextBuilder;
+import com.yahoo.security.X509CertificateWithKey;
import com.yahoo.security.tls.MutableX509KeyManager;
import com.yahoo.vespa.athenz.api.AthenzAccessToken;
import com.yahoo.vespa.athenz.api.AthenzDomain;
@@ -44,6 +44,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
+import java.util.logging.Level;
import java.util.logging.Logger;
import static com.yahoo.security.KeyStoreType.JKS;
@@ -55,6 +56,8 @@ import static com.yahoo.security.KeyStoreType.PKCS12;
* @author mortent
* @author bjorncs
*/
+// This class should probably not implement ServiceIdentityProvider,
+// as that interface is intended for providing the node's identity, not the tenant's application identity.
public final class AthenzIdentityProviderImpl extends AbstractComponent implements AthenzIdentityProvider, ServiceIdentityProvider {
private static final Logger log = Logger.getLogger(AthenzIdentityProviderImpl.class.getName());
@@ -176,6 +179,16 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen
}
@Override
+ public X509CertificateWithKey getIdentityCertificateWithKey() {
+ AthenzCredentials copy = this.credentials;
+ return new X509CertificateWithKey(copy.getCertificate(), copy.getKeyPair().getPrivate());
+ }
+
+ // The files should ideally not be used directly, must be implemented later if necessary
+ @Override public Path certificatePath() { throw new UnsupportedOperationException(); }
+ @Override public Path privateKeyPath() { throw new UnsupportedOperationException(); }
+
+ @Override
public SSLContext getRoleSslContext(String domain, String role) {
// This ssl context should ideally be cached as it is quite expensive to create.
try {
@@ -288,7 +301,7 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen
private static SiaIdentityProvider createNodeIdentityProvider(IdentityConfig config, Path trustStore) {
return new SiaIdentityProvider(
- new AthenzService(config.nodeIdentityName()), SiaUtils.DEFAULT_SIA_DIRECTORY, trustStore.toFile());
+ new AthenzService(config.nodeIdentityName()), SiaUtils.DEFAULT_SIA_DIRECTORY, trustStore);
}
private boolean isExpired(AthenzCredentials credentials) {
diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identity/SiaIdentityProviderTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identity/SiaIdentityProviderTest.java
index ce02860cc78..1fe32561f82 100644
--- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identity/SiaIdentityProviderTest.java
+++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identity/SiaIdentityProviderTest.java
@@ -52,9 +52,9 @@ public class SiaIdentityProviderTest {
SiaIdentityProvider provider =
new SiaIdentityProvider(
new AthenzService("domain", "service-name"),
- keyFile,
- certificateFile,
- trustStoreFile,
+ keyFile.toPath(),
+ certificateFile.toPath(),
+ trustStoreFile.toPath(),
SiaProviderConfig.TrustStoreType.Enum.jks);
assertNotNull(provider.getIdentitySslContext());
@@ -76,9 +76,9 @@ public class SiaIdentityProviderTest {
SiaIdentityProvider provider =
new SiaIdentityProvider(
new AthenzService("domain", "service-name"),
- keyFile,
- certificateFile,
- trustStoreFile,
+ keyFile.toPath(),
+ certificateFile.toPath(),
+ trustStoreFile.toPath(),
SiaProviderConfig.TrustStoreType.Enum.pem);
assertNotNull(provider.getIdentitySslContext());