Exemple #1
0
func TestGenerateMessage(t *testing.T) {
	fc := clock.NewFake()
	stats := metrics.NewNoopScope()
	fromAddress, _ := mail.ParseAddress("happy sender <*****@*****.**>")
	log := blog.UseMock()
	m := New("", "", "", "", *fromAddress, log, stats, 0, 0)
	m.clk = fc
	m.csprgSource = fakeSource{}
	messageBytes, err := m.generateMessage([]string{"*****@*****.**"}, "test subject", "this is the body\n")
	test.AssertNotError(t, err, "Failed to generate email body")
	message := string(messageBytes)
	fields := strings.Split(message, "\r\n")
	test.AssertEquals(t, len(fields), 12)
	fmt.Println(message)
	test.AssertEquals(t, fields[0], "To: \"[email protected]\"")
	test.AssertEquals(t, fields[1], "From: \"happy sender\" <*****@*****.**>")
	test.AssertEquals(t, fields[2], "Subject: test subject")
	test.AssertEquals(t, fields[3], "Date: 01 Jan 70 00:00 UTC")
	test.AssertEquals(t, fields[4], "Message-Id: <*****@*****.**>")
	test.AssertEquals(t, fields[5], "MIME-Version: 1.0")
	test.AssertEquals(t, fields[6], "Content-Type: text/plain; charset=UTF-8")
	test.AssertEquals(t, fields[7], "Content-Transfer-Encoding: quoted-printable")
	test.AssertEquals(t, fields[8], "")
	test.AssertEquals(t, fields[9], "this is the body")
}
Exemple #2
0
func TestCheckCAAFallback(t *testing.T) {
	testSrv := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
	defer testSrv.Close()

	stats := mocks.NewStatter()
	scope := metrics.NewStatsdScope(stats, "VA")
	logger := blog.NewMock()
	caaDR, err := cdr.New(metrics.NewNoopScope(), time.Second, 1, nil, blog.NewMock())
	test.AssertNotError(t, err, "Failed to create CAADistributedResolver")
	caaDR.URI = testSrv.URL
	caaDR.Clients["1.1.1.1"] = new(http.Client)
	va := NewValidationAuthorityImpl(
		&cmd.PortConfig{},
		nil,
		caaDR,
		&bdns.MockDNSResolver{},
		"user agent 1.0",
		"ca.com",
		scope,
		clock.Default(),
		logger)

	prob := va.checkCAA(ctx, core.AcmeIdentifier{Value: "bad-local-resolver.com", Type: "dns"})
	test.Assert(t, prob == nil, fmt.Sprintf("returned ProblemDetails was non-nil: %#v", prob))

	va.caaDR = nil
	prob = va.checkCAA(ctx, core.AcmeIdentifier{Value: "bad-local-resolver.com", Type: "dns"})
	test.Assert(t, prob != nil, "returned ProblemDetails was nil")
	test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
	test.AssertEquals(t, prob.Detail, "server failure at resolver")
}
Exemple #3
0
func setup(t *testing.T) (*MailerImpl, net.Listener, func()) {
	stats := metrics.NewNoopScope()
	fromAddress, _ := mail.ParseAddress("*****@*****.**")
	log := blog.UseMock()

	// Listen on port 0 to get any free available port
	l, err := net.Listen("tcp", ":0")
	if err != nil {
		t.Fatalf("listen: %s", err)
	}
	cleanUp := func() {
		err := l.Close()
		if err != nil {
			t.Errorf("listen.Close: %s", err)
		}
	}

	// We can look at the listener Addr() to figure out which free port was
	// assigned by the operating system
	addr := l.Addr().(*net.TCPAddr)
	port := addr.Port

	m := New(
		"localhost",
		fmt.Sprintf("%d", port),
		"*****@*****.**",
		"paswd",
		*fromAddress,
		log,
		stats,
		time.Second*2, time.Second*10)

	return m, l, cleanUp
}
Exemple #4
0
func TestFailNonASCIIAddress(t *testing.T) {
	log := blog.UseMock()
	stats := metrics.NewNoopScope()
	fromAddress, _ := mail.ParseAddress("*****@*****.**")
	m := New("", "", "", "", *fromAddress, log, stats, 0, 0)
	_, err := m.generateMessage([]string{"遗憾@email.com"}, "test subject", "this is the body\n")
	test.AssertError(t, err, "Allowed a non-ASCII to address incorrectly")
}
Exemple #5
0
// New constructs a Mailer suitable for doing a dry run. It simply logs each
// command that would have been run, at debug level.
func NewDryRun(from mail.Address, logger blog.Logger) *MailerImpl {
	stats := metrics.NewNoopScope()
	return &MailerImpl{
		dialer:      dryRunClient{logger},
		from:        from,
		clk:         clock.Default(),
		csprgSource: realSource{},
		stats:       stats,
	}
}
Exemple #6
0
func TestDNSValidationNoServer(t *testing.T) {
	va, _, _ := setup()
	va.dnsResolver = bdns.NewTestDNSResolverImpl(
		time.Second*5,
		nil,
		metrics.NewNoopScope(),
		clock.Default(),
		1)

	chalDNS := createChallenge(core.ChallengeTypeDNS01)

	_, prob := va.validateChallenge(ctx, ident, chalDNS)

	test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
}
Exemple #7
0
func TestGetCAASetFallback(t *testing.T) {
	testSrv := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
	defer testSrv.Close()

	caaDR, err := cdr.New(metrics.NewNoopScope(), time.Second, 1, nil, blog.NewMock())
	test.AssertNotError(t, err, "Failed to create CAADistributedResolver")
	caaDR.URI = testSrv.URL
	caaDR.Clients["1.1.1.1"] = new(http.Client)
	va, _, _ := setup()
	va.caaDR = caaDR

	set, err := va.getCAASet(ctx, "bad-local-resolver.com")
	test.AssertNotError(t, err, "getCAASet failed to fail back to cdr on timeout")
	test.AssertEquals(t, len(set.Issue), 1)
}
Exemple #8
0
func setup(t *testing.T) (*Impl, *x509.Certificate, *ecdsa.PrivateKey) {
	intermediatePEM, _ := pem.Decode([]byte(testIntermediate))

	pub := New(nil,
		nil,
		0,
		log,
		metrics.NewNoopScope(),
		mocks.NewStorageAuthority(clock.NewFake()))
	pub.issuerBundle = append(pub.issuerBundle, ct.ASN1Cert(intermediatePEM.Bytes))

	leafPEM, _ := pem.Decode([]byte(testLeaf))
	leaf, err := x509.ParseCertificate(leafPEM.Bytes)
	test.AssertNotError(t, err, "Couldn't parse leafPEM.Bytes")

	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	test.AssertNotError(t, err, "Couldn't generate test key")

	return pub, leaf, k
}
func TestHTTPQuorum(t *testing.T) {
	sbh := &slightlyBrokenHandler{}
	testSrv := httptest.NewServer(http.HandlerFunc(sbh.Handler))
	defer testSrv.Close()

	cpr := CAADistributedResolver{
		logger: log,
		Clients: map[string]*http.Client{
			"1.1.1.1": new(http.Client),
			"2.2.2.2": new(http.Client),
			"3.3.3.3": new(http.Client),
		},
		stats:       metrics.NewNoopScope(),
		maxFailures: 1,
		timeout:     time.Second,
		URI:         testSrv.URL,
	}

	set, err := cpr.LookupCAA(context.Background(), "test-domain")
	test.AssertError(t, err, "LookupCAA should've failed")
	test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
}
Exemple #10
0
func TestPurgeAuthzs(t *testing.T) {
	dbMap, err := sa.NewDbMap(vars.DBConnSAFullPerms, 0)
	if err != nil {
		t.Fatalf("Couldn't connect the database: %s", err)
	}
	log := blog.UseMock()
	fc := clock.NewFake()
	fc.Add(time.Hour)
	ssa, err := sa.NewSQLStorageAuthority(dbMap, fc, log)
	if err != nil {
		t.Fatalf("unable to create SQLStorageAuthority: %s", err)
	}
	cleanUp := test.ResetSATestDatabase(t)
	defer cleanUp()
	stats := metrics.NewNoopScope()

	p := expiredAuthzPurger{stats, log, fc, dbMap, 1}

	rows, err := p.purgeAuthzs(time.Time{}, true)
	test.AssertNotError(t, err, "purgeAuthzs failed")
	test.AssertEquals(t, rows, int64(0))

	old, new := fc.Now().Add(-time.Hour), fc.Now().Add(time.Hour)

	reg := satest.CreateWorkingRegistration(t, ssa)
	_, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &old})
	test.AssertNotError(t, err, "NewPendingAuthorization failed")
	_, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &old})
	test.AssertNotError(t, err, "NewPendingAuthorization failed")
	_, err = ssa.NewPendingAuthorization(context.Background(), core.Authorization{RegistrationID: reg.ID, Expires: &new})
	test.AssertNotError(t, err, "NewPendingAuthorization failed")

	rows, err = p.purgeAuthzs(fc.Now(), true)
	test.AssertNotError(t, err, "purgeAuthzs failed")
	test.AssertEquals(t, rows, int64(2))
	rows, err = p.purgeAuthzs(fc.Now().Add(time.Hour), true)
	test.AssertNotError(t, err, "purgeAuthzs failed")
	test.AssertEquals(t, rows, int64(1))
}
func TestDNSValidationNoServer(t *testing.T) {
	c, _ := statsd.NewNoopClient()
	stats := metrics.NewNoopScope()
	va := NewValidationAuthorityImpl(&PortConfig{}, nil, c, clock.Default())
	va.DNSResolver = bdns.NewTestDNSResolverImpl(time.Second*5, []string{}, stats, clock.Default(), 1)
	mockRA := &MockRegistrationAuthority{}
	va.RA = mockRA

	chalDNS := createChallenge(core.ChallengeTypeDNS01)

	var authz = core.Authorization{
		ID:             core.NewToken(),
		RegistrationID: 1,
		Identifier:     ident,
		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.StatusInvalid, "Should be invalid.")
	test.AssertEquals(t, authz.Challenges[0].Error.Type, probs.ConnectionProblem)
}
func TestLookupCAA(t *testing.T) {
	testSrv := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
	defer testSrv.Close()

	cpr := CAADistributedResolver{
		logger: log,
		Clients: map[string]*http.Client{
			"1.1.1.1": new(http.Client),
			"2.2.2.2": new(http.Client),
			"3.3.3.3": new(http.Client),
		},
		stats:       metrics.NewNoopScope(),
		maxFailures: 1,
		timeout:     time.Second,
		URI:         testSrv.URL,
	}

	set, err := cpr.LookupCAA(context.Background(), "test-domain")
	test.AssertNotError(t, err, "LookupCAA method failed")
	test.AssertEquals(t, len(set), 1)
	test.AssertEquals(t, set[0].Hdr.Name, "test-domain.")
	test.AssertEquals(t, set[0].Hdr.Ttl, uint32(10))
	test.AssertEquals(t, set[0].Flag, uint8(0))
	test.AssertEquals(t, set[0].Tag, "issue")
	test.AssertEquals(t, set[0].Value, "ca.com")

	set, err = cpr.LookupCAA(context.Background(), "break")
	test.AssertError(t, err, "LookupCAA should've failed")
	test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")

	set, err = cpr.LookupCAA(context.Background(), "break-rcode")
	test.AssertError(t, err, "LookupCAA should've failed")
	test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")

	set, err = cpr.LookupCAA(context.Background(), "break-dns-quorum")
	test.AssertError(t, err, "LookupCAA should've failed")
	test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
}
Exemple #13
0
func TestAllowNilInIsSafeDomain(t *testing.T) {
	stats := metrics.NewNoopScope()
	va := NewValidationAuthorityImpl(
		&cmd.PortConfig{},
		nil,
		nil,
		nil,
		"user agent 1.0",
		"letsencrypt.org",
		stats,
		clock.NewFake(),
		blog.NewMock())

	// Be cool with a nil SafeBrowsing. This will happen in prod when we have
	// flag mismatch between the VA and RA.
	domain := "example.com"
	resp, err := va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
	if err != nil {
		t.Errorf("nil SafeBrowsing, unexpected error: %s", err)
	}
	if !resp.GetIsSafe() {
		t.Errorf("nil Safebrowsing, should fail open but failed closed")
	}
}
func TestConstructAuthHeader(t *testing.T) {
	stats := metrics.NewNoopScope()
	cpc, err := NewCachePurgeClient(
		"https://akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net",
		"akab-client-token-xxx-xxxxxxxxxxxxxxxx",
		"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=",
		"akab-access-token-xxx-xxxxxxxxxxxxxxxx",
		0,
		time.Second,
		nil,
		stats,
	)
	test.AssertNotError(t, err, "Failed to create cache purge client")
	fc := clock.NewFake()
	cpc.clk = fc
	wantedTimestamp, err := time.Parse(timestampFormat, "20140321T19:34:21+0000")
	test.AssertNotError(t, err, "Failed to parse timestamp")
	fc.Add(wantedTimestamp.Sub(fc.Now()))

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("%s%s", cpc.apiEndpoint, purgePath),
		bytes.NewBuffer([]byte{0}),
	)
	test.AssertNotError(t, err, "Failed to create request")

	expectedHeader := "EG1-HMAC-SHA256 client_token=akab-client-token-xxx-xxxxxxxxxxxxxxxx;access_token=akab-access-token-xxx-xxxxxxxxxxxxxxxx;timestamp=20140321T19:34:21+0000;nonce=nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;signature=hXm4iCxtpN22m4cbZb4lVLW5rhX8Ca82vCFqXzSTPe4="
	authHeader, err := cpc.constructAuthHeader(
		req,
		[]byte("datadatadatadatadatadatadatadata"),
		"/testapi/v1/t3",
		"nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
	)
	test.AssertNotError(t, err, "Failed to create authorization header")
	test.AssertEquals(t, authHeader, expectedHeader)
}
Exemple #15
0
func newTestStats() metrics.Scope {
	return metrics.NewNoopScope()
}
Exemple #16
0
func setup(t *testing.T) *testCtx {
	fc := clock.NewFake()
	fc.Add(1 * time.Hour)

	pa, err := policy.New(nil)
	test.AssertNotError(t, err, "Couldn't create PA")
	err = pa.SetHostnamePolicyFile("../test/hostname-policy.json")
	test.AssertNotError(t, err, "Couldn't set hostname policy")

	// Create a CA
	caConfig := cmd.CAConfig{
		RSAProfile:   rsaProfileName,
		ECDSAProfile: ecdsaProfileName,
		SerialPrefix: 17,
		Expiry:       "8760h",
		LifespanOCSP: cmd.ConfigDuration{Duration: 45 * time.Minute},
		MaxNames:     2,
		CFSSL: cfsslConfig.Config{
			Signing: &cfsslConfig.Signing{
				Profiles: map[string]*cfsslConfig.SigningProfile{
					rsaProfileName: {
						Usage:     []string{"digital signature", "key encipherment", "server auth"},
						CA:        false,
						IssuerURL: []string{"http://not-example.com/issuer-url"},
						OCSP:      "http://not-example.com/ocsp",
						CRL:       "http://not-example.com/crl",

						Policies: []cfsslConfig.CertificatePolicy{
							{
								ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}),
							},
						},
						ExpiryString: "8760h",
						Backdate:     time.Hour,
						CSRWhitelist: &cfsslConfig.CSRWhitelist{
							PublicKeyAlgorithm: true,
							PublicKey:          true,
							SignatureAlgorithm: true,
						},
						ClientProvidesSerialNumbers: true,
						AllowedExtensions: []cfsslConfig.OID{
							cfsslConfig.OID(oidTLSFeature),
						},
					},
					ecdsaProfileName: {
						Usage:     []string{"digital signature", "server auth"},
						CA:        false,
						IssuerURL: []string{"http://not-example.com/issuer-url"},
						OCSP:      "http://not-example.com/ocsp",
						CRL:       "http://not-example.com/crl",

						Policies: []cfsslConfig.CertificatePolicy{
							{
								ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}),
							},
						},
						ExpiryString: "8760h",
						Backdate:     time.Hour,
						CSRWhitelist: &cfsslConfig.CSRWhitelist{
							PublicKeyAlgorithm: true,
							PublicKey:          true,
							SignatureAlgorithm: true,
						},
						ClientProvidesSerialNumbers: true,
					},
				},
				Default: &cfsslConfig.SigningProfile{
					ExpiryString: "8760h",
				},
			},
		},
	}

	issuers := []Issuer{{caKey, caCert}}

	keyPolicy := goodkey.KeyPolicy{
		AllowRSA:           true,
		AllowECDSANISTP256: true,
		AllowECDSANISTP384: true,
	}

	logger := blog.NewMock()

	return &testCtx{
		caConfig,
		pa,
		issuers,
		keyPolicy,
		fc,
		metrics.NewNoopScope(),
		logger,
	}
}
Exemple #17
0
func TestIsSafeDomain(t *testing.T) {
	// TODO(jmhodges): use more of the GSB lib by teaching it how to not make
	// http requests
	// This test is mocked out at the wrong level (SafeBrowsing) because the gsb lib
	// we rely on is a little funny and overcomplicated, but still hasn't
	// learned out how not make HTTP requests in tests.

	stats := metrics.NewNoopScope()
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	sbc := NewMockSafeBrowsing(ctrl)
	sbc.EXPECT().IsListed("good.com").Return("", nil)
	sbc.EXPECT().IsListed("bad.com").Return("bad", nil)
	sbc.EXPECT().IsListed("errorful.com").Return("", errors.New("welp"))
	sbc.EXPECT().IsListed("outofdate.com").Return("", safebrowsing.ErrOutOfDateHashes)
	va := NewValidationAuthorityImpl(
		&cmd.PortConfig{},
		sbc,
		nil,
		nil,
		"user agent 1.0",
		"letsencrypt.org",
		stats,
		clock.NewFake(),
		blog.NewMock())

	domain := "good.com"
	resp, err := va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
	if err != nil {
		t.Errorf("good.com: want no error, got '%s'", err)
	}
	if !resp.GetIsSafe() {
		t.Errorf("good.com: want true, got %t", resp.GetIsSafe())
	}

	domain = "bad.com"
	resp, err = va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
	if err != nil {
		t.Errorf("bad.com: want no error, got '%s'", err)
	}
	if resp.GetIsSafe() {
		t.Errorf("bad.com: want false, got %t", resp.GetIsSafe())
	}

	domain = "errorful.com"
	resp, err = va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
	if err == nil {
		t.Errorf("errorful.com: want error, got none")
	}
	if resp != nil {
		t.Errorf("errorful.com: want resp == nil, got %v", resp)
	}

	domain = "outofdate.com"
	resp, err = va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
	if err != nil {
		t.Errorf("outofdate.com: want no error, got '%s'", err)
	}
	if !resp.GetIsSafe() {
		t.Errorf("outofdate.com: IsSafeDomain should fail open on out of date hashes")
	}
}
func TestChecking(t *testing.T) {
	type CAATest struct {
		Domain  string
		Present bool
		Valid   bool
	}
	tests := []CAATest{
		// Reserved
		{"reserved.com", true, false},
		// Critical
		{"critical.com", true, false},
		{"nx.critical.com", true, false},
		// Good (absent)
		{"absent.com", false, true},
		{"example.co.uk", false, true},
		// Good (present)
		{"present.com", true, true},
		{"present.servfail.com", true, true},
		// Good (multiple critical, one matching)
		{"multi-crit-present.com", true, true},
		// Bad (unknown critical)
		{"unknown-critical.com", true, false},
		{"unknown-critical2.com", true, false},
		// Good (unknown noncritical, no issue/issuewild records)
		{"unknown-noncritical.com", true, true},
		// Good (issue record with unknown parameters)
		{"present-with-parameter.com", true, true},
		// Bad (unsatisfiable issue record)
		{"unsatisfiable.com", true, false},
	}

	stats := metrics.NewNoopScope()
	ccs := &caaCheckerServer{&bdns.MockDNSResolver{}, stats}
	issuerDomain := "letsencrypt.org"

	ctx := context.Background()

	for _, caaTest := range tests {
		result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &caaTest.Domain, IssuerDomain: &issuerDomain})
		if err != nil {
			t.Errorf("CheckCAARecords error for %s: %s", caaTest.Domain, err)
		}
		if *result.Present != caaTest.Present {
			t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Present, caaTest.Present)
		}
		if *result.Valid != caaTest.Valid {
			t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Valid, caaTest.Valid)
		}
	}

	servfail := "servfail.com"
	servfailPresent := "servfail.present.com"
	result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfail, IssuerDomain: &issuerDomain})
	test.AssertError(t, err, "servfail.com")
	test.Assert(t, result == nil, "result should be nil")
	test.AssertEquals(t, grpc.Code(err), bgrpc.DNSError)

	result, err = ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfailPresent, IssuerDomain: &issuerDomain})
	test.AssertError(t, err, "servfail.present.com")
	test.Assert(t, result == nil, "result should be nil")
	test.AssertEquals(t, grpc.Code(err), bgrpc.DNSError)

	timeout := "caa-timeout.com"
	result, err = ccs.ValidForIssuance(ctx, &pb.Check{Name: &timeout, IssuerDomain: &issuerDomain})
	test.AssertError(t, err, "timeout.com")
	test.Assert(t, result == nil, "result should be nil")
	test.AssertEquals(t, grpc.Code(err), bgrpc.DNSQueryTimeout)
}