diff options
author | Bjørn Christian Seime <bjorncs@oath.com> | 2018-04-25 14:15:50 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@oath.com> | 2018-04-25 14:15:50 +0200 |
commit | 448075654a4258a759fb64b778ed5439a684564c (patch) | |
tree | 2df4351354297c8eaa748f57076f55563a616c84 /node-repository | |
parent | d36ba126b204c21406195291acbc67c2acb7db60 (diff) |
Add unit test for AWS host certificates
Diffstat (limited to 'node-repository')
2 files changed, 34 insertions, 7 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticator.java index 977ff97c4ca..d564e02727c 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticator.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticator.java @@ -42,7 +42,7 @@ class HostAuthenticator { List<SubjectAlternativeName> sans = X509CertificateUtils.getSubjectAlternativeNames(clientCertificate); switch (subjectCommonName) { case TENANT_DOCKER_HOST_IDENTITY: - return NodePrincipal.withAthenzIdentity(subjectCommonName, getHostFromCalypsoCertificate(sans), certificateChain); + return NodePrincipal.withAthenzIdentity(subjectCommonName, getHostFromCalypsoOrAwsCertificate(sans), certificateChain); case TENANT_DOCKER_CONTAINER_IDENTITY: return NodePrincipal.withAthenzIdentity(subjectCommonName, getHostFromVespaCertificate(sans), certificateChain); default: @@ -61,6 +61,11 @@ class HostAuthenticator { return issuerCommonName.equals("Yahoo Athenz CA") || issuerCommonName.equals("Athenz AWS CA"); } + // NOTE: AWS instance id is currently stored as the attribute 'openstack-id' in node repository. + private String getHostFromCalypsoOrAwsCertificate(List<SubjectAlternativeName> sans) { + return getHostFromCalypsoCertificate(sans); + } + private String getHostFromCalypsoCertificate(List<SubjectAlternativeName> sans) { String openstackId = getUniqueInstanceId(sans); return nodeRepository.getNodes().stream() diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticatorTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticatorTest.java index fa9bc47c2d5..e6e7880c67c 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticatorTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/HostAuthenticatorTest.java @@ -44,10 +44,12 @@ import static org.junit.Assert.assertEquals; public class HostAuthenticatorTest { private static final String HOSTNAME = "myhostname"; private static final String OPENSTACK_ID = "OPENSTACK-ID"; + private static final String AWS_INSTANCE_ID = "i-abcdef123456"; private static final String INSTANCE_ID = "default"; private static final Zone ZONE = new Zone(SystemName.main, Environment.prod, RegionName.defaultName()); private static final KeyPair KEYPAIR = KeyUtils.generateKeypair(RSA); - private static final X509Certificate ATHENZ_CA_DUMMY = createAthenzCaDummyCertificate(); + private static final X509Certificate ATHENZ_YAHOO_CA_CERT = createDummyCaCertificate("Yahoo Athenz CA"); + private static final X509Certificate ATHENZ_AWS_CA_CERT = createDummyCaCertificate("Athenz AWS CA"); @Test public void accepts_configserver_selfsigned_cert() { @@ -73,7 +75,7 @@ public class HostAuthenticatorTest { .fromKeypair(new X500Principal("CN=" + identityName), KEYPAIR, SHA256_WITH_RSA) .build(); X509Certificate certificate = X509CertificateBuilder - .fromCsr(csr, ATHENZ_CA_DUMMY.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) + .fromCsr(csr, ATHENZ_YAHOO_CA_CERT.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) .addSubjectAlternativeName(OPENSTACK_ID + ".instanceid.athenz.provider-name.ostk.yahoo.cloud") .build(); HostAuthenticator authenticator = new HostAuthenticator(ZONE, nodeRepositoryDummy.nodeRepository()); @@ -84,6 +86,26 @@ public class HostAuthenticatorTest { } @Test + public void accepts_aws_host_certificate() { + NodeRepositoryTester nodeRepositoryDummy = new NodeRepositoryTester(); + nodeRepositoryDummy.addNode(AWS_INSTANCE_ID, HOSTNAME, INSTANCE_ID, NodeType.host); + nodeRepositoryDummy.setNodeState(HOSTNAME, Node.State.active); + String identityName = "vespa.vespa.tenant-host"; + Pkcs10Csr csr = Pkcs10CsrBuilder + .fromKeypair(new X500Principal("CN=" + identityName), KEYPAIR, SHA256_WITH_RSA) + .build(); + X509Certificate certificate = X509CertificateBuilder + .fromCsr(csr, ATHENZ_AWS_CA_CERT.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) + .addSubjectAlternativeName(AWS_INSTANCE_ID + ".instanceid.athenz.aws.oath.cloud") + .build(); + HostAuthenticator authenticator = new HostAuthenticator(ZONE, nodeRepositoryDummy.nodeRepository()); + NodePrincipal identity = authenticator.authenticate(singletonList(certificate)); + assertTrue(identity.getHostname().isPresent()); + assertEquals(HOSTNAME, identity.getHostname().get()); + assertEquals(identityName, identity.getHostIdentityName()); + } + + @Test public void accepts_docker_container_certificate() { String clusterId = "clusterid"; int clusterIndex = 0; @@ -100,7 +122,7 @@ public class HostAuthenticatorTest { .build(); VespaUniqueInstanceId vespaUniqueInstanceId = new VespaUniqueInstanceId(clusterIndex, clusterId, INSTANCE_ID, application, tenant, region, environment); X509Certificate certificate = X509CertificateBuilder - .fromCsr(csr, ATHENZ_CA_DUMMY.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) + .fromCsr(csr, ATHENZ_YAHOO_CA_CERT.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) .addSubjectAlternativeName(vespaUniqueInstanceId.asDottedString() + ".instanceid.athenz.provider-name.vespa.yahoo.cloud") .build(); HostAuthenticator authenticator = new HostAuthenticator(ZONE, nodeRepositoryDummy.nodeRepository()); @@ -118,7 +140,7 @@ public class HostAuthenticatorTest { .fromKeypair(new X500Principal("CN=" + identityName), KEYPAIR, SHA256_WITH_RSA) .build(); X509Certificate certificate = X509CertificateBuilder - .fromCsr(csr, ATHENZ_CA_DUMMY.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) + .fromCsr(csr, ATHENZ_YAHOO_CA_CERT.getSubjectX500Principal(), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), KEYPAIR.getPrivate(), SHA256_WITH_RSA, 1) .build(); HostAuthenticator authenticator = new HostAuthenticator(ZONE, nodeRepositoryDummy.nodeRepository()); NodePrincipal identity = authenticator.authenticate(singletonList(certificate)); @@ -151,11 +173,11 @@ public class HostAuthenticatorTest { } - private static X509Certificate createAthenzCaDummyCertificate() { + private static X509Certificate createDummyCaCertificate(String caCommonName) { KeyPair keyPair = KeyUtils.generateKeypair(RSA); return X509CertificateBuilder .fromKeypair( - keyPair, new X500Principal("CN=Yahoo Athenz CA"), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), SHA256_WITH_RSA, 1) + keyPair, new X500Principal("CN=" + caCommonName), Instant.EPOCH, Instant.EPOCH.plusSeconds(60), SHA256_WITH_RSA, 1) .setBasicConstraints(true, true) .build(); |