Home | History | Annotate | Download | only in x509
      1 // Copyright 2013 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package x509
      6 
      7 import (
      8 	"runtime"
      9 	"testing"
     10 	"time"
     11 )
     12 
     13 func TestSystemRoots(t *testing.T) {
     14 	switch runtime.GOARCH {
     15 	case "arm", "arm64":
     16 		t.Skipf("skipping on %s/%s, no system root", runtime.GOOS, runtime.GOARCH)
     17 	}
     18 
     19 	t0 := time.Now()
     20 	sysRoots := systemRootsPool() // actual system roots
     21 	sysRootsDuration := time.Since(t0)
     22 
     23 	t1 := time.Now()
     24 	execRoots, err := execSecurityRoots() // non-cgo roots
     25 	execSysRootsDuration := time.Since(t1)
     26 
     27 	if err != nil {
     28 		t.Fatalf("failed to read system roots: %v", err)
     29 	}
     30 
     31 	t.Logf("    cgo sys roots: %v", sysRootsDuration)
     32 	t.Logf("non-cgo sys roots: %v", execSysRootsDuration)
     33 
     34 	for _, tt := range []*CertPool{sysRoots, execRoots} {
     35 		if tt == nil {
     36 			t.Fatal("no system roots")
     37 		}
     38 		// On Mavericks, there are 212 bundled certs, at least
     39 		// there was at one point in time on one machine.
     40 		// (Maybe it was a corp laptop with extra certs?)
     41 		// Other OS X users report
     42 		// 135, 142, 145...  Let's try requiring at least 100,
     43 		// since this is just a sanity check.
     44 		t.Logf("got %d roots", len(tt.certs))
     45 		if want, have := 100, len(tt.certs); have < want {
     46 			t.Fatalf("want at least %d system roots, have %d", want, have)
     47 		}
     48 	}
     49 
     50 	// Check that the two cert pools are roughly the same;
     51 	// |AB| > max(|A|, |B|) / 2 should be a reasonably robust check.
     52 
     53 	isect := make(map[string]bool, len(sysRoots.certs))
     54 	for _, c := range sysRoots.certs {
     55 		isect[string(c.Raw)] = true
     56 	}
     57 
     58 	have := 0
     59 	for _, c := range execRoots.certs {
     60 		if isect[string(c.Raw)] {
     61 			have++
     62 		}
     63 	}
     64 
     65 	var want int
     66 	if nsys, nexec := len(sysRoots.certs), len(execRoots.certs); nsys > nexec {
     67 		want = nsys / 2
     68 	} else {
     69 		want = nexec / 2
     70 	}
     71 
     72 	if have < want {
     73 		t.Errorf("insufficient overlap between cgo and non-cgo roots; want at least %d, have %d", want, have)
     74 	}
     75 }
     76