Alternative TLS implementation in Go
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

194 lignes
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. }