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