diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-11-26 09:57:06 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-11-26 09:57:06 +0100 |
commit | 3488082ed378f300c40328891e0ce8dcdd8c4475 (patch) | |
tree | f317ca272d4f5ea3ebe7e3801cf1d27fac956cd3 /security-utils/src/main/java | |
parent | 340042594187f907968bac445bf2ae085fdb9d45 (diff) |
Support SAN URI based rules in authorization policies
Diffstat (limited to 'security-utils/src/main/java')
5 files changed, 55 insertions, 3 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/authz/PeerAuthorizer.java b/security-utils/src/main/java/com/yahoo/security/tls/authz/PeerAuthorizer.java index a40813be96f..1d74f0a170f 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/authz/PeerAuthorizer.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/authz/PeerAuthorizer.java @@ -17,6 +17,7 @@ import java.util.logging.Logger; import static com.yahoo.security.SubjectAlternativeName.Type.DNS_NAME; import static com.yahoo.security.SubjectAlternativeName.Type.IP_ADDRESS; +import static com.yahoo.security.SubjectAlternativeName.Type.UNIFORM_RESOURCE_IDENTIFIER; import static java.util.stream.Collectors.toList; /** @@ -59,6 +60,7 @@ public class PeerAuthorizer { case CN: return cn != null && requiredCredential.pattern().matches(cn); case SAN_DNS: + case SAN_URI: return sans.stream() .anyMatch(san -> requiredCredential.pattern().matches(san)); default: @@ -73,7 +75,7 @@ public class PeerAuthorizer { private static List<String> getSubjectAlternativeNames(X509Certificate peerCertificate) { return X509CertificateUtils.getSubjectAlternativeNames(peerCertificate).stream() - .filter(san -> san.getType() == DNS_NAME || san.getType() == IP_ADDRESS) + .filter(san -> san.getType() == DNS_NAME || san.getType() == IP_ADDRESS || san.getType() == UNIFORM_RESOURCE_IDENTIFIER) .map(SubjectAlternativeName::getValue) .collect(toList()); } diff --git a/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsEntity.java b/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsEntity.java index 83742950dbc..35eef68cef2 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsEntity.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsEntity.java @@ -44,5 +44,5 @@ class TransportSecurityOptionsEntity { @JsonProperty("must-match") String matchExpression; } - enum CredentialField { CN, SAN_DNS } + enum CredentialField { CN, SAN_DNS, SAN_URI } } diff --git a/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsJsonSerializer.java b/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsJsonSerializer.java index 49cae9aa7fb..75134e20b68 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsJsonSerializer.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/json/TransportSecurityOptionsJsonSerializer.java @@ -125,6 +125,7 @@ public class TransportSecurityOptionsJsonSerializer { switch (field) { case CN: return RequiredPeerCredential.Field.CN; case SAN_DNS: return RequiredPeerCredential.Field.SAN_DNS; + case SAN_URI: return RequiredPeerCredential.Field.SAN_URI; default: throw new IllegalArgumentException("Invalid field type: " + field); } } @@ -171,6 +172,7 @@ public class TransportSecurityOptionsJsonSerializer { switch (field) { case CN: return CredentialField.CN; case SAN_DNS: return CredentialField.SAN_DNS; + case SAN_URI: return CredentialField.SAN_URI; default: throw new IllegalArgumentException("Invalid field type: " + field); } } diff --git a/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java b/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java index 1eef3a67521..3ae886fef61 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java @@ -8,7 +8,7 @@ import java.util.Objects; */ public class RequiredPeerCredential { - public enum Field { CN, SAN_DNS } + public enum Field { CN, SAN_DNS, SAN_URI } private final Field field; private final Pattern pattern; @@ -27,6 +27,8 @@ public class RequiredPeerCredential { case CN: case SAN_DNS: return new HostGlobPattern(pattern); + case SAN_URI: + return new UriPattern(pattern); default: throw new IllegalArgumentException("Unknown field: " + field); } diff --git a/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java b/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java new file mode 100644 index 00000000000..18f5c0ce2de --- /dev/null +++ b/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java @@ -0,0 +1,46 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.security.tls.policy; + +import java.util.Objects; + +/** + * Pattern used for matching URIs in X.509 certificate subject alternative names. + * + * @author bjorncs + */ +class UriPattern implements RequiredPeerCredential.Pattern { + + private final String pattern; + + UriPattern(String pattern) { + this.pattern = pattern; + } + + @Override public String asString() { return pattern; } + + @Override + public boolean matches(String fieldValue) { + // Only exact match is supported (unlike for host names) + return fieldValue.equals(pattern); + } + + @Override + public String toString() { + return "UriPattern{" + + "pattern='" + pattern + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UriPattern that = (UriPattern) o; + return Objects.equals(pattern, that.pattern); + } + + @Override + public int hashCode() { + return Objects.hash(pattern); + } +} |