17db2fa27Sjsingpackage verify 27db2fa27Sjsing 37db2fa27Sjsingimport ( 47db2fa27Sjsing "crypto/x509" 57db2fa27Sjsing "encoding/pem" 67db2fa27Sjsing "io/ioutil" 77db2fa27Sjsing "path/filepath" 87db2fa27Sjsing "testing" 97db2fa27Sjsing) 107db2fa27Sjsing 117db2fa27Sjsingfunc TestVerify(t *testing.T) { 127db2fa27Sjsing tests := []struct { 137db2fa27Sjsing id string 147db2fa27Sjsing wantChains int 157db2fa27Sjsing }{ 167db2fa27Sjsing {"1a", 1}, 177db2fa27Sjsing {"2a", 1}, 187db2fa27Sjsing {"2b", 0}, 19*0dfdae75Sbeck {"2c", 1}, 207db2fa27Sjsing {"3a", 1}, 217db2fa27Sjsing {"3b", 0}, 227db2fa27Sjsing {"3c", 0}, 237db2fa27Sjsing {"3d", 0}, 247db2fa27Sjsing {"3e", 1}, 257db2fa27Sjsing {"4a", 2}, 267db2fa27Sjsing {"4b", 1}, 277db2fa27Sjsing {"4c", 1}, 287db2fa27Sjsing {"4d", 1}, 297db2fa27Sjsing {"4e", 1}, 307db2fa27Sjsing {"4f", 2}, 317db2fa27Sjsing {"4g", 1}, 327db2fa27Sjsing {"4h", 1}, 337db2fa27Sjsing {"5a", 2}, 347db2fa27Sjsing {"5b", 1}, 357db2fa27Sjsing {"5c", 1}, 367db2fa27Sjsing {"5d", 1}, 377db2fa27Sjsing {"5e", 1}, 387db2fa27Sjsing {"5f", 1}, 397db2fa27Sjsing {"5g", 2}, 407db2fa27Sjsing {"5h", 1}, 417db2fa27Sjsing {"5i", 1}, 427db2fa27Sjsing {"6a", 1}, // Expired root. 437db2fa27Sjsing {"6b", 1}, // Expired root. 447db2fa27Sjsing {"7a", 1}, // Expired root. 457db2fa27Sjsing {"7b", 1}, // Expired root. 467db2fa27Sjsing {"8a", 0}, // Expired leaf. 477db2fa27Sjsing {"9a", 0}, // Expired intermediate. 487db2fa27Sjsing {"10a", 1}, // Cross signed with expired intermediate. 497db2fa27Sjsing {"10b", 1}, // Cross signed with expired intermediate. 507db2fa27Sjsing {"11a", 1}, // Cross signed with expired intermediate. 517db2fa27Sjsing {"11b", 1}, // Cross signed with expired intermediate. 527db2fa27Sjsing {"12a", 1}, // Cross signed with expired intermediate. 537db2fa27Sjsing {"13a", 1}, // Cross signed with expired root. 547db2fa27Sjsing } 557db2fa27Sjsing 567db2fa27Sjsing for _, test := range tests { 577db2fa27Sjsing t.Run(test.id, func(t *testing.T) { 587db2fa27Sjsing rootsPEM, err := ioutil.ReadFile(filepath.Join(test.id, "roots.pem")) 597db2fa27Sjsing if err != nil { 607db2fa27Sjsing t.Fatalf("Failed to read roots PEM: %v", err) 617db2fa27Sjsing } 627db2fa27Sjsing bundlePEM, err := ioutil.ReadFile(filepath.Join(test.id, "bundle.pem")) 637db2fa27Sjsing if err != nil { 647db2fa27Sjsing t.Fatalf("Failed to read bundle PEM: %v", err) 657db2fa27Sjsing } 667db2fa27Sjsing 677db2fa27Sjsing // Pull the leaf certificate off the top of the bundle. 687db2fa27Sjsing block, intermediatesPEM := pem.Decode(bundlePEM) 697db2fa27Sjsing if block == nil { 707db2fa27Sjsing t.Fatal("Failed to parse leaf from bundle") 717db2fa27Sjsing } 727db2fa27Sjsing cert, err := x509.ParseCertificate(block.Bytes) 737db2fa27Sjsing if err != nil { 747db2fa27Sjsing t.Fatalf("Failed to parse certificate: %v", err) 757db2fa27Sjsing } 767db2fa27Sjsing 777db2fa27Sjsing roots := x509.NewCertPool() 787db2fa27Sjsing if !roots.AppendCertsFromPEM(rootsPEM) { 797db2fa27Sjsing t.Fatal("Failed to parse root certificates") 807db2fa27Sjsing } 817db2fa27Sjsing intermediates := x509.NewCertPool() 827db2fa27Sjsing if len(intermediatesPEM) > 0 { 837db2fa27Sjsing if !intermediates.AppendCertsFromPEM(intermediatesPEM) { 847db2fa27Sjsing t.Fatal("Failed to parse intermediate certificates") 857db2fa27Sjsing } 867db2fa27Sjsing } 877db2fa27Sjsing 887db2fa27Sjsing opts := x509.VerifyOptions{ 897db2fa27Sjsing Roots: roots, 907db2fa27Sjsing Intermediates: intermediates, 917db2fa27Sjsing } 927db2fa27Sjsing 937db2fa27Sjsing chains, err := cert.Verify(opts) 947db2fa27Sjsing if err != nil { 957db2fa27Sjsing if test.wantChains > 0 { 967db2fa27Sjsing t.Errorf("Failed to verify certificate: %v", err) 977db2fa27Sjsing } 987db2fa27Sjsing return 997db2fa27Sjsing } 1007db2fa27Sjsing t.Logf("Found %d chains", len(chains)) 1017db2fa27Sjsing if got, want := len(chains), test.wantChains; got != want { 1027db2fa27Sjsing t.Errorf("Got %d chains, want %d", got, want) 1037db2fa27Sjsing } 1047db2fa27Sjsing for i, chain := range chains { 1057db2fa27Sjsing t.Logf("Chain %d\n", i) 1067db2fa27Sjsing for _, cert := range chain { 1077db2fa27Sjsing t.Logf(" %v\n", cert.Subject) 1087db2fa27Sjsing } 1097db2fa27Sjsing } 1107db2fa27Sjsing }) 1117db2fa27Sjsing } 1127db2fa27Sjsing} 113