// Sign is used with an OCSP signer to request the issuance of // an OCSP response. func (s StandardSigner) Sign(req SignRequest) ([]byte, error) { if req.Certificate == nil { return nil, cferr.New(cferr.OCSPError, cferr.ReadFailed) } // Verify that req.Certificate is issued under s.issuer if bytes.Compare(req.Certificate.RawIssuer, s.issuer.RawSubject) != 0 { return nil, cferr.New(cferr.OCSPError, cferr.IssuerMismatch) } if req.Certificate.CheckSignatureFrom(s.issuer) != nil { return nil, cferr.New(cferr.OCSPError, cferr.IssuerMismatch) } // Round thisUpdate times down to the nearest hour thisUpdate := time.Now().Truncate(time.Hour) nextUpdate := thisUpdate.Add(s.interval) status, ok := StatusCode[req.Status] if !ok { return nil, cferr.New(cferr.OCSPError, cferr.InvalidStatus) } // If the OCSP responder is the same as the issuer, there is no need to // include any certificate in the OCSP response, which decreases the byte size // of OCSP responses dramatically. certificate := s.responder if s.issuer == s.responder || bytes.Equal(s.issuer.Raw, s.responder.Raw) { certificate = nil } template := ocsp.Response{ Status: status, SerialNumber: req.Certificate.SerialNumber, ThisUpdate: thisUpdate, NextUpdate: nextUpdate, Certificate: certificate, ExtraExtensions: req.Extensions, } if status == ocsp.Revoked { template.RevokedAt = req.RevokedAt template.RevocationReason = req.Reason } return ocsp.CreateResponse(s.issuer, s.responder, template, s.key) }
// Sign is used with an OCSP signer to request the issuance of // an OCSP response. func (s StandardSigner) Sign(req SignRequest) ([]byte, error) { if req.Certificate == nil { return nil, cferr.New(cferr.OCSPError, cferr.ReadFailed) } // Verify that req.Certificate is issued under s.issuer if bytes.Compare(req.Certificate.RawIssuer, s.issuer.RawSubject) != 0 { return nil, cferr.New(cferr.OCSPError, cferr.IssuerMismatch) } if req.Certificate.CheckSignatureFrom(s.issuer) != nil { return nil, cferr.New(cferr.OCSPError, cferr.IssuerMismatch) } // Round thisUpdate times down to the nearest hour thisUpdate := time.Now().Truncate(time.Hour) nextUpdate := thisUpdate.Add(s.interval) status, ok := StatusCode[req.Status] if !ok { return nil, cferr.New(cferr.OCSPError, cferr.InvalidStatus) } template := ocsp.Response{ Status: status, SerialNumber: req.Certificate.SerialNumber, ThisUpdate: thisUpdate, NextUpdate: nextUpdate, Certificate: s.responder, } if status == ocsp.Revoked { template.RevokedAt = req.RevokedAt template.RevocationReason = req.Reason } return ocsp.CreateResponse(s.issuer, s.responder, template, s.key) }
func main() { app := cli.NewApp() app.Name = "single-ocsp" app.Usage = `Creates a single OCSP response. According to the BRs, the OCSP responses for intermediate certificate must be issued once per year. So there's a need to issue OCSP responses for these certificates, but it doesn't make sense to use all the infrastructure that the "ocsp-updater" tool requires. This tool allows an administrator to manually generate an OCSP response for an intermediate certificate. ` app.Version = cmd.Version() app.Author = "Boulder contributors" app.Email = "*****@*****.**" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "issuer", Usage: "Issuer certificate (DER)", }, cli.StringFlag{ Name: "responder", Usage: "OCSP responder certificate (DER)", }, cli.StringFlag{ Name: "target", Usage: "Certificate whose status is being reported (DER)", }, cli.StringFlag{ Name: "template", Usage: `OCSP template file (JSON), e.g.: { "Status": 0, // Good "ThisUpdate": "2015-08-26T00:00:00Z", "NextUpdate": "2016-08-26T00:00:00Z" } { "Status": 1, // Revoked "ThisUpdate": "2015-08-26T00:00:00Z", "NextUpdate": "2016-08-26T00:00:00Z", "RevokedAt": "2015-08-20T00:00:00Z", "RevocationReason": 1 // Key compromise } `, }, cli.StringFlag{ Name: "pkcs11", Usage: `PKCS#11 configuration (JSON), e.g.: { "Module": "/Library/OpenSC/lib/opensc-pkcs11.so", "Token": "Yubico Yubikey NEO CCID", "Label": "PIV AUTH key", "PIN": "123456" } `, }, cli.StringFlag{ Name: "out", Usage: "File to which the OCSP response will be written", }, } app.Action = func(c *cli.Context) { issuer, responder, target, template, pkcs11, err := readFiles(c) cmd.FailOnError(err, "Failed to read files") // Instantiate the private key from PKCS11 priv, err := pkcs11key.New(pkcs11.Module, pkcs11.TokenLabel, pkcs11.PIN, pkcs11.PrivateKeyLabel, int(pkcs11.SlotID)) cmd.FailOnError(err, "Failed to load PKCS#11 key") // Populate the remaining fields in the template template.SerialNumber = target.SerialNumber template.Certificate = responder // Sign the OCSP response responseBytes, err := ocsp.CreateResponse(issuer, responder, template, priv) cmd.FailOnError(err, "Failed to sign OCSP response") // Write the OCSP response to stdout outFile := c.GlobalString("out") if len(outFile) == 0 { cmd.FailOnError(fmt.Errorf(""), "No output file provided") } ioutil.WriteFile(outFile, responseBytes, 0666) } err := app.Run(os.Args) cmd.FailOnError(err, "Failed to run application") }