1
2
3
4
5
6
7 package tls
8
9 import (
10 "crypto/rsa"
11 "crypto/x509"
12 "encoding/pem"
13 "io/ioutil"
14 "net"
15 "os"
16 "strings"
17 )
18
19
20
21
22
23 func Server(conn net.Conn, config *Config) *Conn {
24 return &Conn{conn: conn, config: config}
25 }
26
27
28
29
30
31
32 func Client(conn net.Conn, config *Config) *Conn {
33 return &Conn{conn: conn, config: config, isClient: true}
34 }
35
36
37 type Listener struct {
38 listener net.Listener
39 config *Config
40 }
41
42
43
44 func (l *Listener) Accept() (c net.Conn, err os.Error) {
45 c, err = l.listener.Accept()
46 if err != nil {
47 return
48 }
49 c = Server(c, l.config)
50 return
51 }
52
53
54 func (l *Listener) Close() os.Error { return l.listener.Close() }
55
56
57 func (l *Listener) Addr() net.Addr { return l.listener.Addr() }
58
59
60
61
62
63 func NewListener(listener net.Listener, config *Config) (l *Listener) {
64 l = new(Listener)
65 l.listener = listener
66 l.config = config
67 return
68 }
69
70
71
72
73
74 func Listen(network, laddr string, config *Config) (*Listener, os.Error) {
75 if config == nil || len(config.Certificates) == 0 {
76 return nil, os.NewError("tls.Listen: no certificates in configuration")
77 }
78 l, err := net.Listen(network, laddr)
79 if err != nil {
80 return nil, err
81 }
82 return NewListener(l, config), nil
83 }
84
85
86
87
88
89
90
91 func Dial(network, addr string, config *Config) (*Conn, os.Error) {
92 raddr := addr
93 c, err := net.Dial(network, raddr)
94 if err != nil {
95 return nil, err
96 }
97
98 colonPos := strings.LastIndex(raddr, ":")
99 if colonPos == -1 {
100 colonPos = len(raddr)
101 }
102 hostname := raddr[:colonPos]
103
104 if config == nil {
105 config = defaultConfig()
106 }
107 if config.ServerName != "" {
108
109 c := *config
110 c.ServerName = hostname
111 config = &c
112 }
113 conn := Client(c, config)
114 if err = conn.Handshake(); err != nil {
115 c.Close()
116 return nil, err
117 }
118 return conn, nil
119 }
120
121
122
123 func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os.Error) {
124 certPEMBlock, err := ioutil.ReadFile(certFile)
125 if err != nil {
126 return
127 }
128 keyPEMBlock, err := ioutil.ReadFile(keyFile)
129 if err != nil {
130 return
131 }
132 return X509KeyPair(certPEMBlock, keyPEMBlock)
133 }
134
135
136
137 func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err os.Error) {
138 var certDERBlock *pem.Block
139 for {
140 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
141 if certDERBlock == nil {
142 break
143 }
144 if certDERBlock.Type == "CERTIFICATE" {
145 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
146 }
147 }
148
149 if len(cert.Certificate) == 0 {
150 err = os.NewError("crypto/tls: failed to parse certificate PEM data")
151 return
152 }
153
154 keyDERBlock, _ := pem.Decode(keyPEMBlock)
155 if keyDERBlock == nil {
156 err = os.NewError("crypto/tls: failed to parse key PEM data")
157 return
158 }
159
160 key, err := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes)
161 if err != nil {
162 err = os.NewError("crypto/tls: failed to parse key: " + err.String())
163 return
164 }
165
166 cert.PrivateKey = key
167
168
169
170 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
171 if err != nil {
172 return
173 }
174
175 if x509Cert.PublicKeyAlgorithm != x509.RSA || x509Cert.PublicKey.(*rsa.PublicKey).N.Cmp(key.PublicKey.N) != 0 {
176 err = os.NewError("crypto/tls: private key does not match public key")
177 return
178 }
179
180 return
181 }