github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/tls.go (about) 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. 4 5 // Package tls partially implements TLS 1.2, as specified in RFC 5246, 6 // and TLS 1.3, as specified in RFC 8446. 7 // 8 // TLS 1.3 is available only on an opt-in basis in Go 1.12. To enable 9 // it, set the GODEBUG environment variable (comma-separated key=value 10 // options) such that it includes "tls13=1". To enable it from within 11 // the process, set the environment variable before any use of TLS: 12 // 13 // func init() { 14 // os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1") 15 // } 16 package tls 17 18 // BUG(agl): The crypto/tls package only implements some countermeasures 19 // against Lucky13 attacks on CBC-mode encryption, and only on SHA1 20 // variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and 21 // https://www.imperialviolet.org/2013/02/04/luckythirteen.html. 22 23 import ( 24 "crypto" 25 "crypto/ecdsa" 26 "crypto/rsa" 27 "crypto/x509" 28 "encoding/pem" 29 "errors" 30 "fmt" 31 "io/ioutil" 32 "net" 33 "strings" 34 "time" 35 ) 36 37 // Server returns a new TLS server side connection 38 // using conn as the underlying transport. 39 // The configuration config must be non-nil and must include 40 // at least one certificate or else set GetCertificate. 41 func Server(conn net.Conn, config *Config) *Conn { 42 return &Conn{conn: conn, config: config} 43 } 44 45 // Client returns a new TLS client side connection 46 // using conn as the underlying transport. 47 // The config cannot be nil: users must set either ServerName or 48 // InsecureSkipVerify in the config. 49 func Client(conn net.Conn, config *Config) *Conn { 50 return &Conn{conn: conn, config: config, isClient: true} 51 } 52 53 // A listener implements a network listener (net.Listener) for TLS connections. 54 type listener struct { 55 net.Listener 56 config *Config 57 } 58 59 // Accept waits for and returns the next incoming TLS connection. 60 // The returned connection is of type *Conn. 61 func (l *listener) Accept() (net.Conn, error) { 62 c, err := l.Listener.Accept() 63 if err != nil { 64 return nil, err 65 } 66 return Server(c, l.config), nil 67 } 68 69 // NewListener creates a Listener which accepts connections from an inner 70 // Listener and wraps each connection with Server. 71 // The configuration config must be non-nil and must include 72 // at least one certificate or else set GetCertificate. 73 func NewListener(inner net.Listener, config *Config) net.Listener { 74 l := new(listener) 75 l.Listener = inner 76 l.config = config 77 return l 78 } 79 80 // Listen creates a TLS listener accepting connections on the 81 // given network address using net.Listen. 82 // The configuration config must be non-nil and must include 83 // at least one certificate or else set GetCertificate. 84 func Listen(network, laddr string, config *Config) (net.Listener, error) { 85 if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) { 86 return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config") 87 } 88 l, err := net.Listen(network, laddr) 89 if err != nil { 90 return nil, err 91 } 92 return NewListener(l, config), nil 93 } 94 95 type timeoutError struct{} 96 97 func (timeoutError) Error() string { return "tls: DialWithDialer timed out" } 98 func (timeoutError) Timeout() bool { return true } 99 func (timeoutError) Temporary() bool { return true } 100 101 // DialWithDialer connects to the given network address using dialer.Dial and 102 // then initiates a TLS handshake, returning the resulting TLS connection. Any 103 // timeout or deadline given in the dialer apply to connection and TLS 104 // handshake as a whole. 105 // 106 // DialWithDialer interprets a nil configuration as equivalent to the zero 107 // configuration; see the documentation of Config for the defaults. 108 func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { 109 // We want the Timeout and Deadline values from dialer to cover the 110 // whole process: TCP connection and TLS handshake. This means that we 111 // also need to start our own timers now. 112 timeout := dialer.Timeout 113 114 if !dialer.Deadline.IsZero() { 115 deadlineTimeout := time.Until(dialer.Deadline) 116 if timeout == 0 || deadlineTimeout < timeout { 117 timeout = deadlineTimeout 118 } 119 } 120 121 var errChannel chan error 122 123 if timeout != 0 { 124 errChannel = make(chan error, 2) 125 time.AfterFunc(timeout, func() { 126 errChannel <- timeoutError{} 127 }) 128 } 129 130 rawConn, err := dialer.Dial(network, addr) 131 if err != nil { 132 return nil, err 133 } 134 135 colonPos := strings.LastIndex(addr, ":") 136 if colonPos == -1 { 137 colonPos = len(addr) 138 } 139 hostname := addr[:colonPos] 140 141 if config == nil { 142 config = defaultConfig() 143 } 144 // If no ServerName is set, infer the ServerName 145 // from the hostname we're connecting to. 146 if config.ServerName == "" { 147 // Make a copy to avoid polluting argument or default. 148 c := config.Clone() 149 c.ServerName = hostname 150 config = c 151 } 152 153 conn := Client(rawConn, config) 154 155 if timeout == 0 { 156 err = conn.Handshake() 157 } else { 158 go func() { 159 errChannel <- conn.Handshake() 160 }() 161 162 err = <-errChannel 163 } 164 165 if err != nil { 166 rawConn.Close() 167 return nil, err 168 } 169 170 return conn, nil 171 } 172 173 // Dial connects to the given network address using net.Dial 174 // and then initiates a TLS handshake, returning the resulting 175 // TLS connection. 176 // Dial interprets a nil configuration as equivalent to 177 // the zero configuration; see the documentation of Config 178 // for the defaults. 179 func Dial(network, addr string, config *Config) (*Conn, error) { 180 return DialWithDialer(new(net.Dialer), network, addr, config) 181 } 182 183 // LoadX509KeyPair reads and parses a public/private key pair from a pair 184 // of files. The files must contain PEM encoded data. The certificate file 185 // may contain intermediate certificates following the leaf certificate to 186 // form a certificate chain. On successful return, Certificate.Leaf will 187 // be nil because the parsed form of the certificate is not retained. 188 func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { 189 certPEMBlock, err := ioutil.ReadFile(certFile) 190 if err != nil { 191 return Certificate{}, err 192 } 193 keyPEMBlock, err := ioutil.ReadFile(keyFile) 194 if err != nil { 195 return Certificate{}, err 196 } 197 return X509KeyPair(certPEMBlock, keyPEMBlock) 198 } 199 200 // X509KeyPair parses a public/private key pair from a pair of 201 // PEM encoded data. On successful return, Certificate.Leaf will be nil because 202 // the parsed form of the certificate is not retained. 203 func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { 204 fail := func(err error) (Certificate, error) { return Certificate{}, err } 205 206 var cert Certificate 207 var skippedBlockTypes []string 208 for { 209 var certDERBlock *pem.Block 210 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) 211 if certDERBlock == nil { 212 break 213 } 214 if certDERBlock.Type == "CERTIFICATE" { 215 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) 216 } else { 217 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) 218 } 219 } 220 221 if len(cert.Certificate) == 0 { 222 if len(skippedBlockTypes) == 0 { 223 return fail(errors.New("tls: failed to find any PEM data in certificate input")) 224 } 225 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { 226 return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) 227 } 228 return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) 229 } 230 231 skippedBlockTypes = skippedBlockTypes[:0] 232 var keyDERBlock *pem.Block 233 for { 234 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) 235 if keyDERBlock == nil { 236 if len(skippedBlockTypes) == 0 { 237 return fail(errors.New("tls: failed to find any PEM data in key input")) 238 } 239 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { 240 return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) 241 } 242 return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) 243 } 244 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { 245 break 246 } 247 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) 248 } 249 250 // We don't need to parse the public key for TLS, but we so do anyway 251 // to check that it looks sane and matches the private key. 252 x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 253 if err != nil { 254 return fail(err) 255 } 256 257 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) 258 if err != nil { 259 return fail(err) 260 } 261 262 switch pub := x509Cert.PublicKey.(type) { 263 case *rsa.PublicKey: 264 priv, ok := cert.PrivateKey.(*rsa.PrivateKey) 265 if !ok { 266 return fail(errors.New("tls: private key type does not match public key type")) 267 } 268 if pub.N.Cmp(priv.N) != 0 { 269 return fail(errors.New("tls: private key does not match public key")) 270 } 271 case *ecdsa.PublicKey: 272 priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) 273 if !ok { 274 return fail(errors.New("tls: private key type does not match public key type")) 275 } 276 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { 277 return fail(errors.New("tls: private key does not match public key")) 278 } 279 default: 280 return fail(errors.New("tls: unknown public key algorithm")) 281 } 282 283 return cert, nil 284 } 285 286 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates 287 // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. 288 // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. 289 func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { 290 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 291 return key, nil 292 } 293 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { 294 switch key := key.(type) { 295 case *rsa.PrivateKey, *ecdsa.PrivateKey: 296 return key, nil 297 default: 298 return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") 299 } 300 } 301 if key, err := x509.ParseECPrivateKey(der); err == nil { 302 return key, nil 303 } 304 305 return nil, errors.New("tls: failed to parse private key") 306 }