Alternative TLS implementation in Go
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

194 líneas
5.3 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.0, as specified in RFC 2246.
  5. package tls
  6. import (
  7. "crypto/rsa"
  8. "crypto/x509"
  9. "encoding/pem"
  10. "errors"
  11. "io/ioutil"
  12. "net"
  13. "strings"
  14. )
  15. // Server returns a new TLS server side connection
  16. // using conn as the underlying transport.
  17. // The configuration config must be non-nil and must have
  18. // at least one certificate.
  19. func Server(conn net.Conn, config *Config) *Conn {
  20. return &Conn{conn: conn, config: config}
  21. }
  22. // Client returns a new TLS client side connection
  23. // using conn as the underlying transport.
  24. // Client interprets a nil configuration as equivalent to
  25. // the zero configuration; see the documentation of Config
  26. // for the defaults.
  27. func Client(conn net.Conn, config *Config) *Conn {
  28. return &Conn{conn: conn, config: config, isClient: true}
  29. }
  30. // A listener implements a network listener (net.Listener) for TLS connections.
  31. type listener struct {
  32. net.Listener
  33. config *Config
  34. }
  35. // Accept waits for and returns the next incoming TLS connection.
  36. // The returned connection c is a *tls.Conn.
  37. func (l *listener) Accept() (c net.Conn, err error) {
  38. c, err = l.Listener.Accept()
  39. if err != nil {
  40. return
  41. }
  42. c = Server(c, l.config)
  43. return
  44. }
  45. // NewListener creates a Listener which accepts connections from an inner
  46. // Listener and wraps each connection with Server.
  47. // The configuration config must be non-nil and must have
  48. // at least one certificate.
  49. func NewListener(inner net.Listener, config *Config) net.Listener {
  50. l := new(listener)
  51. l.Listener = inner
  52. l.config = config
  53. return l
  54. }
  55. // Listen creates a TLS listener accepting connections on the
  56. // given network address using net.Listen.
  57. // The configuration config must be non-nil and must have
  58. // at least one certificate.
  59. func Listen(network, laddr string, config *Config) (net.Listener, error) {
  60. if config == nil || len(config.Certificates) == 0 {
  61. return nil, errors.New("tls.Listen: no certificates in configuration")
  62. }
  63. l, err := net.Listen(network, laddr)
  64. if err != nil {
  65. return nil, err
  66. }
  67. return NewListener(l, config), nil
  68. }
  69. // Dial connects to the given network address using net.Dial
  70. // and then initiates a TLS handshake, returning the resulting
  71. // TLS connection.
  72. // Dial interprets a nil configuration as equivalent to
  73. // the zero configuration; see the documentation of Config
  74. // for the defaults.
  75. func Dial(network, addr string, config *Config) (*Conn, error) {
  76. raddr := addr
  77. c, err := net.Dial(network, raddr)
  78. if err != nil {
  79. return nil, err
  80. }
  81. colonPos := strings.LastIndex(raddr, ":")
  82. if colonPos == -1 {
  83. colonPos = len(raddr)
  84. }
  85. hostname := raddr[:colonPos]
  86. if config == nil {
  87. config = defaultConfig()
  88. }
  89. // If no ServerName is set, infer the ServerName
  90. // from the hostname we're connecting to.
  91. if config.ServerName == "" {
  92. // Make a copy to avoid polluting argument or default.
  93. c := *config
  94. c.ServerName = hostname
  95. config = &c
  96. }
  97. conn := Client(c, config)
  98. if err = conn.Handshake(); err != nil {
  99. c.Close()
  100. return nil, err
  101. }
  102. return conn, nil
  103. }
  104. // LoadX509KeyPair reads and parses a public/private key pair from a pair of
  105. // files. The files must contain PEM encoded data.
  106. func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
  107. certPEMBlock, err := ioutil.ReadFile(certFile)
  108. if err != nil {
  109. return
  110. }
  111. keyPEMBlock, err := ioutil.ReadFile(keyFile)
  112. if err != nil {
  113. return
  114. }
  115. return X509KeyPair(certPEMBlock, keyPEMBlock)
  116. }
  117. // X509KeyPair parses a public/private key pair from a pair of
  118. // PEM encoded data.
  119. func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
  120. var certDERBlock *pem.Block
  121. for {
  122. certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
  123. if certDERBlock == nil {
  124. break
  125. }
  126. if certDERBlock.Type == "CERTIFICATE" {
  127. cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
  128. }
  129. }
  130. if len(cert.Certificate) == 0 {
  131. err = errors.New("crypto/tls: failed to parse certificate PEM data")
  132. return
  133. }
  134. var keyDERBlock *pem.Block
  135. for {
  136. keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
  137. if keyDERBlock == nil {
  138. err = errors.New("crypto/tls: failed to parse key PEM data")
  139. return
  140. }
  141. if keyDERBlock.Type != "CERTIFICATE" {
  142. break
  143. }
  144. }
  145. // OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
  146. // OpenSSL 1.0.0 generates PKCS#8 keys. We try both.
  147. var key *rsa.PrivateKey
  148. if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil {
  149. var privKey interface{}
  150. if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil {
  151. err = errors.New("crypto/tls: failed to parse key: " + err.Error())
  152. return
  153. }
  154. var ok bool
  155. if key, ok = privKey.(*rsa.PrivateKey); !ok {
  156. err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping")
  157. return
  158. }
  159. }
  160. cert.PrivateKey = key
  161. // We don't need to parse the public key for TLS, but we so do anyway
  162. // to check that it looks sane and matches the private key.
  163. x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
  164. if err != nil {
  165. return
  166. }
  167. if x509Cert.PublicKeyAlgorithm != x509.RSA || x509Cert.PublicKey.(*rsa.PublicKey).N.Cmp(key.PublicKey.N) != 0 {
  168. err = errors.New("crypto/tls: private key does not match public key")
  169. return
  170. }
  171. return
  172. }