Repository navigation
Expand file tree
/
Copy pathdialer_test.go
More file actions
118 lines (99 loc) · 3.24 KB
/
Copy pathdialer_test.go
File metadata and controls
118 lines (99 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package domainfront
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
stdtls "crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"net"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVerifyPeerCertificate(t *testing.T) {
caCert, caKey := newTestCA(t)
leafCert := newTestLeafCert(t, caCert, caKey, "test.example.com", "*.example.com")
roots := x509.NewCertPool()
roots.AddCert(caCert)
leafDER := leafCert.Certificate[0]
caDER := caCert.Raw
t.Run("valid cert", func(t *testing.T) {
err := verifyPeerCertificate([][]byte{leafDER, caDER}, roots, "test.example.com")
assert.NoError(t, err)
})
t.Run("wrong domain", func(t *testing.T) {
err := verifyPeerCertificate([][]byte{leafDER, caDER}, roots, "wrong.example.org")
assert.Error(t, err)
})
t.Run("empty domain accepts any", func(t *testing.T) {
err := verifyPeerCertificate([][]byte{leafDER, caDER}, roots, "")
assert.NoError(t, err)
})
t.Run("no certs", func(t *testing.T) {
err := verifyPeerCertificate([][]byte{}, roots, "test.example.com")
assert.Error(t, err)
})
}
func TestDialFront_WithMockServer(t *testing.T) {
caCert, caKey := newTestCA(t)
// Need a leaf cert with specific domains for the pipe dialer test
leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
leafTemplate := &x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{CommonName: "cdn.example.com"},
DNSNames: []string{"cdn.example.com"},
NotBefore: time.Now().Add(-time.Hour),
NotAfter: time.Now().Add(time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
leafDER, _ := x509.CreateCertificate(rand.Reader, leafTemplate, caCert, &leafKey.PublicKey, caKey)
leafCertParsed, _ := x509.ParseCertificate(leafDER)
roots := x509.NewCertPool()
roots.AddCert(caCert)
serverTLSConfig := &stdtls.Config{
Certificates: []stdtls.Certificate{{
Certificate: [][]byte{leafDER, caCert.Raw},
PrivateKey: leafKey,
Leaf: leafCertParsed,
}},
}
pd := &pipeDialer{serverConfig: serverTLSConfig}
vh := "cdn.example.com"
f := newFront(&Masquerade{
Domain: "cdn.example.com",
IpAddress: "cdn.example.com:443",
SNI: "cdn.example.com",
VerifyHostname: &vh,
}, "test")
result := dialFront(t.Context(), f, roots, utlsHelloGolang(), pd)
require.NoError(t, result.err, "should connect to test TLS server")
result.conn.Close()
}
// pipeDialer creates a net.Pipe and runs a standard TLS server on one end.
type pipeDialer struct {
serverConfig *stdtls.Config
}
func (pd *pipeDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
clientConn, serverConn := net.Pipe()
go func() {
tlsConn := stdtls.Server(serverConn, pd.serverConfig)
if err := tlsConn.Handshake(); err != nil {
serverConn.Close()
return
}
buf := make([]byte, 1)
tlsConn.Read(buf)
tlsConn.Close()
}()
return clientConn, nil
}
func TestClassifyError(t *testing.T) {
assert.True(t, classifyError(net.UnknownNetworkError("timeout")))
assert.False(t, classifyError(net.UnknownNetworkError("certificate invalid")))
assert.False(t, classifyError(net.UnknownNetworkError("handshake failure")))
}