func TestValidateHTTP(t *testing.T) {
	va := NewValidationAuthorityImpl(false)
	va.DNSResolver = &mocks.MockDNS{}
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	tls := false
	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.TLS = &tls
	challHTTP.ValidationRecord = []core.ValidationRecord{}

	hs := simpleSrv(t, challHTTP.Token, tls)
	port, err := getPort(hs)
	test.AssertNotError(t, err, "failed to get test server port")
	va.simpleHTTPPort = port
	defer hs.Close()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}
	va.validate(authz, 0, AccountKey)

	test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status)
}
func TestValidateHTTP(t *testing.T) {
	va := NewValidationAuthorityImpl(true)
	va.DNSResolver = &mocks.MockDNS{}
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	tls := false
	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.TLS = &tls

	stopChanHTTP := make(chan bool, 1)
	waitChanHTTP := make(chan bool, 1)
	go simpleSrv(t, challHTTP.Token, stopChanHTTP, waitChanHTTP, tls)

	// Let them start
	<-waitChanHTTP

	// shutdown cleanly
	defer func() {
		stopChanHTTP <- true
	}()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}
	va.validate(authz, 0, AccountKey)

	test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status)
}
func TestUpdateValidations(t *testing.T) {
	va := NewValidationAuthorityImpl(false)
	va.DNSResolver = &mocks.MockDNS{}
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	tls := false
	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.TLS = &tls
	challHTTP.ValidationRecord = []core.ValidationRecord{}

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}

	started := time.Now()
	va.UpdateValidations(authz, 0, AccountKey)
	took := time.Since(started)

	// Check that the call to va.UpdateValidations didn't block for 3 seconds
	test.Assert(t, (took < (time.Second * 3)), "UpdateValidations blocked")
}
func TestValidateHTTP(t *testing.T) {
	va := NewValidationAuthorityImpl(true)
	va.DNSResolver = core.NewDNSResolver(time.Second*5, []string{"8.8.8.8:53"})
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.Path = "test"

	stopChanHTTP := make(chan bool, 1)
	waitChanHTTP := make(chan bool, 1)
	go simpleSrv(t, challHTTP.Token, stopChanHTTP, waitChanHTTP)

	// Let them start
	<-waitChanHTTP

	// shutdown cleanly
	defer func() {
		stopChanHTTP <- true
	}()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}
	va.validate(authz, 0)

	test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status)
}
func TestUpdateValidations(t *testing.T) {
	va := NewValidationAuthorityImpl(true)
	va.DNSResolver = core.NewDNSResolver(time.Second*5, []string{"8.8.8.8:53"})
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.Path = "wait"

	stopChanHTTP := make(chan bool, 1)
	waitChanHTTP := make(chan bool, 1)
	go simpleSrv(t, challHTTP.Token, stopChanHTTP, waitChanHTTP)

	// Let them start
	<-waitChanHTTP

	// shutdown cleanly
	defer func() {
		stopChanHTTP <- true
	}()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}

	started := time.Now()
	va.UpdateValidations(authz, 0)
	took := time.Since(started)

	// Check that the call to va.UpdateValidations didn't block for 3 seconds
	test.Assert(t, (took < (time.Second * 3)), "UpdateValidations blocked")
}
func TestValidateHTTP(t *testing.T) {
	tls := false
	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.TLS = &tls
	challHTTP.ValidationRecord = []core.ValidationRecord{}
	challHTTP.AccountKey = accountKey

	hs := simpleSrv(t, challHTTP.Token, tls)
	port, err := getPort(hs)
	test.AssertNotError(t, err, "failed to get test server port")
	stats, _ := statsd.NewNoopClient()
	va := NewValidationAuthorityImpl(&PortConfig{SimpleHTTPPort: port}, stats, clock.Default())
	va.DNSResolver = &mocks.MockDNS{}
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	defer hs.Close()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}
	va.validate(authz, 0)

	test.AssertEquals(t, core.StatusValid, mockRA.lastAuthz.Challenges[0].Status)
}
Example #7
0
// 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
}
// 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
}
// 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) (challenges []core.Challenge, combinations [][]int) {
	challenges = []core.Challenge{
		core.SimpleHTTPChallenge(),
		core.DvsniChallenge(),
	}
	combinations = [][]int{
		[]int{0},
		[]int{1},
	}
	return
}
Example #10
0
// 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
}
Example #11
0
func TestAddAuthorization(t *testing.T) {
	sa, cleanUp := initSA(t)
	defer cleanUp()

	PA := core.Authorization{}

	PA, err := sa.NewPendingAuthorization(PA)
	test.AssertNotError(t, err, "Couldn't create new pending authorization")
	test.Assert(t, PA.ID != "", "ID shouldn't be blank")

	dbPa, err := sa.GetAuthorization(PA.ID)
	test.AssertNotError(t, err, "Couldn't get pending authorization with ID "+PA.ID)
	test.AssertMarshaledEquals(t, PA, dbPa)

	expectedPa := core.Authorization{ID: PA.ID}
	test.AssertMarshaledEquals(t, dbPa.ID, expectedPa.ID)

	var jwk jose.JsonWebKey
	err = json.Unmarshal([]byte(theKey), &jwk)
	if err != nil {
		t.Errorf("JSON unmarshal error: %+v", err)
		return
	}

	chall := core.SimpleHTTPChallenge()

	combos := make([][]int, 1)
	combos[0] = []int{0, 1}

	exp := time.Now().AddDate(0, 0, 1)
	identifier := core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "wut.com"}
	newPa := core.Authorization{ID: PA.ID, Identifier: identifier, RegistrationID: 0, Status: core.StatusPending, Expires: &exp, Challenges: []core.Challenge{chall}, Combinations: combos}
	err = sa.UpdatePendingAuthorization(newPa)
	test.AssertNotError(t, err, "Couldn't update pending authorization with ID "+PA.ID)

	newPa.Status = core.StatusValid
	err = sa.FinalizeAuthorization(newPa)
	test.AssertNotError(t, err, "Couldn't finalize pending authorization with ID "+PA.ID)

	dbPa, err = sa.GetAuthorization(PA.ID)
	test.AssertNotError(t, err, "Couldn't get authorization with ID "+PA.ID)
}
func TestUpdateValidations(t *testing.T) {
	va := NewValidationAuthorityImpl(true)
	va.DNSResolver = &mocks.MockDNS{}
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	tls := false
	challHTTP := core.SimpleHTTPChallenge()
	challHTTP.TLS = &tls
	challHTTP.ValidationRecord = []core.ValidationRecord{}

	stopChanHTTP := make(chan bool, 1)
	waitChanHTTP := make(chan bool, 1)
	go simpleSrv(t, challHTTP.Token, stopChanHTTP, waitChanHTTP, tls)

	// Let them start
	<-waitChanHTTP

	// shutdown cleanly
	defer func() {
		stopChanHTTP <- true
	}()

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		Challenges:     []core.Challenge{challHTTP},
	}

	started := time.Now()
	va.UpdateValidations(authz, 0, AccountKey)
	took := time.Since(started)

	// Check that the call to va.UpdateValidations didn't block for 3 seconds
	test.Assert(t, (took < (time.Second * 3)), "UpdateValidations blocked")
}
		Type: "simpleHttp",
	}

	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)
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
}