1 package creds
2
3 import (
4 "context"
5 "crypto/rand"
6 "crypto/rsa"
7 "crypto/tls"
8 "crypto/x509"
9 "math/big"
10 "net"
11 "net/http/httptest"
12 "testing"
13 "time"
14
15 "github.com/letsencrypt/boulder/core"
16 "github.com/letsencrypt/boulder/test"
17 )
18
19 func TestServerTransportCredentials(t *testing.T) {
20 acceptedSANs := map[string]struct{}{
21 "boulder-client": {},
22 }
23 certFile := "testdata/boulder-client/cert.pem"
24 badCertFile := "testdata/example.com/cert.pem"
25 goodCert, err := core.LoadCert(certFile)
26 test.AssertNotError(t, err, "core.LoadCert failed on "+certFile)
27 badCert, err := core.LoadCert(badCertFile)
28 test.AssertNotError(t, err, "core.LoadCert failed on "+badCertFile)
29 servTLSConfig := &tls.Config{}
30
31
32 _, err = NewServerCredentials(nil, acceptedSANs)
33 test.AssertEquals(t, err, ErrNilServerConfig)
34
35
36 wrappedCreds, err := NewServerCredentials(servTLSConfig, nil)
37 test.AssertNotError(t, err, "NewServerCredentials failed with nil acceptedSANs")
38 bcreds := wrappedCreds.(*serverTransportCredentials)
39 emptyState := tls.ConnectionState{}
40 err = bcreds.validateClient(emptyState)
41 test.AssertNotError(t, err, "validateClient() errored for emptyState")
42 wrappedCreds, err = NewServerCredentials(servTLSConfig, map[string]struct{}{})
43 test.AssertNotError(t, err, "NewServerCredentials failed with empty acceptedSANs")
44 bcreds = wrappedCreds.(*serverTransportCredentials)
45 err = bcreds.validateClient(emptyState)
46 test.AssertNotError(t, err, "validateClient() errored for emptyState")
47
48
49 bcreds = &serverTransportCredentials{servTLSConfig, acceptedSANs}
50 err = bcreds.validateClient(emptyState)
51 test.AssertEquals(t, err, ErrEmptyPeerCerts)
52
53
54
55 wrongState := tls.ConnectionState{
56 PeerCertificates: []*x509.Certificate{badCert},
57 }
58 err = bcreds.validateClient(wrongState)
59 var errSANNotAccepted ErrSANNotAccepted
60 test.AssertErrorWraps(t, err, &errSANNotAccepted)
61
62
63
64 rightState := tls.ConnectionState{
65 PeerCertificates: []*x509.Certificate{goodCert},
66 }
67 err = bcreds.validateClient(rightState)
68 test.AssertNotError(t, err, "validateClient(rightState) failed")
69
70
71
72
73 acceptedIPSans := map[string]struct{}{
74 "127.0.0.1": {},
75 }
76 bcreds = &serverTransportCredentials{servTLSConfig, acceptedIPSans}
77 err = bcreds.validateClient(rightState)
78 test.AssertNotError(t, err, "validateClient(rightState) failed with an IP accepted SAN list")
79 }
80
81 func TestClientTransportCredentials(t *testing.T) {
82 priv, err := rsa.GenerateKey(rand.Reader, 1024)
83 test.AssertNotError(t, err, "rsa.GenerateKey failed")
84
85 temp := &x509.Certificate{
86 SerialNumber: big.NewInt(1),
87 DNSNames: []string{"A"},
88 NotBefore: time.Unix(1000, 0),
89 NotAfter: time.Now().AddDate(1, 0, 0),
90 BasicConstraintsValid: true,
91 IsCA: true,
92 }
93 derA, err := x509.CreateCertificate(rand.Reader, temp, temp, priv.Public(), priv)
94 test.AssertNotError(t, err, "x509.CreateCertificate failed")
95 certA, err := x509.ParseCertificate(derA)
96 test.AssertNotError(t, err, "x509.ParserCertificate failed")
97 temp.DNSNames[0] = "B"
98 derB, err := x509.CreateCertificate(rand.Reader, temp, temp, priv.Public(), priv)
99 test.AssertNotError(t, err, "x509.CreateCertificate failed")
100 certB, err := x509.ParseCertificate(derB)
101 test.AssertNotError(t, err, "x509.ParserCertificate failed")
102 roots := x509.NewCertPool()
103 roots.AddCert(certA)
104 roots.AddCert(certB)
105
106 serverA := httptest.NewUnstartedServer(nil)
107 serverA.TLS = &tls.Config{Certificates: []tls.Certificate{{Certificate: [][]byte{derA}, PrivateKey: priv}}}
108 serverB := httptest.NewUnstartedServer(nil)
109 serverB.TLS = &tls.Config{Certificates: []tls.Certificate{{Certificate: [][]byte{derB}, PrivateKey: priv}}}
110
111 tc := NewClientCredentials(roots, []tls.Certificate{}, "")
112
113 serverA.StartTLS()
114 defer serverA.Close()
115 addrA := serverA.Listener.Addr().String()
116 rawConnA, err := net.Dial("tcp", addrA)
117 test.AssertNotError(t, err, "net.Dial failed")
118 defer func() {
119 _ = rawConnA.Close()
120 }()
121
122 conn, _, err := tc.ClientHandshake(context.Background(), "A:2020", rawConnA)
123 test.AssertNotError(t, err, "tc.ClientHandshake failed")
124 test.Assert(t, conn != nil, "tc.ClientHandshake returned a nil net.Conn")
125
126 serverB.StartTLS()
127 defer serverB.Close()
128 addrB := serverB.Listener.Addr().String()
129 rawConnB, err := net.Dial("tcp", addrB)
130 test.AssertNotError(t, err, "net.Dial failed")
131 defer func() {
132 _ = rawConnB.Close()
133 }()
134
135 conn, _, err = tc.ClientHandshake(context.Background(), "B:3030", rawConnB)
136 test.AssertNotError(t, err, "tc.ClientHandshake failed")
137 test.Assert(t, conn != nil, "tc.ClientHandshake returned a nil net.Conn")
138
139
140 ln, err := net.Listen("tcp", "127.0.0.1:0")
141 test.AssertNotError(t, err, "net.Listen failed")
142 defer func() {
143 _ = ln.Close()
144 }()
145 addrC := ln.Addr().String()
146 stop := make(chan struct{}, 1)
147 go func() {
148 for {
149 select {
150 case <-stop:
151 return
152 default:
153 _, _ = ln.Accept()
154 time.Sleep(2 * time.Millisecond)
155 }
156 }
157 }()
158
159 rawConnC, err := net.Dial("tcp", addrC)
160 test.AssertNotError(t, err, "net.Dial failed")
161 defer func() {
162 _ = rawConnB.Close()
163 }()
164
165 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
166 defer cancel()
167 conn, _, err = tc.ClientHandshake(ctx, "A:2020", rawConnC)
168 test.AssertError(t, err, "tc.ClientHandshake didn't timeout")
169 test.AssertEquals(t, err.Error(), "context deadline exceeded")
170 test.Assert(t, conn == nil, "tc.ClientHandshake returned a non-nil net.Conn on failure")
171
172 stop <- struct{}{}
173 }
174
175 type brokenConn struct{}
176
177 func (bc *brokenConn) Read([]byte) (int, error) {
178 return 0, &net.OpError{}
179 }
180
181 func (bc *brokenConn) Write([]byte) (int, error) {
182 return 0, &net.OpError{}
183 }
184
185 func (bc *brokenConn) LocalAddr() net.Addr { return nil }
186 func (bc *brokenConn) RemoteAddr() net.Addr { return nil }
187 func (bc *brokenConn) Close() error { return nil }
188 func (bc *brokenConn) SetDeadline(time.Time) error { return nil }
189 func (bc *brokenConn) SetReadDeadline(time.Time) error { return nil }
190 func (bc *brokenConn) SetWriteDeadline(time.Time) error { return nil }
191
192 func TestClientReset(t *testing.T) {
193 tc := NewClientCredentials(nil, []tls.Certificate{}, "")
194 _, _, err := tc.ClientHandshake(context.Background(), "T:1010", &brokenConn{})
195 test.AssertError(t, err, "ClientHandshake succeeded with brokenConn")
196 var netErr net.Error
197 test.AssertErrorWraps(t, err, &netErr)
198 }
199
View as plain text