diff options
author | Cecylia Bocovich <cohosh@torproject.org> | 2023-06-12 20:34:41 -0400 |
---|---|---|
committer | Cecylia Bocovich <cohosh@torproject.org> | 2023-06-14 18:12:29 -0400 |
commit | f8eb86f24d659f8d41dc67bd12bf496dbd35c0b5 (patch) | |
tree | c09eea855109218552faab252b47a02991842b5a | |
parent | 9edaee65470a1483bbdbe984e5e15a885f1e95d2 (diff) | |
download | snowflake-f8eb86f24d659f8d41dc67bd12bf496dbd35c0b5.tar.gz snowflake-f8eb86f24d659f8d41dc67bd12bf496dbd35c0b5.zip |
Append Let's Encrypt ISRG Root X1 to cert pool
This is a workaround for older versions of android that do not trust
the Let's Encrypt root certificate.
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40087
-rw-r--r-- | client/lib/rendezvous.go | 11 | ||||
-rw-r--r-- | common/certs/certs.go | 54 |
2 files changed, 63 insertions, 2 deletions
diff --git a/client/lib/rendezvous.go b/client/lib/rendezvous.go index ef0bf29..eeb4638 100644 --- a/client/lib/rendezvous.go +++ b/client/lib/rendezvous.go @@ -4,6 +4,7 @@ package snowflake_client import ( + "crypto/tls" "errors" "fmt" @@ -14,6 +15,7 @@ import ( "github.com/pion/webrtc/v3" utls "github.com/refraction-networking/utls" + "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/certs" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/messages" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/nat" @@ -50,7 +52,10 @@ type BrokerChannel struct { // and TLSHandshakeTimeout settings. But we want to disable the default // ProxyFromEnvironment setting. func createBrokerTransport() http.RoundTripper { - transport := http.DefaultTransport.(*http.Transport) + tlsConfig := &tls.Config{ + RootCAs: certs.GetRootCAs(), + } + transport := &http.Transport{TLSClientConfig: tlsConfig} transport.Proxy = nil transport.ResponseHeaderTimeout = 15 * time.Second return transport @@ -70,7 +75,9 @@ func newBrokerChannelFromConfig(config ClientConfig) (*BrokerChannel, error) { if err != nil { return nil, fmt.Errorf("unable to create broker channel: %v", err) } - utlsConfig := &utls.Config{} + utlsConfig := &utls.Config{ + RootCAs: certs.GetRootCAs(), + } brokerTransport = utlsutil.NewUTLSHTTPRoundTripper(utlsClientHelloID, utlsConfig, brokerTransport, config.UTLSRemoveSNI) } diff --git a/common/certs/certs.go b/common/certs/certs.go new file mode 100644 index 0000000..11cb082 --- /dev/null +++ b/common/certs/certs.go @@ -0,0 +1,54 @@ +package certs + +import ( + "crypto/x509" + "log" +) + +// https://crt.sh/?id=3958242236 +const LetsEncryptRootCert = `-----BEGIN CERTIFICATE----- +MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC +ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL +wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D +LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK +4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5 +bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y +sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ +Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4 +FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc +SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql +PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND +TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1 +c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx ++tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB +ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu +b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E +U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu +MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC +5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW +9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG +WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O +he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC +Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5 +-----END CERTIFICATE-----` + +// GetRootCAs is a workaround for older versions of Android that do not trust +// Let's Encrypt's ISRG Root X1. This manually adds the ISRG root to the device's +// existing cert pool. +func GetRootCAs() *x509.CertPool { + rootCerts, err := x509.SystemCertPool() + if err != nil { + rootCerts = x509.NewCertPool() + } + if ok := rootCerts.AppendCertsFromPEM([]byte(LetsEncryptRootCert)); !ok { + log.Println("Error appending Let's Encrypt root certificate to cert poool") + return nil + } + return rootCerts +} |