certificate pinning for websocket
This commit is contained in:
parent
2707a8f0a9
commit
5e620e8e8f
41
ws.go
41
ws.go
@ -1,13 +1,16 @@
|
|||||||
package gost
|
package gost
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptrace"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -749,10 +752,46 @@ func websocketClientConn(url string, conn net.Conn, tlsConfig *tls.Config, optio
|
|||||||
if options.UserAgent != "" {
|
if options.UserAgent != "" {
|
||||||
header.Set("User-Agent", options.UserAgent)
|
header.Set("User-Agent", options.UserAgent)
|
||||||
}
|
}
|
||||||
c, resp, err := dialer.Dial(url, header)
|
|
||||||
|
var verifyErr error = nil
|
||||||
|
trace := &httptrace.ClientTrace{
|
||||||
|
TLSHandshakeDone: func(state tls.ConnectionState, err error) {
|
||||||
|
if tlsConfig.RootCAs == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := x509.VerifyOptions{
|
||||||
|
Roots: tlsConfig.RootCAs,
|
||||||
|
CurrentTime: time.Now(),
|
||||||
|
DNSName: "",
|
||||||
|
Intermediates: x509.NewCertPool(),
|
||||||
|
}
|
||||||
|
|
||||||
|
certs := state.PeerCertificates
|
||||||
|
for i, cert := range certs {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
opts.Intermediates.AddCert(cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = certs[0].Verify(opts)
|
||||||
|
if err != nil {
|
||||||
|
verifyErr = err
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx := httptrace.WithClientTrace(context.Background(), trace)
|
||||||
|
|
||||||
|
c, resp, err := dialer.DialContext(ctx, url, header)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if verifyErr != nil {
|
||||||
|
return nil, verifyErr
|
||||||
|
}
|
||||||
|
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
return &websocketConn{conn: c}, nil
|
return &websocketConn{conn: c}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user