diff options
author | Bjørn Christian Seime <bjorncs@oath.com> | 2018-06-12 18:19:28 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@oath.com> | 2018-06-12 18:19:28 +0200 |
commit | a2989608d5ddee1ce6ad870ce2aeab14495d96e9 (patch) | |
tree | 03f15ceedb5afc42092e6dd1b60fbb795cdebab3 /athenz-identity-provider-service/src | |
parent | d8d316de3028e101140bff177ffa6ce66c17524e (diff) |
Separate generating and validating signature to separate class
- Move signature logic to IdentityDocumentSigner
- Stop using fields from deprecated IdentityDocument to generate signature
Diffstat (limited to 'athenz-identity-provider-service/src')
4 files changed, 17 insertions, 69 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java index 5fff85f695d..0abbb5a64f5 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java @@ -5,11 +5,11 @@ import com.google.inject.Inject; import com.yahoo.config.provision.Zone; import com.yahoo.net.HostName; import com.yahoo.vespa.athenz.api.AthenzService; -import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; +import com.yahoo.vespa.athenz.identityprovider.client.IdentityDocumentSigner; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.KeyProvider; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils; @@ -19,9 +19,7 @@ import com.yahoo.vespa.hosted.provision.node.Allocation; import java.net.URI; import java.security.PrivateKey; -import java.security.Signature; import java.time.Instant; -import java.util.Base64; import java.util.HashSet; import java.util.Set; @@ -33,6 +31,7 @@ import java.util.Set; */ public class IdentityDocumentGenerator { + private final IdentityDocumentSigner signer = new IdentityDocumentSigner(); private final NodeRepository nodeRepository; private final Zone zone; private final KeyProvider keyProvider; @@ -53,16 +52,13 @@ public class IdentityDocumentGenerator { Node node = nodeRepository.getNode(hostname).orElseThrow(() -> new RuntimeException("Unable to find node " + hostname)); try { IdentityDocument identityDocument = generateIdDocument(node, identityType); - String identityDocumentString = Utils.getMapper().writeValueAsString(EntityBindingsMapper.toIdentityDocumentEntity(identityDocument)); - - String encodedIdentityDocument = - Base64.getEncoder().encodeToString(identityDocumentString.getBytes()); - Signature sigGenerator = Signature.getInstance("SHA512withRSA"); PrivateKey privateKey = keyProvider.getPrivateKey(zoneConfig.secretVersion()); - sigGenerator.initSign(privateKey); - sigGenerator.update(encodedIdentityDocument.getBytes()); - String signature = Base64.getEncoder().encodeToString(sigGenerator.sign()); + AthenzService providerService = new AthenzService(zoneConfig.domain(), zoneConfig.serviceName()); + + String signature = signer.generateSignature( + identityDocument.providerUniqueId(), providerService, identityDocument.configServerHostname(), + identityDocument.instanceHostname(), identityDocument.createdAt(), identityDocument.ipAddresses(), identityType, privateKey); return new SignedIdentityDocument( identityDocument, @@ -70,7 +66,7 @@ public class IdentityDocumentGenerator { SignedIdentityDocument.DEFAULT_KEY_VERSION, identityDocument.providerUniqueId(), toZoneDnsSuffix(zone, zoneConfig.certDnsSuffix()), - new AthenzService(zoneConfig.domain(), zoneConfig.serviceName()), + providerService, URI.create(zoneConfig.ztsUrl()), SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION, identityDocument.configServerHostname(), diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java index 0201c46b253..b75f7d05394 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java @@ -11,15 +11,10 @@ import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; -import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity; +import com.yahoo.vespa.athenz.identityprovider.client.IdentityDocumentSigner; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.KeyProvider; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.util.Base64; import java.util.Optional; import java.util.logging.Logger; @@ -35,6 +30,7 @@ public class InstanceValidator { static final String SERVICE_PROPERTIES_DOMAIN_KEY = "identity.domain"; static final String SERVICE_PROPERTIES_SERVICE_KEY = "identity.service"; + private final IdentityDocumentSigner signer = new IdentityDocumentSigner(); private final KeyProvider keyProvider; private final SuperModelProvider superModelProvider; @@ -55,7 +51,9 @@ public class InstanceValidator { } log.log(LogLevel.INFO, () -> String.format("Validating instance %s.", providerUniqueId)); - if (isInstanceSignatureValid(instanceConfirmation)) { + + PublicKey publicKey = keyProvider.getPublicKey(signedIdentityDocument.signingKeyVersion()); + if (signer.hasValidSignature(signedIdentityDocument, publicKey)) { log.log(LogLevel.INFO, () -> String.format("Instance %s is valid.", providerUniqueId)); return true; } @@ -63,24 +61,6 @@ public class InstanceValidator { return false; } - boolean isInstanceSignatureValid(InstanceConfirmation instanceConfirmation) { - SignedIdentityDocumentEntity signedIdentityDocument = instanceConfirmation.signedIdentityDocument; - - PublicKey publicKey = keyProvider.getPublicKey(signedIdentityDocument.signingKeyVersion); - return isSignatureValid(publicKey, signedIdentityDocument.rawIdentityDocument, signedIdentityDocument.signature); - } - - public static boolean isSignatureValid(PublicKey publicKey, String rawIdentityDocument, String signature) { - try { - Signature signatureVerifier = Signature.getInstance("SHA512withRSA"); - signatureVerifier.initVerify(publicKey); - signatureVerifier.update(rawIdentityDocument.getBytes()); - return signatureVerifier.verify(Base64.getDecoder().decode(signature)); - } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { - throw new RuntimeException(e); - } - } - // If/when we dont care about logging exactly whats wrong, this can be simplified // TODO Use identity type to determine if this check should be performed boolean isSameIdentityAsInServicesXml(ApplicationId applicationId, String domain, String service) { diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java index 578c044796f..a1839ec62a2 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java @@ -14,14 +14,12 @@ import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; -import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; -import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity; +import com.yahoo.vespa.athenz.identityprovider.client.IdentityDocumentSigner; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.AutoGeneratedKeyProvider; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig; -import com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation.InstanceValidator; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Allocation; @@ -48,7 +46,7 @@ public class IdentityDocumentGeneratorTest { private static final Zone ZONE = new Zone(SystemName.cd, Environment.dev, RegionName.from("us-north-1")); @Test - public void generates_valid_identity_document() throws Exception { + public void generates_valid_identity_document() { String parentHostname = "docker-host"; String containerHostname = "docker-container"; @@ -99,12 +97,9 @@ public class IdentityDocumentGeneratorTest { // Validate that container ips are present assertThat(signedIdentityDocument.ipAddresses(), Matchers.containsInAnyOrder("::1")); - SignedIdentityDocumentEntity signedIdentityDocumentEntity = EntityBindingsMapper.toSignedIdentityDocumentEntity(signedIdentityDocument); + IdentityDocumentSigner signer = new IdentityDocumentSigner(); // Validate signature - assertTrue("Message", InstanceValidator.isSignatureValid(keyProvider.getPublicKey(0), - signedIdentityDocumentEntity.rawIdentityDocument, - signedIdentityDocument.signature())); - + assertTrue(signer.hasValidSignature(signedIdentityDocument, keyProvider.getPublicKey(0))); } } diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java index 54411b424eb..04c4d4da51a 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java @@ -14,8 +14,6 @@ import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; import com.yahoo.vespa.athenz.identityprovider.api.bindings.IdentityDocumentEntity; import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity; import com.yahoo.vespa.athenz.identityprovider.api.bindings.VespaUniqueInstanceIdEntity; -import com.yahoo.vespa.hosted.athenz.instanceproviderservice.AutoGeneratedKeyProvider; -import com.yahoo.vespa.hosted.athenz.instanceproviderservice.KeyProvider; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils; import org.junit.Test; @@ -49,27 +47,6 @@ public class InstanceValidatorTest { private final String domain = "domain"; private final String service = "service"; - @Test - public void valid_signature() throws Exception { - KeyProvider keyProvider = new AutoGeneratedKeyProvider(); - InstanceValidator instanceValidator = new InstanceValidator(keyProvider, null); - InstanceConfirmation instanceConfirmation = createInstanceConfirmation( - keyProvider.getPrivateKey(0), applicationId, domain, service); - - assertTrue(instanceValidator.isInstanceSignatureValid(instanceConfirmation)); - } - - @Test - public void invalid_signature() throws Exception { - KeyProvider keyProvider = new AutoGeneratedKeyProvider(); - InstanceValidator instanceValidator = new InstanceValidator(keyProvider, null); - - KeyProvider fakeKeyProvider = new AutoGeneratedKeyProvider(); - InstanceConfirmation instanceConfirmation = createInstanceConfirmation( - fakeKeyProvider.getPrivateKey(0), applicationId, domain, service); - - assertFalse(instanceValidator.isInstanceSignatureValid(instanceConfirmation)); - } @Test public void application_does_not_exist() { |