signer.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package goproxy
  2. import (
  3. "crypto/rsa"
  4. "crypto/sha1"
  5. "crypto/tls"
  6. "crypto/x509"
  7. "crypto/x509/pkix"
  8. "math/big"
  9. "net"
  10. "runtime"
  11. "sort"
  12. "time"
  13. )
  14. func hashSorted(lst []string) []byte {
  15. c := make([]string, len(lst))
  16. copy(c, lst)
  17. sort.Strings(c)
  18. h := sha1.New()
  19. for _, s := range c {
  20. h.Write([]byte(s + ","))
  21. }
  22. return h.Sum(nil)
  23. }
  24. func hashSortedBigInt(lst []string) *big.Int {
  25. rv := new(big.Int)
  26. rv.SetBytes(hashSorted(lst))
  27. return rv
  28. }
  29. var goproxySignerVersion = ":goroxy1"
  30. func signHost(ca tls.Certificate, hosts []string) (cert tls.Certificate, err error) {
  31. var x509ca *x509.Certificate
  32. // Use the provided ca and not the global GoproxyCa for certificate generation.
  33. if x509ca, err = x509.ParseCertificate(ca.Certificate[0]); err != nil {
  34. return
  35. }
  36. start := time.Unix(0, 0)
  37. end, err := time.Parse("2006-01-02", "2049-12-31")
  38. if err != nil {
  39. panic(err)
  40. }
  41. hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version()))
  42. serial := new(big.Int)
  43. serial.SetBytes(hash)
  44. template := x509.Certificate{
  45. // TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form.
  46. SerialNumber: serial,
  47. Issuer: x509ca.Subject,
  48. Subject: pkix.Name{
  49. Organization: []string{"GoProxy untrusted MITM proxy Inc"},
  50. },
  51. NotBefore: start,
  52. NotAfter: end,
  53. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  54. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  55. BasicConstraintsValid: true,
  56. }
  57. for _, h := range hosts {
  58. if ip := net.ParseIP(h); ip != nil {
  59. template.IPAddresses = append(template.IPAddresses, ip)
  60. } else {
  61. template.DNSNames = append(template.DNSNames, h)
  62. }
  63. }
  64. var csprng CounterEncryptorRand
  65. if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil {
  66. return
  67. }
  68. var certpriv *rsa.PrivateKey
  69. if certpriv, err = rsa.GenerateKey(&csprng, 1024); err != nil {
  70. return
  71. }
  72. var derBytes []byte
  73. if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, &certpriv.PublicKey, ca.PrivateKey); err != nil {
  74. return
  75. }
  76. return tls.Certificate{
  77. Certificate: [][]byte{derBytes, ca.Certificate[0]},
  78. PrivateKey: certpriv,
  79. }, nil
  80. }