func TestDNSValidationNoAuthorityOK(t *testing.T) { stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default()) va.DNSResolver = &bdns.MockDNSResolver{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA // create a challenge with well known token chalDNS := core.DNSChallenge01(accountKey) chalDNS.Token = expectedToken keyAuthorization, _ := core.NewKeyAuthorization(chalDNS.Token, accountKey) chalDNS.KeyAuthorization = &keyAuthorization goodIdent := core.AcmeIdentifier{ Type: core.IdentifierDNS, Value: "no-authority-dns01.com", } var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: goodIdent, Challenges: []core.Challenge{chalDNS}, } va.validate(context.Background(), authz, 0) test.AssertNotNil(t, mockRA.lastAuthz, "Should have gotten an authorization") test.Assert(t, authz.Challenges[0].Status == core.StatusValid, "Should be valid.") }
func TestTLSSNI(t *testing.T) { chall := createChallenge(core.ChallengeTypeTLSSNI01) hs := tlssniSrv(t, chall) port, err := getPort(hs) test.AssertNotError(t, err, "failed to get test server port") stats, _ := statsd.NewNoopClient() va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default()) va.DNSResolver = &mocks.DNSResolver{} log.Clear() finChall, err := va.validateTLSSNI01(ident, chall) test.AssertEquals(t, finChall.Status, core.StatusValid) test.AssertNotError(t, err, "") test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) log.Clear() invalidChall, err := va.validateTLSSNI01(core.AcmeIdentifier{ Type: core.IdentifierType("ip"), Value: net.JoinHostPort("127.0.0.1", fmt.Sprintf("%d", port)), }, chall) test.AssertEquals(t, invalidChall.Status, core.StatusInvalid) test.AssertError(t, err, "IdentifierType IP shouldn't have worked.") test.AssertEquals(t, invalidChall.Error.Type, core.MalformedProblem) log.Clear() invalidChall, err = va.validateTLSSNI01(core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "always.invalid"}, chall) test.AssertEquals(t, invalidChall.Status, core.StatusInvalid) test.AssertError(t, err, "Domain name was supposed to be invalid.") test.AssertEquals(t, invalidChall.Error.Type, core.UnknownHostProblem) // Need to create a new authorized keys object to get an unknown SNI (from the signature value) chall.Token = core.NewToken() keyAuthorization, _ := core.NewKeyAuthorization(chall.Token, accountKey) chall.KeyAuthorization = &keyAuthorization log.Clear() started := time.Now() invalidChall, err = va.validateTLSSNI01(ident, chall) took := time.Since(started) // Check that the HTTP connection times out after 5 seconds and doesn't block for 10 seconds test.Assert(t, (took > (time.Second * 5)), "HTTP timed out before 5 seconds") test.Assert(t, (took < (time.Second * 10)), "HTTP connection didn't timeout after 5 seconds") test.AssertEquals(t, invalidChall.Status, core.StatusInvalid) test.AssertError(t, err, "Connection should've timed out") test.AssertEquals(t, invalidChall.Error.Type, core.ConnectionProblem) test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost \[using 127.0.0.1\]: \[127.0.0.1\]`)), 1) // Take down validation server and check that validation fails. hs.Close() invalidChall, err = va.validateTLSSNI01(ident, chall) test.AssertEquals(t, invalidChall.Status, core.StatusInvalid) test.AssertError(t, err, "Server's down; expected refusal. Where did we connect?") test.AssertEquals(t, invalidChall.Error.Type, core.ConnectionProblem) }
func makeResponse(ch core.Challenge) (out core.Challenge, err error) { keyAuthorization, err := core.NewKeyAuthorization(ch.Token, ch.AccountKey) if err != nil { return } out = core.Challenge{KeyAuthorization: &keyAuthorization} return }
// setChallengeToken sets the token value both in the Token field and // in the serialized KeyAuthorization object. func setChallengeToken(ch *core.Challenge, token string) (err error) { ch.Token = token keyAuthorization, err := core.NewKeyAuthorization(token, ch.AccountKey) if err != nil { return } ch.KeyAuthorization = &keyAuthorization return }
// challengeType == "tls-sni-00" or "dns-00", since they're the same func createChallenge(challengeType string) core.Challenge { chall := core.Challenge{ Type: challengeType, Status: core.StatusPending, Token: core.NewToken(), ValidationRecord: []core.ValidationRecord{}, AccountKey: accountKey, } keyAuthorization, _ := core.NewKeyAuthorization(chall.Token, accountKey) chall.KeyAuthorization = &keyAuthorization return chall }
// challengeType == "tls-sni-00" or "dns-00", since they're the same func createChallenge(challengeType string) core.Challenge { chall := core.Challenge{ Type: challengeType, Status: core.StatusPending, Token: core.NewToken(), ValidationRecord: []core.ValidationRecord{}, AccountKey: accountKey, } keyAuthorization, _ := core.NewKeyAuthorization(chall.Token, accountKey) chall.KeyAuthorization = &keyAuthorization // TODO(https://github.com/letsencrypt/boulder/issues/894): Remove this block validationPayload, _ := json.Marshal(map[string]interface{}{ "type": chall.Type, "token": chall.Token, }) signer, _ := jose.NewSigner(jose.RS256, &TheKey) chall.Validation, _ = signer.Sign(validationPayload, "") return chall }
func httpSrv(t *testing.T, token string) *httptest.Server { m := http.NewServeMux() server := httptest.NewUnstartedServer(m) defaultToken := token currentToken := defaultToken m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if !strings.HasPrefix(r.Host, "localhost:") && !strings.HasPrefix(r.Host, "other.valid:") { t.Errorf("Bad Host header: " + r.Host) } if strings.HasSuffix(r.URL.Path, path404) { t.Logf("HTTPSRV: Got a 404 req\n") http.NotFound(w, r) } else if strings.HasSuffix(r.URL.Path, pathMoved) { t.Logf("HTTPSRV: Got a 301 redirect req\n") if currentToken == defaultToken { currentToken = pathMoved } http.Redirect(w, r, pathValid, 301) } else if strings.HasSuffix(r.URL.Path, pathFound) { t.Logf("HTTPSRV: Got a 302 redirect req\n") if currentToken == defaultToken { currentToken = pathFound } http.Redirect(w, r, pathMoved, 302) } else if strings.HasSuffix(r.URL.Path, pathWait) { t.Logf("HTTPSRV: Got a wait req\n") time.Sleep(time.Second * 3) } else if strings.HasSuffix(r.URL.Path, pathWaitLong) { t.Logf("HTTPSRV: Got a wait-long req\n") time.Sleep(time.Second * 10) } else if strings.HasSuffix(r.URL.Path, pathReLookup) { t.Logf("HTTPSRV: Got a redirect req to a valid hostname\n") if currentToken == defaultToken { currentToken = pathReLookup } port, err := getPort(server) test.AssertNotError(t, err, "failed to get server test port") http.Redirect(w, r, fmt.Sprintf("http://other.valid:%d/path", port), 302) } else if strings.HasSuffix(r.URL.Path, pathReLookupInvalid) { t.Logf("HTTPSRV: Got a redirect req to a invalid hostname\n") http.Redirect(w, r, "http://invalid.invalid/path", 302) } else if strings.HasSuffix(r.URL.Path, pathLooper) { t.Logf("HTTPSRV: Got a loop req\n") http.Redirect(w, r, r.URL.String(), 301) } else if strings.HasSuffix(r.URL.Path, pathRedirectPort) { t.Logf("HTTPSRV: Got a port redirect req\n") http.Redirect(w, r, "http://other.valid:8080/path", 302) } else { t.Logf("HTTPSRV: Got a valid req\n") t.Logf("HTTPSRV: Path = %s\n", r.URL.Path) keyAuthz, _ := core.NewKeyAuthorization(currentToken, accountKey) t.Logf("HTTPSRV: Key Authz = %s\n", keyAuthz.String()) fmt.Fprint(w, keyAuthz.String()) currentToken = defaultToken } }) server.Start() return server }