Ejemplo n.º 1
0
func TestValidateContacts(t *testing.T) {
	_, _, ra, _, cleanUp := initAuthorities(t)
	defer cleanUp()

	tel, _ := core.ParseAcmeURL("tel:")
	ansible, _ := core.ParseAcmeURL("ansible:earth.sol.milkyway.laniakea/letsencrypt")
	validEmail, _ := core.ParseAcmeURL("mailto:[email protected]")
	malformedEmail, _ := core.ParseAcmeURL("mailto:admin.com")

	err := ra.validateContacts([]*core.AcmeURL{})
	test.AssertNotError(t, err, "No Contacts")

	err = ra.validateContacts([]*core.AcmeURL{tel, validEmail})
	test.AssertError(t, err, "Too Many Contacts")

	err = ra.validateContacts([]*core.AcmeURL{tel})
	test.AssertNotError(t, err, "Simple Telephone")

	err = ra.validateContacts([]*core.AcmeURL{validEmail})
	test.AssertNotError(t, err, "Valid Email")

	err = ra.validateContacts([]*core.AcmeURL{malformedEmail})
	test.AssertError(t, err, "Malformed Email")

	err = ra.validateContacts([]*core.AcmeURL{ansible})
	test.AssertError(t, err, "Unknown scheme")
}
func TestAddRegistration(t *testing.T) {
	sa, clk, cleanUp := initSA(t)
	defer cleanUp()

	jwk := satest.GoodJWK()

	contact, err := core.ParseAcmeURL("mailto:[email protected]")
	if err != nil {
		t.Fatalf("unable to parse contact link: %s", err)
	}
	contacts := []*core.AcmeURL{contact}
	reg, err := sa.NewRegistration(core.Registration{
		Key:       jwk,
		Contact:   contacts,
		InitialIP: net.ParseIP("43.34.43.34"),
	})
	if err != nil {
		t.Fatalf("Couldn't create new registration: %s", err)
	}
	test.Assert(t, reg.ID != 0, "ID shouldn't be 0")
	test.AssertDeepEquals(t, reg.Contact, contacts)

	_, err = sa.GetRegistration(0)
	test.AssertError(t, err, "Registration object for ID 0 was returned")

	dbReg, err := sa.GetRegistration(reg.ID)
	test.AssertNotError(t, err, fmt.Sprintf("Couldn't get registration with ID %v", reg.ID))

	expectedReg := core.Registration{
		ID:        reg.ID,
		Key:       jwk,
		InitialIP: net.ParseIP("43.34.43.34"),
		CreatedAt: clk.Now(),
	}
	test.AssertEquals(t, dbReg.ID, expectedReg.ID)
	test.Assert(t, core.KeyDigestEquals(dbReg.Key, expectedReg.Key), "Stored key != expected")

	u, _ := core.ParseAcmeURL("test.com")

	newReg := core.Registration{
		ID:        reg.ID,
		Key:       jwk,
		Contact:   []*core.AcmeURL{u},
		InitialIP: net.ParseIP("72.72.72.72"),
		Agreement: "yes",
	}
	err = sa.UpdateRegistration(newReg)
	test.AssertNotError(t, err, fmt.Sprintf("Couldn't get registration with ID %v", reg.ID))
	dbReg, err = sa.GetRegistrationByKey(jwk)
	test.AssertNotError(t, err, "Couldn't get registration by key")

	test.AssertEquals(t, dbReg.ID, newReg.ID)
	test.AssertEquals(t, dbReg.Agreement, newReg.Agreement)

	var anotherJWK jose.JsonWebKey
	err = json.Unmarshal([]byte(anotherKey), &anotherJWK)
	test.AssertNotError(t, err, "couldn't unmarshal anotherJWK")
	_, err = sa.GetRegistrationByKey(anotherJWK)
	test.AssertError(t, err, "Registration object for invalid key was returned")
}
Ejemplo n.º 3
0
func TestValidateContacts(t *testing.T) {
	_, _, ra, _, cleanUp := initAuthorities(t)
	defer cleanUp()

	ansible, _ := core.ParseAcmeURL("ansible:earth.sol.milkyway.laniakea/letsencrypt")
	validEmail, _ := core.ParseAcmeURL("mailto:[email protected]")
	otherValidEmail, _ := core.ParseAcmeURL("mailto:[email protected]")
	malformedEmail, _ := core.ParseAcmeURL("mailto:admin.com")

	err := ra.validateContacts(context.Background(), &[]*core.AcmeURL{})
	test.AssertNotError(t, err, "No Contacts")

	err = ra.validateContacts(context.Background(), &[]*core.AcmeURL{validEmail, otherValidEmail})
	test.AssertError(t, err, "Too Many Contacts")

	err = ra.validateContacts(context.Background(), &[]*core.AcmeURL{validEmail})
	test.AssertNotError(t, err, "Valid Email")

	err = ra.validateContacts(context.Background(), &[]*core.AcmeURL{malformedEmail})
	test.AssertError(t, err, "Malformed Email")

	err = ra.validateContacts(context.Background(), &[]*core.AcmeURL{ansible})
	test.AssertError(t, err, "Unknown scheme")

	err = ra.validateContacts(context.Background(), &[]*core.AcmeURL{nil})
	test.AssertError(t, err, "Nil AcmeURL")
}
Ejemplo n.º 4
0
func TestValidateContacts(t *testing.T) {
	tel, _ := core.ParseAcmeURL("tel:")
	ansible, _ := core.ParseAcmeURL("ansible:earth.sol.milkyway.laniakea/letsencrypt")
	validEmail, _ := core.ParseAcmeURL("mailto:[email protected]")
	invalidEmail, _ := core.ParseAcmeURL("mailto:[email protected]")
	malformedEmail, _ := core.ParseAcmeURL("mailto:admin.com")

	err := validateContacts([]*core.AcmeURL{}, &mocks.MockDNS{})
	test.AssertNotError(t, err, "No Contacts")

	err = validateContacts([]*core.AcmeURL{tel}, &mocks.MockDNS{})
	test.AssertNotError(t, err, "Simple Telephone")

	err = validateContacts([]*core.AcmeURL{validEmail}, &mocks.MockDNS{})
	test.AssertNotError(t, err, "Valid Email")

	err = validateContacts([]*core.AcmeURL{invalidEmail}, &mocks.MockDNS{})
	test.AssertError(t, err, "Invalid Email")

	err = validateContacts([]*core.AcmeURL{malformedEmail}, &mocks.MockDNS{})
	test.AssertError(t, err, "Malformed Email")

	err = validateContacts([]*core.AcmeURL{ansible}, &mocks.MockDNS{})
	test.AssertError(t, err, "Unknown scehme")
}
Ejemplo n.º 5
0
func TestSendNags(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	mc := mocks.Mailer{}
	rs := newFakeRegStore()
	fc := newFakeClock(t)

	m := mailer{
		stats:         stats,
		mailer:        &mc,
		emailTemplate: tmpl,
		rs:            rs,
		clk:           fc,
	}

	cert := &x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy",
		},
		NotAfter: fc.Now().AddDate(0, 0, 2),
		DNSNames: []string{"example.com"},
	}

	email, _ := core.ParseAcmeURL("mailto:[email protected]")
	emailB, _ := core.ParseAcmeURL("mailto:[email protected]")

	err := m.sendNags([]*core.AcmeURL{email}, []*x509.Certificate{cert})
	test.AssertNotError(t, err, "Failed to send warning messages")
	test.AssertEquals(t, len(mc.Messages), 1)
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), mc.Messages[0])

	mc.Clear()
	err = m.sendNags([]*core.AcmeURL{email, emailB}, []*x509.Certificate{cert})
	test.AssertNotError(t, err, "Failed to send warning messages")
	test.AssertEquals(t, len(mc.Messages), 2)
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), mc.Messages[0])
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 2 days (%s)`, cert.NotAfter.Format(time.RFC822Z)), mc.Messages[1])

	mc.Clear()
	err = m.sendNags([]*core.AcmeURL{}, []*x509.Certificate{cert})
	test.AssertNotError(t, err, "Not an error to pass no email contacts")
	test.AssertEquals(t, len(mc.Messages), 0)

	templates, err := template.ParseGlob("../../data/*.template")
	test.AssertNotError(t, err, "Failed to parse templates")
	for _, template := range templates.Templates() {
		m.emailTemplate = template
		err = m.sendNags(nil, []*x509.Certificate{cert})
		test.AssertNotError(t, err, "failed to send nag")
	}
}
Ejemplo n.º 6
0
func CreateDomainAuthWithRegId(t *testing.T, domainName string, sa *SQLStorageAuthority, regID int64) (authz core.Authorization) {

	// create pending auth
	authz, err := sa.NewPendingAuthorization(core.Authorization{RegistrationID: regID, Challenges: []core.Challenge{core.Challenge{}}})
	if err != nil {
		t.Fatalf("Couldn't create new pending authorization: %s", err)
	}
	test.Assert(t, authz.ID != "", "ID shouldn't be blank")

	// prepare challenge for auth
	u, err := core.ParseAcmeURL(domainName)
	test.AssertNotError(t, err, "Couldn't parse domainName "+domainName)
	chall := core.Challenge{Type: "simpleHttp", Status: core.StatusValid, URI: u, Token: "THISWOULDNTBEAGOODTOKEN"}
	combos := make([][]int, 1)
	combos[0] = []int{0, 1}
	exp := time.Now().AddDate(0, 0, 1) // expire in 1 day

	// validate pending auth
	authz.Status = core.StatusPending
	authz.Identifier = core.AcmeIdentifier{Type: core.IdentifierDNS, Value: domainName}
	authz.Expires = &exp
	authz.Challenges = []core.Challenge{chall}
	authz.Combinations = combos

	// save updated auth
	err = sa.UpdatePendingAuthorization(authz)
	test.AssertNotError(t, err, "Couldn't update pending authorization with ID "+authz.ID)

	return
}
Ejemplo n.º 7
0
func mustParseAcmeURL(acmeURL string) *core.AcmeURL {
	c, err := core.ParseAcmeURL(acmeURL)
	if err != nil {
		panic(fmt.Sprintf("unable to parse as AcmeURL %#v: %s", acmeURL, err))
	}
	return c
}
Ejemplo n.º 8
0
func TestNewRegistration(t *testing.T) {
	_, sa, ra, _, cleanUp := initAuthorities(t)
	defer cleanUp()
	mailto, _ := core.ParseAcmeURL("mailto:[email protected]")
	input := core.Registration{
		Contact:   []*core.AcmeURL{mailto},
		Key:       AccountKeyB,
		InitialIP: net.ParseIP("7.6.6.5"),
	}

	result, err := ra.NewRegistration(input)
	if err != nil {
		t.Fatalf("could not create new registration: %s", err)
	}

	test.Assert(t, core.KeyDigestEquals(result.Key, AccountKeyB), "Key didn't match")
	test.Assert(t, len(result.Contact) == 1, "Wrong number of contacts")
	test.Assert(t, mailto.String() == result.Contact[0].String(),
		"Contact didn't match")
	test.Assert(t, result.Agreement == "", "Agreement didn't default empty")

	reg, err := sa.GetRegistration(result.ID)
	test.AssertNotError(t, err, "Failed to retrieve registration")
	test.Assert(t, core.KeyDigestEquals(reg.Key, AccountKeyB), "Retrieved registration differed.")
}
Ejemplo n.º 9
0
func TestNewRegistrationNoFieldOverwrite(t *testing.T) {
	_, _, _, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	mailto, _ := core.ParseAcmeURL("mailto:[email protected]")
	input := core.Registration{
		ID:        23,
		Key:       AccountKeyC,
		Contact:   []*core.AcmeURL{mailto},
		Agreement: "I agreed",
	}

	result, err := ra.NewRegistration(input)
	test.AssertNotError(t, err, "Could not create new registration")

	test.Assert(t, result.ID != 23, "ID shouldn't be set by user")
	// TODO: Enable this test case once we validate terms agreement.
	//test.Assert(t, result.Agreement != "I agreed", "Agreement shouldn't be set with invalid URL")

	id := result.ID
	result2, err := ra.UpdateRegistration(result, core.Registration{
		ID:  33,
		Key: ShortKey,
	})
	test.AssertNotError(t, err, "Could not update registration")
	test.Assert(t, result2.ID != 33, fmt.Sprintf("ID shouldn't be overwritten. expected %d, got %d", id, result2.ID))
	test.Assert(t, !core.KeyDigestEquals(result2.Key, ShortKey), "Key shouldn't be overwritten")
}
Ejemplo n.º 10
0
func TestDontFindRevokedCert(t *testing.T) {
	expiresIn := 24 * time.Hour
	ctx := setup(t, []time.Duration{expiresIn})

	var keyA jose.JsonWebKey
	err := json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")

	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")

	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key:       keyA,
		InitialIP: net.ParseIP("6.5.5.6"),
	}
	regA, err = ctx.ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},

		NotAfter:     ctx.fc.Now().Add(expiresIn),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "001",
		Expires:        rawCertA.NotAfter,
		DER:            certDerA,
	}

	certStatusA := &core.CertificateStatus{
		Serial: "001",
		Status: core.OCSPStatusRevoked,
	}

	setupDBMap, err := sa.NewDbMap("mysql+tcp://test_setup@localhost:3306/boulder_sa_test")
	err = setupDBMap.Insert(certA)
	test.AssertNotError(t, err, "unable to insert Certificate")
	err = setupDBMap.Insert(certStatusA)
	test.AssertNotError(t, err, "unable to insert CertificateStatus")

	err = ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "err from findExpiringCertificates")

	if len(ctx.mc.Messages) != 0 {
		t.Errorf("no emails should have been sent, but sent %d", len(ctx.mc.Messages))
	}
}
Ejemplo n.º 11
0
func TestSendNags(t *testing.T) {
	stats, _ := statsd.NewNoopClient(nil)
	mc := mockMail{}
	rs := newFakeRegStore()
	fc := clock.NewFake()
	fc.Add(7 * 24 * time.Hour)

	m := mailer{
		stats:         stats,
		mailer:        &mc,
		emailTemplate: tmpl,
		rs:            rs,
		clk:           fc,
	}

	cert := &x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy",
		},
		NotAfter: fc.Now().AddDate(0, 0, 2),
		DNSNames: []string{"example.com"},
	}

	email, _ := core.ParseAcmeURL("mailto:[email protected]")
	emailB, _ := core.ParseAcmeURL("mailto:[email protected]")

	err := m.sendNags(cert, []*core.AcmeURL{email})
	test.AssertNotError(t, err, "Failed to send warning messages")
	test.AssertEquals(t, len(mc.Messages), 1)
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 3 days (%s)`, cert.NotAfter), mc.Messages[0])

	mc.Clear()
	err = m.sendNags(cert, []*core.AcmeURL{email, emailB})
	test.AssertNotError(t, err, "Failed to send warning messages")
	test.AssertEquals(t, len(mc.Messages), 2)
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 3 days (%s)`, cert.NotAfter), mc.Messages[0])
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example.com is going to expire in 3 days (%s)`, cert.NotAfter), mc.Messages[1])

	mc.Clear()
	err = m.sendNags(cert, []*core.AcmeURL{})
	test.AssertNotError(t, err, "Not an error to pass no email contacts")
	test.AssertEquals(t, len(mc.Messages), 0)
}
Ejemplo n.º 12
0
func TestNewRegistrationBadKey(t *testing.T) {
	_, _, _, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	mailto, _ := core.ParseAcmeURL("mailto:[email protected]")
	input := core.Registration{
		Contact: []*core.AcmeURL{mailto},
		Key:     ShortKey,
	}

	_, err := ra.NewRegistration(input)
	test.AssertError(t, err, "Should have rejected authorization with short key")
}
Ejemplo n.º 13
0
// CreateWorkingRegistration inserts a new, correct Registration into
// SA using GoodKey under the hood. This a hack to allow both the CA
// and SA tests to benefit because the CA tests currently require a
// full-fledged SQLSAImpl. Long term, when the CA tests no longer need
// CreateWorkingRegistration, this and CreateWorkingRegistration can
// be pushed back into the SA tests proper.
func CreateWorkingRegistration(t *testing.T, sa core.StorageAuthority) core.Registration {
	contact, err := core.ParseAcmeURL("mailto:[email protected]")
	if err != nil {
		t.Fatalf("unable to parse contact link: %s", err)
	}
	contacts := []*core.AcmeURL{contact}
	reg, err := sa.NewRegistration(core.Registration{
		Key:     GoodJWK(),
		Contact: contacts,
	})
	if err != nil {
		t.Fatalf("Unable to create new registration")
	}
	return reg
}
Ejemplo n.º 14
0
func modelToChallenge(cm *challModel) (core.Challenge, error) {
	c := core.Challenge{
		Type:      cm.Type,
		Status:    cm.Status,
		Validated: cm.Validated,
		Token:     cm.Token,
		TLS:       cm.TLS,
	}
	if len(cm.URI) > 0 {
		uri, err := core.ParseAcmeURL(cm.URI)
		if err != nil {
			return core.Challenge{}, err
		}
		c.URI = uri
	}
	if len(cm.Validation) > 0 {
		val, err := jose.ParseSigned(string(cm.Validation))
		if err != nil {
			return core.Challenge{}, err
		}
		c.Validation = val
	}
	if len(cm.Error) > 0 {
		var problem core.ProblemDetails
		err := json.Unmarshal(cm.Error, &problem)
		if err != nil {
			return core.Challenge{}, err
		}
		c.Error = &problem
	}
	if len(cm.ValidationRecord) > 0 {
		var vr []core.ValidationRecord
		err := json.Unmarshal(cm.ValidationRecord, &vr)
		if err != nil {
			return core.Challenge{}, err
		}
		c.ValidationRecord = vr
	}
	if len(cm.AccountKey) > 0 {
		var ak jose.JsonWebKey
		err := json.Unmarshal(cm.AccountKey, &ak)
		if err != nil {
			return core.Challenge{}, err
		}
		c.AccountKey = &ak
	}
	return c, nil
}
Ejemplo n.º 15
0
// CreateWorkingRegistration inserts a new, correct Registration into
// SA using GoodKey under the hood. This a hack to allow both the CA
// and SA tests to benefit because the CA tests currently require a
// full-fledged SQLSAImpl. Long term, when the CA tests no longer need
// CreateWorkingRegistration, this and CreateWorkingRegistration can
// be pushed back into the SA tests proper.
func CreateWorkingRegistration(t *testing.T, sa core.StorageAdder) core.Registration {
	contact, err := core.ParseAcmeURL("mailto:[email protected]")
	if err != nil {
		t.Fatalf("unable to parse contact link: %s", err)
	}
	contacts := &[]*core.AcmeURL{contact}
	reg, err := sa.NewRegistration(context.Background(), core.Registration{
		Key:       GoodJWK(),
		Contact:   contacts,
		InitialIP: net.ParseIP("88.77.66.11"),
		CreatedAt: time.Date(2003, 5, 10, 0, 0, 0, 0, time.UTC),
	})
	if err != nil {
		t.Fatalf("Unable to create new registration: %s", err)
	}
	return reg
}
Ejemplo n.º 16
0
func TestLifetimeOfACert(t *testing.T) {
	ctx := setup(t, []time.Duration{time.Hour * 24, time.Hour * 24 * 4, time.Hour * 24 * 7})
	defer ctx.cleanUp()

	var keyA jose.JsonWebKey
	err := json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")

	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")

	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key:       keyA,
		InitialIP: net.ParseIP("1.2.2.1"),
	}
	regA, err = ctx.ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},

		NotAfter:     ctx.fc.Now(),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "001",
		Expires:        rawCertA.NotAfter,
		DER:            certDerA,
	}

	certStatusA := &core.CertificateStatus{
		Serial: "001",
		Status: core.OCSPStatusGood,
	}

	setupDBMap, err := sa.NewDbMap("mysql+tcp://test_setup@localhost:3306/boulder_sa_test")
	err = setupDBMap.Insert(certA)
	test.AssertNotError(t, err, "unable to insert Certificate")
	err = setupDBMap.Insert(certStatusA)
	test.AssertNotError(t, err, "unable to insert CertificateStatus")

	type lifeTest struct {
		timeLeft time.Duration
		numMsgs  int
		context  string
	}
	tests := []lifeTest{
		{
			timeLeft: 9 * 24 * time.Hour, // 9 days before expiration

			numMsgs: 0,
			context: "Expected no emails sent because we are more than 7 days out.",
		},
		{
			(7*24 + 12) * time.Hour, // 7.5 days before
			1,
			"Sent 1 for 7 day notice.",
		},
		{
			7 * 24 * time.Hour,
			1,
			"The 7 day email was already sent.",
		},
		{
			(4*24 - 1) * time.Hour, // <4 days before, the mailer did not run yesterday
			2,
			"Sent 1 for the 7 day notice, and 1 for the 4 day notice.",
		},
		{
			36 * time.Hour, // within 1day + nagMargin
			3,
			"Sent 1 for the 7 day notice, 1 for the 4 day notice, and 1 for the 1 day notice.",
		},
		{
			12 * time.Hour,
			3,
			"The 1 day before email was already sent.",
		},
		{
			-2 * 24 * time.Hour, // 2 days after expiration
			3,
			"No expiration warning emails are sent after expiration",
		},
	}

	for _, tt := range tests {
		ctx.fc.Add(-tt.timeLeft)
		err = ctx.m.findExpiringCertificates()
		test.AssertNotError(t, err, "error calling findExpiringCertificates")
		if len(ctx.mc.Messages) != tt.numMsgs {
			t.Errorf(tt.context+" number of messages: expected %d, got %d", tt.numMsgs, len(ctx.mc.Messages))
		}
		ctx.fc.Add(tt.timeLeft)
	}
}
Ejemplo n.º 17
0
func TestFindExpiringCertificates(t *testing.T) {
	ctx := setup(t, []time.Duration{time.Hour * 24, time.Hour * 24 * 4, time.Hour * 24 * 7})

	log.Clear()
	err := ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed on no certificates")
	test.AssertEquals(t, len(log.GetAllMatching("Searching for certificates that expire between.*")), 3)

	// Add some expiring certificates and registrations
	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")
	emailB, _ := core.ParseAcmeURL("mailto:[email protected]")
	var keyA jose.JsonWebKey
	var keyB jose.JsonWebKey
	err = json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyB, &keyB)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key:       keyA,
		InitialIP: net.ParseIP("2.3.2.3"),
	}
	regB := core.Registration{
		ID: 2,
		Contact: []*core.AcmeURL{
			emailB,
		},
		Key:       keyB,
		InitialIP: net.ParseIP("2.3.2.3"),
	}
	regA, err = ctx.ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	regB, err = ctx.ssa.NewRegistration(regB)
	if err != nil {
		t.Fatalf("Couldn't store regB: %s", err)
	}

	// Expires in <1d, last nag was the 4d nag
	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},
		NotAfter:     ctx.fc.Now().Add(23 * time.Hour),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "001",
		Expires:        rawCertA.NotAfter,
		DER:            certDerA,
	}
	certStatusA := &core.CertificateStatus{
		Serial:                "001",
		LastExpirationNagSent: ctx.fc.Now().AddDate(0, 0, -3),
		Status:                core.OCSPStatusGood,
	}

	// Expires in 3d, already sent 4d nag at 4.5d
	rawCertB := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy B",
		},
		NotAfter:     ctx.fc.Now().AddDate(0, 0, 3),
		DNSNames:     []string{"example-b.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerB, _ := x509.CreateCertificate(rand.Reader, &rawCertB, &rawCertB, &testKey.PublicKey, &testKey)
	certB := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "002",
		Expires:        rawCertB.NotAfter,
		DER:            certDerB,
	}
	certStatusB := &core.CertificateStatus{
		Serial:                "002",
		LastExpirationNagSent: ctx.fc.Now().Add(-36 * time.Hour),
		Status:                core.OCSPStatusGood,
	}

	// Expires in 7d and change, no nag sent at all yet
	rawCertC := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy C",
		},
		NotAfter:     ctx.fc.Now().Add((7*24 + 1) * time.Hour),
		DNSNames:     []string{"example-c.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerC, _ := x509.CreateCertificate(rand.Reader, &rawCertC, &rawCertC, &testKey.PublicKey, &testKey)
	certC := &core.Certificate{
		RegistrationID: regB.ID,
		Serial:         "003",
		Expires:        rawCertC.NotAfter,
		DER:            certDerC,
	}
	certStatusC := &core.CertificateStatus{
		Serial: "003",
		Status: core.OCSPStatusGood,
	}

	setupDBMap, err := sa.NewDbMap("mysql+tcp://test_setup@localhost:3306/boulder_sa_test")
	err = setupDBMap.Insert(certA)
	test.AssertNotError(t, err, "Couldn't add certA")
	err = setupDBMap.Insert(certB)
	test.AssertNotError(t, err, "Couldn't add certB")
	err = setupDBMap.Insert(certC)
	test.AssertNotError(t, err, "Couldn't add certC")
	err = setupDBMap.Insert(certStatusA)
	test.AssertNotError(t, err, "Couldn't add certStatusA")
	err = setupDBMap.Insert(certStatusB)
	test.AssertNotError(t, err, "Couldn't add certStatusB")
	err = setupDBMap.Insert(certStatusC)
	test.AssertNotError(t, err, "Couldn't add certStatusC")

	log.Clear()
	err = ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	// Should get 001 and 003
	test.AssertEquals(t, len(ctx.mc.Messages), 2)

	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-a.com is going to expire in 0 days (%s)`, rawCertA.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), ctx.mc.Messages[0])
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-c.com is going to expire in 7 days (%s)`, rawCertC.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), ctx.mc.Messages[1])

	// A consecutive run shouldn't find anything
	ctx.mc.Clear()
	log.Clear()
	err = ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	test.AssertEquals(t, len(ctx.mc.Messages), 0)
}
Ejemplo n.º 18
0
func TestFindExpiringCertificates(t *testing.T) {
	ctx := setup(t, []time.Duration{time.Hour * 24, time.Hour * 24 * 4, time.Hour * 24 * 7})

	ctx.fc.Add(7 * 24 * time.Hour)

	log.Clear()
	err := ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed on no certificates")
	test.AssertEquals(t, len(log.GetAllMatching("Searching for certificates that expire between.*")), 3)

	// Add some expiring certificates and registrations
	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")
	emailB, _ := core.ParseAcmeURL("mailto:[email protected]")
	var keyA jose.JsonWebKey
	var keyB jose.JsonWebKey
	err = json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyB, &keyB)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key: keyA,
	}
	regB := core.Registration{
		ID: 2,
		Contact: []*core.AcmeURL{
			emailB,
		},
		Key: keyB,
	}
	regA, err = ctx.ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	regB, err = ctx.ssa.NewRegistration(regB)
	if err != nil {
		t.Fatalf("Couldn't store regB: %s", err)
	}

	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},
		// This is slightly within the ultime nag window (one day)
		NotAfter:     ctx.fc.Now().AddDate(0, 0, 1).Add(-time.Hour),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "001",
		Expires:        rawCertA.NotAfter,
		DER:            certDerA,
	}
	// Already sent a nag but too long ago
	certStatusA := &core.CertificateStatus{
		Serial:                "001",
		LastExpirationNagSent: ctx.fc.Now().Add(-time.Hour * 24 * 3),
		Status:                core.OCSPStatusGood,
	}
	rawCertB := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy B",
		},
		NotAfter:     ctx.fc.Now().AddDate(0, 0, 3),
		DNSNames:     []string{"example-b.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerB, _ := x509.CreateCertificate(rand.Reader, &rawCertB, &rawCertB, &testKey.PublicKey, &testKey)
	certB := &core.Certificate{
		RegistrationID: regA.ID,
		Serial:         "002",
		Expires:        rawCertB.NotAfter,
		DER:            certDerB,
	}
	// Already sent a nag for this period
	certStatusB := &core.CertificateStatus{
		Serial:                "002",
		LastExpirationNagSent: ctx.fc.Now().Add(-time.Hour * 24 * 3),
		Status:                core.OCSPStatusGood,
	}
	rawCertC := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy C",
		},
		// This is within the earliest nag window (7 days)
		NotAfter:     ctx.fc.Now().AddDate(0, 0, 6),
		DNSNames:     []string{"example-c.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerC, _ := x509.CreateCertificate(rand.Reader, &rawCertC, &rawCertC, &testKey.PublicKey, &testKey)
	certC := &core.Certificate{
		RegistrationID: regB.ID,
		Serial:         "003",
		Expires:        rawCertC.NotAfter,
		DER:            certDerC,
	}
	certStatusC := &core.CertificateStatus{
		Serial: "003",
		Status: core.OCSPStatusGood,
	}

	err = ctx.dbMap.Insert(certA)
	test.AssertNotError(t, err, "Couldn't add certA")
	err = ctx.dbMap.Insert(certB)
	test.AssertNotError(t, err, "Couldn't add certB")
	err = ctx.dbMap.Insert(certC)
	test.AssertNotError(t, err, "Couldn't add certC")
	err = ctx.dbMap.Insert(certStatusA)
	test.AssertNotError(t, err, "Couldn't add certStatusA")
	err = ctx.dbMap.Insert(certStatusB)
	test.AssertNotError(t, err, "Couldn't add certStatusB")
	err = ctx.dbMap.Insert(certStatusC)
	test.AssertNotError(t, err, "Couldn't add certStatusC")

	log.Clear()
	err = ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	// Should get 001 and 003
	test.AssertEquals(t, len(ctx.mc.Messages), 2)

	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-a.com is going to expire in 1 days (%s)`, rawCertA.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), ctx.mc.Messages[0])
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-c.com is going to expire in 7 days (%s)`, rawCertC.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), ctx.mc.Messages[1])

	// A consecutive run shouldn't find anything
	ctx.mc.Clear()
	log.Clear()
	err = ctx.m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	test.AssertEquals(t, len(ctx.mc.Messages), 0)
}
Ejemplo n.º 19
0
// NewAuthorization constuct a new Authz from a request.
func (ra *RegistrationAuthorityImpl) NewAuthorization(request core.Authorization, regID int64) (authz core.Authorization, err error) {
	reg, err := ra.SA.GetRegistration(regID)
	if err != nil {
		err = core.MalformedRequestError(fmt.Sprintf("Invalid registration ID: %d", regID))
		return authz, err
	}

	identifier := request.Identifier

	// Check that the identifier is present and appropriate
	if err = ra.PA.WillingToIssue(identifier); err != nil {
		err = core.UnauthorizedError(err.Error())
		return authz, err
	}

	// Check CAA records for the requested identifier
	present, valid, err := ra.VA.CheckCAARecords(identifier)
	if err != nil {
		return authz, err
	}
	// AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c
	ra.log.Audit(fmt.Sprintf("Checked CAA records for %s, registration ID %d [Present: %t, Valid for issuance: %t]", identifier.Value, regID, present, valid))
	if !valid {
		err = errors.New("CAA check for identifier failed")
		return authz, err
	}

	// Create validations, but we have to update them with URIs later
	challenges, combinations := ra.PA.ChallengesFor(identifier)

	// Partially-filled object
	authz = core.Authorization{
		Identifier:     identifier,
		RegistrationID: regID,
		Status:         core.StatusPending,
		Combinations:   combinations,
		Challenges:     challenges,
	}

	// Get a pending Auth first so we can get our ID back, then update with challenges
	authz, err = ra.SA.NewPendingAuthorization(authz)
	if err != nil {
		// InternalServerError since the user-data was validated before being
		// passed to the SA.
		err = core.InternalServerError(fmt.Sprintf("Invalid authorization request: %s", err))
		return authz, err
	}

	// Construct all the challenge URIs
	for i := range authz.Challenges {
		// Ignoring these errors because we construct the URLs to be correct
		challengeURI, _ := core.ParseAcmeURL(ra.AuthzBase + authz.ID + "?challenge=" + strconv.Itoa(i))
		authz.Challenges[i].URI = challengeURI

		// Add the account key used to generate the challenge
		authz.Challenges[i].AccountKey = &reg.Key

		if !authz.Challenges[i].IsSane(false) {
			// InternalServerError because we generated these challenges, they should
			// be OK.
			err = core.InternalServerError(fmt.Sprintf("Challenge didn't pass sanity check: %+v", authz.Challenges[i]))
			return authz, err
		}
	}

	// Store the authorization object, then return it
	err = ra.SA.UpdatePendingAuthorization(authz)
	if err != nil {
		// InternalServerError because we created the authorization just above,
		// and adding Sane challenges should not break it.
		err = core.InternalServerError(err.Error())
	}
	return authz, err
}
Ejemplo n.º 20
0
func TestFindExpiringCertificates(t *testing.T) {
	dbMap, err := sa.NewDbMap(dbConnStr)
	if err != nil {
		t.Fatalf("Couldn't connect the database: %s", err)
	}
	cleanUp := test.ResetTestDatabase(t, dbMap.Db)
	ssa, err := sa.NewSQLStorageAuthority(dbMap)
	if err != nil {
		t.Fatalf("unable to create SQLStorageAuthority: %s", err)
	}
	defer cleanUp()
	tmpl, err := template.New("expiry-email").Parse(testTmpl)
	test.AssertNotError(t, err, "Couldn't parse test email template")
	stats, _ := statsd.NewNoopClient(nil)
	mc := mockMail{}
	m := mailer{
		log:           blog.GetAuditLogger(),
		stats:         stats,
		mailer:        &mc,
		emailTemplate: tmpl,
		dbMap:         dbMap,
		rs:            ssa,
		nagTimes:      []time.Duration{time.Hour * 24, time.Hour * 24 * 4, time.Hour * 24 * 7},
		limit:         100,
	}

	log.Clear()
	err = m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed on no certificates")
	test.AssertEquals(t, len(log.GetAllMatching("Searching for certificates that expire between.*")), 3)

	// Add some expiring certificates and registrations
	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")
	emailB, _ := core.ParseAcmeURL("mailto:[email protected]")
	var keyA jose.JsonWebKey
	var keyB jose.JsonWebKey
	err = json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyB, &keyB)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key: keyA,
	}
	regB := core.Registration{
		ID: 2,
		Contact: []*core.AcmeURL{
			emailB,
		},
		Key: keyB,
	}
	regA, err = ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	regB, err = ssa.NewRegistration(regB)
	if err != nil {
		t.Fatalf("Couldn't store regB: %s", err)
	}

	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},
		NotAfter:     time.Now().AddDate(0, 0, 1),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Status:         core.StatusValid,
		Serial:         "001",
		Expires:        time.Now().AddDate(0, 0, 1),
		DER:            certDerA,
	}
	// Already sent a nag but too long ago
	certStatusA := &core.CertificateStatus{Serial: "001", LastExpirationNagSent: time.Now().Add(-time.Hour * 24 * 3)}
	rawCertB := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy B",
		},
		NotAfter:     time.Now().AddDate(0, 0, 3),
		DNSNames:     []string{"example-b.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerB, _ := x509.CreateCertificate(rand.Reader, &rawCertB, &rawCertB, &testKey.PublicKey, &testKey)
	certB := &core.Certificate{
		RegistrationID: regA.ID,
		Status:         core.StatusValid,
		Serial:         "002",
		Expires:        time.Now().AddDate(0, 0, 3),
		DER:            certDerB,
	}
	// Already sent a nag for this period
	certStatusB := &core.CertificateStatus{Serial: "002", LastExpirationNagSent: time.Now().Add(-time.Hour * 24 * 3)}
	rawCertC := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy C",
		},
		NotAfter:     time.Now().AddDate(0, 0, 7),
		DNSNames:     []string{"example-c.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerC, _ := x509.CreateCertificate(rand.Reader, &rawCertC, &rawCertC, &testKey.PublicKey, &testKey)
	certC := &core.Certificate{
		RegistrationID: regB.ID,
		Status:         core.StatusValid,
		Serial:         "003",
		Expires:        time.Now().AddDate(0, 0, 7),
		DER:            certDerC,
	}
	certStatusC := &core.CertificateStatus{Serial: "003"}

	err = dbMap.Insert(certA)
	test.AssertNotError(t, err, "Couldn't add certA")
	err = dbMap.Insert(certB)
	test.AssertNotError(t, err, "Couldn't add certB")
	err = dbMap.Insert(certC)
	test.AssertNotError(t, err, "Couldn't add certC")
	err = dbMap.Insert(certStatusA)
	test.AssertNotError(t, err, "Couldn't add certStatusA")
	err = dbMap.Insert(certStatusB)
	test.AssertNotError(t, err, "Couldn't add certStatusB")
	err = dbMap.Insert(certStatusC)
	test.AssertNotError(t, err, "Couldn't add certStatusC")

	log.Clear()
	err = m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	// Should get 001 and 003
	test.AssertEquals(t, len(mc.Messages), 2)

	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-a.com is going to expire in 1 days (%s)`, rawCertA.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), mc.Messages[0])
	test.AssertEquals(t, fmt.Sprintf(`hi, cert for DNS names example-c.com is going to expire in 7 days (%s)`, rawCertC.NotAfter.UTC().Format("2006-01-02 15:04:05 -0700 MST")), mc.Messages[1])

	// A consecutive run shouldn't find anything
	mc.Clear()
	log.Clear()
	err = m.findExpiringCertificates()
	test.AssertNotError(t, err, "Failed to find expiring certs")
	test.AssertEquals(t, len(mc.Messages), 0)
}
Ejemplo n.º 21
0
	ft, err := time.Parse(fakeTimeFormat, fakeTimeFormat)
	if err != nil {
		t.Fatal(err)
	}
	fc := clock.NewFake()
	fc.Set(ft.UTC())
	return fc
}

const testTmpl = `hi, cert for DNS names {{.DNSNames}} is going to expire in {{.DaysToExpiration}} days ({{.ExpirationDate}})`
const testEmailSubject = `email subject for test`
const emailARaw = "*****@*****.**"
const emailBRaw = "*****@*****.**"

var (
	emailA, _ = core.ParseAcmeURL("mailto:" + emailARaw)
	emailB, _ = core.ParseAcmeURL("mailto:" + emailBRaw)
	jsonKeyA  = []byte(`{
  "kty":"RSA",
  "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  "e":"AQAB"
}`)
	jsonKeyB = []byte(`{
  "kty":"RSA",
  "n":"z8bp-jPtHt4lKBqepeKF28g_QAEOuEsCIou6sZ9ndsQsEjxEOQxQ0xNOQezsKa63eogw8YS3vzjUcPP5BJuVzfPfGd5NVUdT-vSSwxk3wvk_jtNqhrpcoG0elRPQfMVsQWmxCAXCVRz3xbcFI8GTe-syynG3l-g1IzYIIZVNI6jdljCZML1HOMTTW4f7uJJ8mM-08oQCeHbr5ejK7O2yMSSYxW03zY-Tj1iVEebROeMv6IEEJNFSS4yM-hLpNAqVuQxFGetwtwjDMC1Drs1dTWrPuUAAjKGrP151z1_dE74M5evpAhZUmpKv1hY-x85DC6N0hFPgowsanmTNNiV75w",
  "e":"AAEAAQ"
}`)
	jsonKeyC = []byte(`{
  "kty":"RSA",
  "n":"rFH5kUBZrlPj73epjJjyCxzVzZuV--JjKgapoqm9pOuOt20BUTdHqVfC2oDclqM7HFhkkX9OSJMTHgZ7WaVqZv9u1X2yjdx9oVmMLuspX7EytW_ZKDZSzL-sCOFCuQAuYKkLbsdcA3eHBK_lwc4zwdeHFMKIulNvLqckkqYB9s8GpgNXBDIQ8GjR5HuJke_WUNjYHSd8jY1LU9swKWsLQe2YoQUz_ekQvBvBCoaFEtrtRaSJKNLIVDObXFr2TLIiFiM0Em90kK01-eQ7ZiruZTKomll64bRFPoNo4_uwubddg3xTqur2vdF3NyhTrYdvAgTem4uC0PFjEQ1bK_djBQ",
  "e":"AQAB"
Ejemplo n.º 22
0
func (c testCtx) addRegistrations(t *testing.T) {
	emailA, _ := core.ParseAcmeURL("mailto:" + emailARaw)
	emailB, _ := core.ParseAcmeURL("mailto:" + emailBRaw)
	emailC, _ := core.ParseAcmeURL("mailto:" + emailCRaw)
	tel, _ := core.ParseAcmeURL("tel:" + telNum)

	// Every registration needs a unique JOSE key
	jsonKeyA := []byte(`{
  "kty":"RSA",
  "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  "e":"AQAB"
}`)
	jsonKeyB := []byte(`{
  "kty":"RSA",
  "n":"z8bp-jPtHt4lKBqepeKF28g_QAEOuEsCIou6sZ9ndsQsEjxEOQxQ0xNOQezsKa63eogw8YS3vzjUcPP5BJuVzfPfGd5NVUdT-vSSwxk3wvk_jtNqhrpcoG0elRPQfMVsQWmxCAXCVRz3xbcFI8GTe-syynG3l-g1IzYIIZVNI6jdljCZML1HOMTTW4f7uJJ8mM-08oQCeHbr5ejK7O2yMSSYxW03zY-Tj1iVEebROeMv6IEEJNFSS4yM-hLpNAqVuQxFGetwtwjDMC1Drs1dTWrPuUAAjKGrP151z1_dE74M5evpAhZUmpKv1hY-x85DC6N0hFPgowsanmTNNiV75w",
  "e":"AAEAAQ"
}`)
	jsonKeyC := []byte(`{
  "kty":"RSA",
  "n":"rFH5kUBZrlPj73epjJjyCxzVzZuV--JjKgapoqm9pOuOt20BUTdHqVfC2oDclqM7HFhkkX9OSJMTHgZ7WaVqZv9u1X2yjdx9oVmMLuspX7EytW_ZKDZSzL-sCOFCuQAuYKkLbsdcA3eHBK_lwc4zwdeHFMKIulNvLqckkqYB9s8GpgNXBDIQ8GjR5HuJke_WUNjYHSd8jY1LU9swKWsLQe2YoQUz_ekQvBvBCoaFEtrtRaSJKNLIVDObXFr2TLIiFiM0Em90kK01-eQ7ZiruZTKomll64bRFPoNo4_uwubddg3xTqur2vdF3NyhTrYdvAgTem4uC0PFjEQ1bK_djBQ",
  "e":"AQAB"
}`)
	jsonKeyD := []byte(`{
  "kty":"RSA",
  "n":"rFH5kUBZrlPj73epjJjyCxzVzZuV--JjKgapoqm9pOuOt20BUTdHqVfC2oDclqM7HFhkkX9OSJMTHgZ7WaVqZv9u1X2yjdx9oVmMLuspX7EytW_ZKDZSzL-FCOFCuQAuYKkLbsdcA3eHBK_lwc4zwdeHFMKIulNvLqckkqYB9s8GpgNXBDIQ8GjR5HuJke_WUNjYHSd8jY1LU9swKWsLQe2YoQUz_ekQvBvBCoaFEtrtRaSJKNLIVDObXFr2TLIiFiM0Em90kK01-eQ7ZiruZTKomll64bRFPoNo4_uwubddg3xTqur2vdF3NyhTrYdvAgTem4uC0PFjEQ1bK_djBQ",
  "e":"AQAB"
}`)

	var keyA jose.JsonWebKey
	var keyB jose.JsonWebKey
	var keyC jose.JsonWebKey
	var keyD jose.JsonWebKey
	err := json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyB, &keyB)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyC, &keyC)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
	err = json.Unmarshal(jsonKeyD, &keyD)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")

	// Regs A through C have `mailto:` contact ACME URL's
	regA = core.Registration{
		ID: 1,
		Contact: &[]*core.AcmeURL{
			emailA,
		},
		Key:       keyA,
		InitialIP: net.ParseIP("127.0.0.1"),
	}
	regB = core.Registration{
		ID: 2,
		Contact: &[]*core.AcmeURL{
			emailB,
		},
		Key:       keyB,
		InitialIP: net.ParseIP("127.0.0.1"),
	}
	regC = core.Registration{
		ID: 3,
		Contact: &[]*core.AcmeURL{
			emailC,
		},
		Key:       keyC,
		InitialIP: net.ParseIP("127.0.0.1"),
	}
	// Reg D has a `tel:` contact ACME URL
	regD = core.Registration{
		ID: 4,
		Contact: &[]*core.AcmeURL{
			tel,
		},
		Key:       keyD,
		InitialIP: net.ParseIP("127.0.0.1"),
	}

	// Add the four test registrations
	ctx := context.Background()
	regA, err = c.ssa.NewRegistration(ctx, regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	regB, err = c.ssa.NewRegistration(ctx, regB)
	if err != nil {
		t.Fatalf("Couldn't store regB: %s", err)
	}
	regC, err = c.ssa.NewRegistration(ctx, regC)
	if err != nil {
		t.Fatalf("Couldn't store regC: %s", err)
	}
	regD, err = c.ssa.NewRegistration(ctx, regD)
	if err != nil {
		t.Fatalf("Couldn't store regD: %s", err)
	}
}
Ejemplo n.º 23
0
func TestLifetimeOfACert(t *testing.T) {
	dbMap, err := sa.NewDbMap(dbConnStr)
	if err != nil {
		t.Fatalf("Couldn't connect the database: %s", err)
	}
	cleanUp := test.ResetTestDatabase(t, dbMap.Db)
	ssa, err := sa.NewSQLStorageAuthority(dbMap)
	if err != nil {
		t.Fatalf("unable to create SQLStorageAuthority: %s", err)
	}
	defer cleanUp()

	stats, _ := statsd.NewNoopClient(nil)
	mc := mockMail{}
	fc := clock.NewFake()

	m := mailer{
		log:           blog.GetAuditLogger(),
		stats:         stats,
		mailer:        &mc,
		emailTemplate: tmpl,
		dbMap:         dbMap,
		rs:            ssa,
		nagTimes:      []time.Duration{time.Hour * 24, time.Hour * 24 * 4, time.Hour * 24 * 7},
		limit:         100,
		clk:           fc,
	}

	var keyA jose.JsonWebKey
	err = json.Unmarshal(jsonKeyA, &keyA)
	test.AssertNotError(t, err, "Failed to unmarshal public JWK")

	emailA, _ := core.ParseAcmeURL("mailto:[email protected]")

	regA := core.Registration{
		ID: 1,
		Contact: []*core.AcmeURL{
			emailA,
		},
		Key: keyA,
	}
	regA, err = ssa.NewRegistration(regA)
	if err != nil {
		t.Fatalf("Couldn't store regA: %s", err)
	}
	rawCertA := x509.Certificate{
		Subject: pkix.Name{
			CommonName: "happy A",
		},

		NotAfter:     fc.Now(),
		DNSNames:     []string{"example-a.com"},
		SerialNumber: big.NewInt(1337),
	}
	certDerA, _ := x509.CreateCertificate(rand.Reader, &rawCertA, &rawCertA, &testKey.PublicKey, &testKey)
	certA := &core.Certificate{
		RegistrationID: regA.ID,
		Status:         core.StatusValid,
		Serial:         "001",
		Expires:        rawCertA.NotAfter,
		DER:            certDerA,
	}

	certStatusA := &core.CertificateStatus{
		Serial: "001",
	}

	err = dbMap.Insert(certA)
	test.AssertNotError(t, err, "unable to insert Certificate")
	err = dbMap.Insert(certStatusA)
	test.AssertNotError(t, err, "unable to insert CertificateStatus")

	type lifeTest struct {
		timeLeft time.Duration
		numMsgs  int
		context  string
	}
	tests := []lifeTest{
		{
			timeLeft: 8 * 24 * time.Hour, // 8 days before expiration

			numMsgs: 0,
			context: "Expected no emails sent because we are more than 7 days out.",
		},
		{
			7 * 24 * time.Hour, // 7 days before
			1,
			"Sent 1 for 7 day notice.",
		},
		{
			5 * 24 * time.Hour,
			1,
			"The 7 day email was already sent.",
		},
		{
			3 * 24 * time.Hour, // 3 days before, the mailer wasn't run the day before
			2,
			"Sent 1 for the 7 day notice, and 1 for the 4 day notice.",
		},
		{
			1 * 24 * time.Hour,
			3,
			"Sent 1 for the 7 day notice, 1 for the 4 day notice, and 1 for the 1 day notice.",
		},
		{
			12 * time.Hour,
			3,
			"The 1 day before email was already sent.",
		},
		{
			-2 * 24 * time.Hour, // 2 days after expiration
			3,
			"No expiration warning emails are sent after expiration",
		},
	}

	for _, tt := range tests {
		fc.Add(-tt.timeLeft)
		err = m.findExpiringCertificates()
		test.AssertNotError(t, err, "error calling findExpiringCertificates")
		if len(mc.Messages) != tt.numMsgs {
			t.Errorf(tt.context+" number of messages: expected %d, got %d", tt.numMsgs, len(mc.Messages))
		}
		fc.Add(tt.timeLeft)
	}
}