| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- package goproxy
- import (
- "crypto"
- "crypto/ecdsa"
- "crypto/elliptic"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/tls"
- "crypto/x509"
- "crypto/x509/pkix"
- "fmt"
- "math/big"
- "math/rand"
- "net"
- "runtime"
- "sort"
- "time"
- )
- func hashSorted(lst []string) []byte {
- c := make([]string, len(lst))
- copy(c, lst)
- sort.Strings(c)
- h := sha1.New()
- for _, s := range c {
- h.Write([]byte(s + ","))
- }
- return h.Sum(nil)
- }
- func hashSortedBigInt(lst []string) *big.Int {
- rv := new(big.Int)
- rv.SetBytes(hashSorted(lst))
- return rv
- }
- var goproxySignerVersion = ":goroxy1"
- func signHost(ca tls.Certificate, hosts []string) (cert *tls.Certificate, err error) {
- var x509ca *x509.Certificate
- // Use the provided ca and not the global GoproxyCa for certificate generation.
- if x509ca, err = x509.ParseCertificate(ca.Certificate[0]); err != nil {
- return
- }
- start := time.Unix(0, 0)
- end, err := time.Parse("2006-01-02", "2049-12-31")
- if err != nil {
- panic(err)
- }
- serial := big.NewInt(rand.Int63())
- template := x509.Certificate{
- // TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form.
- SerialNumber: serial,
- Issuer: x509ca.Subject,
- Subject: pkix.Name{
- Organization: []string{"GoProxy untrusted MITM proxy Inc"},
- },
- NotBefore: start,
- NotAfter: end,
- KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
- ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
- BasicConstraintsValid: true,
- }
- for _, h := range hosts {
- if ip := net.ParseIP(h); ip != nil {
- template.IPAddresses = append(template.IPAddresses, ip)
- } else {
- template.DNSNames = append(template.DNSNames, h)
- template.Subject.CommonName = h
- }
- }
- hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version()))
- var csprng CounterEncryptorRand
- if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil {
- return
- }
- var certpriv crypto.Signer
- switch ca.PrivateKey.(type) {
- case *rsa.PrivateKey:
- if certpriv, err = rsa.GenerateKey(&csprng, 2048); err != nil {
- return
- }
- case *ecdsa.PrivateKey:
- if certpriv, err = ecdsa.GenerateKey(elliptic.P256(), &csprng); err != nil {
- return
- }
- default:
- err = fmt.Errorf("unsupported key type %T", ca.PrivateKey)
- }
- var derBytes []byte
- if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, certpriv.Public(), ca.PrivateKey); err != nil {
- return
- }
- return &tls.Certificate{
- Certificate: [][]byte{derBytes, ca.Certificate[0]},
- PrivateKey: certpriv,
- }, nil
- }
- func init() {
- // Avoid deterministic random numbers
- rand.Seed(time.Now().UnixNano())
- }
|