Source file src/pkg/crypto/tls/tls.go
1
2
3
4
5
6 package tls
7
8 import (
9 "crypto"
10 "crypto/ecdsa"
11 "crypto/rsa"
12 "crypto/x509"
13 "encoding/pem"
14 "errors"
15 "io/ioutil"
16 "net"
17 "strings"
18 )
19
20
21
22
23
24 func Server(conn net.Conn, config *Config) *Conn {
25 return &Conn{conn: conn, config: config}
26 }
27
28
29
30
31
32
33 func Client(conn net.Conn, config *Config) *Conn {
34 return &Conn{conn: conn, config: config, isClient: true}
35 }
36
37
38 type listener struct {
39 net.Listener
40 config *Config
41 }
42
43
44
45 func (l *listener) Accept() (c net.Conn, err error) {
46 c, err = l.Listener.Accept()
47 if err != nil {
48 return
49 }
50 c = Server(c, l.config)
51 return
52 }
53
54
55
56
57
58 func NewListener(inner net.Listener, config *Config) net.Listener {
59 l := new(listener)
60 l.Listener = inner
61 l.config = config
62 return l
63 }
64
65
66
67
68
69 func Listen(network, laddr string, config *Config) (net.Listener, error) {
70 if config == nil || len(config.Certificates) == 0 {
71 return nil, errors.New("tls.Listen: no certificates in configuration")
72 }
73 l, err := net.Listen(network, laddr)
74 if err != nil {
75 return nil, err
76 }
77 return NewListener(l, config), nil
78 }
79
80
81
82
83
84
85
86 func Dial(network, addr string, config *Config) (*Conn, error) {
87 raddr := addr
88 c, err := net.Dial(network, raddr)
89 if err != nil {
90 return nil, err
91 }
92
93 colonPos := strings.LastIndex(raddr, ":")
94 if colonPos == -1 {
95 colonPos = len(raddr)
96 }
97 hostname := raddr[:colonPos]
98
99 if config == nil {
100 config = defaultConfig()
101 }
102
103
104 if config.ServerName == "" {
105
106 c := *config
107 c.ServerName = hostname
108 config = &c
109 }
110 conn := Client(c, config)
111 if err = conn.Handshake(); err != nil {
112 c.Close()
113 return nil, err
114 }
115 return conn, nil
116 }
117
118
119
120 func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
121 certPEMBlock, err := ioutil.ReadFile(certFile)
122 if err != nil {
123 return
124 }
125 keyPEMBlock, err := ioutil.ReadFile(keyFile)
126 if err != nil {
127 return
128 }
129 return X509KeyPair(certPEMBlock, keyPEMBlock)
130 }
131
132
133
134 func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
135 var certDERBlock *pem.Block
136 for {
137 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
138 if certDERBlock == nil {
139 break
140 }
141 if certDERBlock.Type == "CERTIFICATE" {
142 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
143 }
144 }
145
146 if len(cert.Certificate) == 0 {
147 err = errors.New("crypto/tls: failed to parse certificate PEM data")
148 return
149 }
150
151 var keyDERBlock *pem.Block
152 for {
153 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
154 if keyDERBlock == nil {
155 err = errors.New("crypto/tls: failed to parse key PEM data")
156 return
157 }
158 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
159 break
160 }
161 }
162
163 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
164 if err != nil {
165 return
166 }
167
168
169
170 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
171 if err != nil {
172 return
173 }
174
175 switch pub := x509Cert.PublicKey.(type) {
176 case *rsa.PublicKey:
177 priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
178 if !ok {
179 err = errors.New("crypto/tls: private key type does not match public key type")
180 return
181 }
182 if pub.N.Cmp(priv.N) != 0 {
183 err = errors.New("crypto/tls: private key does not match public key")
184 return
185 }
186 case *ecdsa.PublicKey:
187 priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
188 if !ok {
189 err = errors.New("crypto/tls: private key type does not match public key type")
190 return
191
192 }
193 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
194 err = errors.New("crypto/tls: private key does not match public key")
195 return
196 }
197 default:
198 err = errors.New("crypto/tls: unknown public key algorithm")
199 return
200 }
201
202 return
203 }
204
205
206
207
208 func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
209 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
210 return key, nil
211 }
212 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
213 switch key := key.(type) {
214 case *rsa.PrivateKey, *ecdsa.PrivateKey:
215 return key, nil
216 default:
217 return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping")
218 }
219 }
220 if key, err := x509.ParseECPrivateKey(der); err == nil {
221 return key, nil
222 }
223
224 return nil, errors.New("crypto/tls: failed to parse private key")
225 }
View as plain text