func revokeMain(args []string, c cli.Config) (err error) { if len(args) > 0 { return errors.New("argument is provided but not defined; please refer to the usage by flag -h") } if len(c.Serial) == 0 { return errors.New("serial number is required but not provided") } if c.DBConfigFile == "" { return errors.New("need DB config file (provide with -db-config)") } var db *sql.DB db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return err } var reasonCode int reasonCode, err = ocsp.ReasonStringToCode(c.Reason) if err != nil { log.Error("Invalid reason code: ", err) return } err = certdb.RevokeCertificate(db, c.Serial, reasonCode) return }
// LoadRoot parses a config structure into a Root structure func LoadRoot(cfg map[string]string) (*Root, error) { var root Root var err error spec, ok := cfg["private"] if !ok { return nil, ErrMissingPrivateKey } certPath, ok := cfg["certificate"] if !ok { return nil, ErrMissingCertificatePath } configPath, ok := cfg["config"] if !ok { return nil, ErrMissingConfigPath } root.PrivateKey, err = parsePrivateKeySpec(spec, cfg) if err != nil { return nil, err } in, err := ioutil.ReadFile(certPath) if err != nil { return nil, err } root.Certificate, err = helpers.ParseCertificatePEM(in) if err != nil { return nil, err } conf, err := config.LoadFile(configPath) if err != nil { return nil, err } root.Config = conf.Signing nets := cfg["nets"] if nets != "" { root.ACL, err = parseACL(nets) if err != nil { return nil, err } } dbConfig := cfg["dbconfig"] if dbConfig != "" { db, err := certdb.DBFromConfig(dbConfig) if err != nil { return nil, err } root.DB = db } return &root, nil }
// SignerFromConfig takes the Config and creates the appropriate // signer.Signer object func SignerFromConfig(c cli.Config) (s signer.Signer, err error) { var db *sql.DB if c.DBConfigFile != "" { db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return nil, err } } return SignerFromConfigAndDB(c, db) }
// serverMain is the command line entry point to the API server. It sets up a // new HTTP server to handle sign, bundle, and validate requests. func serverMain(args []string, c cli.Config) error { conf = c // serve doesn't support arguments. if len(args) > 0 { return errors.New("argument is provided but not defined; please refer to the usage by flag -h") } bundler.IntermediateStash = conf.IntDir var err error if err = ubiquity.LoadPlatforms(conf.Metadata); err != nil { return err } if c.DBConfigFile != "" { db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return err } } log.Info("Initializing signer") if s, err = sign.SignerFromConfigAndDB(c, db); err != nil { log.Warningf("couldn't initialize signer: %v", err) } if ocspSigner, err = ocspsign.SignerFromConfig(c); err != nil { log.Warningf("couldn't initialize ocsp signer: %v", err) } registerHandlers() addr := net.JoinHostPort(conf.Address, strconv.Itoa(conf.Port)) if conf.TLSCertFile == "" || conf.TLSKeyFile == "" { log.Info("Now listening on ", addr) return http.ListenAndServe(addr, nil) } log.Info("Now listening on https://", addr) return http.ListenAndServeTLS(addr, conf.TLSCertFile, conf.TLSKeyFile, nil) }
// ocspdumpMain is the main CLI of OCSP dump functionality. func ocspdumpMain(args []string, c cli.Config) (err error) { if c.DBConfigFile == "" { log.Error("need DB config file (provide with -db-config)") return } var db *sql.DB db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return err } var records []*certdb.OCSPRecord records, err = certdb.GetUnexpiredOCSPs(db) if err != nil { return err } for _, certRecord := range records { fmt.Printf("%s\n", base64.StdEncoding.EncodeToString([]byte(certRecord.Body))) } return nil }
// serverMain is the command line entry point to the API server. It sets up a // new HTTP server to handle sign, bundle, and validate requests. func serverMain(args []string, c cli.Config) error { conf = c // serve doesn't support arguments. if len(args) > 0 { return errors.New("argument is provided but not defined; please refer to the usage by flag -h") } bundler.IntermediateStash = conf.IntDir var err error if err = ubiquity.LoadPlatforms(conf.Metadata); err != nil { return err } if c.DBConfigFile != "" { db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return err } } log.Info("Initializing signer") if s, err = sign.SignerFromConfigAndDB(c, db); err != nil { log.Warningf("couldn't initialize signer: %v", err) } if ocspSigner, err = ocspsign.SignerFromConfig(c); err != nil { log.Warningf("couldn't initialize ocsp signer: %v", err) } registerHandlers(conf.Stats) addr := net.JoinHostPort(conf.Address, strconv.Itoa(conf.Port)) if conf.TLSCertFile == "" || conf.TLSKeyFile == "" { log.Info("Now listening on ", addr) return http.ListenAndServe(addr, nil) } log.Info("Now listening on https://", addr) if !conf.RequireClientTLSCertificates { fmt.Printf("Client certificates are not required.\n") return http.ListenAndServeTLS(addr, conf.TLSCertFile, conf.TLSKeyFile, nil) } else { server := &http.Server{ Addr: addr, TLSConfig: &tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, }, } fmt.Printf("Client certificates are required.\n") if conf.TrustAnchorFile != "" { fmt.Printf(" tls trust anchors: %s\n", conf.TrustAnchorFile) pem, err := ioutil.ReadFile(conf.TrustAnchorFile) if err != nil { return err } pool := x509.NewCertPool() if !pool.AppendCertsFromPEM(pem) { return fmt.Errorf("Failed to load: %s\n", conf.TrustAnchorFile) } server.TLSConfig.ClientCAs = pool } else { fmt.Printf(" tls trust anchors: <from system>\n") } return server.ListenAndServeTLS(conf.TLSCertFile, conf.TLSKeyFile) } }
// ocsprefreshMain is the main CLI of OCSP refresh functionality. func ocsprefreshMain(args []string, c cli.Config) (err error) { if c.DBConfigFile == "" { log.Error("need DB config file (provide with -db-config)") return } if c.ResponderFile == "" { log.Error("need responder certificate (provide with -responder)") return } if c.ResponderKeyFile == "" { log.Error("need responder key (provide with -responder-key)") return } if c.CAFile == "" { log.Error("need CA certificate (provide with -ca)") return } s, err := SignerFromConfig(c) if err != nil { log.Critical("Unable to create OCSP signer: ", err) return err } var db *sql.DB db, err = certdb.DBFromConfig(c.DBConfigFile) if err != nil { return err } var certs []*certdb.CertificateRecord certs, err = certdb.GetUnexpiredCertificates(db) if err != nil { return err } // Set an expiry timestamp for all certificates refreshed in this batch ocspExpiry := time.Now().Add(c.Interval) for _, certRecord := range certs { cert, err := helpers.ParseCertificatePEM([]byte(certRecord.PEM)) if err != nil { log.Critical("Unable to parse certificate: ", err) return err } req := ocsp.SignRequest{ Certificate: cert, Status: certRecord.Status, } if certRecord.Status == "revoked" { req.Reason = int(certRecord.Reason) req.RevokedAt = certRecord.RevokedAt } resp, err := s.Sign(req) if err != nil { log.Critical("Unable to sign OCSP response: ", err) return err } err = certdb.UpsertOCSP(db, cert.SerialNumber.String(), string(resp), ocspExpiry) if err != nil { log.Critical("Unable to save OCSP response: ", err) return err } } return nil }