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.

181 lignes
4.6 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
  5. import (
  6. "crypto/rand"
  7. "crypto/rsa"
  8. "io"
  9. "io/ioutil"
  10. "sync"
  11. "time"
  12. )
  13. const (
  14. maxPlaintext = 16384 // maximum plaintext payload length
  15. maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
  16. recordHeaderLen = 5 // record header length
  17. maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
  18. minVersion = 0x0301 // minimum supported version - TLS 1.0
  19. maxVersion = 0x0302 // maximum supported version - TLS 1.1
  20. )
  21. // TLS record types.
  22. type recordType uint8
  23. const (
  24. recordTypeChangeCipherSpec recordType = 20
  25. recordTypeAlert recordType = 21
  26. recordTypeHandshake recordType = 22
  27. recordTypeApplicationData recordType = 23
  28. )
  29. // TLS handshake message types.
  30. const (
  31. typeClientHello uint8 = 1
  32. typeServerHello uint8 = 2
  33. typeCertificate uint8 = 11
  34. typeCertificateRequest uint8 = 13
  35. typeServerHelloDone uint8 = 14
  36. typeCertificateVerify uint8 = 15
  37. typeClientKeyExchange uint8 = 16
  38. typeFinished uint8 = 20
  39. typeCertificateStatus uint8 = 22
  40. typeNextProtocol uint8 = 67 // Not IANA assigned
  41. )
  42. // TLS cipher suites.
  43. const (
  44. TLS_RSA_WITH_RC4_128_SHA uint16 = 5
  45. )
  46. // TLS compression types.
  47. const (
  48. compressionNone uint8 = 0
  49. )
  50. // TLS extension numbers
  51. var (
  52. extensionServerName uint16 = 0
  53. extensionStatusRequest uint16 = 5
  54. extensionNextProtoNeg uint16 = 13172 // not IANA assigned
  55. )
  56. // TLS CertificateStatusType (RFC 3546)
  57. const (
  58. statusTypeOCSP uint8 = 1
  59. )
  60. // Certificate types (for certificateRequestMsg)
  61. const (
  62. certTypeRSASign = 1 // A certificate containing an RSA key
  63. certTypeDSSSign = 2 // A certificate containing a DSA key
  64. certTypeRSAFixedDH = 3 // A certificate containing a static DH key
  65. certTypeDSSFixedDH = 4 // A certficiate containing a static DH key
  66. // Rest of these are reserved by the TLS spec
  67. )
  68. type ConnectionState struct {
  69. HandshakeComplete bool
  70. CipherSuite uint16
  71. NegotiatedProtocol string
  72. }
  73. // A Config structure is used to configure a TLS client or server. After one
  74. // has been passed to a TLS function it must not be modified.
  75. type Config struct {
  76. // Rand provides the source of entropy for nonces and RSA blinding.
  77. Rand io.Reader
  78. // Time returns the current time as the number of seconds since the epoch.
  79. Time func() int64
  80. // Certificates contains one or more certificate chains.
  81. Certificates []Certificate
  82. RootCAs *CASet
  83. // NextProtos is a list of supported, application level protocols.
  84. // Currently only server-side handling is supported.
  85. NextProtos []string
  86. // ServerName is included in the client's handshake to support virtual
  87. // hosting.
  88. ServerName string
  89. // AuthenticateClient determines if a server will request a certificate
  90. // from the client. It does not require that the client send a
  91. // certificate nor, if it does, that the certificate is anything more
  92. // than self-signed.
  93. AuthenticateClient bool
  94. }
  95. type Certificate struct {
  96. // Certificate contains a chain of one or more certificates. Leaf
  97. // certificate first.
  98. Certificate [][]byte
  99. PrivateKey *rsa.PrivateKey
  100. }
  101. // A TLS record.
  102. type record struct {
  103. contentType recordType
  104. major, minor uint8
  105. payload []byte
  106. }
  107. type handshakeMessage interface {
  108. marshal() []byte
  109. unmarshal([]byte) bool
  110. }
  111. type encryptor interface {
  112. // XORKeyStream xors the contents of the slice with bytes from the key stream.
  113. XORKeyStream(buf []byte)
  114. }
  115. // mutualVersion returns the protocol version to use given the advertised
  116. // version of the peer.
  117. func mutualVersion(vers uint16) (uint16, bool) {
  118. if vers < minVersion {
  119. return 0, false
  120. }
  121. if vers > maxVersion {
  122. vers = maxVersion
  123. }
  124. return vers, true
  125. }
  126. // The defaultConfig is used in place of a nil *Config in the TLS server and client.
  127. var varDefaultConfig *Config
  128. var once sync.Once
  129. func defaultConfig() *Config {
  130. once.Do(initDefaultConfig)
  131. return varDefaultConfig
  132. }
  133. // Possible certificate files; stop after finding one.
  134. // On OS X we should really be using the Directory Services keychain
  135. // but that requires a lot of Mach goo to get at. Instead we use
  136. // the same root set that curl uses.
  137. var certFiles = []string{
  138. "/etc/ssl/certs/ca-certificates.crt", // Linux etc
  139. "/usr/share/curl/curl-ca-bundle.crt", // OS X
  140. }
  141. func initDefaultConfig() {
  142. roots := NewCASet()
  143. for _, file := range certFiles {
  144. data, err := ioutil.ReadFile(file)
  145. if err == nil {
  146. roots.SetFromPEM(data)
  147. break
  148. }
  149. }
  150. varDefaultConfig = &Config{
  151. Rand: rand.Reader,
  152. Time: time.Seconds,
  153. RootCAs: roots,
  154. }
  155. }