Alternative TLS implementation in Go
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

291 Zeilen
9.0 KiB

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