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