summaryrefslogtreecommitdiffstats
path: root/container-disc
diff options
context:
space:
mode:
authorMorten Tokle <mortent@oath.com>2017-10-24 13:08:24 +0200
committerMorten Tokle <mortent@oath.com>2017-10-24 13:08:24 +0200
commit045d7020da4384b460ffb1c4b8edea924b7ba118 (patch)
tree15644f4d3dd2f817d464bb9fe7a7c4755618b5a6 /container-disc
parent52f40803e3c989b7aecf7784d656b7b485d89b88 (diff)
separate interface from implementation
Diffstat (limited to 'container-disc')
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java144
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java145
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java7
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProviderTest.java3
4 files changed, 157 insertions, 142 deletions
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java
index f7717f93db0..55485f2a3ea 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java
@@ -1,149 +1,11 @@
package com.yahoo.container.jdisc.athenz;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.annotations.Beta;
-import com.google.inject.Inject;
-import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.component.AbstractComponent;
-import com.yahoo.container.core.identity.IdentityConfig;
-import com.yahoo.container.jdisc.athenz.impl.AthenzService;
-import com.yahoo.container.jdisc.athenz.impl.InstanceIdentity;
-import com.yahoo.container.jdisc.athenz.impl.InstanceRegisterInformation;
-import com.yahoo.container.jdisc.athenz.impl.ServiceProviderApi;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.ExtensionsGenerator;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.bouncycastle.pkcs.PKCS10CertificationRequest;
-import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
-import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
-import org.bouncycastle.util.io.pem.PemObject;
-
-import javax.security.auth.x500.X500Principal;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-
/**
* @author mortent
*/
-@Beta
-// TODO Separate out into interface and "hidden" implementation
-public final class AthenzIdentityProvider extends AbstractComponent {
-
- private InstanceIdentity instanceIdentity;
-
- private final String dnsSuffix;
- private final String providerUniqueId;
-
- @Inject
- public AthenzIdentityProvider(IdentityConfig config, ConfigserverConfig configserverConfig) throws IOException {
- this(config, new ServiceProviderApi(configserverConfig.loadBalancerAddress()), new AthenzService());
- }
-
- // Test only
- public AthenzIdentityProvider(IdentityConfig config, ServiceProviderApi serviceProviderApi, AthenzService athenzService) throws IOException {
- KeyPair keyPair = createKeyPair();
- String signedIdentityDocument = serviceProviderApi.getSignedIdentityDocument();
- String athenzUrl = getZtsEndpoint(signedIdentityDocument);
- dnsSuffix = getDnsSuffix(signedIdentityDocument);
- providerUniqueId = getProviderUniqueId(signedIdentityDocument);
- String providerServiceName = getProviderServiceName(signedIdentityDocument);
-
- InstanceRegisterInformation instanceRegisterInformation = new InstanceRegisterInformation(
- providerServiceName,
- config.domain(),
- config.serviceName(),
- signedIdentityDocument,
- createCSR(keyPair, config),
- true
- );
- instanceIdentity = athenzService.sendInstanceRegisterRequest(instanceRegisterInformation, athenzUrl);
- }
-
- private static String getProviderUniqueId(String signedIdentityDocument) throws IOException {
- return getJsonNode(signedIdentityDocument, "provider-unique-id");
- }
-
- private static String getDnsSuffix(String signedIdentityDocument) throws IOException {
- return getJsonNode(signedIdentityDocument, "dns-suffix");
- }
-
- private static String getProviderServiceName(String signedIdentityDocument) throws IOException {
- return getJsonNode(signedIdentityDocument, "provider-service");
- }
+public interface AthenzIdentityProvider {
- private static String getZtsEndpoint(String signedIdentityDocument) throws IOException {
- return getJsonNode(signedIdentityDocument, "zts-endpoint");
- }
+ String getNToken();
- private static String getJsonNode(String jsonString, String path) throws IOException {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = mapper.readTree(jsonString);
- return jsonNode.get(path).asText();
- }
-
- private static KeyPair createKeyPair() {
- try {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
- return kpg.generateKeyPair();
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
- }
-
- private String createCSR(KeyPair keyPair, IdentityConfig identityConfig) throws IOException {
-
- try {
- // Add SAN dnsname <service>.<domain-with-dashes>.<provider-dnsname-suffix>
- // and SAN dnsname <provider-unique-instance-id>.instanceid.athenz.<provider-dnsname-suffix>
- GeneralNames subjectAltNames = new GeneralNames(new GeneralName[]{
- new GeneralName(GeneralName.dNSName, String.format("%s.%s.%s",
- identityConfig.serviceName(),
- identityConfig.domain().replace(".", "-"),
- dnsSuffix)),
- new GeneralName(GeneralName.dNSName, String.format("%s.instanceid.athenz.%s",
- providerUniqueId,
- dnsSuffix))
- });
-
- ExtensionsGenerator extGen = new ExtensionsGenerator();
- extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
-
- X500Principal subject = new X500Principal(
- String.format("CN=%s.%s", identityConfig.domain(), identityConfig.serviceName()));
-
- PKCS10CertificationRequestBuilder requestBuilder =
- new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
- requestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
- PKCS10CertificationRequest csr = requestBuilder.build(
- new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate()));
-
- PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());
- try (StringWriter stringWriter = new StringWriter()) {
- try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
- pemWriter.writeObject(pemObject);
- return stringWriter.toString();
- }
- }
- } catch (OperatorCreationException e) {
- throw new RuntimeException(e);
- }
- }
-
- public String getNToken() {
- return instanceIdentity.getServiceToken();
- }
-
- public String getX509Cert() {
- return instanceIdentity.getX509Certificate();
- }
+ String getX509Cert();
}
-
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java
new file mode 100644
index 00000000000..d269747c418
--- /dev/null
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java
@@ -0,0 +1,145 @@
+package com.yahoo.container.jdisc.athenz.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.container.core.identity.IdentityConfig;
+import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.ExtensionsGenerator;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.pkcs.PKCS10CertificationRequest;
+import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
+import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
+import org.bouncycastle.util.io.pem.PemObject;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author mortent
+ */
+public final class AthenzIdentityProviderImpl extends AbstractComponent implements AthenzIdentityProvider {
+
+ private InstanceIdentity instanceIdentity;
+
+ private final String dnsSuffix;
+ private final String providerUniqueId;
+
+ @Inject
+ public AthenzIdentityProviderImpl(IdentityConfig config, ConfigserverConfig configserverConfig) throws IOException {
+ this(config, new ServiceProviderApi(configserverConfig.loadBalancerAddress()), new AthenzService());
+ }
+
+ // Test only
+ public AthenzIdentityProviderImpl(IdentityConfig config, ServiceProviderApi serviceProviderApi, AthenzService athenzService) throws IOException {
+ KeyPair keyPair = createKeyPair();
+ String signedIdentityDocument = serviceProviderApi.getSignedIdentityDocument();
+ String athenzUrl = getZtsEndpoint(signedIdentityDocument);
+ dnsSuffix = getDnsSuffix(signedIdentityDocument);
+ providerUniqueId = getProviderUniqueId(signedIdentityDocument);
+ String providerServiceName = getProviderServiceName(signedIdentityDocument);
+
+ InstanceRegisterInformation instanceRegisterInformation = new InstanceRegisterInformation(
+ providerServiceName,
+ config.domain(),
+ config.serviceName(),
+ signedIdentityDocument,
+ createCSR(keyPair, config),
+ true
+ );
+ instanceIdentity = athenzService.sendInstanceRegisterRequest(instanceRegisterInformation, athenzUrl);
+ }
+
+ private static String getProviderUniqueId(String signedIdentityDocument) throws IOException {
+ return getJsonNode(signedIdentityDocument, "provider-unique-id");
+ }
+
+ private static String getDnsSuffix(String signedIdentityDocument) throws IOException {
+ return getJsonNode(signedIdentityDocument, "dns-suffix");
+ }
+
+ private static String getProviderServiceName(String signedIdentityDocument) throws IOException {
+ return getJsonNode(signedIdentityDocument, "provider-service");
+ }
+
+ private static String getZtsEndpoint(String signedIdentityDocument) throws IOException {
+ return getJsonNode(signedIdentityDocument, "zts-endpoint");
+ }
+
+ private static String getJsonNode(String jsonString, String path) throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = mapper.readTree(jsonString);
+ return jsonNode.get(path).asText();
+ }
+
+ private static KeyPair createKeyPair() {
+ try {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ return kpg.generateKeyPair();
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String createCSR(KeyPair keyPair, IdentityConfig identityConfig) throws IOException {
+
+ try {
+ // Add SAN dnsname <service>.<domain-with-dashes>.<provider-dnsname-suffix>
+ // and SAN dnsname <provider-unique-instance-id>.instanceid.athenz.<provider-dnsname-suffix>
+ GeneralNames subjectAltNames = new GeneralNames(new GeneralName[]{
+ new GeneralName(GeneralName.dNSName, String.format("%s.%s.%s",
+ identityConfig.serviceName(),
+ identityConfig.domain().replace(".", "-"),
+ dnsSuffix)),
+ new GeneralName(GeneralName.dNSName, String.format("%s.instanceid.athenz.%s",
+ providerUniqueId,
+ dnsSuffix))
+ });
+
+ ExtensionsGenerator extGen = new ExtensionsGenerator();
+ extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
+
+ X500Principal subject = new X500Principal(
+ String.format("CN=%s.%s", identityConfig.domain(), identityConfig.serviceName()));
+
+ PKCS10CertificationRequestBuilder requestBuilder =
+ new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
+ requestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
+ PKCS10CertificationRequest csr = requestBuilder.build(
+ new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate()));
+
+ PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());
+ try (StringWriter stringWriter = new StringWriter()) {
+ try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
+ pemWriter.writeObject(pemObject);
+ return stringWriter.toString();
+ }
+ }
+ } catch (OperatorCreationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getNToken() {
+ return instanceIdentity.getServiceToken();
+ }
+
+ @Override
+ public String getX509Cert() {
+ return instanceIdentity.getX509Certificate();
+ }
+}
+
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java
new file mode 100644
index 00000000000..b239d8480ec
--- /dev/null
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * @author mortent
+ */
+@ExportPackage
+package com.yahoo.container.jdisc.athenz.impl;
+
+import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProviderTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProviderTest.java
index 2651cfd3a63..4577402b8c1 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProviderTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProviderTest.java
@@ -1,6 +1,7 @@
package com.yahoo.container.jdisc.athenz;
import com.yahoo.container.core.identity.IdentityConfig;
+import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl;
import com.yahoo.container.jdisc.athenz.impl.AthenzService;
import com.yahoo.container.jdisc.athenz.impl.InstanceIdentity;
import com.yahoo.container.jdisc.athenz.impl.ServiceProviderApi;
@@ -29,7 +30,7 @@ public class AthenzIdentityProviderTest {
when(athenzService.sendInstanceRegisterRequest(any(), anyString())).thenReturn(
new InstanceIdentity(null, null, null, null, null, null, null, null, "TOKEN"));
- AthenzIdentityProvider identityProvider = new AthenzIdentityProvider(config, serviceProviderApi, athenzService);
+ AthenzIdentityProvider identityProvider = new AthenzIdentityProviderImpl(config, serviceProviderApi, athenzService);
Assert.assertEquals("TOKEN", identityProvider.getNToken());
}