1
2
3
4
5
6
7
8 package 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
32
33 type ResponseStatus int
34
35 const (
36 Success ResponseStatus = 0
37 Malformed ResponseStatus = 1
38 InternalError ResponseStatus = 2
39 TryLater ResponseStatus = 3
40
41
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
66
67
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
77
78
79 type certID struct {
80 HashAlgorithm pkix.AlgorithmIdentifier
81 NameHash []byte
82 IssuerKeyHash []byte
83 SerialNumber *big.Int
84 }
85
86
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
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) },
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
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
251
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
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
281
282
283
284 const (
285
286 Good = 0
287
288 Revoked = 1
289
290 Unknown = 2
291
292
293
294 ServerFailed = 3
295 )
296
297
298 const (
299 Unspecified = 0
300 KeyCompromise = 1
301 CACompromise = 2
302 AffiliationChanged = 3
303 Superseded = 4
304 CessationOfOperation = 5
305 CertificateHold = 6
306
307 RemoveFromCRL = 8
308 PrivilegeWithdrawn = 9
309 AACompromise = 10
310 )
311
312
313 type Request struct {
314 HashAlgorithm crypto.Hash
315 IssuerNameHash []byte
316 IssuerKeyHash []byte
317 SerialNumber *big.Int
318 }
319
320
321 func (req *Request) Marshal() ([]byte, error) {
322 hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm)
323 if hashAlg == nil {
324 return nil, errors.New("Unknown hash algorithm")
325 }
326 return asn1.Marshal(ocspRequest{
327 tbsRequest{
328 Version: 0,
329 RequestList: []request{
330 {
331 Cert: certID{
332 pkix.AlgorithmIdentifier{
333 Algorithm: hashAlg,
334 Parameters: asn1.RawValue{Tag: 5 },
335 },
336 req.IssuerNameHash,
337 req.IssuerKeyHash,
338 req.SerialNumber,
339 },
340 },
341 },
342 },
343 })
344 }
345
346
347
348 type Response struct {
349 Raw []byte
350
351
352 Status int
353 SerialNumber *big.Int
354 ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
355 RevocationReason int
356 Certificate *x509.Certificate
357
358
359 TBSResponseData []byte
360 Signature []byte
361 SignatureAlgorithm x509.SignatureAlgorithm
362
363
364
365
366 IssuerHash crypto.Hash
367
368
369
370
371 RawResponderName []byte
372
373
374
375 ResponderKeyHash []byte
376
377
378
379
380
381
382 Extensions []pkix.Extension
383
384
385
386
387
388
389 ExtraExtensions []pkix.Extension
390 }
391
392
393
394
395
396 var (
397 MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
398 InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
399 TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
400 SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
401 UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
402 )
403
404
405
406
407
408
409 func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
410 return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
411 }
412
413
414 type ParseError string
415
416 func (p ParseError) Error() string {
417 return string(p)
418 }
419
420
421
422
423 func ParseRequest(bytes []byte) (*Request, error) {
424 var req ocspRequest
425 rest, err := asn1.Unmarshal(bytes, &req)
426 if err != nil {
427 return nil, err
428 }
429 if len(rest) > 0 {
430 return nil, ParseError("trailing data in OCSP request")
431 }
432
433 if len(req.TBSRequest.RequestList) == 0 {
434 return nil, ParseError("OCSP request contains no request body")
435 }
436 innerRequest := req.TBSRequest.RequestList[0]
437
438 hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
439 if hashFunc == crypto.Hash(0) {
440 return nil, ParseError("OCSP request uses unknown hash function")
441 }
442
443 return &Request{
444 HashAlgorithm: hashFunc,
445 IssuerNameHash: innerRequest.Cert.NameHash,
446 IssuerKeyHash: innerRequest.Cert.IssuerKeyHash,
447 SerialNumber: innerRequest.Cert.SerialNumber,
448 }, nil
449 }
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466 func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
467 return ParseResponseForCert(bytes, nil, issuer)
468 }
469
470
471
472
473
474
475 func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
476 var resp responseASN1
477 rest, err := asn1.Unmarshal(bytes, &resp)
478 if err != nil {
479 return nil, err
480 }
481 if len(rest) > 0 {
482 return nil, ParseError("trailing data in OCSP response")
483 }
484
485 if status := ResponseStatus(resp.Status); status != Success {
486 return nil, ResponseError{status}
487 }
488
489 if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
490 return nil, ParseError("bad OCSP response type")
491 }
492
493 var basicResp basicResponse
494 rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
495 if err != nil {
496 return nil, err
497 }
498 if len(rest) > 0 {
499 return nil, ParseError("trailing data in OCSP response")
500 }
501
502 if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
503 return nil, ParseError("OCSP response contains bad number of responses")
504 }
505
506 var singleResp singleResponse
507 if cert == nil {
508 singleResp = basicResp.TBSResponseData.Responses[0]
509 } else {
510 match := false
511 for _, resp := range basicResp.TBSResponseData.Responses {
512 if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
513 singleResp = resp
514 match = true
515 break
516 }
517 }
518 if !match {
519 return nil, ParseError("no response matching the supplied certificate")
520 }
521 }
522
523 ret := &Response{
524 Raw: bytes,
525 TBSResponseData: basicResp.TBSResponseData.Raw,
526 Signature: basicResp.Signature.RightAlign(),
527 SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm),
528 Extensions: singleResp.SingleExtensions,
529 SerialNumber: singleResp.CertID.SerialNumber,
530 ProducedAt: basicResp.TBSResponseData.ProducedAt,
531 ThisUpdate: singleResp.ThisUpdate,
532 NextUpdate: singleResp.NextUpdate,
533 }
534
535
536
537
538 rawResponderID := basicResp.TBSResponseData.RawResponderID
539 switch rawResponderID.Tag {
540 case 1:
541 var rdn pkix.RDNSequence
542 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 {
543 return nil, ParseError("invalid responder name")
544 }
545 ret.RawResponderName = rawResponderID.Bytes
546 case 2:
547 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 {
548 return nil, ParseError("invalid responder key hash")
549 }
550 default:
551 return nil, ParseError("invalid responder id tag")
552 }
553
554 if len(basicResp.Certificates) > 0 {
555
556
557
558
559
560
561
562 ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
563 if err != nil {
564 return nil, err
565 }
566
567 if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
568 return nil, ParseError("bad signature on embedded certificate: " + err.Error())
569 }
570
571 if issuer != nil {
572 if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
573 return nil, ParseError("bad OCSP signature: " + err.Error())
574 }
575 }
576 } else if issuer != nil {
577 if err := ret.CheckSignatureFrom(issuer); err != nil {
578 return nil, ParseError("bad OCSP signature: " + err.Error())
579 }
580 }
581
582 for _, ext := range singleResp.SingleExtensions {
583 if ext.Critical {
584 return nil, ParseError("unsupported critical extension")
585 }
586 }
587
588 for h, oid := range hashOIDs {
589 if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) {
590 ret.IssuerHash = h
591 break
592 }
593 }
594 if ret.IssuerHash == 0 {
595 return nil, ParseError("unsupported issuer hash algorithm")
596 }
597
598 switch {
599 case bool(singleResp.Good):
600 ret.Status = Good
601 case bool(singleResp.Unknown):
602 ret.Status = Unknown
603 default:
604 ret.Status = Revoked
605 ret.RevokedAt = singleResp.Revoked.RevocationTime
606 ret.RevocationReason = int(singleResp.Revoked.Reason)
607 }
608
609 return ret, nil
610 }
611
612
613 type RequestOptions struct {
614
615
616 Hash crypto.Hash
617 }
618
619 func (opts *RequestOptions) hash() crypto.Hash {
620 if opts == nil || opts.Hash == 0 {
621
622 return crypto.SHA1
623 }
624 return opts.Hash
625 }
626
627
628
629 func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
630 hashFunc := opts.hash()
631
632
633
634
635 _, ok := hashOIDs[hashFunc]
636 if !ok {
637 return nil, x509.ErrUnsupportedAlgorithm
638 }
639
640 if !hashFunc.Available() {
641 return nil, x509.ErrUnsupportedAlgorithm
642 }
643 h := opts.hash().New()
644
645 var publicKeyInfo struct {
646 Algorithm pkix.AlgorithmIdentifier
647 PublicKey asn1.BitString
648 }
649 if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
650 return nil, err
651 }
652
653 h.Write(publicKeyInfo.PublicKey.RightAlign())
654 issuerKeyHash := h.Sum(nil)
655
656 h.Reset()
657 h.Write(issuer.RawSubject)
658 issuerNameHash := h.Sum(nil)
659
660 req := &Request{
661 HashAlgorithm: hashFunc,
662 IssuerNameHash: issuerNameHash,
663 IssuerKeyHash: issuerKeyHash,
664 SerialNumber: cert.SerialNumber,
665 }
666 return req.Marshal()
667 }
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683 func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
684 var publicKeyInfo struct {
685 Algorithm pkix.AlgorithmIdentifier
686 PublicKey asn1.BitString
687 }
688 if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
689 return nil, err
690 }
691
692 if template.IssuerHash == 0 {
693 template.IssuerHash = crypto.SHA1
694 }
695 hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
696 if hashOID == nil {
697 return nil, errors.New("unsupported issuer hash algorithm")
698 }
699
700 if !template.IssuerHash.Available() {
701 return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
702 }
703 h := template.IssuerHash.New()
704 h.Write(publicKeyInfo.PublicKey.RightAlign())
705 issuerKeyHash := h.Sum(nil)
706
707 h.Reset()
708 h.Write(issuer.RawSubject)
709 issuerNameHash := h.Sum(nil)
710
711 innerResponse := singleResponse{
712 CertID: certID{
713 HashAlgorithm: pkix.AlgorithmIdentifier{
714 Algorithm: hashOID,
715 Parameters: asn1.RawValue{Tag: 5 },
716 },
717 NameHash: issuerNameHash,
718 IssuerKeyHash: issuerKeyHash,
719 SerialNumber: template.SerialNumber,
720 },
721 ThisUpdate: template.ThisUpdate.UTC(),
722 NextUpdate: template.NextUpdate.UTC(),
723 SingleExtensions: template.ExtraExtensions,
724 }
725
726 switch template.Status {
727 case Good:
728 innerResponse.Good = true
729 case Unknown:
730 innerResponse.Unknown = true
731 case Revoked:
732 innerResponse.Revoked = revokedInfo{
733 RevocationTime: template.RevokedAt.UTC(),
734 Reason: asn1.Enumerated(template.RevocationReason),
735 }
736 }
737
738 rawResponderID := asn1.RawValue{
739 Class: 2,
740 Tag: 1,
741 IsCompound: true,
742 Bytes: responderCert.RawSubject,
743 }
744 tbsResponseData := responseData{
745 Version: 0,
746 RawResponderID: rawResponderID,
747 ProducedAt: time.Now().Truncate(time.Minute).UTC(),
748 Responses: []singleResponse{innerResponse},
749 }
750
751 tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
752 if err != nil {
753 return nil, err
754 }
755
756 hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
757 if err != nil {
758 return nil, err
759 }
760
761 responseHash := hashFunc.New()
762 responseHash.Write(tbsResponseDataDER)
763 signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
764 if err != nil {
765 return nil, err
766 }
767
768 response := basicResponse{
769 TBSResponseData: tbsResponseData,
770 SignatureAlgorithm: signatureAlgorithm,
771 Signature: asn1.BitString{
772 Bytes: signature,
773 BitLength: 8 * len(signature),
774 },
775 }
776 if template.Certificate != nil {
777 response.Certificates = []asn1.RawValue{
778 {FullBytes: template.Certificate.Raw},
779 }
780 }
781 responseDER, err := asn1.Marshal(response)
782 if err != nil {
783 return nil, err
784 }
785
786 return asn1.Marshal(responseASN1{
787 Status: asn1.Enumerated(Success),
788 Response: responseBytes{
789 ResponseType: idPKIXOCSPBasic,
790 Response: responseDER,
791 },
792 })
793 }
794
View as plain text