func TestValidateDvsniNotSane(t *testing.T) { va := NewValidationAuthorityImpl(true) va.DNSResolver = core.NewDNSResolver(time.Second*5, []string{"8.8.8.8:53"}) mockRA := &MockRegistrationAuthority{} va.RA = mockRA challDvsni := core.DvsniChallenge() challDvsni.R = "boulder" // Not a sane thing to do. waitChanDvsni := make(chan bool, 1) stopChanDvsni := make(chan bool, 1) ar, _ := core.B64dec(challDvsni.R) as, _ := core.B64dec(challDvsni.S) go dvsniSrv(t, ar, as, stopChanDvsni, waitChanDvsni) // Let them start <-waitChanDvsni // shutdown cleanly defer func() { stopChanDvsni <- true }() var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{challDvsni}, } va.validate(authz, 0) test.AssertEquals(t, core.StatusInvalid, mockRA.lastAuthz.Challenges[0].Status) }
// ChallengesFor makes a decision of what challenges, and combinations, are // acceptable for the given identifier. // // Note: Current implementation is static, but future versions may not be. func (pa PolicyAuthorityImpl) ChallengesFor(identifier core.AcmeIdentifier, accountKey *jose.JsonWebKey) (challenges []core.Challenge, combinations [][]int, err error) { challenges = []core.Challenge{} combinations = [][]int{} // TODO(https://github.com/letsencrypt/boulder/issues/894): Remove this block if pa.enabledChallenges[core.ChallengeTypeSimpleHTTP] { challenges = append(challenges, core.SimpleHTTPChallenge(accountKey)) } // TODO(https://github.com/letsencrypt/boulder/issues/894): Remove this block if pa.enabledChallenges[core.ChallengeTypeDVSNI] { challenges = append(challenges, core.DvsniChallenge(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeHTTP01] { challenges = append(challenges, core.HTTPChallenge01(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeTLSSNI01] { challenges = append(challenges, core.TLSSNIChallenge01(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeDNS01] { challenges = append(challenges, core.DNSChallenge01(accountKey)) } combinations = make([][]int, len(challenges)) for i := range combinations { combinations[i] = []int{i} } return }
func TestValidateDvsni(t *testing.T) { va := NewValidationAuthorityImpl(true) va.DNSResolver = &mocks.MockDNS{} mockRA := &MockRegistrationAuthority{} va.RA = mockRA challDvsni := core.DvsniChallenge() challDvsni.S = challDvsni.R waitChanDvsni := make(chan bool, 1) stopChanDvsni := make(chan bool, 1) ar, _ := core.B64dec(challDvsni.R) as, _ := core.B64dec(challDvsni.S) go dvsniSrv(t, ar, as, stopChanDvsni, waitChanDvsni) // Let them start <-waitChanDvsni // shutdown cleanly defer func() { stopChanDvsni <- true }() var authz = core.Authorization{ ID: core.NewToken(), RegistrationID: 1, Identifier: ident, Challenges: []core.Challenge{challDvsni}, } va.validate(authz, 0) test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status) }
// ChallengesFor makes a decision of what challenges, and combinations, are // acceptable for the given identifier. // // Note: Current implementation is static, but future versions may not be. func (pa PolicyAuthorityImpl) ChallengesFor(identifier core.AcmeIdentifier, accountKey *jose.JsonWebKey) (challenges []core.Challenge, combinations [][]int, err error) { // TODO(https://github.com/letsencrypt/boulder/issues/894): Update these lines challenges = []core.Challenge{ core.SimpleHTTPChallenge(accountKey), core.DvsniChallenge(accountKey), core.HTTPChallenge01(accountKey), core.TLSSNIChallenge01(accountKey), } combinations = [][]int{[]int{0}, []int{1}, []int{2}, []int{3}} return }
// For now, we just issue DVSNI and SimpleHTTPS challenges for everything func (pa PolicyAuthorityImpl) ChallengesFor(identifier core.AcmeIdentifier) (challenges []core.Challenge, combinations [][]int) { challenges = []core.Challenge{ core.SimpleHTTPSChallenge(), core.DvsniChallenge(), } combinations = [][]int{ []int{0}, []int{1}, } return }
// ChallengesFor makes a decision of what challenges, and combinations, are // acceptable for the given identifier. // // Note: Current implementation is static, but future versions may not be. func (pa PolicyAuthorityImpl) ChallengesFor(identifier core.AcmeIdentifier, accountKey *jose.JsonWebKey) ([]core.Challenge, [][]int, error) { challenges := []core.Challenge{} // TODO(https://github.com/letsencrypt/boulder/issues/894): Remove this block if pa.enabledChallenges[core.ChallengeTypeSimpleHTTP] { challenges = append(challenges, core.SimpleHTTPChallenge(accountKey)) } // TODO(https://github.com/letsencrypt/boulder/issues/894): Remove this block if pa.enabledChallenges[core.ChallengeTypeDVSNI] { challenges = append(challenges, core.DvsniChallenge(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeHTTP01] { challenges = append(challenges, core.HTTPChallenge01(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeTLSSNI01] { challenges = append(challenges, core.TLSSNIChallenge01(accountKey)) } if pa.enabledChallenges[core.ChallengeTypeDNS01] { challenges = append(challenges, core.DNSChallenge01(accountKey)) } // We shuffle the challenges and combinations to prevent ACME clients from // relying on the specific order that boulder returns them in. shuffled := make([]core.Challenge, len(challenges)) combinations := make([][]int, len(challenges)) for i, challIdx := range pa.pseudoRNG.Perm(len(challenges)) { shuffled[i] = challenges[challIdx] combinations[i] = []int{i} } shuffledCombos := make([][]int, len(combinations)) for i, comboIdx := range pa.pseudoRNG.Perm(len(combinations)) { shuffledCombos[i] = combinations[comboIdx] } return shuffled, shuffledCombos, nil }
} ExampleCSR = &x509.CertificateRequest{} // These values are populated by the tests as we go url0, _ = url.Parse("http://acme.invalid/authz/60p2Dc_XmUB2UUJBV4wYkF7BJbPD9KlDnUL3SmFMuTE?challenge=0") url1, _ = url.Parse("http://acme.invalid/authz/60p2Dc_XmUB2UUJBV4wYkF7BJbPD9KlDnUL3SmFMuTE?challenge=0") Registration = core.Registration{} AuthzInitial = core.Authorization{ ID: "60p2Dc_XmUB2UUJBV4wYkF7BJbPD9KlDnUL3SmFMuTE", Identifier: core.AcmeIdentifier{Type: "dns", Value: "not-example.com"}, RegistrationID: 1, Status: "pending", Challenges: []core.Challenge{ core.SimpleHTTPChallenge(), core.DvsniChallenge(), }, Combinations: [][]int{[]int{0}, []int{1}}, } AuthzUpdated = core.Authorization{} AuthzFinal = core.Authorization{} log = mocks.UseMockLog() // TODO(jmhodges): Turn this into boulder_sa_test dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test" ) func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK")
func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, clock.FakeClock, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshal JWK") simpleHTTP := core.SimpleHTTPChallenge(&AccountKeyA) dvsni := core.DvsniChallenge(&AccountKeyA) AuthzInitial.Challenges = []core.Challenge{simpleHTTP, dvsni} fc := clock.NewFake() dbMap, err := sa.NewDbMap(vars.DBConnSA) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } ssa, err := sa.NewSQLStorageAuthority(dbMap, fc) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetSATestDatabase(t) va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CAkeyPEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CAcertPEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) basicPolicy := &cfsslConfig.Signing{ Default: &cfsslConfig.SigningProfile{ Usage: []string{"server auth", "client auth"}, Expiry: 1 * time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, DNSNames: true, }, }, } signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy) ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour) paDbMap, err := sa.NewDbMap(vars.DBConnPolicy) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } policyDBCleanUp := test.ResetPolicyTestDatabase(t) pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false) test.AssertNotError(t, err, "Couldn't create PA") ca := ca.CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, SA: ssa, PA: pa, ValidityPeriod: time.Hour * 2190, NotAfter: time.Now().Add(time.Hour * 8761), Clk: fc, Publisher: &mocks.Publisher{}, } cleanUp := func() { saDBCleanUp() policyDBCleanUp() } csrDER, _ := hex.DecodeString(CSRhex) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) Registration, _ = ssa.NewRegistration(core.Registration{ Key: AccountKeyA, InitialIP: net.ParseIP("3.2.3.3"), }) stats, _ := statsd.NewNoopClient() ra := NewRegistrationAuthorityImpl(fc, blog.GetAuditLogger(), stats, cmd.RateLimitConfig{ TotalCertificates: cmd.RateLimitPolicy{ Threshold: 100, Window: cmd.ConfigDuration{Duration: 24 * 90 * time.Hour}, }, }, 1) ra.SA = ssa ra.VA = va ra.CA = &ca ra.PA = pa ra.DNSResolver = &mocks.DNSResolver{} AuthzInitial.RegistrationID = Registration.ID AuthzFinal = AuthzInitial AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return va, ssa, &ra, fc, cleanUp }