From eceedab23b7c943126d76f1c2822d5d0b7f4cbd1 Mon Sep 17 00:00:00 2001 From: Martin Polden Date: Wed, 4 Oct 2023 13:42:55 +0200 Subject: Require that endpoint DNS name is matched by SAN --- .../certificates/EndpointCertificate.java | 23 ++++++++++++++++ .../certificates/EndpointCertificateTest.java | 31 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateTest.java (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificate.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificate.java index 6f056edd226..6988da6a0ad 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificate.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificate.java @@ -135,4 +135,27 @@ public record EndpointCertificate(String keyName, String certName, int version, this.generatedId); } + /** Returns whether given DNS name matches any of the requested SANs in this */ + public boolean sanMatches(String dnsName) { + return sanMatches(dnsName, requestedDnsSans); + } + + static boolean sanMatches(String dnsName, List sanDnsNames) { + return sanDnsNames.stream().anyMatch(sanDnsName -> sanMatches(dnsName, sanDnsName)); + } + + private static boolean sanMatches(String dnsName, String sanDnsName) { + String[] sanNameParts = sanDnsName.split("\\."); + String[] dnsNameParts = dnsName.split("\\."); + if (sanNameParts.length != dnsNameParts.length || sanNameParts.length == 0) { + return false; + } + for (int i = 0; i < sanNameParts.length; i++) { + if (!sanNameParts[i].equals("*") && !sanNameParts[i].equals(dnsNameParts[i])) { + return false; + } + } + return true; + } + } diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateTest.java new file mode 100644 index 00000000000..e165157dac2 --- /dev/null +++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateTest.java @@ -0,0 +1,31 @@ +package com.yahoo.vespa.hosted.controller.api.integration.certificates; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author mpolden + */ +class EndpointCertificateTest { + + @Test + public void san_matches() { + List sans = List.of("*.a.example.com", "b.example.com", "c.example.com"); + assertTrue(EndpointCertificate.sanMatches("b.example.com", sans)); + assertTrue(EndpointCertificate.sanMatches("c.example.com", sans)); + assertTrue(EndpointCertificate.sanMatches("foo.a.example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("", List.of())); + assertFalse(EndpointCertificate.sanMatches("example.com", List.of())); + assertFalse(EndpointCertificate.sanMatches("example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("d.example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("a.example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("aa.example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("c.c.example.com", sans)); + assertFalse(EndpointCertificate.sanMatches("a.a.a.example.com", sans)); + } + +} -- cgit v1.2.3