25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

290 satır
8.0 KiB

  1. // Copyright 2015 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package mitm provides tooling for MITMing TLS connections. It provides
  15. // tooling to create CA certs and generate TLS configs that can be used to MITM
  16. // a TLS connection with a provided CA certificate.
  17. package mitm
  18. import (
  19. "bytes"
  20. "crypto/rand"
  21. "crypto/rsa"
  22. "crypto/sha1"
  23. "crypto/tls"
  24. "crypto/x509"
  25. "crypto/x509/pkix"
  26. "errors"
  27. "math/big"
  28. "net"
  29. "net/http"
  30. "sync"
  31. "time"
  32. "github.com/google/martian/log"
  33. )
  34. // MaxSerialNumber is the upper boundary that is used to create unique serial
  35. // numbers for the certificate. This can be any unsigned integer up to 20
  36. // bytes (2^(8*20)-1).
  37. var MaxSerialNumber = big.NewInt(0).SetBytes(bytes.Repeat([]byte{255}, 20))
  38. // Config is a set of configuration values that are used to build TLS configs
  39. // capable of MITM.
  40. type Config struct {
  41. ca *x509.Certificate
  42. capriv interface{}
  43. priv *rsa.PrivateKey
  44. keyID []byte
  45. validity time.Duration
  46. org string
  47. getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
  48. roots *x509.CertPool
  49. skipVerify bool
  50. handshakeErrorCallback func(*http.Request, error)
  51. certmu sync.RWMutex
  52. certs map[string]*tls.Certificate
  53. }
  54. // NewAuthority creates a new CA certificate and associated
  55. // private key.
  56. func NewAuthority(name, organization string, validity time.Duration) (*x509.Certificate, *rsa.PrivateKey, error) {
  57. priv, err := rsa.GenerateKey(rand.Reader, 2048)
  58. if err != nil {
  59. return nil, nil, err
  60. }
  61. pub := priv.Public()
  62. // Subject Key Identifier support for end entity certificate.
  63. // https://www.ietf.org/rfc/rfc3280.txt (section 4.2.1.2)
  64. pkixpub, err := x509.MarshalPKIXPublicKey(pub)
  65. if err != nil {
  66. return nil, nil, err
  67. }
  68. h := sha1.New()
  69. h.Write(pkixpub)
  70. keyID := h.Sum(nil)
  71. // TODO: keep a map of used serial numbers to avoid potentially reusing a
  72. // serial multiple times.
  73. serial, err := rand.Int(rand.Reader, MaxSerialNumber)
  74. if err != nil {
  75. return nil, nil, err
  76. }
  77. tmpl := &x509.Certificate{
  78. SerialNumber: serial,
  79. Subject: pkix.Name{
  80. CommonName: name,
  81. Organization: []string{organization},
  82. },
  83. SubjectKeyId: keyID,
  84. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
  85. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  86. BasicConstraintsValid: true,
  87. NotBefore: time.Now().Add(-validity),
  88. NotAfter: time.Now().Add(validity),
  89. DNSNames: []string{name},
  90. IsCA: true,
  91. }
  92. raw, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, pub, priv)
  93. if err != nil {
  94. return nil, nil, err
  95. }
  96. // Parse certificate bytes so that we have a leaf certificate.
  97. x509c, err := x509.ParseCertificate(raw)
  98. if err != nil {
  99. return nil, nil, err
  100. }
  101. return x509c, priv, nil
  102. }
  103. // NewConfig creates a MITM config using the CA certificate and
  104. // private key to generate on-the-fly certificates.
  105. func NewConfig(ca *x509.Certificate, privateKey interface{}) (*Config, error) {
  106. roots := x509.NewCertPool()
  107. roots.AddCert(ca)
  108. priv, err := rsa.GenerateKey(rand.Reader, 2048)
  109. if err != nil {
  110. return nil, err
  111. }
  112. pub := priv.Public()
  113. // Subject Key Identifier support for end entity certificate.
  114. // https://www.ietf.org/rfc/rfc3280.txt (section 4.2.1.2)
  115. pkixpub, err := x509.MarshalPKIXPublicKey(pub)
  116. if err != nil {
  117. return nil, err
  118. }
  119. h := sha1.New()
  120. h.Write(pkixpub)
  121. keyID := h.Sum(nil)
  122. return &Config{
  123. ca: ca,
  124. capriv: privateKey,
  125. priv: priv,
  126. keyID: keyID,
  127. validity: time.Hour,
  128. org: "Martian Proxy",
  129. certs: make(map[string]*tls.Certificate),
  130. roots: roots,
  131. }, nil
  132. }
  133. // SetValidity sets the validity window around the current time that the
  134. // certificate is valid for.
  135. func (c *Config) SetValidity(validity time.Duration) {
  136. c.validity = validity
  137. }
  138. // SkipTLSVerify skips the TLS certification verification check.
  139. func (c *Config) SkipTLSVerify(skip bool) {
  140. c.skipVerify = skip
  141. }
  142. // SetOrganization sets the organization of the certificate.
  143. func (c *Config) SetOrganization(org string) {
  144. c.org = org
  145. }
  146. // SetHandshakeErrorCallback sets the handshakeErrorCallback function.
  147. func (c *Config) SetHandshakeErrorCallback(cb func(*http.Request, error)) {
  148. c.handshakeErrorCallback = cb
  149. }
  150. // HandshakeErrorCallback calls the handshakeErrorCallback function in this
  151. // Config, if it is non-nil. Request is the connect request that this handshake
  152. // is being executed through.
  153. func (c *Config) HandshakeErrorCallback(r *http.Request, err error) {
  154. if c.handshakeErrorCallback != nil {
  155. c.handshakeErrorCallback(r, err)
  156. }
  157. }
  158. // TLS returns a *tls.Config that will generate certificates on-the-fly using
  159. // the SNI extension in the TLS ClientHello.
  160. func (c *Config) TLS() *tls.Config {
  161. return &tls.Config{
  162. InsecureSkipVerify: c.skipVerify,
  163. GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
  164. if clientHello.ServerName == "" {
  165. return nil, errors.New("mitm: SNI not provided, failed to build certificate")
  166. }
  167. return c.cert(clientHello.ServerName)
  168. },
  169. NextProtos: []string{"http/1.1"},
  170. }
  171. }
  172. // TLSForHost returns a *tls.Config that will generate certificates on-the-fly
  173. // using SNI from the connection, or fall back to the provided hostname.
  174. func (c *Config) TLSForHost(hostname string) *tls.Config {
  175. return &tls.Config{
  176. InsecureSkipVerify: c.skipVerify,
  177. GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
  178. host := clientHello.ServerName
  179. if host == "" {
  180. host = hostname
  181. }
  182. return c.cert(host)
  183. },
  184. NextProtos: []string{"http/1.1"},
  185. }
  186. }
  187. func (c *Config) cert(hostname string) (*tls.Certificate, error) {
  188. // Remove the port if it exists.
  189. host, _, err := net.SplitHostPort(hostname)
  190. if err == nil {
  191. hostname = host
  192. }
  193. c.certmu.RLock()
  194. tlsc, ok := c.certs[hostname]
  195. c.certmu.RUnlock()
  196. if ok {
  197. log.Debugf("mitm: cache hit for %s", hostname)
  198. // Check validity of the certificate for hostname match, expiry, etc. In
  199. // particular, if the cached certificate has expired, create a new one.
  200. if _, err := tlsc.Leaf.Verify(x509.VerifyOptions{
  201. DNSName: hostname,
  202. Roots: c.roots,
  203. }); err == nil {
  204. return tlsc, nil
  205. }
  206. log.Debugf("mitm: invalid certificate in cache for %s", hostname)
  207. }
  208. log.Debugf("mitm: cache miss for %s", hostname)
  209. serial, err := rand.Int(rand.Reader, MaxSerialNumber)
  210. if err != nil {
  211. return nil, err
  212. }
  213. tmpl := &x509.Certificate{
  214. SerialNumber: serial,
  215. Subject: pkix.Name{
  216. CommonName: hostname,
  217. Organization: []string{c.org},
  218. },
  219. SubjectKeyId: c.keyID,
  220. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  221. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  222. BasicConstraintsValid: true,
  223. NotBefore: time.Now().Add(-c.validity),
  224. NotAfter: time.Now().Add(c.validity),
  225. }
  226. if ip := net.ParseIP(hostname); ip != nil {
  227. tmpl.IPAddresses = []net.IP{ip}
  228. } else {
  229. tmpl.DNSNames = []string{hostname}
  230. }
  231. raw, err := x509.CreateCertificate(rand.Reader, tmpl, c.ca, c.priv.Public(), c.capriv)
  232. if err != nil {
  233. return nil, err
  234. }
  235. // Parse certificate bytes so that we have a leaf certificate.
  236. x509c, err := x509.ParseCertificate(raw)
  237. if err != nil {
  238. return nil, err
  239. }
  240. tlsc = &tls.Certificate{
  241. Certificate: [][]byte{raw, c.ca.Raw},
  242. PrivateKey: c.priv,
  243. Leaf: x509c,
  244. }
  245. c.certmu.Lock()
  246. c.certs[hostname] = tlsc
  247. c.certmu.Unlock()
  248. return tlsc, nil
  249. }