goproxy
goproxy copied to clipboard
feat: should copy information from server when proxy generate certificate for client
we know that some app might verify the SNI or DNSName, and app might also delegate the webview's http connect, so we should copy the correct cert information from server, which would lower the possibility of fail when goproxy handshake with client.
following is my code in my practice.
var certs = make(map[string]*tls.Certificate)
func TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *goproxy.ProxyCtx) (*tls.Config, error) {
return func(host string, ctx *goproxy.ProxyCtx) (*tls.Config, error) {
ctx.Logf("signing for %s", host)
// should add the certstore back
cert, err := getCert(host, ca)
if err != nil {
ctx.Warnf("Cannot sign host certificate with provided CA: %s", err)
return nil, err
}
config := &tls.Config{
InsecureSkipVerify: true,
Certificates: []tls.Certificate{*cert},
}
return config, nil
}
}
func getCert(hostport string, ca *tls.Certificate) (*tls.Certificate, error) {
hostname, _, _ := net.SplitHostPort(hostport)
if cert, ok := certs[hostname]; ok {
return cert, nil
}
conn, err := tls.Dial("tcp", hostport, &tls.Config{InsecureSkipVerify: true})
if err != nil {
fmt.Println("failed to connect:", hostport, "Err:", err)
return nil, err
}
defer conn.Close()
err = conn.Handshake()
if err != nil {
return nil, err
}
state := conn.ConnectionState()
cert, err := signHost(ca, state.PeerCertificates[0], []string{hostname})
if err != nil {
return nil, err
}
certs[hostname] = cert
return cert, err
}
func signHost(ca *tls.Certificate, orig *x509.Certificate, hosts []string) (cert *tls.Certificate, err error) {
//
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
}
}
//... insert code here, copy information from server
if orig != nil {
template.Subject = orig.Subject
template.DNSNames = orig.DNSNames
template.EmailAddresses = orig.EmailAddresses
template.IPAddresses = orig.IPAddresses
template.URIs = orig.URIs
template.NotBefore = orig.NotBefore
template.NotAfter = orig.NotAfter
template.KeyUsage = orig.KeyUsage
template.ExtKeyUsage = orig.ExtKeyUsage
}
//...
}
Hello. I was looking at implementing this but the code does not match the current master. There is no "orig" in signHost for example. Do you have a fork where you implemented this?
Hello. I was looking at implementing this but the code does not match the current master. There is no "orig" in signHost for example. Do you have a fork where you implemented this?
this code could work with the current master, according to the example: https://github.com/elazarl/goproxy/blob/master/examples/goproxy-customca/cert.go
we can use our own TLSConfigFromCA to DIY the signHost function.