github.com/letsencrypt/boulder@v0.20251208.0/va/tlsalpn_test.go (about)

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