func TestNewCertGeneratorHandlerFromSigner(t *testing.T) { var expiry = 1 * time.Minute var CAConfig = &config.Config{ Signing: &config.Signing{ Profiles: map[string]*config.SigningProfile{ "signature": { Usage: []string{"digital signature"}, Expiry: expiry, }, }, Default: &config.SigningProfile{ Usage: []string{"cert sign", "crl sign"}, ExpiryString: "43800h", Expiry: expiry, CAConstraint: config.CAConstraint{IsCA: true}, ClientProvidesSerialNumbers: true, }, }, } s, err := local.NewSignerFromFile(testCaFile, testCaKeyFile, CAConfig.Signing) if err != nil { t.Fatal(err) } h := NewCertGeneratorHandlerFromSigner(CSRValidate, s) _, ok := h.(http.Handler) if !ok { t.Fatal("A HTTP handler has not been returned") } }
// newHandler generates a new sign handler (or info handler) using the certificate // authority private key and certficate to sign certificates. func newHandler(t *testing.T, caFile, caKeyFile, op string) (http.Handler, error) { var expiry = 1 * time.Minute var CAConfig = &config.Config{ Signing: &config.Signing{ Profiles: map[string]*config.SigningProfile{ "signature": &config.SigningProfile{ Usage: []string{"digital signature"}, Expiry: expiry, }, }, Default: &config.SigningProfile{ Usage: []string{"cert sign", "crl sign"}, ExpiryString: "43800h", Expiry: expiry, CA: true, UseSerialSeq: true, }, }, } s, err := local.NewSignerFromFile(testCaFile, testCaKeyFile, CAConfig.Signing) if err != nil { t.Fatal(err) } if op == "sign" { return NewSignHandlerFromSigner(s) } else if op == "info" { return apiinfo.NewHandler(s) } t.Fatal("Bad op code") return nil, nil }
func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Duration, caCertFile, caKeyFile string, approveAllKubeletCSRsForGroup string) (*CertificateController, error) { // Send events to the apiserver eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")}) // Configure cfssl signer // TODO: support non-default policy and remote/pkcs11 signing policy := &config.Signing{ Default: config.DefaultConfig(), } ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy) if err != nil { return nil, err } cc := &CertificateController{ kubeClient: kubeClient, queue: workqueue.New(), signer: ca, approveAllKubeletCSRsForGroup: approveAllKubeletCSRsForGroup, } // Manage the addition/update of certificate requests cc.csrStore.Store, cc.csrController = framework.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { return cc.kubeClient.Certificates().CertificateSigningRequests().List(options) }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { return cc.kubeClient.Certificates().CertificateSigningRequests().Watch(options) }, }, &certificates.CertificateSigningRequest{}, syncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { csr := obj.(*certificates.CertificateSigningRequest) glog.V(4).Infof("Adding certificate request %s", csr.Name) cc.enqueueCertificateRequest(obj) }, UpdateFunc: func(old, new interface{}) { oldCSR := old.(*certificates.CertificateSigningRequest) glog.V(4).Infof("Updating certificate request %s", oldCSR.Name) cc.enqueueCertificateRequest(new) }, DeleteFunc: func(obj interface{}) { csr := obj.(*certificates.CertificateSigningRequest) glog.V(4).Infof("Deleting certificate request %s", csr.Name) cc.enqueueCertificateRequest(obj) }, }, ) cc.syncHandler = cc.maybeSignCertificate return cc, nil }
func TestChromeWarning(t *testing.T) { b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, "") s, err := local.NewSignerFromFile(sha1Intermediate, intermediateKey, nil) if err != nil { t.Fatal(err) } csrBytes, err := ioutil.ReadFile(leafCSR) if err != nil { t.Fatal(err) } signingRequest := signer.SignRequest{Request: string(csrBytes)} certBytes, err := s.Sign(signingRequest) if err != nil { t.Fatal(err) } // Bundle a leaf cert with default 1 year expiration bundle, err := b.BundleFromPEMorDER(certBytes, nil, Ubiquitous, "") if err != nil { t.Fatal("bundling failed: ", err) } // should be not ubiquitous due to SHA2 and ECDSA support issues in legacy platforms if bundle.Status.Code&errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { t.Fatal("Incorrect bundle status code. Bundle status code:", bundle.Status.Code) } fullChain := append(bundle.Chain, bundle.Root) sha1Msgs := ubiquity.SHA1DeprecationMessages(fullChain) // Since the new SHA-1 cert is expired after 2015, it definitely trigger Chrome's deprecation policies. if len(sha1Msgs) == 0 { t.Fatal("SHA1 Deprecation Message should not be empty") } // check SHA1 deprecation warnings var sha1MsgNotFound bool for _, sha1Msg := range sha1Msgs { foundMsg := false for _, message := range bundle.Status.Messages { if message == sha1Msg { foundMsg = true } } if !foundMsg { sha1MsgNotFound = true break } } if sha1MsgNotFound { t.Fatalf("Incorrect bundle status messages. Bundle status messages:%v, expected to contain: %v\n", bundle.Status.Messages, sha1Msgs) } }
// fileBackedSigner determines whether a file-backed local signer is supported. func fileBackedSigner(root *Root, policy *config.Signing) (signer.Signer, bool, error) { keyFile := root.Config["key-file"] certFile := root.Config["cert-file"] if keyFile == "" { return nil, false, nil } signer, err := local.NewSignerFromFile(certFile, keyFile, policy) return signer, true, err }
func newTestHandler(t *testing.T) (h http.Handler) { signer, err := local.NewSignerFromFile(testCaFile, testCaKeyFile, nil) if err != nil { t.Fatal(err) } h, err = NewHandler(signer) if err != nil { t.Fatal(err) } return }
func newTestMultiHandler(t *testing.T) (h http.Handler) { signer1, err := local.NewSignerFromFile(testCaFile, testCaKeyFile, nil) if err != nil { t.Fatal(err) } signer2, err := local.NewSignerFromFile(testCaFile2, testCaKeyFile2, nil) if err != nil { t.Fatal(err) } signers := map[string]signer.Signer{ "test1": signer1, "test2": signer2, } h, err = NewMultiHandler(signers, "test1") if err != nil { t.Fatalf("%v", err) } return }
// create a test intermediate cert in PEM func createInterCert(t *testing.T, csrFile string, policy *config.Signing, profileName string) (certPEM []byte) { s, err := local.NewSignerFromFile(testCAFile, testCAKeyFile, policy) if err != nil { t.Fatal(err) } csr, err := ioutil.ReadFile(csrFile) if err != nil { t.Fatal(err) } req := signer.SignRequest{ Hosts: []string{"cloudflare-inter.com"}, Request: string(csr), Profile: profileName, Label: "", } certPEM, err = s.Sign(req) if err != nil { t.Fatal(err) } return }
func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Duration, caCertFile, caKeyFile string, approver AutoApprover) (*CertificateController, error) { // Send events to the apiserver eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) // Configure cfssl signer // TODO: support non-default policy and remote/pkcs11 signing policy := &config.Signing{ Default: config.DefaultConfig(), } ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy) if err != nil { return nil, err } cc := &CertificateController{ kubeClient: kubeClient, queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "certificate"), signer: ca, approver: approver, } // Manage the addition/update of certificate requests cc.csrStore.Store, cc.csrController = cache.NewInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { return cc.kubeClient.Certificates().CertificateSigningRequests().List(options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { return cc.kubeClient.Certificates().CertificateSigningRequests().Watch(options) }, }, &certificates.CertificateSigningRequest{}, syncPeriod, cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { csr := obj.(*certificates.CertificateSigningRequest) glog.V(4).Infof("Adding certificate request %s", csr.Name) cc.enqueueCertificateRequest(obj) }, UpdateFunc: func(old, new interface{}) { oldCSR := old.(*certificates.CertificateSigningRequest) glog.V(4).Infof("Updating certificate request %s", oldCSR.Name) cc.enqueueCertificateRequest(new) }, DeleteFunc: func(obj interface{}) { csr, ok := obj.(*certificates.CertificateSigningRequest) if !ok { tombstone, ok := obj.(cache.DeletedFinalStateUnknown) if !ok { glog.V(2).Infof("Couldn't get object from tombstone %#v", obj) return } csr, ok = tombstone.Obj.(*certificates.CertificateSigningRequest) if !ok { glog.V(2).Infof("Tombstone contained object that is not a CSR: %#v", obj) return } } glog.V(4).Infof("Deleting certificate request %s", csr.Name) cc.enqueueCertificateRequest(obj) }, }, ) cc.syncHandler = cc.maybeSignCertificate return cc, nil }
func TestSignerDBPersistence(t *testing.T) { conf, err := config.LoadConfig([]byte(validLocalConfigLongerExpiry)) if err != nil { t.Fatal(err) } var s *local.Signer s, err = local.NewSignerFromFile(testCaFile, testCaKeyFile, conf.Signing) if err != nil { t.Fatal(err) } db := testdb.SQLiteDB("../../certdb/testdb/certstore_development.db") if err != nil { t.Fatal(err) } dbAccessor = sql.NewAccessor(db) s.SetDBAccessor(dbAccessor) var handler *api.HTTPHandler handler, err = NewHandlerFromSigner(signer.Signer(s)) if err != nil { t.Fatal(err) } ts := httptest.NewServer(handler) defer ts.Close() var csrPEM, body []byte csrPEM, err = ioutil.ReadFile(testCSRFile) if err != nil { t.Fatal(err) } blob, err := json.Marshal(&map[string]string{"certificate_request": string(csrPEM)}) if err != nil { t.Fatal(err) } var resp *http.Response resp, err = http.Post(ts.URL, "application/json", bytes.NewReader(blob)) if err != nil { t.Fatal(err) } body, err = ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } if resp.StatusCode != http.StatusOK { t.Fatal(resp.Status, string(body)) } message := new(api.Response) err = json.Unmarshal(body, message) if err != nil { t.Fatalf("failed to read response body: %v", err) } if !message.Success { t.Fatal("API operation failed") } crs, err := dbAccessor.GetUnexpiredCertificates() if err != nil { t.Fatal("Failed to get unexpired certificates") } if len(crs) != 1 { t.Fatal("Expected 1 unexpired certificate in the database after signing 1: len(crs)=", len(crs)) } }
// Load reads the key and certificate from the files specified in the // CA. func Load(lca *CA, profiles *config.Signing) (err error) { lca.s, err = local.NewSignerFromFile(lca.CertFile, lca.KeyFile, profiles) return err }