ocsp.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2010 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. // Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses
  5. // are signed messages attesting to the validity of a certificate for a small
  6. // period of time. This is used to manage revocation for X.509 certificates.
  7. package ocsp
  8. import (
  9. "crypto"
  10. "crypto/rsa"
  11. _ "crypto/sha1"
  12. "crypto/x509"
  13. "crypto/x509/pkix"
  14. "encoding/asn1"
  15. "time"
  16. )
  17. var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
  18. var idSHA1WithRSA = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 1, 5})
  19. // These are internal structures that reflect the ASN.1 structure of an OCSP
  20. // response. See RFC 2560, section 4.2.
  21. const (
  22. ocspSuccess = 0
  23. ocspMalformed = 1
  24. ocspInternalError = 2
  25. ocspTryLater = 3
  26. ocspSigRequired = 4
  27. ocspUnauthorized = 5
  28. )
  29. type certID struct {
  30. HashAlgorithm pkix.AlgorithmIdentifier
  31. NameHash []byte
  32. IssuerKeyHash []byte
  33. SerialNumber asn1.RawValue
  34. }
  35. type responseASN1 struct {
  36. Status asn1.Enumerated
  37. Response responseBytes `asn1:"explicit,tag:0"`
  38. }
  39. type responseBytes struct {
  40. ResponseType asn1.ObjectIdentifier
  41. Response []byte
  42. }
  43. type basicResponse struct {
  44. TBSResponseData responseData
  45. SignatureAlgorithm pkix.AlgorithmIdentifier
  46. Signature asn1.BitString
  47. Certificates []asn1.RawValue `asn1:"explicit,tag:0,optional"`
  48. }
  49. type responseData struct {
  50. Raw asn1.RawContent
  51. Version int `asn1:"optional,default:1,explicit,tag:0"`
  52. RequestorName pkix.RDNSequence `asn1:"optional,explicit,tag:1"`
  53. KeyHash []byte `asn1:"optional,explicit,tag:2"`
  54. ProducedAt time.Time
  55. Responses []singleResponse
  56. }
  57. type singleResponse struct {
  58. CertID certID
  59. Good asn1.Flag `asn1:"explicit,tag:0,optional"`
  60. Revoked revokedInfo `asn1:"explicit,tag:1,optional"`
  61. Unknown asn1.Flag `asn1:"explicit,tag:2,optional"`
  62. ThisUpdate time.Time
  63. NextUpdate time.Time `asn1:"explicit,tag:0,optional"`
  64. }
  65. type revokedInfo struct {
  66. RevocationTime time.Time
  67. Reason int `asn1:"explicit,tag:0,optional"`
  68. }
  69. // This is the exposed reflection of the internal OCSP structures.
  70. const (
  71. // Good means that the certificate is valid.
  72. Good = iota
  73. // Revoked means that the certificate has been deliberately revoked.
  74. Revoked = iota
  75. // Unknown means that the OCSP responder doesn't know about the certificate.
  76. Unknown = iota
  77. // ServerFailed means that the OCSP responder failed to process the request.
  78. ServerFailed = iota
  79. )
  80. // Response represents an OCSP response. See RFC 2560.
  81. type Response struct {
  82. // Status is one of {Good, Revoked, Unknown, ServerFailed}
  83. Status int
  84. SerialNumber []byte
  85. ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
  86. RevocationReason int
  87. Certificate *x509.Certificate
  88. }
  89. // ParseError results from an invalid OCSP response.
  90. type ParseError string
  91. func (p ParseError) Error() string {
  92. return string(p)
  93. }
  94. // ParseResponse parses an OCSP response in DER form. It only supports
  95. // responses for a single certificate and only those using RSA signatures.
  96. // Non-RSA responses will result in an x509.UnsupportedAlgorithmError.
  97. // Signature errors or parse failures will result in a ParseError.
  98. func ParseResponse(bytes []byte) (*Response, error) {
  99. var resp responseASN1
  100. rest, err := asn1.Unmarshal(bytes, &resp)
  101. if err != nil {
  102. return nil, err
  103. }
  104. if len(rest) > 0 {
  105. return nil, ParseError("trailing data in OCSP response")
  106. }
  107. ret := new(Response)
  108. if resp.Status != ocspSuccess {
  109. ret.Status = ServerFailed
  110. return ret, nil
  111. }
  112. if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
  113. return nil, ParseError("bad OCSP response type")
  114. }
  115. var basicResp basicResponse
  116. rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
  117. if err != nil {
  118. return nil, err
  119. }
  120. if len(basicResp.Certificates) != 1 {
  121. return nil, ParseError("OCSP response contains bad number of certificates")
  122. }
  123. if len(basicResp.TBSResponseData.Responses) != 1 {
  124. return nil, ParseError("OCSP response contains bad number of responses")
  125. }
  126. ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
  127. if err != nil {
  128. return nil, err
  129. }
  130. if ret.Certificate.PublicKeyAlgorithm != x509.RSA || !basicResp.SignatureAlgorithm.Algorithm.Equal(idSHA1WithRSA) {
  131. return nil, x509.ErrUnsupportedAlgorithm
  132. }
  133. hashType := crypto.SHA1
  134. h := hashType.New()
  135. pub := ret.Certificate.PublicKey.(*rsa.PublicKey)
  136. h.Write(basicResp.TBSResponseData.Raw)
  137. digest := h.Sum(nil)
  138. signature := basicResp.Signature.RightAlign()
  139. if rsa.VerifyPKCS1v15(pub, hashType, digest, signature) != nil {
  140. return nil, ParseError("bad OCSP signature")
  141. }
  142. r := basicResp.TBSResponseData.Responses[0]
  143. ret.SerialNumber = r.CertID.SerialNumber.Bytes
  144. switch {
  145. case bool(r.Good):
  146. ret.Status = Good
  147. case bool(r.Unknown):
  148. ret.Status = Unknown
  149. default:
  150. ret.Status = Revoked
  151. ret.RevokedAt = r.Revoked.RevocationTime
  152. ret.RevocationReason = r.Revoked.Reason
  153. }
  154. ret.ProducedAt = basicResp.TBSResponseData.ProducedAt
  155. ret.ThisUpdate = r.ThisUpdate
  156. ret.NextUpdate = r.NextUpdate
  157. return ret, nil
  158. }