...

Source file src/github.com/letsencrypt/boulder/va/tlsalpn_test.go

Documentation: github.com/letsencrypt/boulder/va

     1  package va
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"crypto/sha256"
     7  	"crypto/tls"
     8  	"crypto/x509"
     9  	"crypto/x509/pkix"
    10  	"encoding/asn1"
    11  	"encoding/hex"
    12  	"fmt"
    13  	"math/big"
    14  	"net"
    15  	"net/http"
    16  	"net/http/httptest"
    17  	"net/url"
    18  	"strconv"
    19  	"strings"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/letsencrypt/boulder/bdns"
    24  	"github.com/letsencrypt/boulder/core"
    25  	"github.com/letsencrypt/boulder/identifier"
    26  	"github.com/letsencrypt/boulder/probs"
    27  	"github.com/letsencrypt/boulder/test"
    28  	"github.com/prometheus/client_golang/prometheus"
    29  )
    30  
    31  func tlsalpnChallenge() core.Challenge {
    32  	return createChallenge(core.ChallengeTypeTLSALPN01)
    33  }
    34  
    35  func tlsCertTemplate(names []string) *x509.Certificate {
    36  	return &x509.Certificate{
    37  		SerialNumber: big.NewInt(1337),
    38  		Subject: pkix.Name{
    39  			Organization: []string{"tests"},
    40  		},
    41  		NotBefore: time.Now(),
    42  		NotAfter:  time.Now().AddDate(0, 0, 1),
    43  
    44  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
    45  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    46  		BasicConstraintsValid: true,
    47  
    48  		DNSNames: names,
    49  	}
    50  }
    51  
    52  func makeACert(names []string) *tls.Certificate {
    53  	template := tlsCertTemplate(names)
    54  	certBytes, _ := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
    55  	return &tls.Certificate{
    56  		Certificate: [][]byte{certBytes},
    57  		PrivateKey:  &TheKey,
    58  	}
    59  }
    60  
    61  // tlssniSrvWithNames is kept around for the use of TestValidateTLSALPN01UnawareSrv
    62  func tlssniSrvWithNames(t *testing.T, names ...string) *httptest.Server {
    63  	t.Helper()
    64  
    65  	cert := makeACert(names)
    66  	tlsConfig := &tls.Config{
    67  		Certificates: []tls.Certificate{*cert},
    68  		ClientAuth:   tls.NoClientCert,
    69  		GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
    70  			return cert, nil
    71  		},
    72  		NextProtos: []string{"http/1.1"},
    73  	}
    74  
    75  	hs := httptest.NewUnstartedServer(http.DefaultServeMux)
    76  	hs.TLS = tlsConfig
    77  	hs.StartTLS()
    78  	return hs
    79  }
    80  
    81  func tlsalpn01SrvWithCert(t *testing.T, acmeCert *tls.Certificate, tlsVersion uint16) *httptest.Server {
    82  	t.Helper()
    83  
    84  	tlsConfig := &tls.Config{
    85  		Certificates: []tls.Certificate{},
    86  		ClientAuth:   tls.NoClientCert,
    87  		GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
    88  			return acmeCert, nil
    89  		},
    90  		NextProtos: []string{"http/1.1", ACMETLS1Protocol},
    91  		MinVersion: tlsVersion,
    92  		MaxVersion: tlsVersion,
    93  	}
    94  
    95  	hs := httptest.NewUnstartedServer(http.DefaultServeMux)
    96  	hs.TLS = tlsConfig
    97  	hs.Config.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){
    98  		ACMETLS1Protocol: func(_ *http.Server, conn *tls.Conn, _ http.Handler) {
    99  			_ = conn.Close()
   100  		},
   101  	}
   102  	hs.StartTLS()
   103  	return hs
   104  }
   105  
   106  func tlsalpn01Srv(
   107  	t *testing.T,
   108  	chall core.Challenge,
   109  	oid asn1.ObjectIdentifier,
   110  	tlsVersion uint16,
   111  	names ...string) (*httptest.Server, error) {
   112  	template := tlsCertTemplate(names)
   113  
   114  	shasum := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   115  	encHash, err := asn1.Marshal(shasum[:])
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	acmeExtension := pkix.Extension{
   120  		Id:       oid,
   121  		Critical: true,
   122  		Value:    encHash,
   123  	}
   124  	template.ExtraExtensions = []pkix.Extension{acmeExtension}
   125  
   126  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	acmeCert := &tls.Certificate{
   132  		Certificate: [][]byte{certBytes},
   133  		PrivateKey:  &TheKey,
   134  	}
   135  
   136  	return tlsalpn01SrvWithCert(t, acmeCert, tlsVersion), nil
   137  }
   138  
   139  func TestTLSALPN01FailIP(t *testing.T) {
   140  	chall := tlsalpnChallenge()
   141  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, 0, "expected")
   142  	test.AssertNotError(t, err, "Error creating test server")
   143  
   144  	va, _ := setup(hs, 0, "", nil)
   145  
   146  	port := getPort(hs)
   147  	_, prob := va.validateTLSALPN01(ctx, identifier.ACMEIdentifier{
   148  		Type:  identifier.IdentifierType("ip"),
   149  		Value: net.JoinHostPort("127.0.0.1", strconv.Itoa(port)),
   150  	}, chall)
   151  	if prob == nil {
   152  		t.Fatalf("IdentifierType IP shouldn't have worked.")
   153  	}
   154  	test.AssertEquals(t, prob.Type, probs.MalformedProblem)
   155  }
   156  
   157  func slowTLSSrv() *httptest.Server {
   158  	server := httptest.NewUnstartedServer(http.DefaultServeMux)
   159  	server.TLS = &tls.Config{
   160  		NextProtos: []string{"http/1.1", ACMETLS1Protocol},
   161  		GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
   162  			time.Sleep(100 * time.Millisecond)
   163  			return makeACert([]string{"nomatter"}), nil
   164  		},
   165  	}
   166  	server.StartTLS()
   167  	return server
   168  }
   169  
   170  func TestTLSALPNTimeoutAfterConnect(t *testing.T) {
   171  	chall := tlsalpnChallenge()
   172  	hs := slowTLSSrv()
   173  	va, _ := setup(hs, 0, "", nil)
   174  
   175  	timeout := 50 * time.Millisecond
   176  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   177  	defer cancel()
   178  
   179  	started := time.Now()
   180  	_, prob := va.validateTLSALPN01(ctx, dnsi("slow.server"), chall)
   181  	if prob == nil {
   182  		t.Fatalf("Validation should've failed")
   183  	}
   184  	// Check that the TLS connection doesn't return before a timeout, and times
   185  	// out after the expected time
   186  	took := time.Since(started)
   187  	// Check that the HTTP connection doesn't return too fast, and times
   188  	// out after the expected time
   189  	if took < timeout/2 {
   190  		t.Fatalf("TLSSNI returned before %s (%s) with %#v", timeout, took, prob)
   191  	}
   192  	if took > 2*timeout {
   193  		t.Fatalf("TLSSNI didn't timeout after %s (took %s to return %#v)", timeout,
   194  			took, prob)
   195  	}
   196  	if prob == nil {
   197  		t.Fatalf("Connection should've timed out")
   198  	}
   199  	test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
   200  
   201  	expected := "127.0.0.1: Timeout after connect (your server may be slow or overloaded)"
   202  	if prob.Detail != expected {
   203  		t.Errorf("Wrong error detail. Expected %q, got %q", expected, prob.Detail)
   204  	}
   205  }
   206  
   207  func TestTLSALPN01DialTimeout(t *testing.T) {
   208  	chall := tlsalpnChallenge()
   209  	hs := slowTLSSrv()
   210  	va, _ := setup(hs, 0, "", nil)
   211  	va.dnsClient = dnsMockReturnsUnroutable{&bdns.MockClient{}}
   212  	started := time.Now()
   213  
   214  	timeout := 50 * time.Millisecond
   215  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   216  	defer cancel()
   217  
   218  	// The only method I've found so far to trigger a connect timeout is to
   219  	// connect to an unrouteable IP address. This usually generates a connection
   220  	// timeout, but will rarely return "Network unreachable" instead. If we get
   221  	// that, just retry until we get something other than "Network unreachable".
   222  	var prob *probs.ProblemDetails
   223  	for i := 0; i < 20; i++ {
   224  		_, prob = va.validateTLSALPN01(ctx, dnsi("unroutable.invalid"), chall)
   225  		if prob != nil && strings.Contains(prob.Detail, "Network unreachable") {
   226  			continue
   227  		} else {
   228  			break
   229  		}
   230  	}
   231  
   232  	if prob == nil {
   233  		t.Fatalf("Validation should've failed")
   234  	}
   235  	// Check that the TLS connection doesn't return before a timeout, and times
   236  	// out after the expected time
   237  	took := time.Since(started)
   238  	// Check that the HTTP connection doesn't return too fast, and times
   239  	// out after the expected time
   240  	if took < timeout/2 {
   241  		t.Fatalf("TLSSNI returned before %s (%s) with %#v", timeout, took, prob)
   242  	}
   243  	if took > 2*timeout {
   244  		t.Fatalf("TLSSNI didn't timeout after %s", timeout)
   245  	}
   246  	if prob == nil {
   247  		t.Fatalf("Connection should've timed out")
   248  	}
   249  	test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
   250  	expected := "198.51.100.1: Timeout during connect (likely firewall problem)"
   251  	if prob.Detail != expected {
   252  		t.Errorf("Wrong error detail. Expected %q, got %q", expected, prob.Detail)
   253  	}
   254  }
   255  
   256  func TestTLSALPN01Refused(t *testing.T) {
   257  	chall := tlsalpnChallenge()
   258  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, 0, "expected")
   259  	test.AssertNotError(t, err, "Error creating test server")
   260  
   261  	va, _ := setup(hs, 0, "", nil)
   262  	// Take down validation server and check that validation fails.
   263  	hs.Close()
   264  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   265  	if prob == nil {
   266  		t.Fatalf("Server's down; expected refusal. Where did we connect?")
   267  	}
   268  	test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
   269  	expected := "127.0.0.1: Connection refused"
   270  	if prob.Detail != expected {
   271  		t.Errorf("Wrong error detail. Expected %q, got %q", expected, prob.Detail)
   272  	}
   273  }
   274  
   275  func TestTLSALPN01TalkingToHTTP(t *testing.T) {
   276  	chall := tlsalpnChallenge()
   277  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, 0, "expected")
   278  	test.AssertNotError(t, err, "Error creating test server")
   279  
   280  	va, _ := setup(hs, 0, "", nil)
   281  	httpOnly := httpSrv(t, "")
   282  	va.tlsPort = getPort(httpOnly)
   283  
   284  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   285  	test.AssertError(t, prob, "TLS-SNI-01 validation passed when talking to a HTTP-only server")
   286  	expected := "Server only speaks HTTP, not TLS"
   287  	if !strings.HasSuffix(prob.Detail, expected) {
   288  		t.Errorf("Got wrong error detail. Expected %q, got %q", expected, prob.Detail)
   289  	}
   290  }
   291  
   292  func brokenTLSSrv() *httptest.Server {
   293  	server := httptest.NewUnstartedServer(http.DefaultServeMux)
   294  	server.TLS = &tls.Config{
   295  		GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
   296  			return nil, fmt.Errorf("Failing on purpose")
   297  		},
   298  	}
   299  	server.StartTLS()
   300  	return server
   301  }
   302  
   303  func TestTLSError(t *testing.T) {
   304  	chall := tlsalpnChallenge()
   305  	hs := brokenTLSSrv()
   306  
   307  	va, _ := setup(hs, 0, "", nil)
   308  
   309  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   310  	if prob == nil {
   311  		t.Fatalf("TLS validation should have failed: What cert was used?")
   312  	}
   313  	if prob.Type != probs.TLSProblem {
   314  		t.Errorf("Wrong problem type: got %s, expected type %s",
   315  			prob, probs.TLSProblem)
   316  	}
   317  }
   318  
   319  func TestDNSError(t *testing.T) {
   320  	chall := tlsalpnChallenge()
   321  	hs := brokenTLSSrv()
   322  
   323  	va, _ := setup(hs, 0, "", nil)
   324  
   325  	_, prob := va.validateTLSALPN01(ctx, dnsi("always.invalid"), chall)
   326  	if prob == nil {
   327  		t.Fatalf("TLS validation should have failed: what IP was used?")
   328  	}
   329  	if prob.Type != probs.DNSProblem {
   330  		t.Errorf("Wrong problem type: got %s, expected type %s",
   331  			prob, probs.DNSProblem)
   332  	}
   333  }
   334  
   335  func TestCertNames(t *testing.T) {
   336  	uri, err := url.Parse("ftp://something.else:1234")
   337  	test.AssertNotError(t, err, "failed to parse fake URI")
   338  
   339  	// We duplicate names inside the fields corresponding to the SAN set
   340  	template := &x509.Certificate{
   341  		SerialNumber:          big.NewInt(1337),
   342  		NotBefore:             time.Now(),
   343  		NotAfter:              time.Now().AddDate(0, 0, 1),
   344  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   345  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   346  		BasicConstraintsValid: true,
   347  
   348  		Subject: pkix.Name{
   349  			// We also duplicate a name from the SANs as the CN
   350  			CommonName: "hello.world",
   351  		},
   352  		DNSNames: []string{
   353  			"hello.world", "goodbye.world",
   354  			"hello.world", "goodbye.world",
   355  			"bonjour.le.monde", "au.revoir.le.monde",
   356  			"bonjour.le.monde", "au.revoir.le.monde",
   357  		},
   358  		EmailAddresses: []string{
   359  			"hello@world.gov", "hello@world.gov",
   360  		},
   361  		IPAddresses: []net.IP{
   362  			net.ParseIP("192.168.0.1"), net.ParseIP("192.168.0.1"),
   363  			net.ParseIP("2001:db8::68"), net.ParseIP("2001:db8::68"),
   364  		},
   365  		URIs: []*url.URL{
   366  			uri, uri,
   367  		},
   368  	}
   369  
   370  	// We expect only unique names, in sorted order.
   371  	expected := []string{
   372  		"192.168.0.1",
   373  		"2001:db8::68",
   374  		"au.revoir.le.monde",
   375  		"bonjour.le.monde",
   376  		"ftp://something.else:1234",
   377  		"goodbye.world",
   378  		"hello.world",
   379  		"hello@world.gov",
   380  	}
   381  
   382  	// Create the certificate, check that certNames provides the expected result
   383  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   384  	test.AssertNotError(t, err, "Error creating certificate")
   385  
   386  	cert, err := x509.ParseCertificate(certBytes)
   387  	test.AssertNotError(t, err, "Error parsing certificate")
   388  
   389  	actual := certAltNames(cert)
   390  	test.AssertDeepEquals(t, actual, expected)
   391  }
   392  
   393  func TestTLSALPN01Success(t *testing.T) {
   394  	chall := tlsalpnChallenge()
   395  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, 0, "expected")
   396  	test.AssertNotError(t, err, "Error creating test server")
   397  
   398  	va, _ := setup(hs, 0, "", nil)
   399  
   400  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   401  	if prob != nil {
   402  		t.Errorf("Validation failed: %v", prob)
   403  	}
   404  	test.AssertMetricWithLabelsEquals(
   405  		t, va.metrics.tlsALPNOIDCounter, prometheus.Labels{"oid": IdPeAcmeIdentifier.String()}, 1)
   406  
   407  	hs.Close()
   408  }
   409  
   410  func TestTLSALPN01ObsoleteFailure(t *testing.T) {
   411  	// NOTE: unfortunately another document claimed the OID we were using in
   412  	// draft-ietf-acme-tls-alpn-01 for their own extension and IANA chose to
   413  	// assign it early. Because of this we had to increment the
   414  	// id-pe-acmeIdentifier OID. We supported this obsolete OID for a long time,
   415  	// but no longer do so.
   416  	// As defined in https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.1
   417  	// id-pe OID + 30 (acmeIdentifier) + 1 (v1)
   418  	IdPeAcmeIdentifierV1Obsolete := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
   419  
   420  	chall := tlsalpnChallenge()
   421  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifierV1Obsolete, 0, "expected")
   422  	test.AssertNotError(t, err, "Error creating test server")
   423  
   424  	va, _ := setup(hs, 0, "", nil)
   425  
   426  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   427  	test.AssertNotNil(t, prob, "expected validation to fail")
   428  }
   429  
   430  func TestValidateTLSALPN01BadChallenge(t *testing.T) {
   431  	chall := tlsalpnChallenge()
   432  	chall2 := chall
   433  	setChallengeToken(&chall2, "bad token")
   434  
   435  	hs, err := tlsalpn01Srv(t, chall2, IdPeAcmeIdentifier, 0, "expected")
   436  	test.AssertNotError(t, err, "Error creating test server")
   437  
   438  	va, _ := setup(hs, 0, "", nil)
   439  
   440  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   441  
   442  	if prob == nil {
   443  		t.Fatalf("TLS ALPN validation should have failed.")
   444  	}
   445  	test.AssertEquals(t, prob.Type, probs.UnauthorizedProblem)
   446  
   447  	expectedDigest := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   448  	badDigest := sha256.Sum256([]byte(chall2.ProvidedKeyAuthorization))
   449  
   450  	test.AssertContains(t, prob.Detail, string(core.ChallengeTypeTLSALPN01))
   451  	test.AssertContains(t, prob.Detail, hex.EncodeToString(expectedDigest[:]))
   452  	test.AssertContains(t, prob.Detail, hex.EncodeToString(badDigest[:]))
   453  }
   454  
   455  func TestValidateTLSALPN01BrokenSrv(t *testing.T) {
   456  	chall := tlsalpnChallenge()
   457  	hs := brokenTLSSrv()
   458  
   459  	va, _ := setup(hs, 0, "", nil)
   460  
   461  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   462  	if prob == nil {
   463  		t.Fatalf("TLS ALPN validation should have failed.")
   464  	}
   465  	test.AssertEquals(t, prob.Type, probs.TLSProblem)
   466  }
   467  
   468  func TestValidateTLSALPN01UnawareSrv(t *testing.T) {
   469  	chall := tlsalpnChallenge()
   470  	hs := tlssniSrvWithNames(t, "expected")
   471  
   472  	va, _ := setup(hs, 0, "", nil)
   473  
   474  	_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   475  	if prob == nil {
   476  		t.Fatalf("TLS ALPN validation should have failed.")
   477  	}
   478  	test.AssertEquals(t, prob.Type, probs.TLSProblem)
   479  }
   480  
   481  // TestValidateTLSALPN01BadUTFSrv tests that validating TLS-ALPN-01 against
   482  // a host that returns a certificate with a SAN/CN that contains invalid UTF-8
   483  // will result in a problem with the invalid UTF-8.
   484  func TestValidateTLSALPN01BadUTFSrv(t *testing.T) {
   485  	chall := tlsalpnChallenge()
   486  	_, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, 0, "expected", "\xf0\x28\x8c\xbc")
   487  	test.AssertContains(t, err.Error(), "cannot be encoded as an IA5String")
   488  }
   489  
   490  // TestValidateTLSALPN01MalformedExtnValue tests that validating TLS-ALPN-01
   491  // against a host that returns a certificate that contains an ASN.1 DER
   492  // acmeValidation extension value that does not parse or is the wrong length
   493  // will result in an Unauthorized problem
   494  func TestValidateTLSALPN01MalformedExtnValue(t *testing.T) {
   495  	chall := tlsalpnChallenge()
   496  
   497  	names := []string{"expected"}
   498  	template := tlsCertTemplate(names)
   499  
   500  	wrongTypeDER, _ := asn1.Marshal("a string")
   501  	wrongLengthDER, _ := asn1.Marshal(make([]byte, 31))
   502  	badExtensions := []pkix.Extension{
   503  		{
   504  			Id:       IdPeAcmeIdentifier,
   505  			Critical: true,
   506  			Value:    wrongTypeDER,
   507  		},
   508  		{
   509  			Id:       IdPeAcmeIdentifier,
   510  			Critical: true,
   511  			Value:    wrongLengthDER,
   512  		},
   513  	}
   514  
   515  	for _, badExt := range badExtensions {
   516  		template.ExtraExtensions = []pkix.Extension{badExt}
   517  		certBytes, _ := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   518  		acmeCert := &tls.Certificate{
   519  			Certificate: [][]byte{certBytes},
   520  			PrivateKey:  &TheKey,
   521  		}
   522  
   523  		hs := tlsalpn01SrvWithCert(t, acmeCert, 0)
   524  		va, _ := setup(hs, 0, "", nil)
   525  
   526  		_, prob := va.validateTLSALPN01(ctx, dnsi("expected"), chall)
   527  		hs.Close()
   528  
   529  		if prob == nil {
   530  			t.Errorf("TLS ALPN validation should have failed for acmeValidation extension %+v.",
   531  				badExt)
   532  			continue
   533  		}
   534  		test.AssertEquals(t, prob.Type, probs.UnauthorizedProblem)
   535  		test.AssertContains(t, prob.Detail, string(core.ChallengeTypeTLSALPN01))
   536  		test.AssertContains(t, prob.Detail, "malformed acmeValidationV1 extension value")
   537  	}
   538  }
   539  
   540  func TestTLSALPN01TLSVersion(t *testing.T) {
   541  	for _, tc := range []struct {
   542  		version     uint16
   543  		expectError bool
   544  	}{
   545  		{
   546  			version:     tls.VersionTLS11,
   547  			expectError: true,
   548  		},
   549  		{
   550  			version:     tls.VersionTLS12,
   551  			expectError: false,
   552  		},
   553  		{
   554  			version:     tls.VersionTLS13,
   555  			expectError: false,
   556  		},
   557  	} {
   558  		chall := tlsalpnChallenge()
   559  
   560  		// Create a server that only negotiates the given TLS version
   561  		hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, tc.version, "expected")
   562  		test.AssertNotError(t, err, "Error creating test server")
   563  
   564  		va, _ := setup(hs, 0, "", nil)
   565  
   566  		_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   567  		if !tc.expectError {
   568  			if prob != nil {
   569  				t.Errorf("expected success, got: %v", prob)
   570  			}
   571  			// The correct TLS-ALPN-01 OID counter should have been incremented
   572  			test.AssertMetricWithLabelsEquals(
   573  				t, va.metrics.tlsALPNOIDCounter, prometheus.Labels{"oid": IdPeAcmeIdentifier.String()}, 1)
   574  		} else {
   575  			test.AssertNotNil(t, prob, "expected validation error")
   576  			test.AssertMetricWithLabelsEquals(
   577  				t, va.metrics.tlsALPNOIDCounter, prometheus.Labels{"oid": IdPeAcmeIdentifier.String()}, 0)
   578  		}
   579  
   580  		hs.Close()
   581  	}
   582  }
   583  
   584  func TestTLSALPN01WrongName(t *testing.T) {
   585  	chall := tlsalpnChallenge()
   586  
   587  	// Create a cert with a different name from what we're validating
   588  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, tls.VersionTLS12, "incorrect")
   589  	test.AssertNotError(t, err, "failed to set up tls-alpn-01 server")
   590  
   591  	va, _ := setup(hs, 0, "", nil)
   592  
   593  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   594  	test.AssertError(t, prob, "validation should have failed")
   595  }
   596  
   597  func TestTLSALPN01ExtraNames(t *testing.T) {
   598  	chall := tlsalpnChallenge()
   599  
   600  	// Create a cert with two names when we only want to validate one.
   601  	hs, err := tlsalpn01Srv(t, chall, IdPeAcmeIdentifier, tls.VersionTLS12, "expected", "extra")
   602  	test.AssertNotError(t, err, "failed to set up tls-alpn-01 server")
   603  
   604  	va, _ := setup(hs, 0, "", nil)
   605  
   606  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   607  	test.AssertError(t, prob, "validation should have failed")
   608  }
   609  
   610  func TestTLSALPN01NotSelfSigned(t *testing.T) {
   611  	chall := tlsalpnChallenge()
   612  
   613  	// Create a cert with an extra non-dnsName identifier.
   614  	template := &x509.Certificate{
   615  		SerialNumber: big.NewInt(1337),
   616  		Subject: pkix.Name{
   617  			Organization: []string{"tests"},
   618  		},
   619  		NotBefore: time.Now(),
   620  		NotAfter:  time.Now().AddDate(0, 0, 1),
   621  
   622  		KeyUsage:    x509.KeyUsageDigitalSignature,
   623  		ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   624  
   625  		DNSNames:    []string{"expected"},
   626  		IPAddresses: []net.IP{net.ParseIP("192.168.0.1")},
   627  	}
   628  
   629  	shasum := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   630  	encHash, err := asn1.Marshal(shasum[:])
   631  	test.AssertNotError(t, err, "failed to create key authorization")
   632  
   633  	acmeExtension := pkix.Extension{
   634  		Id:       IdPeAcmeIdentifier,
   635  		Critical: true,
   636  		Value:    encHash,
   637  	}
   638  	template.ExtraExtensions = []pkix.Extension{acmeExtension}
   639  
   640  	parent := &x509.Certificate{
   641  		SerialNumber: big.NewInt(1234),
   642  		Subject: pkix.Name{
   643  			Organization: []string{"testissuer"},
   644  		},
   645  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   646  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   647  		BasicConstraintsValid: true,
   648  	}
   649  
   650  	// Note that this currently only tests that the subject and issuer are the
   651  	// same; it does not test the case where the cert is signed by a different key.
   652  	certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, &TheKey.PublicKey, &TheKey)
   653  	test.AssertNotError(t, err, "failed to create acme-tls/1 cert")
   654  
   655  	acmeCert := &tls.Certificate{
   656  		Certificate: [][]byte{certBytes},
   657  		PrivateKey:  &TheKey,
   658  	}
   659  
   660  	hs := tlsalpn01SrvWithCert(t, acmeCert, tls.VersionTLS12)
   661  
   662  	va, _ := setup(hs, 0, "", nil)
   663  
   664  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   665  	test.AssertError(t, prob, "validation should have failed")
   666  	test.AssertContains(t, prob.Detail, "not self-signed")
   667  }
   668  
   669  func TestTLSALPN01ExtraIdentifiers(t *testing.T) {
   670  	chall := tlsalpnChallenge()
   671  
   672  	// Create a cert with an extra non-dnsName identifier.
   673  	template := &x509.Certificate{
   674  		SerialNumber: big.NewInt(1337),
   675  		Subject: pkix.Name{
   676  			Organization: []string{"tests"},
   677  		},
   678  		NotBefore: time.Now(),
   679  		NotAfter:  time.Now().AddDate(0, 0, 1),
   680  
   681  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   682  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   683  		BasicConstraintsValid: true,
   684  
   685  		DNSNames:    []string{"expected"},
   686  		IPAddresses: []net.IP{net.ParseIP("192.168.0.1")},
   687  	}
   688  
   689  	shasum := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   690  	encHash, err := asn1.Marshal(shasum[:])
   691  	test.AssertNotError(t, err, "failed to create key authorization")
   692  
   693  	acmeExtension := pkix.Extension{
   694  		Id:       IdPeAcmeIdentifier,
   695  		Critical: true,
   696  		Value:    encHash,
   697  	}
   698  	template.ExtraExtensions = []pkix.Extension{acmeExtension}
   699  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   700  	test.AssertNotError(t, err, "failed to create acme-tls/1 cert")
   701  
   702  	acmeCert := &tls.Certificate{
   703  		Certificate: [][]byte{certBytes},
   704  		PrivateKey:  &TheKey,
   705  	}
   706  
   707  	hs := tlsalpn01SrvWithCert(t, acmeCert, tls.VersionTLS12)
   708  
   709  	va, _ := setup(hs, 0, "", nil)
   710  
   711  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   712  	test.AssertError(t, prob, "validation should have failed")
   713  }
   714  
   715  func TestTLSALPN01ExtraSANs(t *testing.T) {
   716  	chall := tlsalpnChallenge()
   717  
   718  	// Create a cert with multiple SAN extensions
   719  	template := &x509.Certificate{
   720  		SerialNumber: big.NewInt(1337),
   721  		Subject: pkix.Name{
   722  			Organization: []string{"tests"},
   723  		},
   724  		NotBefore: time.Now(),
   725  		NotAfter:  time.Now().AddDate(0, 0, 1),
   726  
   727  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   728  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   729  		BasicConstraintsValid: true,
   730  	}
   731  
   732  	shasum := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   733  	encHash, err := asn1.Marshal(shasum[:])
   734  	test.AssertNotError(t, err, "failed to create key authorization")
   735  
   736  	acmeExtension := pkix.Extension{
   737  		Id:       IdPeAcmeIdentifier,
   738  		Critical: true,
   739  		Value:    encHash,
   740  	}
   741  
   742  	subjectAltName := pkix.Extension{}
   743  	subjectAltName.Id = asn1.ObjectIdentifier{2, 5, 29, 17}
   744  	subjectAltName.Critical = false
   745  	subjectAltName.Value, err = asn1.Marshal([]asn1.RawValue{
   746  		{Tag: 2, Class: 2, Bytes: []byte(`expected`)},
   747  	})
   748  	test.AssertNotError(t, err, "failed to marshal first SAN")
   749  
   750  	extraSubjectAltName := pkix.Extension{}
   751  	extraSubjectAltName.Id = asn1.ObjectIdentifier{2, 5, 29, 17}
   752  	extraSubjectAltName.Critical = false
   753  	extraSubjectAltName.Value, err = asn1.Marshal([]asn1.RawValue{
   754  		{Tag: 2, Class: 2, Bytes: []byte(`expected`)},
   755  	})
   756  	test.AssertNotError(t, err, "failed to marshal extra SAN")
   757  
   758  	template.ExtraExtensions = []pkix.Extension{acmeExtension, subjectAltName, extraSubjectAltName}
   759  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   760  	test.AssertNotError(t, err, "failed to create acme-tls/1 cert")
   761  
   762  	acmeCert := &tls.Certificate{
   763  		Certificate: [][]byte{certBytes},
   764  		PrivateKey:  &TheKey,
   765  	}
   766  
   767  	hs := tlsalpn01SrvWithCert(t, acmeCert, tls.VersionTLS12)
   768  
   769  	va, _ := setup(hs, 0, "", nil)
   770  
   771  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   772  	test.AssertError(t, prob, "validation should have failed")
   773  	// In go >= 1.19, the TLS client library detects that the certificate has
   774  	// a duplicate extension and terminates the connection itself.
   775  	test.AssertContains(t, prob.Error(), "Error getting validation data")
   776  }
   777  
   778  func TestTLSALPN01ExtraAcmeExtensions(t *testing.T) {
   779  	chall := tlsalpnChallenge()
   780  
   781  	// Create a cert with multiple SAN extensions
   782  	template := &x509.Certificate{
   783  		SerialNumber: big.NewInt(1337),
   784  		Subject: pkix.Name{
   785  			Organization: []string{"tests"},
   786  		},
   787  		NotBefore: time.Now(),
   788  		NotAfter:  time.Now().AddDate(0, 0, 1),
   789  
   790  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
   791  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
   792  		BasicConstraintsValid: true,
   793  
   794  		DNSNames: []string{"expected"},
   795  	}
   796  
   797  	shasum := sha256.Sum256([]byte(chall.ProvidedKeyAuthorization))
   798  	encHash, err := asn1.Marshal(shasum[:])
   799  	test.AssertNotError(t, err, "failed to create key authorization")
   800  
   801  	acmeExtension := pkix.Extension{
   802  		Id:       IdPeAcmeIdentifier,
   803  		Critical: true,
   804  		Value:    encHash,
   805  	}
   806  
   807  	extraAcmeExtension := pkix.Extension{
   808  		Id:       IdPeAcmeIdentifier,
   809  		Critical: true,
   810  		Value:    encHash,
   811  	}
   812  
   813  	template.ExtraExtensions = []pkix.Extension{acmeExtension, extraAcmeExtension}
   814  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &TheKey.PublicKey, &TheKey)
   815  	test.AssertNotError(t, err, "failed to create acme-tls/1 cert")
   816  
   817  	acmeCert := &tls.Certificate{
   818  		Certificate: [][]byte{certBytes},
   819  		PrivateKey:  &TheKey,
   820  	}
   821  
   822  	hs := tlsalpn01SrvWithCert(t, acmeCert, tls.VersionTLS12)
   823  
   824  	va, _ := setup(hs, 0, "", nil)
   825  
   826  	_, prob := va.validateChallenge(ctx, dnsi("expected"), chall)
   827  	test.AssertError(t, prob, "validation should have failed")
   828  	// In go >= 1.19, the TLS client library detects that the certificate has
   829  	// a duplicate extension and terminates the connection itself.
   830  	test.AssertContains(t, prob.Error(), "Error getting validation data")
   831  }
   832  
   833  func TestAcceptableExtensions(t *testing.T) {
   834  	requireAcmeAndSAN := []asn1.ObjectIdentifier{
   835  		IdPeAcmeIdentifier,
   836  		IdCeSubjectAltName,
   837  	}
   838  
   839  	var err error
   840  	subjectAltName := pkix.Extension{}
   841  	subjectAltName.Id = asn1.ObjectIdentifier{2, 5, 29, 17}
   842  	subjectAltName.Critical = false
   843  	subjectAltName.Value, err = asn1.Marshal([]asn1.RawValue{
   844  		{Tag: 2, Class: 2, Bytes: []byte(`expected`)},
   845  	})
   846  	test.AssertNotError(t, err, "failed to marshal SAN")
   847  
   848  	acmeExtension := pkix.Extension{
   849  		Id:       IdPeAcmeIdentifier,
   850  		Critical: true,
   851  		Value:    []byte{},
   852  	}
   853  
   854  	weirdExt := pkix.Extension{
   855  		Id:       asn1.ObjectIdentifier{99, 99, 99, 99},
   856  		Critical: false,
   857  		Value:    []byte(`because I'm tacky`),
   858  	}
   859  
   860  	doubleAcmeExts := []pkix.Extension{subjectAltName, acmeExtension, acmeExtension}
   861  	err = checkAcceptableExtensions(doubleAcmeExts, requireAcmeAndSAN)
   862  	test.AssertError(t, err, "Two ACME extensions isn't okay")
   863  
   864  	doubleSANExts := []pkix.Extension{subjectAltName, subjectAltName, acmeExtension}
   865  	err = checkAcceptableExtensions(doubleSANExts, requireAcmeAndSAN)
   866  	test.AssertError(t, err, "Two SAN extensions isn't okay")
   867  
   868  	onlyUnexpectedExt := []pkix.Extension{weirdExt}
   869  	err = checkAcceptableExtensions(onlyUnexpectedExt, requireAcmeAndSAN)
   870  	test.AssertError(t, err, "Missing required extensions")
   871  	test.AssertContains(t, err.Error(), "Required extension OID 1.3.6.1.5.5.7.1.31 is not present")
   872  
   873  	okayExts := []pkix.Extension{acmeExtension, subjectAltName}
   874  	err = checkAcceptableExtensions(okayExts, requireAcmeAndSAN)
   875  	test.AssertNotError(t, err, "Correct type and number of extensions")
   876  
   877  	okayWithUnexpectedExt := []pkix.Extension{weirdExt, acmeExtension, subjectAltName}
   878  	err = checkAcceptableExtensions(okayWithUnexpectedExt, requireAcmeAndSAN)
   879  	test.AssertNotError(t, err, "Correct type and number of extensions")
   880  }
   881  

View as plain text