func TestAddPoliciesWithQualifiers(t *testing.T) { var cert x509.Certificate addPolicies(&cert, []config.CertificatePolicy{ { ID: config.OID([]int{1, 2, 3, 4}), Qualifiers: []config.CertificatePolicyQualifier{ { Type: "id-qt-cps", Value: "http://example.com/cps", }, { Type: "id-qt-unotice", Value: "Do What Thou Wilt", }, }, }, }) if len(cert.ExtraExtensions) != 1 { t.Fatal("No extension added") } ext := cert.ExtraExtensions[0] if !reflect.DeepEqual(ext.Id, asn1.ObjectIdentifier{2, 5, 29, 32}) { t.Fatal(fmt.Sprintf("Wrong OID for policy qualifier %v", ext.Id)) } if ext.Critical { t.Fatal("Policy qualifier marked critical") } expectedBytes, _ := hex.DecodeString("304e304c06032a03043045302206082b060105050702011616687474703a2f2f6578616d706c652e636f6d2f637073301f06082b0601050507020230130c11446f20576861742054686f752057696c74") if !bytes.Equal(ext.Value, expectedBytes) { t.Fatal(fmt.Sprintf("Value didn't match expected bytes: %s vs %s", hex.EncodeToString(ext.Value), hex.EncodeToString(expectedBytes))) } }
func TestAddPolicies(t *testing.T) { var cert x509.Certificate addPolicies(&cert, []config.CertificatePolicy{ { ID: config.OID([]int{1, 2, 3, 4}), }, }) if len(cert.ExtraExtensions) != 1 { t.Fatal("No extension added") } ext := cert.ExtraExtensions[0] if !reflect.DeepEqual(ext.Id, asn1.ObjectIdentifier{2, 5, 29, 32}) { t.Fatal(fmt.Sprintf("Wrong OID for policy qualifier %v", ext.Id)) } if ext.Critical { t.Fatal("Policy qualifier marked critical") } expectedBytes, _ := hex.DecodeString("3007300506032a0304") if !bytes.Equal(ext.Value, expectedBytes) { t.Fatal(fmt.Sprintf("Value didn't match expected bytes: got %s, expected %s", hex.EncodeToString(ext.Value), hex.EncodeToString(expectedBytes))) } }
func TestExtensionSign(t *testing.T) { csrPEM, err := ioutil.ReadFile(testCSR) if err != nil { t.Fatalf("%v", err) } s := newCustomSigner(t, testECDSACaFile, testECDSACaKeyFile) // By default, no extensions should be allowed request := signer.SignRequest{ Request: string(csrPEM), Extensions: []signer.Extension{ signer.Extension{ID: config.OID(asn1.ObjectIdentifier{1, 2, 3, 4})}, }, } _, err = s.Sign(request) if err == nil { t.Fatalf("expected a policy error") } // Whitelist a specific extension. The extension with OID 1.2.3.4 should be // allowed through, but the one with OID 1.2.3.5 should not. s.policy = &config.Signing{ Default: &config.SigningProfile{ Usage: []string{"cert sign", "crl sign"}, ExpiryString: "1h", Expiry: 1 * time.Hour, CA: true, ExtensionWhitelist: map[string]bool{"1.2.3.4": true}, }, } // Test that a forbidden extension triggers a sign error request = signer.SignRequest{ Request: string(csrPEM), Extensions: []signer.Extension{ signer.Extension{ID: config.OID(asn1.ObjectIdentifier{1, 2, 3, 5})}, }, } _, err = s.Sign(request) if err == nil { t.Fatalf("expected a policy error") } extValue := []byte{0x05, 0x00} extValueHex := hex.EncodeToString(extValue) // Test that an allowed extension makes it through request = signer.SignRequest{ Request: string(csrPEM), Extensions: []signer.Extension{ signer.Extension{ ID: config.OID(asn1.ObjectIdentifier{1, 2, 3, 4}), Critical: false, Value: extValueHex, }, }, } certPEM, err := s.Sign(request) if err != nil { t.Fatalf("%v", err) } cert, err := helpers.ParseCertificatePEM(certPEM) if err != nil { t.Fatalf("%v", err) } foundAllowed := false for _, ext := range cert.Extensions { if ext.Id.String() == "1.2.3.4" { foundAllowed = true if ext.Critical { t.Fatalf("Extensions should not be marked critical") } if !bytes.Equal(extValue, ext.Value) { t.Fatalf("Extension has wrong value: %s != %s", hex.EncodeToString(ext.Value), extValueHex) } } } if !foundAllowed { t.Fatalf("Custom extension not included in the certificate") } }
) // OID and fixed value for the "must staple" variant of the TLS Feature // extension: // // Features ::= SEQUENCE OF INTEGER [RFC7633] // enum { ... status_request(5) ...} ExtensionType; [RFC6066] // // DER Encoding: // 30 03 - SEQUENCE (3 octets) // |-- 02 01 - INTEGER (1 octet) // | |-- 05 - 5 var ( mustStapleFeatureValue = []byte{0x30, 0x03, 0x02, 0x01, 0x05} mustStapleExtension = signer.Extension{ ID: cfsslConfig.OID(oidTLSFeature), Critical: false, Value: hex.EncodeToString(mustStapleFeatureValue), } ) // Metrics for CA statistics const ( // Increments when CA observes an HSM or signing error metricSigningError = "CA.SigningError" metricHSMError = metricSigningError + ".HSMError" // Increments when CA handles a CSR requesting a "basic" extension: // authorityInfoAccess, authorityKeyIdentifier, extKeyUsage, keyUsage, // basicConstraints, certificatePolicies, crlDistributionPoints, // subjectAlternativeName, subjectKeyIdentifier,
func setup(t *testing.T) *testCtx { fc := clock.NewFake() fc.Add(1 * time.Hour) pa, err := policy.New(nil) test.AssertNotError(t, err, "Couldn't create PA") err = pa.SetHostnamePolicyFile("../test/hostname-policy.json") test.AssertNotError(t, err, "Couldn't set hostname policy") // Create a CA caConfig := cmd.CAConfig{ RSAProfile: rsaProfileName, ECDSAProfile: ecdsaProfileName, SerialPrefix: 17, Expiry: "8760h", LifespanOCSP: cmd.ConfigDuration{Duration: 45 * time.Minute}, MaxNames: 2, DoNotForceCN: true, CFSSL: cfsslConfig.Config{ Signing: &cfsslConfig.Signing{ Profiles: map[string]*cfsslConfig.SigningProfile{ rsaProfileName: { Usage: []string{"digital signature", "key encipherment", "server auth"}, CA: false, IssuerURL: []string{"http://not-example.com/issuer-url"}, OCSP: "http://not-example.com/ocsp", CRL: "http://not-example.com/crl", Policies: []cfsslConfig.CertificatePolicy{ { ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}), }, }, ExpiryString: "8760h", Backdate: time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKeyAlgorithm: true, PublicKey: true, SignatureAlgorithm: true, }, ClientProvidesSerialNumbers: true, AllowedExtensions: []cfsslConfig.OID{ cfsslConfig.OID(oidTLSFeature), }, }, ecdsaProfileName: { Usage: []string{"digital signature", "server auth"}, CA: false, IssuerURL: []string{"http://not-example.com/issuer-url"}, OCSP: "http://not-example.com/ocsp", CRL: "http://not-example.com/crl", Policies: []cfsslConfig.CertificatePolicy{ { ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}), }, }, ExpiryString: "8760h", Backdate: time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKeyAlgorithm: true, PublicKey: true, SignatureAlgorithm: true, }, ClientProvidesSerialNumbers: true, }, }, Default: &cfsslConfig.SigningProfile{ ExpiryString: "8760h", }, }, }, } stats := mocks.NewStatter() issuers := []Issuer{{caKey, caCert}} keyPolicy := core.KeyPolicy{ AllowRSA: true, AllowECDSANISTP256: true, AllowECDSANISTP384: true, } return &testCtx{ caConfig, pa, issuers, keyPolicy, fc, stats, } }