From 5445e983ae453d78307ce332c3ece427e2f2cf32 Mon Sep 17 00:00:00 2001 From: mpl Date: Mon, 4 Apr 2016 23:49:50 +0200 Subject: [PATCH] pkg/httputil: fix checkSystemRoots for Go1.6 Something changed in x509 in Go1.6 so that when verifying an empty Cert, one now gets the errNotParsed (x509: missing ASN.1 contents; use ParseCertificate) error, instead of the SystemRootsError. Since we rely on getting the SystemRootsError to find out that we're on CoreOS, we now need to verify a non empty cert, when performing this check. Fixes issue #705 Change-Id: I40a4f9aa4ef49bbdd3b7b15b127f890e26f31de4 --- pkg/httputil/certs.go | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/pkg/httputil/certs.go b/pkg/httputil/certs.go index f300c7f9f..bd2ea553d 100644 --- a/pkg/httputil/certs.go +++ b/pkg/httputil/certs.go @@ -197,11 +197,51 @@ func checkSystemRoots() { return } + // Copied from https://golang.org/pkg/crypto/x509/#example_Certificate_Verify + // because, as of Go1.6, we need to verify against a real certificate, to check + // if the RootCAs are found. + const dummyCertPEM = ` +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIIE31FZVaPXTUwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl +cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMTI5MTMyNzQzWhcNMTQwNTI5MDAwMDAw +WjBpMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN +TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEYMBYGA1UEAwwPbWFp +bC5nb29nbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfRrObuSW5T7q +5CnSEqefEmtH4CCv6+5EckuriNr1CjfVvqzwfAhopXkLrq45EQm8vkmf7W96XJhC +7ZM0dYi1/qOCAU8wggFLMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAa +BgNVHREEEzARgg9tYWlsLmdvb2dsZS5jb20wCwYDVR0PBAQDAgeAMGgGCCsGAQUF +BwEBBFwwWjArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcy +LmNydDArBggrBgEFBQcwAYYfaHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20vb2Nz +cDAdBgNVHQ4EFgQUiJxtimAuTfwb+aUtBn5UYKreKvMwDAYDVR0TAQH/BAIwADAf +BgNVHSMEGDAWgBRK3QYWG7z2aLV29YG2u2IaulqBLzAXBgNVHSAEEDAOMAwGCisG +AQQB1nkCBQEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUuY29t +L0dJQUcyLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAH6RYHxHdcGpMpFE3oxDoFnP+ +gtuBCHan2yE2GRbJ2Cw8Lw0MmuKqHlf9RSeYfd3BXeKkj1qO6TVKwCh+0HdZk283 +TZZyzmEOyclm3UGFYe82P/iDFt+CeQ3NpmBg+GoaVCuWAARJN/KfglbLyyYygcQq +0SgeDh8dRKUiaW3HQSoYvTvdTuqzwK4CXsr3b5/dAOY8uMuG/IAR3FgwTbZ1dtoW +RvOTa8hYiU6A475WuZKyEHcwnGYe57u2I2KbMgcKjPniocj4QzgYsVAVKW3IwaOh +yE+vPxsiUkvQHdO2fojCkY8jg70jxM+gu59tPDNbw3Uh/2Ij310FgTHsnGQMyA== +-----END CERTIFICATE-----` + // Verify a dummy cert just to test whether the system roots // are available. This depends on knowing that the x509 // package returns this type of error first, before checking // the certificate's validity. - _, err := new(x509.Certificate).Verify(x509.VerifyOptions{}) + // The dummy cert should not be just an empty cert, because as of Go + // 1.6, one would get the + // "x509: missing ASN.1 contents; use ParseCertificate" error before + // hitting the SystemRootsError. + // Related: https://github.com/camlistore/camlistore/issues/705 + block, _ := pem.Decode([]byte(dummyCertPEM)) + if block == nil { + panic("failed to decode dummy certificate PEM") + } + dummyCert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + panic("failed to parse dummy certificate: " + err.Error()) + } + _, err = dummyCert.Verify(x509.VerifyOptions{}) _, isSysRootError := err.(x509.SystemRootsError) sysRootsGood = !isSysRootError }