Daily bump.
[official-gcc.git] / libgo / go / crypto / tls / tls.go
blob6c67506fc3610aee314b138e7ccad5666684c46b
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package tls partially implements TLS 1.2, as specified in RFC 5246.
6 package tls
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"
20 // Server returns a new TLS server side connection
21 // using conn as the underlying transport.
22 // The configuration config must be non-nil and must have
23 // at least one certificate.
24 func Server(conn net.Conn, config *Config) *Conn {
25 return &Conn{conn: conn, config: config}
28 // Client returns a new TLS client side connection
29 // using conn as the underlying transport.
30 // Client interprets a nil configuration as equivalent to
31 // the zero configuration; see the documentation of Config
32 // for the defaults.
33 func Client(conn net.Conn, config *Config) *Conn {
34 return &Conn{conn: conn, config: config, isClient: true}
37 // A listener implements a network listener (net.Listener) for TLS connections.
38 type listener struct {
39 net.Listener
40 config *Config
43 // Accept waits for and returns the next incoming TLS connection.
44 // The returned connection c is a *tls.Conn.
45 func (l *listener) Accept() (c net.Conn, err error) {
46 c, err = l.Listener.Accept()
47 if err != nil {
48 return
50 c = Server(c, l.config)
51 return
54 // NewListener creates a Listener which accepts connections from an inner
55 // Listener and wraps each connection with Server.
56 // The configuration config must be non-nil and must have
57 // at least one certificate.
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
65 // Listen creates a TLS listener accepting connections on the
66 // given network address using net.Listen.
67 // The configuration config must be non-nil and must have
68 // at least one certificate.
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")
73 l, err := net.Listen(network, laddr)
74 if err != nil {
75 return nil, err
77 return NewListener(l, config), nil
80 // Dial connects to the given network address using net.Dial
81 // and then initiates a TLS handshake, returning the resulting
82 // TLS connection.
83 // Dial interprets a nil configuration as equivalent to
84 // the zero configuration; see the documentation of Config
85 // for the defaults.
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
93 colonPos := strings.LastIndex(raddr, ":")
94 if colonPos == -1 {
95 colonPos = len(raddr)
97 hostname := raddr[:colonPos]
99 if config == nil {
100 config = defaultConfig()
102 // If no ServerName is set, infer the ServerName
103 // from the hostname we're connecting to.
104 if config.ServerName == "" {
105 // Make a copy to avoid polluting argument or default.
106 c := *config
107 c.ServerName = hostname
108 config = &c
110 conn := Client(c, config)
111 if err = conn.Handshake(); err != nil {
112 c.Close()
113 return nil, err
115 return conn, nil
118 // LoadX509KeyPair reads and parses a public/private key pair from a pair of
119 // files. The files must contain PEM encoded data.
120 func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
121 certPEMBlock, err := ioutil.ReadFile(certFile)
122 if err != nil {
123 return
125 keyPEMBlock, err := ioutil.ReadFile(keyFile)
126 if err != nil {
127 return
129 return X509KeyPair(certPEMBlock, keyPEMBlock)
132 // X509KeyPair parses a public/private key pair from a pair of
133 // PEM encoded data.
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
141 if certDERBlock.Type == "CERTIFICATE" {
142 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
146 if len(cert.Certificate) == 0 {
147 err = errors.New("crypto/tls: failed to parse certificate PEM data")
148 return
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
158 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
159 break
163 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
164 if err != nil {
165 return
168 // We don't need to parse the public key for TLS, but we so do anyway
169 // to check that it looks sane and matches the private key.
170 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
171 if err != nil {
172 return
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
182 if pub.N.Cmp(priv.N) != 0 {
183 err = errors.New("crypto/tls: private key does not match public key")
184 return
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
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
197 default:
198 err = errors.New("crypto/tls: unknown public key algorithm")
199 return
202 return
205 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
206 // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
207 // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
208 func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
209 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
210 return key, nil
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")
220 if key, err := x509.ParseECPrivateKey(der); err == nil {
221 return key, nil
224 return nil, errors.New("crypto/tls: failed to parse private key")