func makeCASigner(certBytes, keyBytes []byte, sigAlgo x509.SignatureAlgorithm, t *testing.T) signer.Signer { cert, err := helpers.ParseCertificatePEM(certBytes) if err != nil { t.Fatal(err) } key, err := helpers.ParsePrivateKeyPEM(keyBytes) if err != nil { t.Fatal(err) } defaultProfile := &config.SigningProfile{ Usage: []string{"cert sign"}, CA: true, Expiry: time.Hour, ExpiryString: "1h", } policy := &config.Signing{ Profiles: map[string]*config.SigningProfile{}, Default: defaultProfile, } s, err := local.NewSigner(key, cert, sigAlgo, policy) if err != nil { t.Fatal(err) } return s }
// signWithCSR creates a new root certificate from signing a X509.CertificateRequest // by a crypto.Signer. func signWithCSR(tpl *x509.CertificateRequest, priv crypto.Signer) (cert, csrPEM []byte, err error) { csrPEM, err = x509.CreateCertificateRequest(rand.Reader, tpl, priv) if err != nil { log.Errorf("failed to generate a CSR: %v", err) // The use of CertificateError was a matter of some // debate; it is the one edge case in which a new // error category specifically for CSRs might be // useful, but it was deemed that one edge case did // not a new category justify. err = cferr.Wrap(cferr.CertificateError, cferr.BadRequest, err) return } p := &pem.Block{ Type: "CERTIFICATE REQUEST", Bytes: csrPEM, } csrPEM = pem.EncodeToMemory(p) s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), nil) if err != nil { log.Errorf("failed to create signer: %v", err) return } s.SetPolicy(CAPolicy) signReq := signer.SignRequest{Request: string(csrPEM)} cert, err = s.Sign(signReq) return }
func parseSigner(root *config.Root) (signer.Signer, error) { privateKey := root.PrivateKey switch priv := privateKey.(type) { case *rsa.PrivateKey, *ecdsa.PrivateKey: s, err := local.NewSigner(priv, root.Certificate, signer.DefaultSigAlgo(priv), nil) if err != nil { return nil, err } s.SetPolicy(root.Config) if root.DB != nil { s.SetDB(root.DB) } return s, nil default: return nil, errors.New("unsupported private key type") } }
// New creates a new root certificate from the certificate request. func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { if req.CA != nil { if req.CA.Expiry != "" { CAPolicy.Default.ExpiryString = req.CA.Expiry CAPolicy.Default.Expiry, err = time.ParseDuration(req.CA.Expiry) } if req.CA.PathLength != 0 { signer.MaxPathLen = req.CA.PathLength } } g := &csr.Generator{Validator: validator} csrPEM, key, err = g.ProcessRequest(req) if err != nil { log.Errorf("failed to process request: %v", err) key = nil return } priv, err := helpers.ParsePrivateKeyPEM(key) if err != nil { log.Errorf("failed to parse private key: %v", err) return } s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), nil) if err != nil { log.Errorf("failed to create signer: %v", err) return } s.SetPolicy(CAPolicy) signReq := signer.SignRequest{Hosts: req.Hosts, Request: string(csrPEM)} cert, err = s.Sign(signReq) return }
// New returns a new PKCS #11 signer. func New(caCertFile string, policy *config.Signing, cfg *Config) (signer.Signer, error) { if cfg == nil { return nil, errors.New(errors.PrivateKeyError, errors.ReadFailed) } log.Debugf("Loading PKCS #11 module %s", cfg.Module) certData, err := ioutil.ReadFile(caCertFile) if err != nil { return nil, errors.New(errors.PrivateKeyError, errors.ReadFailed) } cert, err := helpers.ParseCertificatePEM(certData) if err != nil { return nil, err } priv, err := pkcs11key.New(cfg.Module, cfg.Token, cfg.PIN, cfg.Label) if err != nil { return nil, errors.New(errors.PrivateKeyError, errors.ReadFailed) } sigAlgo := signer.DefaultSigAlgo(priv) return local.NewSigner(priv, cert, sigAlgo, policy) }
func TestInitCA(t *testing.T) { var req *csr.CertificateRequest hostname := "cloudflare.com" for _, param := range validKeyParams { req = &csr.CertificateRequest{ Names: []csr.Name{ { C: "US", ST: "California", L: "San Francisco", O: "CloudFlare", OU: "Systems Engineering", }, }, CN: hostname, Hosts: []string{hostname, "www." + hostname}, KeyRequest: ¶m, } certBytes, _, keyBytes, err := New(req) if err != nil { t.Fatal("InitCA failed:", err) } key, err := helpers.ParsePrivateKeyPEM(keyBytes) if err != nil { t.Fatal("InitCA private key parsing failed:", err) } cert, err := helpers.ParseCertificatePEM(certBytes) if err != nil { t.Fatal("InitCA cert parsing failed:", err) } // Verify key parameters. switch req.KeyRequest.Algo() { case "rsa": if cert.PublicKey.(*rsa.PublicKey).N.BitLen() != param.Size() { t.Fatal("Cert key length mismatch.") } if key.(*rsa.PrivateKey).N.BitLen() != param.Size() { t.Fatal("Private key length mismatch.") } case "ecdsa": if cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().BitSize != param.Size() { t.Fatal("Cert key length mismatch.") } if key.(*ecdsa.PrivateKey).Curve.Params().BitSize != param.Size() { t.Fatal("Private key length mismatch.") } } // Start a signer var CAPolicy = &config.Signing{ Default: &config.SigningProfile{ Usage: []string{"cert sign", "crl sign"}, ExpiryString: "300s", Expiry: 300 * time.Second, CA: true, }, } s, err := local.NewSigner(key, cert, signer.DefaultSigAlgo(key), nil) if err != nil { t.Fatal("Signer Creation error:", err) } s.SetPolicy(CAPolicy) // Sign RSA and ECDSA customer CSRs. for _, csrFile := range csrFiles { csrBytes, err := ioutil.ReadFile(csrFile) if err != nil { t.Fatal("CSR loading error:", err) } req := signer.SignRequest{ Request: string(csrBytes), Hosts: signer.SplitHosts(hostname), Profile: "", Label: "", } bytes, err := s.Sign(req) if err != nil { t.Fatal(err) } customerCert, _ := helpers.ParseCertificatePEM(bytes) if customerCert.SignatureAlgorithm != s.SigAlgo() { t.Fatal("Signature Algorithm mismatch") } err = customerCert.CheckSignatureFrom(cert) if err != nil { t.Fatal("Signing CSR failed.", err) } } } }