mirror of https://github.com/k3s-io/k3s
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package goproxy
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"crypto/sha1"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"math/big"
|
|
"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)
|
|
}
|
|
hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version()))
|
|
serial := new(big.Int)
|
|
serial.SetBytes(hash)
|
|
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)
|
|
}
|
|
}
|
|
var csprng CounterEncryptorRand
|
|
if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil {
|
|
return
|
|
}
|
|
var certpriv *rsa.PrivateKey
|
|
if certpriv, err = rsa.GenerateKey(&csprng, 1024); err != nil {
|
|
return
|
|
}
|
|
var derBytes []byte
|
|
if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, &certpriv.PublicKey, ca.PrivateKey); err != nil {
|
|
return
|
|
}
|
|
return tls.Certificate{
|
|
Certificate: [][]byte{derBytes, ca.Certificate[0]},
|
|
PrivateKey: certpriv,
|
|
}, nil
|
|
}
|