xref: /openbsd-src/regress/lib/libcrypto/certs/verify_test.go (revision 0dfdae75f5014d4c34d6d2bc6f597d42ac6440d1)
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