1package verify 2 3import ( 4 "crypto/x509" 5 "encoding/pem" 6 "io/ioutil" 7 "path/filepath" 8 "testing" 9) 10 11func TestVerify(t *testing.T) { 12 tests := []struct { 13 id string 14 wantChains int 15 }{ 16 {"1a", 1}, 17 {"2a", 1}, 18 {"2b", 0}, 19 {"3a", 1}, 20 {"3b", 0}, 21 {"3c", 0}, 22 {"3d", 0}, 23 {"3e", 1}, 24 {"4a", 2}, 25 {"4b", 1}, 26 {"4c", 1}, 27 {"4d", 1}, 28 {"4e", 1}, 29 {"4f", 2}, 30 {"4g", 1}, 31 {"4h", 1}, 32 {"5a", 2}, 33 {"5b", 1}, 34 {"5c", 1}, 35 {"5d", 1}, 36 {"5e", 1}, 37 {"5f", 1}, 38 {"5g", 2}, 39 {"5h", 1}, 40 {"5i", 1}, 41 {"6a", 1}, // Expired root. 42 {"6b", 1}, // Expired root. 43 {"7a", 1}, // Expired root. 44 {"7b", 1}, // Expired root. 45 {"8a", 0}, // Expired leaf. 46 {"9a", 0}, // Expired intermediate. 47 {"10a", 1}, // Cross signed with expired intermediate. 48 {"10b", 1}, // Cross signed with expired intermediate. 49 {"11a", 1}, // Cross signed with expired intermediate. 50 {"11b", 1}, // Cross signed with expired intermediate. 51 {"12a", 1}, // Cross signed with expired intermediate. 52 {"13a", 1}, // Cross signed with expired root. 53 } 54 55 for _, test := range tests { 56 t.Run(test.id, func(t *testing.T) { 57 rootsPEM, err := ioutil.ReadFile(filepath.Join(test.id, "roots.pem")) 58 if err != nil { 59 t.Fatalf("Failed to read roots PEM: %v", err) 60 } 61 bundlePEM, err := ioutil.ReadFile(filepath.Join(test.id, "bundle.pem")) 62 if err != nil { 63 t.Fatalf("Failed to read bundle PEM: %v", err) 64 } 65 66 // Pull the leaf certificate off the top of the bundle. 67 block, intermediatesPEM := pem.Decode(bundlePEM) 68 if block == nil { 69 t.Fatal("Failed to parse leaf from bundle") 70 } 71 cert, err := x509.ParseCertificate(block.Bytes) 72 if err != nil { 73 t.Fatalf("Failed to parse certificate: %v", err) 74 } 75 76 roots := x509.NewCertPool() 77 if !roots.AppendCertsFromPEM(rootsPEM) { 78 t.Fatal("Failed to parse root certificates") 79 } 80 intermediates := x509.NewCertPool() 81 if len(intermediatesPEM) > 0 { 82 if !intermediates.AppendCertsFromPEM(intermediatesPEM) { 83 t.Fatal("Failed to parse intermediate certificates") 84 } 85 } 86 87 opts := x509.VerifyOptions{ 88 Roots: roots, 89 Intermediates: intermediates, 90 } 91 92 chains, err := cert.Verify(opts) 93 if err != nil { 94 if test.wantChains > 0 { 95 t.Errorf("Failed to verify certificate: %v", err) 96 } 97 return 98 } 99 t.Logf("Found %d chains", len(chains)) 100 if got, want := len(chains), test.wantChains; got != want { 101 t.Errorf("Got %d chains, want %d", got, want) 102 } 103 for i, chain := range chains { 104 t.Logf("Chain %d\n", i) 105 for _, cert := range chain { 106 t.Logf(" %v\n", cert.Subject) 107 } 108 } 109 }) 110 } 111} 112