var data C.CFDataRef = nil
err := C.FetchPEMRoots(&data)
- if err != -1 {
- defer C.CFRelease(C.CFTypeRef(data))
- buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
- roots.AppendCertsFromPEM(buf)
+ if err == -1 {
+ return
}
+ defer C.CFRelease(C.CFTypeRef(data))
+ buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
+ roots.AppendCertsFromPEM(buf)
systemRoots = roots
}
return "x509: certificate signed by unknown authority"
}
+// SystemRootsError results when we fail to load the system root certificates.
+type SystemRootsError struct {
+}
+
+func (e SystemRootsError) Error() string {
+ return "x509: failed to load system roots and no roots provided"
+}
+
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
// because other PKIX verification APIs have ended up needing many options.
type VerifyOptions struct {
if opts.Roots == nil {
opts.Roots = systemRootsPool()
+ if opts.Roots == nil {
+ return nil, SystemRootsError{}
+ }
}
err = c.isValid(leafCertificate, nil, &opts)
)
type verifyTest struct {
- leaf string
- intermediates []string
- roots []string
- currentTime int64
- dnsName string
- systemSkip bool
- keyUsages []ExtKeyUsage
+ leaf string
+ intermediates []string
+ roots []string
+ currentTime int64
+ dnsName string
+ systemSkip bool
+ keyUsages []ExtKeyUsage
+ testSystemRootsError bool
errorCallback func(*testing.T, int, error) bool
expectedChains [][]string
}
var verifyTests = []verifyTest{
+ {
+ leaf: googleLeaf,
+ intermediates: []string{thawteIntermediate},
+ currentTime: 1302726541,
+ dnsName: "www.google.com",
+ testSystemRootsError: true,
+ systemSkip: true,
+
+ // Without any roots specified we should get a system roots
+ // error.
+ errorCallback: expectSystemRootsError,
+ },
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
return true
}
+func expectSystemRootsError(t *testing.T, i int, err error) bool {
+ if _, ok := err.(SystemRootsError); !ok {
+ t.Errorf("#%d: error was not SystemRootsError: %s", i, err)
+ return false
+ }
+ return true
+}
+
func certificateFromPEM(pemBytes string) (*Certificate, error) {
block, _ := pem.Decode([]byte(pemBytes))
if block == nil {
return
}
+ var oldSystemRoots *CertPool
+ if test.testSystemRootsError {
+ oldSystemRoots = systemRootsPool()
+ systemRoots = nil
+ opts.Roots = nil
+ }
+
chains, err := leaf.Verify(opts)
+ if test.testSystemRootsError {
+ systemRoots = oldSystemRoots
+ }
+
if test.errorCallback == nil && err != nil {
t.Errorf("#%d: unexpected error: %s", i, err)
}