aboutsummaryrefslogtreecommitdiffstats
path: root/vespa-athenz
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-12-09 17:22:42 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2021-12-09 17:22:42 +0100
commitcad25c9064222f975841f0ef41fd1576a099a2e4 (patch)
tree465073eef0078363b121140e415b08ade8ac3cb7 /vespa-athenz
parent828ebd77e0a57c1da583f43f1f2bc0512ab698e9 (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.java46
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();
+ }
+
}