github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/crypto/ocsp/ocsp.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses 6 // are signed messages attesting to the validity of a certificate for a small 7 // period of time. This is used to manage revocation for X.509 certificates. 8 package ocsp // import "golang.org/x/crypto/ocsp" 9 10 import ( 11 "crypto" 12 "crypto/ecdsa" 13 "crypto/elliptic" 14 "crypto/rand" 15 "crypto/rsa" 16 _ "crypto/sha1" 17 _ "crypto/sha256" 18 _ "crypto/sha512" 19 "crypto/x509" 20 "crypto/x509/pkix" 21 "encoding/asn1" 22 "errors" 23 "fmt" 24 "math/big" 25 "strconv" 26 "time" 27 ) 28 29 var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) 30 31 // ResponseStatus contains the result of an OCSP request. See 32 // https://tools.ietf.org/html/rfc6960#section-2.3 33 type ResponseStatus int 34 35 const ( 36 Success ResponseStatus = 0 37 Malformed ResponseStatus = 1 38 InternalError ResponseStatus = 2 39 TryLater ResponseStatus = 3 40 // Status code four is unused in OCSP. See 41 // https://tools.ietf.org/html/rfc6960#section-4.2.1 42 SignatureRequired ResponseStatus = 5 43 Unauthorized ResponseStatus = 6 44 ) 45 46 func (r ResponseStatus) String() string { 47 switch r { 48 case Success: 49 return "success" 50 case Malformed: 51 return "malformed" 52 case InternalError: 53 return "internal error" 54 case TryLater: 55 return "try later" 56 case SignatureRequired: 57 return "signature required" 58 case Unauthorized: 59 return "unauthorized" 60 default: 61 return "unknown OCSP status: " + strconv.Itoa(int(r)) 62 } 63 } 64 65 // ResponseError is an error that may be returned by ParseResponse to indicate 66 // that the response itself is an error, not just that it's indicating that a 67 // certificate is revoked, unknown, etc. 68 type ResponseError struct { 69 Status ResponseStatus 70 } 71 72 func (r ResponseError) Error() string { 73 return "ocsp: error from server: " + r.Status.String() 74 } 75 76 // These are internal structures that reflect the ASN.1 structure of an OCSP 77 // response. See RFC 2560, section 4.2. 78 79 type certID struct { 80 HashAlgorithm pkix.AlgorithmIdentifier 81 NameHash []byte 82 IssuerKeyHash []byte 83 SerialNumber *big.Int 84 } 85 86 // https://tools.ietf.org/html/rfc2560#section-4.1.1 87 type ocspRequest struct { 88 TBSRequest tbsRequest 89 } 90 91 type tbsRequest struct { 92 Version int `asn1:"explicit,tag:0,default:0,optional"` 93 RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"` 94 RequestList []request 95 } 96 97 type request struct { 98 Cert certID 99 } 100 101 type responseASN1 struct { 102 Status asn1.Enumerated 103 Response responseBytes `asn1:"explicit,tag:0,optional"` 104 } 105 106 type responseBytes struct { 107 ResponseType asn1.ObjectIdentifier 108 Response []byte 109 } 110 111 type basicResponse struct { 112 TBSResponseData responseData 113 SignatureAlgorithm pkix.AlgorithmIdentifier 114 Signature asn1.BitString 115 Certificates []asn1.RawValue `asn1:"explicit,tag:0,optional"` 116 } 117 118 type responseData struct { 119 Raw asn1.RawContent 120 Version int `asn1:"optional,default:0,explicit,tag:0"` 121 RawResponderID asn1.RawValue 122 ProducedAt time.Time `asn1:"generalized"` 123 Responses []singleResponse 124 } 125 126 type singleResponse struct { 127 CertID certID 128 Good asn1.Flag `asn1:"tag:0,optional"` 129 Revoked revokedInfo `asn1:"tag:1,optional"` 130 Unknown asn1.Flag `asn1:"tag:2,optional"` 131 ThisUpdate time.Time `asn1:"generalized"` 132 NextUpdate time.Time `asn1:"generalized,explicit,tag:0,optional"` 133 SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"` 134 } 135 136 type revokedInfo struct { 137 RevocationTime time.Time `asn1:"generalized"` 138 Reason asn1.Enumerated `asn1:"explicit,tag:0,optional"` 139 } 140 141 var ( 142 oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} 143 oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} 144 oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} 145 oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} 146 oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} 147 oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} 148 oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} 149 oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} 150 oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} 151 oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} 152 oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} 153 oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} 154 ) 155 156 var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{ 157 crypto.SHA1: asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}), 158 crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}), 159 crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}), 160 crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}), 161 } 162 163 // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below 164 var signatureAlgorithmDetails = []struct { 165 algo x509.SignatureAlgorithm 166 oid asn1.ObjectIdentifier 167 pubKeyAlgo x509.PublicKeyAlgorithm 168 hash crypto.Hash 169 }{ 170 {x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, 171 {x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, 172 {x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, 173 {x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, 174 {x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, 175 {x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, 176 {x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, 177 {x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, 178 {x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, 179 {x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, 180 {x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, 181 {x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, 182 } 183 184 // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below 185 func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { 186 var pubType x509.PublicKeyAlgorithm 187 188 switch pub := pub.(type) { 189 case *rsa.PublicKey: 190 pubType = x509.RSA 191 hashFunc = crypto.SHA256 192 sigAlgo.Algorithm = oidSignatureSHA256WithRSA 193 sigAlgo.Parameters = asn1.RawValue{ 194 Tag: 5, 195 } 196 197 case *ecdsa.PublicKey: 198 pubType = x509.ECDSA 199 200 switch pub.Curve { 201 case elliptic.P224(), elliptic.P256(): 202 hashFunc = crypto.SHA256 203 sigAlgo.Algorithm = oidSignatureECDSAWithSHA256 204 case elliptic.P384(): 205 hashFunc = crypto.SHA384 206 sigAlgo.Algorithm = oidSignatureECDSAWithSHA384 207 case elliptic.P521(): 208 hashFunc = crypto.SHA512 209 sigAlgo.Algorithm = oidSignatureECDSAWithSHA512 210 default: 211 err = errors.New("x509: unknown elliptic curve") 212 } 213 214 default: 215 err = errors.New("x509: only RSA and ECDSA keys supported") 216 } 217 218 if err != nil { 219 return 220 } 221 222 if requestedSigAlgo == 0 { 223 return 224 } 225 226 found := false 227 for _, details := range signatureAlgorithmDetails { 228 if details.algo == requestedSigAlgo { 229 if details.pubKeyAlgo != pubType { 230 err = errors.New("x509: requested SignatureAlgorithm does not match private key type") 231 return 232 } 233 sigAlgo.Algorithm, hashFunc = details.oid, details.hash 234 if hashFunc == 0 { 235 err = errors.New("x509: cannot sign with hash function requested") 236 return 237 } 238 found = true 239 break 240 } 241 } 242 243 if !found { 244 err = errors.New("x509: unknown SignatureAlgorithm") 245 } 246 247 return 248 } 249 250 // TODO(agl): this is taken from crypto/x509 and so should probably be exported 251 // from crypto/x509 or crypto/x509/pkix. 252 func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm { 253 for _, details := range signatureAlgorithmDetails { 254 if oid.Equal(details.oid) { 255 return details.algo 256 } 257 } 258 return x509.UnknownSignatureAlgorithm 259 } 260 261 // TODO(rlb): This is not taken from crypto/x509, but it's of the same general form. 262 func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash { 263 for hash, oid := range hashOIDs { 264 if oid.Equal(target) { 265 return hash 266 } 267 } 268 return crypto.Hash(0) 269 } 270 271 func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier { 272 for hash, oid := range hashOIDs { 273 if hash == target { 274 return oid 275 } 276 } 277 return nil 278 } 279 280 // This is the exposed reflection of the internal OCSP structures. 281 282 // The status values that can be expressed in OCSP. See RFC 6960. 283 const ( 284 // Good means that the certificate is valid. 285 Good = iota 286 // Revoked means that the certificate has been deliberately revoked. 287 Revoked 288 // Unknown means that the OCSP responder doesn't know about the certificate. 289 Unknown 290 // ServerFailed is unused and was never used (see 291 // https://go-review.googlesource.com/#/c/18944). ParseResponse will 292 // return a ResponseError when an error response is parsed. 293 ServerFailed 294 ) 295 296 // The enumerated reasons for revoking a certificate. See RFC 5280. 297 const ( 298 Unspecified = 0 299 KeyCompromise = 1 300 CACompromise = 2 301 AffiliationChanged = 3 302 Superseded = 4 303 CessationOfOperation = 5 304 CertificateHold = 6 305 306 RemoveFromCRL = 8 307 PrivilegeWithdrawn = 9 308 AACompromise = 10 309 ) 310 311 // Request represents an OCSP request. See RFC 6960. 312 type Request struct { 313 HashAlgorithm crypto.Hash 314 IssuerNameHash []byte 315 IssuerKeyHash []byte 316 SerialNumber *big.Int 317 } 318 319 // Marshal marshals the OCSP request to ASN.1 DER encoded form. 320 func (req *Request) Marshal() ([]byte, error) { 321 hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm) 322 if hashAlg == nil { 323 return nil, errors.New("Unknown hash algorithm") 324 } 325 return asn1.Marshal(ocspRequest{ 326 tbsRequest{ 327 Version: 0, 328 RequestList: []request{ 329 { 330 Cert: certID{ 331 pkix.AlgorithmIdentifier{ 332 Algorithm: hashAlg, 333 Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, 334 }, 335 req.IssuerNameHash, 336 req.IssuerKeyHash, 337 req.SerialNumber, 338 }, 339 }, 340 }, 341 }, 342 }) 343 } 344 345 // Response represents an OCSP response containing a single SingleResponse. See 346 // RFC 6960. 347 type Response struct { 348 Raw []byte 349 350 // Status is one of {Good, Revoked, Unknown} 351 Status int 352 SerialNumber *big.Int 353 ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time 354 RevocationReason int 355 Certificate *x509.Certificate 356 // TBSResponseData contains the raw bytes of the signed response. If 357 // Certificate is nil then this can be used to verify Signature. 358 TBSResponseData []byte 359 Signature []byte 360 SignatureAlgorithm x509.SignatureAlgorithm 361 362 // IssuerHash is the hash used to compute the IssuerNameHash and IssuerKeyHash. 363 // Valid values are crypto.SHA1, crypto.SHA256, crypto.SHA384, and crypto.SHA512. 364 // If zero, the default is crypto.SHA1. 365 IssuerHash crypto.Hash 366 367 // RawResponderName optionally contains the DER-encoded subject of the 368 // responder certificate. Exactly one of RawResponderName and 369 // ResponderKeyHash is set. 370 RawResponderName []byte 371 // ResponderKeyHash optionally contains the SHA-1 hash of the 372 // responder's public key. Exactly one of RawResponderName and 373 // ResponderKeyHash is set. 374 ResponderKeyHash []byte 375 376 // Extensions contains raw X.509 extensions from the singleExtensions field 377 // of the OCSP response. When parsing certificates, this can be used to 378 // extract non-critical extensions that are not parsed by this package. When 379 // marshaling OCSP responses, the Extensions field is ignored, see 380 // ExtraExtensions. 381 Extensions []pkix.Extension 382 383 // ExtraExtensions contains extensions to be copied, raw, into any marshaled 384 // OCSP response (in the singleExtensions field). Values override any 385 // extensions that would otherwise be produced based on the other fields. The 386 // ExtraExtensions field is not populated when parsing certificates, see 387 // Extensions. 388 ExtraExtensions []pkix.Extension 389 } 390 391 // These are pre-serialized error responses for the various non-success codes 392 // defined by OCSP. The Unauthorized code in particular can be used by an OCSP 393 // responder that supports only pre-signed responses as a response to requests 394 // for certificates with unknown status. See RFC 5019. 395 var ( 396 MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01} 397 InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02} 398 TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03} 399 SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05} 400 UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06} 401 ) 402 403 // CheckSignatureFrom checks that the signature in resp is a valid signature 404 // from issuer. This should only be used if resp.Certificate is nil. Otherwise, 405 // the OCSP response contained an intermediate certificate that created the 406 // signature. That signature is checked by ParseResponse and only 407 // resp.Certificate remains to be validated. 408 func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error { 409 return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature) 410 } 411 412 // ParseError results from an invalid OCSP response. 413 type ParseError string 414 415 func (p ParseError) Error() string { 416 return string(p) 417 } 418 419 // ParseRequest parses an OCSP request in DER form. It only supports 420 // requests for a single certificate. Signed requests are not supported. 421 // If a request includes a signature, it will result in a ParseError. 422 func ParseRequest(bytes []byte) (*Request, error) { 423 var req ocspRequest 424 rest, err := asn1.Unmarshal(bytes, &req) 425 if err != nil { 426 return nil, err 427 } 428 if len(rest) > 0 { 429 return nil, ParseError("trailing data in OCSP request") 430 } 431 432 if len(req.TBSRequest.RequestList) == 0 { 433 return nil, ParseError("OCSP request contains no request body") 434 } 435 innerRequest := req.TBSRequest.RequestList[0] 436 437 hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm) 438 if hashFunc == crypto.Hash(0) { 439 return nil, ParseError("OCSP request uses unknown hash function") 440 } 441 442 return &Request{ 443 HashAlgorithm: hashFunc, 444 IssuerNameHash: innerRequest.Cert.NameHash, 445 IssuerKeyHash: innerRequest.Cert.IssuerKeyHash, 446 SerialNumber: innerRequest.Cert.SerialNumber, 447 }, nil 448 } 449 450 // ParseResponse parses an OCSP response in DER form. The response must contain 451 // only one certificate status. To parse the status of a specific certificate 452 // from a response which may contain multiple statuses, use ParseResponseForCert 453 // instead. 454 // 455 // If the response contains an embedded certificate, then that certificate will 456 // be used to verify the response signature. If the response contains an 457 // embedded certificate and issuer is not nil, then issuer will be used to verify 458 // the signature on the embedded certificate. 459 // 460 // If the response does not contain an embedded certificate and issuer is not 461 // nil, then issuer will be used to verify the response signature. 462 // 463 // Invalid responses and parse failures will result in a ParseError. 464 // Error responses will result in a ResponseError. 465 func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) { 466 return ParseResponseForCert(bytes, nil, issuer) 467 } 468 469 // ParseResponseForCert acts identically to ParseResponse, except it supports 470 // parsing responses that contain multiple statuses. If the response contains 471 // multiple statuses and cert is not nil, then ParseResponseForCert will return 472 // the first status which contains a matching serial, otherwise it will return an 473 // error. If cert is nil, then the first status in the response will be returned. 474 func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) { 475 var resp responseASN1 476 rest, err := asn1.Unmarshal(bytes, &resp) 477 if err != nil { 478 return nil, err 479 } 480 if len(rest) > 0 { 481 return nil, ParseError("trailing data in OCSP response") 482 } 483 484 if status := ResponseStatus(resp.Status); status != Success { 485 return nil, ResponseError{status} 486 } 487 488 if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) { 489 return nil, ParseError("bad OCSP response type") 490 } 491 492 var basicResp basicResponse 493 rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp) 494 if err != nil { 495 return nil, err 496 } 497 if len(rest) > 0 { 498 return nil, ParseError("trailing data in OCSP response") 499 } 500 501 if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 { 502 return nil, ParseError("OCSP response contains bad number of responses") 503 } 504 505 var singleResp singleResponse 506 if cert == nil { 507 singleResp = basicResp.TBSResponseData.Responses[0] 508 } else { 509 match := false 510 for _, resp := range basicResp.TBSResponseData.Responses { 511 if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 { 512 singleResp = resp 513 match = true 514 break 515 } 516 } 517 if !match { 518 return nil, ParseError("no response matching the supplied certificate") 519 } 520 } 521 522 ret := &Response{ 523 Raw: bytes, 524 TBSResponseData: basicResp.TBSResponseData.Raw, 525 Signature: basicResp.Signature.RightAlign(), 526 SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm), 527 Extensions: singleResp.SingleExtensions, 528 SerialNumber: singleResp.CertID.SerialNumber, 529 ProducedAt: basicResp.TBSResponseData.ProducedAt, 530 ThisUpdate: singleResp.ThisUpdate, 531 NextUpdate: singleResp.NextUpdate, 532 } 533 534 // Handle the ResponderID CHOICE tag. ResponderID can be flattened into 535 // TBSResponseData once https://go-review.googlesource.com/34503 has been 536 // released. 537 rawResponderID := basicResp.TBSResponseData.RawResponderID 538 switch rawResponderID.Tag { 539 case 1: // Name 540 var rdn pkix.RDNSequence 541 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 { 542 return nil, ParseError("invalid responder name") 543 } 544 ret.RawResponderName = rawResponderID.Bytes 545 case 2: // KeyHash 546 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 { 547 return nil, ParseError("invalid responder key hash") 548 } 549 default: 550 return nil, ParseError("invalid responder id tag") 551 } 552 553 if len(basicResp.Certificates) > 0 { 554 // Responders should only send a single certificate (if they 555 // send any) that connects the responder's certificate to the 556 // original issuer. We accept responses with multiple 557 // certificates due to a number responders sending them[1], but 558 // ignore all but the first. 559 // 560 // [1] https://github.com/golang/go/issues/21527 561 ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes) 562 if err != nil { 563 return nil, err 564 } 565 566 if err := ret.CheckSignatureFrom(ret.Certificate); err != nil { 567 return nil, ParseError("bad signature on embedded certificate: " + err.Error()) 568 } 569 570 if issuer != nil { 571 if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil { 572 return nil, ParseError("bad OCSP signature: " + err.Error()) 573 } 574 } 575 } else if issuer != nil { 576 if err := ret.CheckSignatureFrom(issuer); err != nil { 577 return nil, ParseError("bad OCSP signature: " + err.Error()) 578 } 579 } 580 581 for _, ext := range singleResp.SingleExtensions { 582 if ext.Critical { 583 return nil, ParseError("unsupported critical extension") 584 } 585 } 586 587 for h, oid := range hashOIDs { 588 if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) { 589 ret.IssuerHash = h 590 break 591 } 592 } 593 if ret.IssuerHash == 0 { 594 return nil, ParseError("unsupported issuer hash algorithm") 595 } 596 597 switch { 598 case bool(singleResp.Good): 599 ret.Status = Good 600 case bool(singleResp.Unknown): 601 ret.Status = Unknown 602 default: 603 ret.Status = Revoked 604 ret.RevokedAt = singleResp.Revoked.RevocationTime 605 ret.RevocationReason = int(singleResp.Revoked.Reason) 606 } 607 608 return ret, nil 609 } 610 611 // RequestOptions contains options for constructing OCSP requests. 612 type RequestOptions struct { 613 // Hash contains the hash function that should be used when 614 // constructing the OCSP request. If zero, SHA-1 will be used. 615 Hash crypto.Hash 616 } 617 618 func (opts *RequestOptions) hash() crypto.Hash { 619 if opts == nil || opts.Hash == 0 { 620 // SHA-1 is nearly universally used in OCSP. 621 return crypto.SHA1 622 } 623 return opts.Hash 624 } 625 626 // CreateRequest returns a DER-encoded, OCSP request for the status of cert. If 627 // opts is nil then sensible defaults are used. 628 func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) { 629 hashFunc := opts.hash() 630 631 // OCSP seems to be the only place where these raw hash identifiers are 632 // used. I took the following from 633 // http://msdn.microsoft.com/en-us/library/ff635603.aspx 634 _, ok := hashOIDs[hashFunc] 635 if !ok { 636 return nil, x509.ErrUnsupportedAlgorithm 637 } 638 639 if !hashFunc.Available() { 640 return nil, x509.ErrUnsupportedAlgorithm 641 } 642 h := opts.hash().New() 643 644 var publicKeyInfo struct { 645 Algorithm pkix.AlgorithmIdentifier 646 PublicKey asn1.BitString 647 } 648 if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { 649 return nil, err 650 } 651 652 h.Write(publicKeyInfo.PublicKey.RightAlign()) 653 issuerKeyHash := h.Sum(nil) 654 655 h.Reset() 656 h.Write(issuer.RawSubject) 657 issuerNameHash := h.Sum(nil) 658 659 req := &Request{ 660 HashAlgorithm: hashFunc, 661 IssuerNameHash: issuerNameHash, 662 IssuerKeyHash: issuerKeyHash, 663 SerialNumber: cert.SerialNumber, 664 } 665 return req.Marshal() 666 } 667 668 // CreateResponse returns a DER-encoded OCSP response with the specified contents. 669 // The fields in the response are populated as follows: 670 // 671 // The responder cert is used to populate the responder's name field, and the 672 // certificate itself is provided alongside the OCSP response signature. 673 // 674 // The issuer cert is used to populate the IssuerNameHash and IssuerKeyHash fields. 675 // 676 // The template is used to populate the SerialNumber, Status, RevokedAt, 677 // RevocationReason, ThisUpdate, and NextUpdate fields. 678 // 679 // If template.IssuerHash is not set, SHA1 will be used. 680 // 681 // The ProducedAt date is automatically set to the current date, to the nearest minute. 682 func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) { 683 var publicKeyInfo struct { 684 Algorithm pkix.AlgorithmIdentifier 685 PublicKey asn1.BitString 686 } 687 if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { 688 return nil, err 689 } 690 691 if template.IssuerHash == 0 { 692 template.IssuerHash = crypto.SHA1 693 } 694 hashOID := getOIDFromHashAlgorithm(template.IssuerHash) 695 if hashOID == nil { 696 return nil, errors.New("unsupported issuer hash algorithm") 697 } 698 699 if !template.IssuerHash.Available() { 700 return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash) 701 } 702 h := template.IssuerHash.New() 703 h.Write(publicKeyInfo.PublicKey.RightAlign()) 704 issuerKeyHash := h.Sum(nil) 705 706 h.Reset() 707 h.Write(issuer.RawSubject) 708 issuerNameHash := h.Sum(nil) 709 710 innerResponse := singleResponse{ 711 CertID: certID{ 712 HashAlgorithm: pkix.AlgorithmIdentifier{ 713 Algorithm: hashOID, 714 Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, 715 }, 716 NameHash: issuerNameHash, 717 IssuerKeyHash: issuerKeyHash, 718 SerialNumber: template.SerialNumber, 719 }, 720 ThisUpdate: template.ThisUpdate.UTC(), 721 NextUpdate: template.NextUpdate.UTC(), 722 SingleExtensions: template.ExtraExtensions, 723 } 724 725 switch template.Status { 726 case Good: 727 innerResponse.Good = true 728 case Unknown: 729 innerResponse.Unknown = true 730 case Revoked: 731 innerResponse.Revoked = revokedInfo{ 732 RevocationTime: template.RevokedAt.UTC(), 733 Reason: asn1.Enumerated(template.RevocationReason), 734 } 735 } 736 737 rawResponderID := asn1.RawValue{ 738 Class: 2, // context-specific 739 Tag: 1, // Name (explicit tag) 740 IsCompound: true, 741 Bytes: responderCert.RawSubject, 742 } 743 tbsResponseData := responseData{ 744 Version: 0, 745 RawResponderID: rawResponderID, 746 ProducedAt: time.Now().Truncate(time.Minute).UTC(), 747 Responses: []singleResponse{innerResponse}, 748 } 749 750 tbsResponseDataDER, err := asn1.Marshal(tbsResponseData) 751 if err != nil { 752 return nil, err 753 } 754 755 hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) 756 if err != nil { 757 return nil, err 758 } 759 760 responseHash := hashFunc.New() 761 responseHash.Write(tbsResponseDataDER) 762 signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc) 763 if err != nil { 764 return nil, err 765 } 766 767 response := basicResponse{ 768 TBSResponseData: tbsResponseData, 769 SignatureAlgorithm: signatureAlgorithm, 770 Signature: asn1.BitString{ 771 Bytes: signature, 772 BitLength: 8 * len(signature), 773 }, 774 } 775 if template.Certificate != nil { 776 response.Certificates = []asn1.RawValue{ 777 {FullBytes: template.Certificate.Raw}, 778 } 779 } 780 responseDER, err := asn1.Marshal(response) 781 if err != nil { 782 return nil, err 783 } 784 785 return asn1.Marshal(responseASN1{ 786 Status: asn1.Enumerated(Success), 787 Response: responseBytes{ 788 ResponseType: idPKIXOCSPBasic, 789 Response: responseDER, 790 }, 791 }) 792 }