blob: b1139bbf9c638ca4fcca807d5aa30edca6804d35 [file] [log] [blame]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package x509
import (
"encoding/json"
"os"
"path/filepath"
"slices"
"testing"
)
var nistTestPolicies = map[string]OID{
"anyPolicy": anyPolicyOID,
"NIST-test-policy-1": mustNewOIDFromInts([]uint64{2, 16, 840, 1, 101, 3, 2, 1, 48, 1}),
"NIST-test-policy-2": mustNewOIDFromInts([]uint64{2, 16, 840, 1, 101, 3, 2, 1, 48, 2}),
"NIST-test-policy-3": mustNewOIDFromInts([]uint64{2, 16, 840, 1, 101, 3, 2, 1, 48, 3}),
"NIST-test-policy-6": mustNewOIDFromInts([]uint64{2, 16, 840, 1, 101, 3, 2, 1, 48, 6}),
}
func TestNISTPKITSPolicy(t *testing.T) {
// This test runs a subset of the NIST PKI path validation test suite that
// focuses of policy validation, rather than the entire suite. Since the
// suite assumes you are only validating the path, rather than building
// _and_ validating the path, we take the path as given and run
// policiesValid on it.
certDir := "testdata/nist-pkits/certs"
var testcases []struct {
Name string
CertPath []string
InitialPolicySet []string
InitialPolicyMappingInhibit bool
InitialExplicitPolicy bool
InitialAnyPolicyInhibit bool
ShouldValidate bool
Skipped bool
}
b, err := os.ReadFile("testdata/nist-pkits/vectors.json")
if err != nil {
t.Fatal(err)
}
if err := json.Unmarshal(b, &testcases); err != nil {
t.Fatal(err)
}
policyTests := map[string]bool{
"4.8.1 All Certificates Same Policy Test1 (Subpart 1)": true,
"4.8.1 All Certificates Same Policy Test1 (Subpart 2)": true,
"4.8.1 All Certificates Same Policy Test1 (Subpart 3)": true,
"4.8.1 All Certificates Same Policy Test1 (Subpart 4)": true,
"4.8.2 All Certificates No Policies Test2 (Subpart 1)": true,
"4.8.2 All Certificates No Policies Test2 (Subpart 2)": true,
"4.8.3 Different Policies Test3 (Subpart 1)": true,
"4.8.3 Different Policies Test3 (Subpart 2)": true,
"4.8.3 Different Policies Test3 (Subpart 3)": true,
"4.8.4 Different Policies Test4": true,
"4.8.5 Different Policies Test5": true,
"4.8.6 Overlapping Policies Test6 (Subpart 1)": true,
"4.8.6 Overlapping Policies Test6 (Subpart 2)": true,
"4.8.6 Overlapping Policies Test6 (Subpart 3)": true,
"4.8.7 Different Policies Test7": true,
"4.8.8 Different Policies Test8": true,
"4.8.9 Different Policies Test9": true,
"4.8.10 All Certificates Same Policies Test10 (Subpart 1)": true,
"4.8.10 All Certificates Same Policies Test10 (Subpart 2)": true,
"4.8.10 All Certificates Same Policies Test10 (Subpart 3)": true,
"4.8.11 All Certificates AnyPolicy Test11 (Subpart 1)": true,
"4.8.11 All Certificates AnyPolicy Test11 (Subpart 2)": true,
"4.8.12 Different Policies Test12": true,
"4.8.13 All Certificates Same Policies Test13 (Subpart 1)": true,
"4.8.13 All Certificates Same Policies Test13 (Subpart 2)": true,
"4.8.13 All Certificates Same Policies Test13 (Subpart 3)": true,
"4.8.14 AnyPolicy Test14 (Subpart 1)": true,
"4.8.14 AnyPolicy Test14 (Subpart 2)": true,
"4.8.15 User Notice Qualifier Test15": true,
"4.8.16 User Notice Qualifier Test16": true,
"4.8.17 User Notice Qualifier Test17": true,
"4.8.18 User Notice Qualifier Test18 (Subpart 1)": true,
"4.8.18 User Notice Qualifier Test18 (Subpart 2)": true,
"4.8.19 User Notice Qualifier Test19": true,
"4.8.20 CPS Pointer Qualifier Test20": true,
"4.9.1 Valid RequireExplicitPolicy Test1": true,
"4.9.2 Valid RequireExplicitPolicy Test2": true,
"4.9.3 Invalid RequireExplicitPolicy Test3": true,
"4.9.4 Valid RequireExplicitPolicy Test4": true,
"4.9.5 Invalid RequireExplicitPolicy Test5": true,
"4.9.6 Valid Self-Issued requireExplicitPolicy Test6": true,
"4.9.7 Invalid Self-Issued requireExplicitPolicy Test7": true,
"4.9.8 Invalid Self-Issued requireExplicitPolicy Test8": true,
"4.10.1.1 Valid Policy Mapping Test1 (Subpart 1)": true,
"4.10.1.2 Valid Policy Mapping Test1 (Subpart 2)": true,
"4.10.1.3 Valid Policy Mapping Test1 (Subpart 3)": true,
"4.10.2 Invalid Policy Mapping Test2 (Subpart 1)": true,
"4.10.2 Invalid Policy Mapping Test2 (Subpart 2)": true,
"4.10.3 Valid Policy Mapping Test3 (Subpart 1)": true,
"4.10.3 Valid Policy Mapping Test3 (Subpart 2)": true,
"4.10.4 Invalid Policy Mapping Test4": true,
"4.10.5 Valid Policy Mapping Test5 (Subpart 1)": true,
"4.10.5 Valid Policy Mapping Test5 (Subpart 2)": true,
"4.10.6 Valid Policy Mapping Test6 (Subpart 1)": true,
"4.10.6 Valid Policy Mapping Test6 (Subpart 2)": true,
"4.10.7 Invalid Mapping From anyPolicy Test7": true,
"4.10.8 Invalid Mapping To anyPolicy Test8": true,
"4.10.9 Valid Policy Mapping Test9": true,
"4.10.10 Invalid Policy Mapping Test10": true,
"4.10.11 Valid Policy Mapping Test11": true,
"4.10.12 Valid Policy Mapping Test12 (Subpart 1)": true,
"4.10.12 Valid Policy Mapping Test12 (Subpart 2)": true,
"4.10.13 Valid Policy Mapping Test13 (Subpart 1)": true,
"4.10.13 Valid Policy Mapping Test13 (Subpart 2)": true,
"4.10.13 Valid Policy Mapping Test13 (Subpart 3)": true,
"4.10.14 Valid Policy Mapping Test14": true,
"4.11.1 Invalid inhibitPolicyMapping Test1": true,
"4.11.2 Valid inhibitPolicyMapping Test2": true,
"4.11.3 Invalid inhibitPolicyMapping Test3": true,
"4.11.4 Valid inhibitPolicyMapping Test4": true,
"4.11.5 Invalid inhibitPolicyMapping Test5": true,
"4.11.6 Invalid inhibitPolicyMapping Test6": true,
"4.11.7 Valid Self-Issued inhibitPolicyMapping Test7": true,
"4.11.8 Invalid Self-Issued inhibitPolicyMapping Test8": true,
"4.11.9 Invalid Self-Issued inhibitPolicyMapping Test9": true,
"4.11.10 Invalid Self-Issued inhibitPolicyMapping Test10": true,
"4.11.11 Invalid Self-Issued inhibitPolicyMapping Test11": true,
"4.12.1 Invalid inhibitAnyPolicy Test1": true,
"4.12.2 Valid inhibitAnyPolicy Test2": true,
"4.12.3 inhibitAnyPolicy Test3 (Subpart 1)": true,
"4.12.3 inhibitAnyPolicy Test3 (Subpart 2)": true,
"4.12.4 Invalid inhibitAnyPolicy Test4": true,
"4.12.5 Invalid inhibitAnyPolicy Test5": true,
"4.12.6 Invalid inhibitAnyPolicy Test6": true,
"4.12.7 Valid Self-Issued inhibitAnyPolicy Test7": true,
"4.12.8 Invalid Self-Issued inhibitAnyPolicy Test8": true,
"4.12.9 Valid Self-Issued inhibitAnyPolicy Test9": true,
"4.12.10 Invalid Self-Issued inhibitAnyPolicy Test10": true,
}
for _, tc := range testcases {
if !policyTests[tc.Name] {
continue
}
t.Run(tc.Name, func(t *testing.T) {
var chain []*Certificate
for _, c := range tc.CertPath {
certDER, err := os.ReadFile(filepath.Join(certDir, c))
if err != nil {
t.Fatal(err)
}
cert, err := ParseCertificate(certDER)
if err != nil {
t.Fatal(err)
}
chain = append(chain, cert)
}
slices.Reverse(chain)
var initialPolicies []OID
for _, pstr := range tc.InitialPolicySet {
policy, ok := nistTestPolicies[pstr]
if !ok {
t.Fatalf("unknown test policy: %s", pstr)
}
initialPolicies = append(initialPolicies, policy)
}
valid := policiesValid(chain, VerifyOptions{
CertificatePolicies: initialPolicies,
inhibitPolicyMapping: tc.InitialPolicyMappingInhibit,
requireExplicitPolicy: tc.InitialExplicitPolicy,
inhibitAnyPolicy: tc.InitialAnyPolicyInhibit,
})
if !valid {
if !tc.ShouldValidate {
return
}
t.Fatalf("Failed to validate: %s", err)
}
if !tc.ShouldValidate {
t.Fatal("Expected path validation to fail")
}
})
}
}