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 }