Skip to content

Commit 9660231

Browse files
kirbyquerbyhfwang
authored andcommitted
Use a custom peer certificate check that verifies that the certificate is signed by the server CA since go 10.11 doesn't accept our non-standard CNs when verifying. (GoogleCloudPlatform#196)
Thankfully, we retrieve the certificates from the Cloud SQL API and that connection is encrypted and verified, so customers are not risking a MITM attack with this.
1 parent 39c05c5 commit 9660231

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

Diff for: proxy/proxy/client.go

+35
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,45 @@ func (c *Client) refreshCfg(instance string) (addr string, cfg *tls.Config, err
194194
ServerName: name,
195195
Certificates: []tls.Certificate{mycert},
196196
RootCAs: certs,
197+
// We need to set InsecureSkipVerify to true due to
198+
// https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/194
199+
// https://tip.golang.org/doc/go1.11#crypto/x509
200+
//
201+
// Since we have a secure channel to the Cloud SQL API which we use to retrieve the
202+
// certificates, we instead need to implement our own VerifyPeerCertificate function
203+
// that will verify that the certificate is OK.
204+
InsecureSkipVerify: true,
205+
VerifyPeerCertificate: genVerifyPeerCertificateFunc(name, certs),
197206
}
198207
return fmt.Sprintf("%s:%d", addr, c.Port), cfg, nil
199208
}
200209

210+
// genVerifyPeerCertificateFunc creates a VerifyPeerCertificate func that verifies that the peer
211+
// certificate is in the cert pool. We need to define our own because of our sketchy non-standard
212+
// CNs.
213+
func genVerifyPeerCertificateFunc(instanceName string, pool *x509.CertPool) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
214+
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
215+
if len(rawCerts) == 0 {
216+
return fmt.Errorf("no certificate to verify")
217+
}
218+
219+
cert, err := x509.ParseCertificate(rawCerts[0])
220+
if err != nil {
221+
return fmt.Errorf("x509.ParseCertificate(rawCerts[0]) returned error: %v", err)
222+
}
223+
224+
opts := x509.VerifyOptions{Roots: pool}
225+
if _, err = cert.Verify(opts); err != nil {
226+
return err
227+
}
228+
229+
if cert.Subject.CommonName != instanceName {
230+
return fmt.Errorf("certificate had CN %q, expected %q", cert.Subject.CommonName, instanceName)
231+
}
232+
return nil
233+
}
234+
}
235+
201236
func (c *Client) cachedCfg(instance string) (string, *tls.Config) {
202237
c.cfgL.RLock()
203238
ret, ok := c.cfgCache[instance]

0 commit comments

Comments
 (0)