diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-09 17:22:42 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-09 17:22:42 +0100 |
commit | cad25c9064222f975841f0ef41fd1576a099a2e4 (patch) | |
tree | 465073eef0078363b121140e415b08ade8ac3cb7 /vespa-athenz | |
parent | 828ebd77e0a57c1da583f43f1f2bc0512ab698e9 (diff) |
Add helpers to extract Athenz instance id from X.509 certificate
Diffstat (limited to 'vespa-athenz')
-rw-r--r-- | vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java index 5f75ace6ac5..4b54b392d12 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java @@ -1,14 +1,20 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.athenz.tls; +import com.yahoo.security.SubjectAlternativeName; +import com.yahoo.security.X509CertificateUtils; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.api.AthenzRole; import com.yahoo.vespa.athenz.utils.AthenzIdentities; +import java.net.URI; import java.security.cert.X509Certificate; import java.util.List; +import java.util.Optional; +import static com.yahoo.security.SubjectAlternativeName.Type.DNS_NAME; import static com.yahoo.security.SubjectAlternativeName.Type.RFC822_NAME; +import static com.yahoo.security.SubjectAlternativeName.Type.UNIFORM_RESOURCE_IDENTIFIER; /** * Utility methods for Athenz issued x509 certificates @@ -40,4 +46,44 @@ public class AthenzX509CertificateUtils { return AthenzIdentities.from(email.substring(0, separator)); } + /** @return Athenz unique instance id from an Athenz X.509 certificate (specified in the Subject Alternative Name extension) */ + public static Optional<String> getInstanceId(X509Certificate cert) { + return getInstanceId(X509CertificateUtils.getSubjectAlternativeNames(cert)); + } + + /** @return Athenz unique instance id from the Subject Alternative Name extension */ + public static Optional<String> getInstanceId(List<SubjectAlternativeName> sans) { + // Prefer instance id from SAN URI over the legacy DNS entry + return getAthenzUniqueInstanceIdFromSanUri(sans) + .or(() -> getAthenzUniqueInstanceIdFromSanDns(sans)); + } + + private static Optional<String> getAthenzUniqueInstanceIdFromSanUri(List<SubjectAlternativeName> sans) { + String uriPrefix = "athenz://instanceid/"; + return sans.stream() + .filter(san -> { + if (san.getType() != UNIFORM_RESOURCE_IDENTIFIER) return false; + return san.getValue().startsWith(uriPrefix); + }) + .map(san -> { + String uriPath = URI.create(san.getValue()).getPath(); + return uriPath.substring(uriPath.lastIndexOf('/') + 1); // last path segment contains instance id + }) + .findFirst(); + } + + private static Optional<String> getAthenzUniqueInstanceIdFromSanDns(List<SubjectAlternativeName> sans) { + String dnsNameDelimiter = ".instanceid.athenz."; + return sans.stream() + .filter(san -> { + if (san.getType() != DNS_NAME) return false; + return san.getValue().contains(dnsNameDelimiter); + }) + .map(san -> { + String dnsName = san.getValue(); + return dnsName.substring(0, dnsName.indexOf(dnsNameDelimiter)); + }) + .findFirst(); + } + } |