diff options
author | Bjørn Christian Seime <bjorncs@oath.com> | 2018-06-20 13:09:55 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@oath.com> | 2018-06-20 13:15:11 +0200 |
commit | b38471d94959eb172e82ee102404bc669a14d96b (patch) | |
tree | d1a9e399c6c4f4bb1ee76a1b80454125cfbbd0fe /vespa-athenz | |
parent | bf74c1a064739c123921a2e85e9427bae7019290 (diff) |
Add new Athenz security filter based on ZPE
- Allow flexible configuration of filter using a resource mapper
- Add helper class to extract role and identity from role certificates
Diffstat (limited to 'vespa-athenz')
-rw-r--r-- | vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java | 58 |
1 files changed, 58 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 new file mode 100644 index 00000000000..46aca707be1 --- /dev/null +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/tls/AthenzX509CertificateUtils.java @@ -0,0 +1,58 @@ +// Copyright 2018 Yahoo Holdings. 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.vespa.athenz.api.AthenzIdentity; +import com.yahoo.vespa.athenz.api.AthenzRole; +import com.yahoo.vespa.athenz.utils.AthenzIdentities; + +import java.security.cert.X509Certificate; +import java.util.List; + +import static com.yahoo.vespa.athenz.tls.SubjectAlternativeName.Type.RFC822_NAME; + +/** + * Utility methods for Athenz issued x509 certificates + * + * @author bjorncs + */ +public class AthenzX509CertificateUtils { + + private static final String COMMON_NAME_ROLE_DELIMITER = ":role."; + + private AthenzX509CertificateUtils() {} + + public static boolean isAthenzRoleCertificate(X509Certificate certificate) { + return isAthenzIssuedCertificate(certificate) && + X509CertificateUtils.getSubjectCommonNames(certificate).get(0).contains(COMMON_NAME_ROLE_DELIMITER); + } + + public static boolean isAthenzIssuedCertificate(X509Certificate certificate) { + return X509CertificateUtils.getIssuerCommonNames(certificate).stream() + .anyMatch(cn -> cn.equalsIgnoreCase("Yahoo Athenz CA") || cn.equalsIgnoreCase("Athenz AWS CA")); + } + + public static AthenzIdentity getIdentityFromRoleCertificate(X509Certificate certificate) { + List<SubjectAlternativeName> sans = X509CertificateUtils.getSubjectAlternativeNames(certificate); + return sans.stream() + .filter(san -> san.getType() == RFC822_NAME) + .map(SubjectAlternativeName::getValue) + .map(AthenzX509CertificateUtils::getIdentityFromSanEmail) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Could not find identity in SAN: " + sans)); + } + + public static AthenzRole getRolesFromRoleCertificate(X509Certificate certificate) { + String commonName = X509CertificateUtils.getSubjectCommonNames(certificate).get(0); + int delimiterIndex = commonName.indexOf(COMMON_NAME_ROLE_DELIMITER); + String domain = commonName.substring(0, delimiterIndex); + String roleName = commonName.substring(delimiterIndex + COMMON_NAME_ROLE_DELIMITER.length()); + return new AthenzRole(domain, roleName); + } + + private static AthenzIdentity getIdentityFromSanEmail(String email) { + int separator = email.indexOf('@'); + if (separator == -1) throw new IllegalArgumentException("Invalid SAN email: " + email); + return AthenzIdentities.from(email.substring(0, separator)); + } + +} |