tlsutil.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package tlsutil
  7. import (
  8. "bufio"
  9. "crypto/ecdsa"
  10. "crypto/elliptic"
  11. "crypto/rsa"
  12. "crypto/tls"
  13. "crypto/x509"
  14. "crypto/x509/pkix"
  15. "encoding/pem"
  16. "fmt"
  17. "io"
  18. "math/big"
  19. "net"
  20. "os"
  21. "time"
  22. "github.com/syncthing/syncthing/lib/rand"
  23. )
  24. var (
  25. ErrIdentificationFailed = fmt.Errorf("failed to identify socket type")
  26. )
  27. // NewCertificate generates and returns a new TLS certificate. If tlsRSABits
  28. // is greater than zero we generate an RSA certificate with the specified
  29. // number of bits. Otherwise we create a 384 bit ECDSA certificate.
  30. func NewCertificate(certFile, keyFile, tlsDefaultCommonName string, tlsRSABits int) (tls.Certificate, error) {
  31. var priv interface{}
  32. var err error
  33. if tlsRSABits > 0 {
  34. priv, err = rsa.GenerateKey(rand.Reader, tlsRSABits)
  35. } else {
  36. priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
  37. }
  38. if err != nil {
  39. return tls.Certificate{}, fmt.Errorf("generate key: %s", err)
  40. }
  41. notBefore := time.Now()
  42. notAfter := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC)
  43. template := x509.Certificate{
  44. SerialNumber: new(big.Int).SetInt64(rand.Int63()),
  45. Subject: pkix.Name{
  46. CommonName: tlsDefaultCommonName,
  47. },
  48. NotBefore: notBefore,
  49. NotAfter: notAfter,
  50. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  51. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  52. BasicConstraintsValid: true,
  53. }
  54. derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
  55. if err != nil {
  56. return tls.Certificate{}, fmt.Errorf("create cert: %s", err)
  57. }
  58. certOut, err := os.Create(certFile)
  59. if err != nil {
  60. return tls.Certificate{}, fmt.Errorf("save cert: %s", err)
  61. }
  62. err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
  63. if err != nil {
  64. return tls.Certificate{}, fmt.Errorf("save cert: %s", err)
  65. }
  66. err = certOut.Close()
  67. if err != nil {
  68. return tls.Certificate{}, fmt.Errorf("save cert: %s", err)
  69. }
  70. keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
  71. if err != nil {
  72. return tls.Certificate{}, fmt.Errorf("save key: %s", err)
  73. }
  74. block, err := pemBlockForKey(priv)
  75. if err != nil {
  76. return tls.Certificate{}, fmt.Errorf("save key: %s", err)
  77. }
  78. err = pem.Encode(keyOut, block)
  79. if err != nil {
  80. return tls.Certificate{}, fmt.Errorf("save key: %s", err)
  81. }
  82. err = keyOut.Close()
  83. if err != nil {
  84. return tls.Certificate{}, fmt.Errorf("save key: %s", err)
  85. }
  86. return tls.LoadX509KeyPair(certFile, keyFile)
  87. }
  88. type DowngradingListener struct {
  89. net.Listener
  90. TLSConfig *tls.Config
  91. }
  92. func (l *DowngradingListener) Accept() (net.Conn, error) {
  93. conn, isTLS, err := l.AcceptNoWrapTLS()
  94. // We failed to identify the socket type, pretend that everything is fine,
  95. // and pass it to the underlying handler, and let them deal with it.
  96. if err == ErrIdentificationFailed {
  97. return conn, nil
  98. }
  99. if err != nil {
  100. return conn, err
  101. }
  102. if isTLS {
  103. return tls.Server(conn, l.TLSConfig), nil
  104. }
  105. return conn, nil
  106. }
  107. func (l *DowngradingListener) AcceptNoWrapTLS() (net.Conn, bool, error) {
  108. conn, err := l.Listener.Accept()
  109. if err != nil {
  110. return nil, false, err
  111. }
  112. br := bufio.NewReader(conn)
  113. conn.SetReadDeadline(time.Now().Add(1 * time.Second))
  114. bs, err := br.Peek(1)
  115. conn.SetReadDeadline(time.Time{})
  116. if err != nil {
  117. // We hit a read error here, but the Accept() call succeeded so we must not return an error.
  118. // We return the connection as is with a special error which handles this
  119. // special case in Accept().
  120. return conn, false, ErrIdentificationFailed
  121. }
  122. return &UnionedConnection{br, conn}, bs[0] == 0x16, nil
  123. }
  124. type UnionedConnection struct {
  125. io.Reader
  126. net.Conn
  127. }
  128. func (c *UnionedConnection) Read(b []byte) (n int, err error) {
  129. return c.Reader.Read(b)
  130. }
  131. func publicKey(priv interface{}) interface{} {
  132. switch k := priv.(type) {
  133. case *rsa.PrivateKey:
  134. return &k.PublicKey
  135. case *ecdsa.PrivateKey:
  136. return &k.PublicKey
  137. default:
  138. return nil
  139. }
  140. }
  141. func pemBlockForKey(priv interface{}) (*pem.Block, error) {
  142. switch k := priv.(type) {
  143. case *rsa.PrivateKey:
  144. return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil
  145. case *ecdsa.PrivateKey:
  146. b, err := x509.MarshalECPrivateKey(k)
  147. if err != nil {
  148. return nil, err
  149. }
  150. return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}, nil
  151. default:
  152. return nil, fmt.Errorf("unknown key type")
  153. }
  154. }