From c03d96212b5ba93c8308db1e9949a523f6e91bf8 Mon Sep 17 00:00:00 2001 From: Roland Bracewell Shoemaker Date: Wed, 13 Sep 2017 12:23:38 -0700 Subject: [PATCH] Update vendored github.com/cloudflare/cfssl (#3078) --- Godeps/Godeps.json | 56 ++++++------- cmd/ocsp-responder/main.go | 10 +-- cmd/ocsp-responder/main_test.go | 4 +- .../cloudflare/cfssl/certdb/certdb.go | 1 + .../cloudflare/cfssl/helpers/helpers.go | 48 +----------- .../github.com/cloudflare/cfssl/ocsp/ocsp.go | 19 ++++- .../cloudflare/cfssl/ocsp/responder.go | 78 ++++++++++++++----- .../cloudflare/cfssl/signer/local/local.go | 25 ++++-- .../cloudflare/cfssl/signer/signer.go | 49 +++++++----- 9 files changed, 159 insertions(+), 131 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 7c7ade4ec..17402c526 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -12,73 +12,73 @@ }, { "ImportPath": "github.com/cloudflare/cfssl/auth", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/certdb", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/config", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs7", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/csr", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/errors", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/helpers", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/helpers/derhelpers", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/info", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/log", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/ocsp", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/ocsp/config", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/signer", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/cloudflare/cfssl/signer/local", - "Comment": "1.2.0-169-gc9a961e", - "Rev": "c9a961ed337dbde794abb97a2a302320a99869da" + "Comment": "1.2.0-195-gb92b544", + "Rev": "b92b544a91e70c91d9db888dfc9216197329df30" }, { "ImportPath": "github.com/davecgh/go-spew/spew", diff --git a/cmd/ocsp-responder/main.go b/cmd/ocsp-responder/main.go index 8744da83c..f09d1e2f0 100644 --- a/cmd/ocsp-responder/main.go +++ b/cmd/ocsp-responder/main.go @@ -69,11 +69,11 @@ type dbResponse struct { } // Response is called by the HTTP server to handle a new OCSP request. -func (src *DBSource) Response(req *ocsp.Request) ([]byte, bool) { +func (src *DBSource) Response(req *ocsp.Request) ([]byte, http.Header, error) { // Check that this request is for the proper CA if bytes.Compare(req.IssuerKeyHash, src.caKeyHash) != 0 { src.log.Debug(fmt.Sprintf("Request intended for CA Cert ID: %s", hex.EncodeToString(req.IssuerKeyHash))) - return nil, false + return nil, nil, cfocsp.ErrNotFound } serialString := core.SerialToString(req.SerialNumber) @@ -94,14 +94,14 @@ func (src *DBSource) Response(req *ocsp.Request) ([]byte, bool) { src.log.AuditErr(fmt.Sprintf("Failed to retrieve response from certificateStatus table: %s", err)) } if err != nil { - return nil, false + return nil, nil, cfocsp.ErrNotFound } if response.OCSPLastUpdated.IsZero() { src.log.Debug(fmt.Sprintf("OCSP Response not sent (ocspLastUpdated is zero) for CA=%s, Serial=%s", hex.EncodeToString(src.caKeyHash), serialString)) - return nil, false + return nil, nil, cfocsp.ErrNotFound } - return response.OCSPResponse, true + return response.OCSPResponse, nil, nil } func makeDBSource(dbMap dbSelector, issuerCert string, log blog.Logger) (*DBSource, error) { diff --git a/cmd/ocsp-responder/main_test.go b/cmd/ocsp-responder/main_test.go index 13d7b0f47..87933c1a8 100644 --- a/cmd/ocsp-responder/main_test.go +++ b/cmd/ocsp-responder/main_test.go @@ -133,8 +133,8 @@ func TestErrorLog(t *testing.T) { ocspReq, err := ocsp.ParseRequest(req) test.AssertNotError(t, err, "Failed to parse OCSP request") - _, found := src.Response(ocspReq) - test.Assert(t, !found, "Somehow found OCSP response") + _, _, err = src.Response(ocspReq) + test.AssertEquals(t, err, cfocsp.ErrNotFound) test.AssertEquals(t, len(mockLog.GetAllMatching("Failed to retrieve response from certificateStatus table")), 1) } diff --git a/vendor/github.com/cloudflare/cfssl/certdb/certdb.go b/vendor/github.com/cloudflare/cfssl/certdb/certdb.go index 356e1ea8b..dc8c856c3 100644 --- a/vendor/github.com/cloudflare/cfssl/certdb/certdb.go +++ b/vendor/github.com/cloudflare/cfssl/certdb/certdb.go @@ -32,6 +32,7 @@ type Accessor interface { GetCertificate(serial, aki string) ([]CertificateRecord, error) GetUnexpiredCertificates() ([]CertificateRecord, error) GetRevokedAndUnexpiredCertificates() ([]CertificateRecord, error) + GetRevokedAndUnexpiredCertificatesByLabel(label string) ([]CertificateRecord, error) RevokeCertificate(serial, aki string, reasonCode int) error InsertOCSP(rr OCSPRecord) error GetOCSP(serial, aki string) ([]OCSPRecord, error) diff --git a/vendor/github.com/cloudflare/cfssl/helpers/helpers.go b/vendor/github.com/cloudflare/cfssl/helpers/helpers.go index 4514a8182..c9506077a 100644 --- a/vendor/github.com/cloudflare/cfssl/helpers/helpers.go +++ b/vendor/github.com/cloudflare/cfssl/helpers/helpers.go @@ -18,7 +18,6 @@ import ( "fmt" "io" "io/ioutil" - "math/big" "os" "github.com/google/certificate-transparency-go" @@ -383,51 +382,6 @@ func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) { return nil, cferr.New(cferr.PrivateKeyError, cferr.DecodeFailed) } -// CheckSignature verifies a signature made by the key on a CSR, such -// as on the CSR itself. -func CheckSignature(csr *x509.CertificateRequest, algo x509.SignatureAlgorithm, signed, signature []byte) error { - var hashType crypto.Hash - - switch algo { - case x509.SHA1WithRSA, x509.ECDSAWithSHA1: - hashType = crypto.SHA1 - case x509.SHA256WithRSA, x509.ECDSAWithSHA256: - hashType = crypto.SHA256 - case x509.SHA384WithRSA, x509.ECDSAWithSHA384: - hashType = crypto.SHA384 - case x509.SHA512WithRSA, x509.ECDSAWithSHA512: - hashType = crypto.SHA512 - default: - return x509.ErrUnsupportedAlgorithm - } - - if !hashType.Available() { - return x509.ErrUnsupportedAlgorithm - } - h := hashType.New() - - h.Write(signed) - digest := h.Sum(nil) - - switch pub := csr.PublicKey.(type) { - case *rsa.PublicKey: - return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) - case *ecdsa.PublicKey: - ecdsaSig := new(struct{ R, S *big.Int }) - if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("x509: ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { - return errors.New("x509: ECDSA verification failure") - } - return nil - } - return x509.ErrUnsupportedAlgorithm -} - // ParseCSR parses a PEM- or DER-encoded PKCS #10 certificate signing request. func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) { in = bytes.TrimSpace(in) @@ -446,7 +400,7 @@ func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) return nil, rest, err } - err = CheckSignature(csr, csr.SignatureAlgorithm, csr.RawTBSCertificateRequest, csr.Signature) + err = csr.CheckSignature() if err != nil { return nil, rest, err } diff --git a/vendor/github.com/cloudflare/cfssl/ocsp/ocsp.go b/vendor/github.com/cloudflare/cfssl/ocsp/ocsp.go index 65bd19ea0..a78b69c2e 100644 --- a/vendor/github.com/cloudflare/cfssl/ocsp/ocsp.go +++ b/vendor/github.com/cloudflare/cfssl/ocsp/ocsp.go @@ -58,6 +58,10 @@ type SignRequest struct { // in the OCSP response. Valid values are crypto.SHA1, crypto.SHA256, crypto.SHA384, // and crypto.SHA512. If zero, the default is crypto.SHA1. IssuerHash crypto.Hash + // If provided ThisUpdate will override the default usage of time.Now().Truncate(time.Hour) + ThisUpdate *time.Time + // If provided NextUpdate will override the default usage of ThisUpdate.Add(signerInterval) + NextUpdate *time.Time } // Signer represents a general signer of OCSP responses. It is @@ -164,9 +168,18 @@ func (s StandardSigner) Sign(req SignRequest) ([]byte, error) { 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) + var thisUpdate, nextUpdate time.Time + if req.ThisUpdate != nil { + thisUpdate = *req.ThisUpdate + } else { + // Round thisUpdate times down to the nearest hour + thisUpdate = time.Now().Truncate(time.Hour) + } + if req.NextUpdate != nil { + nextUpdate = *req.NextUpdate + } else { + nextUpdate = thisUpdate.Add(s.interval) + } status, ok := StatusCode[req.Status] if !ok { diff --git a/vendor/github.com/cloudflare/cfssl/ocsp/responder.go b/vendor/github.com/cloudflare/cfssl/ocsp/responder.go index 56f7c09ae..b1ae2f7f7 100644 --- a/vendor/github.com/cloudflare/cfssl/ocsp/responder.go +++ b/vendor/github.com/cloudflare/cfssl/ocsp/responder.go @@ -11,6 +11,7 @@ import ( "crypto/sha256" "encoding/base64" "encoding/hex" + "errors" "fmt" "io/ioutil" "net/http" @@ -30,14 +31,25 @@ var ( tryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03} sigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05} unauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06} + + // ErrNotFound indicates the request OCSP response was not found. It is used to + // indicate that the responder should reply with unauthorizedErrorResponse. + ErrNotFound = errors.New("Request OCSP Response not found") ) // Source represents the logical source of OCSP responses, i.e., // the logic that actually chooses a response based on a request. In // order to create an actual responder, wrap one of these in a Responder -// object and pass it to http.Handle. +// object and pass it to http.Handle. By default the Responder will set +// the headers Cache-Control to "max-age=(response.NextUpdate-now), public, no-transform, must-revalidate", +// Last-Modified to response.ThisUpdate, Expires to response.NextUpdate, +// ETag to the SHA256 hash of the response, and Content-Type to +// application/ocsp-response. If you want to override these headers, +// or set extra headers, your source should return a http.Header +// with the headers you wish to set. If you don't want to set any +// extra headers you may return nil instead. type Source interface { - Response(*ocsp.Request) ([]byte, bool) + Response(*ocsp.Request) ([]byte, http.Header, error) } // An InMemorySource is a map from serialNumber -> der(response) @@ -46,9 +58,12 @@ type InMemorySource map[string][]byte // Response looks up an OCSP response to provide for a given request. // InMemorySource looks up a response purely based on serial number, // without regard to what issuer the request is asking for. -func (src InMemorySource) Response(request *ocsp.Request) (response []byte, present bool) { - response, present = src[request.SerialNumber.String()] - return +func (src InMemorySource) Response(request *ocsp.Request) ([]byte, http.Header, error) { + response, present := src[request.SerialNumber.String()] + if !present { + return nil, nil, ErrNotFound + } + return response, nil, nil } // DBSource represnts a source of OCSP responses backed by the certdb package. @@ -65,26 +80,23 @@ func NewDBSource(dbAccessor certdb.Accessor) Source { // Response implements cfssl.ocsp.responder.Source, which returns the // OCSP response in the Database for the given request with the expiration -// date furthest in the future. Response also returns a bool that is false -// if there were any errors obtaining the OCSP response and/or no OCSP response -// is present in the DB for the given request. Response will return a true -// bool if the byte array returned is a valid OCSP response. -func (src DBSource) Response(req *ocsp.Request) ([]byte, bool) { +// date furthest in the future. +func (src DBSource) Response(req *ocsp.Request) ([]byte, http.Header, error) { if req == nil { - return nil, false + return nil, nil, errors.New("called with nil request") } aki := hex.EncodeToString(req.IssuerKeyHash) sn := req.SerialNumber if sn == nil { - return nil, false + return nil, nil, errors.New("request contains no serial") } strSN := sn.String() if src.Accessor == nil { log.Errorf("No DB Accessor") - return nil, false + return nil, nil, errors.New("called with nil DB accessor") } records, err := src.Accessor.GetOCSP(strSN, aki) @@ -92,11 +104,11 @@ func (src DBSource) Response(req *ocsp.Request) ([]byte, bool) { // and returns nil, false. if err != nil { log.Errorf("Error obtaining OCSP response: %s", err) - return nil, false + return nil, nil, fmt.Errorf("failed to obtain OCSP response: %s", err) } if len(records) == 0 { - return nil, false + return nil, nil, ErrNotFound } // Response() finds the OCSPRecord with the expiration date furthest in the future. @@ -106,7 +118,7 @@ func (src DBSource) Response(req *ocsp.Request) ([]byte, bool) { cur = rec } } - return []byte(cur.Body), true + return []byte(cur.Body), nil, nil } // NewSourceFromFile reads the named file into an InMemorySource. @@ -161,6 +173,19 @@ func NewResponder(source Source) *Responder { } } +func overrideHeaders(response http.ResponseWriter, headers http.Header) { + for k, v := range headers { + if len(v) == 1 { + response.Header().Set(k, v[0]) + } else if len(v) > 1 { + response.Header().Del(k) + for _, e := range v { + response.Header().Add(k, e) + } + } + } +} + // A Responder can process both GET and POST requests. The mapping // from an OCSP request to an OCSP response is done by the Source; // the Responder simply decodes the request, and passes back whatever @@ -243,11 +268,18 @@ func (rs Responder) ServeHTTP(response http.ResponseWriter, request *http.Reques } // Look up OCSP response from source - ocspResponse, found := rs.Source.Response(ocspRequest) - if !found { - log.Infof("No response found for request: serial %x, request body %s", - ocspRequest.SerialNumber, b64Body) - response.Write(unauthorizedErrorResponse) + ocspResponse, headers, err := rs.Source.Response(ocspRequest) + if err != nil { + if err == ErrNotFound { + log.Infof("No response found for request: serial %x, request body %s", + ocspRequest.SerialNumber, b64Body) + response.Write(unauthorizedErrorResponse) + return + } + log.Infof("Error retrieving response for request: serial %x, request body %s, error: %s", + ocspRequest.SerialNumber, b64Body, err) + response.WriteHeader(http.StatusInternalServerError) + response.Write(internalErrorErrorResponse) return } @@ -281,6 +313,10 @@ func (rs Responder) ServeHTTP(response http.ResponseWriter, request *http.Reques responseHash := sha256.Sum256(ocspResponse) response.Header().Add("ETag", fmt.Sprintf("\"%X\"", responseHash)) + if headers != nil { + overrideHeaders(response, headers) + } + // RFC 7232 says that a 304 response must contain the above // headers if they would also be sent for a 200 for the same // request, so we have to wait until here to do this diff --git a/vendor/github.com/cloudflare/cfssl/signer/local/local.go b/vendor/github.com/cloudflare/cfssl/signer/local/local.go index c17e704a9..686deac9d 100644 --- a/vendor/github.com/cloudflare/cfssl/signer/local/local.go +++ b/vendor/github.com/cloudflare/cfssl/signer/local/local.go @@ -29,6 +29,7 @@ import ( "github.com/google/certificate-transparency-go/client" "github.com/google/certificate-transparency-go/jsonclient" "golang.org/x/net/context" + "time" ) // Signer contains a signer that uses the standard library to @@ -96,14 +97,14 @@ func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signe return NewSigner(priv, parsedCa, signer.DefaultSigAlgo(priv), policy) } -func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile) (cert []byte, err error) { +func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile, notBefore time.Time, notAfter time.Time) (cert []byte, err error) { var distPoints = template.CRLDistributionPoints - err = signer.FillTemplate(template, s.policy.Default, profile) if distPoints != nil && len(distPoints) > 0 { template.CRLDistributionPoints = distPoints } + err = signer.FillTemplate(template, s.policy.Default, profile, notBefore, notAfter) if err != nil { - return + return nil, err } var initRoot bool @@ -342,7 +343,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}} var poisonedPreCert = certTBS poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension) - cert, err = s.sign(&poisonedPreCert, profile) + cert, err = s.sign(&poisonedPreCert, profile, req.NotBefore, req.NotAfter) if err != nil { return } @@ -382,17 +383,22 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension) } var signedCert []byte - signedCert, err = s.sign(&certTBS, profile) + signedCert, err = s.sign(&certTBS, profile, req.NotBefore, req.NotAfter) if err != nil { return nil, err } + // Get the AKI from signedCert. This is required to support Go 1.9+. + // In prior versions of Go, x509.CreateCertificate updated the + // AuthorityKeyId of certTBS. + parsedCert, _ := helpers.ParseCertificatePEM(signedCert) + if s.dbAccessor != nil { var certRecord = certdb.CertificateRecord{ Serial: certTBS.SerialNumber.String(), // this relies on the specific behavior of x509.CreateCertificate - // which updates certTBS AuthorityKeyId from the signer's SubjectKeyId - AKI: hex.EncodeToString(certTBS.AuthorityKeyId), + // which sets the AuthorityKeyId from the signer's SubjectKeyId + AKI: hex.EncodeToString(parsedCert.AuthorityKeyId), CALabel: req.Label, Status: "good", Expiry: certTBS.NotAfter, @@ -452,6 +458,11 @@ func (s *Signer) SetDBAccessor(dba certdb.Accessor) { s.dbAccessor = dba } +// GetDBAccessor returns the signers' cert db accessor +func (s *Signer) GetDBAccessor() certdb.Accessor { + return s.dbAccessor +} + // SetReqModifier does nothing for local func (s *Signer) SetReqModifier(func(*http.Request, []byte)) { // noop diff --git a/vendor/github.com/cloudflare/cfssl/signer/signer.go b/vendor/github.com/cloudflare/cfssl/signer/signer.go index a90e3d217..20101f682 100644 --- a/vendor/github.com/cloudflare/cfssl/signer/signer.go +++ b/vendor/github.com/cloudflare/cfssl/signer/signer.go @@ -20,7 +20,6 @@ import ( "github.com/cloudflare/cfssl/config" "github.com/cloudflare/cfssl/csr" cferr "github.com/cloudflare/cfssl/errors" - "github.com/cloudflare/cfssl/helpers" "github.com/cloudflare/cfssl/info" ) @@ -56,6 +55,15 @@ type SignRequest struct { Label string `json:"label"` Serial *big.Int `json:"serial,omitempty"` Extensions []Extension `json:"extensions,omitempty"` + // If provided, NotBefore will be used without modification (except + // for canonicalization) as the value of the notBefore field of the + // certificate. In particular no backdating adjustment will be made + // when NotBefore is provided. + NotBefore time.Time + // If provided, NotAfter will be used without modification (except + // for canonicalization) as the value of the notAfter field of the + // certificate. + NotAfter time.Time } // appendIf appends to a if s is not an empty string. @@ -97,6 +105,7 @@ type Signer interface { Info(info.Req) (*info.Resp, error) Policy() *config.Signing SetDBAccessor(certdb.Accessor) + GetDBAccessor() certdb.Accessor SetPolicy(*config.Signing) SigAlgo() x509.SignatureAlgorithm Sign(req SignRequest) (cert []byte, err error) @@ -163,7 +172,7 @@ func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certific return } - err = helpers.CheckSignature(csrv, csrv.SignatureAlgorithm, csrv.RawTBSCertificateRequest, csrv.Signature) + err = csrv.CheckSignature() if err != nil { err = cferr.Wrap(cferr.CSRError, cferr.KeyMismatch, err) return @@ -231,7 +240,7 @@ func ComputeSKI(template *x509.Certificate) ([]byte, error) { // the certificate template as possible from the profiles and current // template. It fills in the key uses, expiration, revocation URLs // and SKI. -func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.SigningProfile) error { +func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.SigningProfile, notBefore time.Time, notAfter time.Time) error { ski, err := ComputeSKI(template) if err != nil { return err @@ -242,8 +251,6 @@ func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.Si ku x509.KeyUsage backdate time.Duration expiry time.Duration - notBefore time.Time - notAfter time.Time crlURL, ocspURL string issuerURL = profile.IssuerURL ) @@ -270,23 +277,29 @@ func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.Si if ocspURL = profile.OCSP; ocspURL == "" { ocspURL = defaultProfile.OCSP } - if backdate = profile.Backdate; backdate == 0 { - backdate = -5 * time.Minute - } else { - backdate = -1 * profile.Backdate - } - if !profile.NotBefore.IsZero() { - notBefore = profile.NotBefore.UTC() - } else { - notBefore = time.Now().Round(time.Minute).Add(backdate).UTC() + if notBefore.IsZero() { + if !profile.NotBefore.IsZero() { + notBefore = profile.NotBefore + } else { + if backdate = profile.Backdate; backdate == 0 { + backdate = -5 * time.Minute + } else { + backdate = -1 * profile.Backdate + } + notBefore = time.Now().Round(time.Minute).Add(backdate) + } } + notBefore = notBefore.UTC() - if !profile.NotAfter.IsZero() { - notAfter = profile.NotAfter.UTC() - } else { - notAfter = notBefore.Add(expiry).UTC() + if notAfter.IsZero() { + if !profile.NotAfter.IsZero() { + notAfter = profile.NotAfter + } else { + notAfter = notBefore.Add(expiry) + } } + notAfter = notAfter.UTC() template.NotBefore = notBefore template.NotAfter = notAfter