summaryrefslogtreecommitdiffstats
path: root/security-utils
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-12-02 16:56:34 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2021-12-02 16:56:34 +0100
commit959bf31ebc57a18bd60209279278cd86e1779905 (patch)
tree1773cb6b08af01d897c83f9508732f2ca2bdef3e /security-utils
parent482a30d82ab06a8f8ddfbc1d3e1222daa0b3389f (diff)
Support glob pattern for URIs with '/' as boundary
Diffstat (limited to 'security-utils')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java2
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/policy/UriGlobPattern.java (renamed from security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java)24
-rw-r--r--security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java8
-rw-r--r--security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java34
4 files changed, 49 insertions, 19 deletions
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 3bdc35c6a2f..4c96a2935f8 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
@@ -28,7 +28,7 @@ public class RequiredPeerCredential {
case SAN_DNS:
return new HostGlobPattern(pattern);
case SAN_URI:
- return new UriPattern(pattern);
+ return new UriGlobPattern(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/UriGlobPattern.java
index 7c36244d781..006ca83a403 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/policy/UriGlobPattern.java
@@ -8,26 +8,22 @@ import java.util.Objects;
*
* @author bjorncs
*/
-class UriPattern implements RequiredPeerCredential.Pattern {
+class UriGlobPattern implements RequiredPeerCredential.Pattern {
- private final String pattern;
+ private final GlobPattern globPattern;
- UriPattern(String pattern) {
- this.pattern = pattern;
+ UriGlobPattern(String globPattern) {
+ this.globPattern = new GlobPattern(globPattern, new char[] {'/'});
}
- @Override public String asString() { return pattern; }
+ @Override public String asString() { return globPattern.asString(); }
- @Override
- public boolean matches(String fieldValue) {
- // Only exact match is supported (unlike for host names)
- return fieldValue.equals(pattern);
- }
+ @Override public boolean matches(String fieldValue) { return globPattern.matches(fieldValue); }
@Override
public String toString() {
return "UriPattern{" +
- "pattern='" + pattern + '\'' +
+ "pattern='" + globPattern + '\'' +
'}';
}
@@ -35,12 +31,12 @@ class UriPattern implements RequiredPeerCredential.Pattern {
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);
+ UriGlobPattern that = (UriGlobPattern) o;
+ return Objects.equals(globPattern, that.globPattern);
}
@Override
public int hashCode() {
- return Objects.hash(pattern);
+ return Objects.hash(globPattern);
}
}
diff --git a/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java b/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java
index 518ec08d38e..fdfed781286 100644
--- a/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java
+++ b/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java
@@ -102,17 +102,17 @@ public class PeerAuthorizerTest {
}
@Test
- public void can_exact_match_policy_with_san_uri_pattern() {
+ public void can_match_policy_with_san_uri_pattern() {
RequiredPeerCredential cnRequirement = createRequiredCredential(CN, "*.matching.cn");
- RequiredPeerCredential sanUriRequirement = createRequiredCredential(SAN_URI, "myscheme://my/exact/uri");
+ RequiredPeerCredential sanUriRequirement = createRequiredCredential(SAN_URI, "myscheme://my/*/uri");
PeerAuthorizer authorizer = createPeerAuthorizer(createPolicy(POLICY_1, createRoles(ROLE_1), cnRequirement, sanUriRequirement));
- AuthorizationResult result = authorizer.authorizePeer(createCertificate("foo.matching.cn", singletonList("foo.irrelevant.san"), singletonList("myscheme://my/exact/uri")));
+ AuthorizationResult result = authorizer.authorizePeer(createCertificate("foo.matching.cn", singletonList("foo.irrelevant.san"), singletonList("myscheme://my/matching/uri")));
assertAuthorized(result);
assertThat(result.assumedRoles()).extracting(Role::name).containsOnly(ROLE_1);
assertThat(result.matchedPolicies()).containsOnly(POLICY_1);
- assertUnauthorized(authorizer.authorizePeer(createCertificate("foo.matching.cn", emptyList(), singletonList("myscheme://my/nonmatching/uri"))));
+ assertUnauthorized(authorizer.authorizePeer(createCertificate("foo.matching.cn", emptyList(), singletonList("myscheme://my/nonmatching/url"))));
}
private static X509Certificate createCertificate(String subjectCn, List<String> sanDns, List<String> sanUri) {
diff --git a/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java b/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java
new file mode 100644
index 00000000000..98f8119b40e
--- /dev/null
+++ b/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java
@@ -0,0 +1,34 @@
+package com.yahoo.security.tls.policy;// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author bjorncs
+ */
+class UriGlobPatternTest {
+
+ @Test
+ void matches_correctly() {
+ assertMatches("scheme://hostname/*", "scheme://hostname/mypath");
+ assertMatches("scheme://hostname/*/segment2", "scheme://hostname/segment1/segment2");
+ assertMatches("scheme://hostname/segment1/*", "scheme://hostname/segment1/segment2");
+ assertNotMatches("scheme://hostname/*", "scheme://hostname/segment1/segment2");
+ assertMatches("scheme://*/segment1/segment2", "scheme://hostname/segment1/segment2");
+ assertMatches("scheme://*.name/", "scheme://host.name/");
+ assertNotMatches("scheme://*", "scheme://hostname/");
+ }
+
+ private void assertMatches(String pattern, String value) {
+ assertTrue(new UriGlobPattern(pattern).matches(value),
+ () -> String.format("Expected '%s' to match '%s'", pattern, value));
+ }
+
+ private void assertNotMatches(String pattern, String value) {
+ assertFalse(new UriGlobPattern(pattern).matches(value),
+ () -> String.format("Expected '%s' to not match '%s'", pattern, value));
+ }
+
+} \ No newline at end of file