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