From c621cbd33f512627c6a82b0918eb26dccd56df97 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Fri, 9 Mar 2018 22:49:36 -0800 Subject: [PATCH] Reject overlaps with wildcards. (#3542) Requesting a certificate with "*.example.com" and "www.example.com" as separate SANs doesn't make sense, because "www.example.com" is covered by the wildcard. #3524 --- ra/ra.go | 24 ++++++++++++++++++++++++ ra/ra_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/ra/ra.go b/ra/ra.go index 6004f4fec..c792fad12 100644 --- a/ra/ra.go +++ b/ra/ra.go @@ -1708,6 +1708,10 @@ func (ra *RegistrationAuthorityImpl) NewOrder(ctx context.Context, req *rapb.New } } + if err := wildcardOverlap(order.Names); err != nil { + return nil, err + } + // See if there is an existing, pending, unexpired order that can be reused // for this account existingOrder, err := ra.SA.GetOrderForNames(ctx, &sapb.GetOrderForNamesRequest{ @@ -1910,3 +1914,23 @@ func (ra *RegistrationAuthorityImpl) authzValidChallengeEnabled(authz *core.Auth } return false } + +// wildcardOverlap takes a slice of domain names and returns an error if any of +// them is a non-wildcard FQDN that overlaps with a wildcard domain in the map. +func wildcardOverlap(dnsNames []string) error { + nameMap := make(map[string]bool, len(dnsNames)) + for _, v := range dnsNames { + nameMap[v] = true + } + for name := range nameMap { + if name[0] == '*' { + continue + } + labels := strings.Split(name, ".") + labels[0] = "*" + if nameMap[strings.Join(labels, ".")] { + return fmt.Errorf("Domain name %q is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.", name) + } + } + return nil +} diff --git a/ra/ra_test.go b/ra/ra_test.go index 99fcf5f6a..b92f6046f 100644 --- a/ra/ra_test.go +++ b/ra/ra_test.go @@ -3345,6 +3345,32 @@ func TestCTPolicyMeasurements(t *testing.T) { test.AssertEquals(t, test.CountHistogramSamples(ra.ctpolicyResults.With(prometheus.Labels{"result": "failure"})), 1) } +func TestWildcardOverlap(t *testing.T) { + err := wildcardOverlap([]string{ + "*.example.com", + "*.example.net", + }) + if err != nil { + t.Errorf("Got error %q, expected none", err) + } + err = wildcardOverlap([]string{ + "*.example.com", + "*.example.net", + "www.example.com", + }) + if err == nil { + t.Errorf("Got no error, expected one") + } + err = wildcardOverlap([]string{ + "*.foo.example.com", + "*.example.net", + "www.example.com", + }) + if err != nil { + t.Errorf("Got error %q, expected none", err) + } +} + var CAkeyPEM = ` -----BEGIN RSA PRIVATE KEY----- MIIJKQIBAAKCAgEAqmM0dEf/J9MCk2ItzevL0dKJ84lVUtf/vQ7AXFi492vFXc3b