tlsutil.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. "crypto/ecdsa"
  9. "crypto/elliptic"
  10. "crypto/rsa"
  11. "crypto/tls"
  12. "crypto/x509"
  13. "crypto/x509/pkix"
  14. "encoding/pem"
  15. "errors"
  16. "fmt"
  17. "math/big"
  18. "net"
  19. "os"
  20. "time"
  21. "github.com/syncthing/syncthing/lib/rand"
  22. )
  23. var (
  24. ErrIdentificationFailed = errors.New("failed to identify socket type")
  25. )
  26. var (
  27. // The list of cipher suites we will use / suggest for TLS 1.2 connections.
  28. cipherSuites = []uint16{
  29. // Suites that are good and fast on hardware *without* AES-NI.
  30. tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
  31. tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
  32. // Suites that are good and fast on hardware with AES-NI. These are
  33. // reordered from the Go default to put the 256 bit ciphers above the
  34. // 128 bit ones - because that looks cooler, even though there is
  35. // probably no relevant difference in strength yet.
  36. tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
  37. tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
  38. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  39. tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  40. // The rest of the suites, minus DES stuff.
  41. tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
  42. tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
  43. tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
  44. tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
  45. tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
  46. tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
  47. tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
  48. tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
  49. tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
  50. tls.TLS_RSA_WITH_AES_128_CBC_SHA,
  51. tls.TLS_RSA_WITH_AES_256_CBC_SHA,
  52. }
  53. )
  54. // SecureDefault returns a tls.Config with reasonable, secure defaults set.
  55. // This variant allows only TLS 1.3.
  56. func SecureDefaultTLS13() *tls.Config {
  57. return &tls.Config{
  58. // TLS 1.3 is the minimum we accept
  59. MinVersion: tls.VersionTLS13,
  60. }
  61. }
  62. // SecureDefaultWithTLS12 returns a tls.Config with reasonable, secure
  63. // defaults set. This variant allows TLS 1.2.
  64. func SecureDefaultWithTLS12() *tls.Config {
  65. // paranoia
  66. cs := make([]uint16, len(cipherSuites))
  67. copy(cs, cipherSuites)
  68. return &tls.Config{
  69. // TLS 1.2 is the minimum we accept
  70. MinVersion: tls.VersionTLS12,
  71. // The cipher suite lists built above. These are ignored in TLS 1.3.
  72. CipherSuites: cs,
  73. // We've put some thought into this choice and would like it to
  74. // matter.
  75. PreferServerCipherSuites: true,
  76. }
  77. }
  78. // generateCertificate generates a PEM formatted key pair and self-signed certificate in memory.
  79. func generateCertificate(commonName string, lifetimeDays int) (*pem.Block, *pem.Block, error) {
  80. priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
  81. if err != nil {
  82. return nil, nil, fmt.Errorf("generate key: %w", err)
  83. }
  84. notBefore := time.Now().Truncate(24 * time.Hour)
  85. notAfter := notBefore.Add(time.Duration(lifetimeDays*24) * time.Hour)
  86. // NOTE: update lib/api.shouldRegenerateCertificate() appropriately if
  87. // you add or change attributes in here, especially DNSNames or
  88. // IPAddresses.
  89. template := x509.Certificate{
  90. SerialNumber: new(big.Int).SetUint64(rand.Uint64()),
  91. Subject: pkix.Name{
  92. CommonName: commonName,
  93. Organization: []string{"Syncthing"},
  94. OrganizationalUnit: []string{"Automatically Generated"},
  95. },
  96. DNSNames: []string{commonName},
  97. NotBefore: notBefore,
  98. NotAfter: notAfter,
  99. SignatureAlgorithm: x509.ECDSAWithSHA256,
  100. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  101. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  102. BasicConstraintsValid: true,
  103. }
  104. derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv)
  105. if err != nil {
  106. return nil, nil, fmt.Errorf("create cert: %w", err)
  107. }
  108. certBlock := &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}
  109. keyBlock, err := pemBlockForKey(priv)
  110. if err != nil {
  111. return nil, nil, fmt.Errorf("save key: %w", err)
  112. }
  113. return certBlock, keyBlock, nil
  114. }
  115. // NewCertificate generates and returns a new TLS certificate, saved to the given PEM files.
  116. func NewCertificate(certFile, keyFile string, commonName string, lifetimeDays int) (tls.Certificate, error) {
  117. certBlock, keyBlock, err := generateCertificate(commonName, lifetimeDays)
  118. if err != nil {
  119. return tls.Certificate{}, err
  120. }
  121. certOut, err := os.Create(certFile)
  122. if err != nil {
  123. return tls.Certificate{}, fmt.Errorf("save cert: %w", err)
  124. }
  125. if err = pem.Encode(certOut, certBlock); err != nil {
  126. return tls.Certificate{}, fmt.Errorf("save cert: %w", err)
  127. }
  128. if err = certOut.Close(); err != nil {
  129. return tls.Certificate{}, fmt.Errorf("save cert: %w", err)
  130. }
  131. keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
  132. if err != nil {
  133. return tls.Certificate{}, fmt.Errorf("save key: %w", err)
  134. }
  135. if err = pem.Encode(keyOut, keyBlock); err != nil {
  136. return tls.Certificate{}, fmt.Errorf("save key: %w", err)
  137. }
  138. if err = keyOut.Close(); err != nil {
  139. return tls.Certificate{}, fmt.Errorf("save key: %w", err)
  140. }
  141. return tls.X509KeyPair(pem.EncodeToMemory(certBlock), pem.EncodeToMemory(keyBlock))
  142. }
  143. // NewCertificateInMemory generates and returns a new TLS certificate, kept only in memory.
  144. func NewCertificateInMemory(commonName string, lifetimeDays int) (tls.Certificate, error) {
  145. certBlock, keyBlock, err := generateCertificate(commonName, lifetimeDays)
  146. if err != nil {
  147. return tls.Certificate{}, err
  148. }
  149. return tls.X509KeyPair(pem.EncodeToMemory(certBlock), pem.EncodeToMemory(keyBlock))
  150. }
  151. type DowngradingListener struct {
  152. net.Listener
  153. TLSConfig *tls.Config
  154. }
  155. func (l *DowngradingListener) Accept() (net.Conn, error) {
  156. conn, isTLS, err := l.AcceptNoWrapTLS()
  157. // We failed to identify the socket type, pretend that everything is fine,
  158. // and pass it to the underlying handler, and let them deal with it.
  159. if err == ErrIdentificationFailed {
  160. return conn, nil
  161. }
  162. if err != nil {
  163. return conn, err
  164. }
  165. if isTLS {
  166. return tls.Server(conn, l.TLSConfig), nil
  167. }
  168. return conn, nil
  169. }
  170. func (l *DowngradingListener) AcceptNoWrapTLS() (net.Conn, bool, error) {
  171. conn, err := l.Listener.Accept()
  172. if err != nil {
  173. return nil, false, err
  174. }
  175. union := &UnionedConnection{Conn: conn}
  176. conn.SetReadDeadline(time.Now().Add(1 * time.Second))
  177. n, err := conn.Read(union.first[:])
  178. conn.SetReadDeadline(time.Time{})
  179. if err != nil || n == 0 {
  180. // We hit a read error here, but the Accept() call succeeded so we must not return an error.
  181. // We return the connection as is with a special error which handles this
  182. // special case in Accept().
  183. return conn, false, ErrIdentificationFailed
  184. }
  185. return union, union.first[0] == 0x16, nil
  186. }
  187. type UnionedConnection struct {
  188. first [1]byte
  189. firstDone bool
  190. net.Conn
  191. }
  192. func (c *UnionedConnection) Read(b []byte) (n int, err error) {
  193. if !c.firstDone {
  194. if len(b) == 0 {
  195. // this probably doesn't happen, but handle it anyway
  196. return 0, nil
  197. }
  198. b[0] = c.first[0]
  199. c.firstDone = true
  200. return 1, nil
  201. }
  202. return c.Conn.Read(b)
  203. }
  204. func pemBlockForKey(priv interface{}) (*pem.Block, error) {
  205. switch k := priv.(type) {
  206. case *rsa.PrivateKey:
  207. return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil
  208. case *ecdsa.PrivateKey:
  209. b, err := x509.MarshalECPrivateKey(k)
  210. if err != nil {
  211. return nil, err
  212. }
  213. return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}, nil
  214. default:
  215. return nil, errors.New("unknown key type")
  216. }
  217. }