Index: net/cert/internal/parse_ocsp.h |
diff --git a/net/cert/internal/parse_ocsp.h b/net/cert/internal/parse_ocsp.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..49f9b06e257d29d811ca823326c20db54a412a0b |
--- /dev/null |
+++ b/net/cert/internal/parse_ocsp.h |
@@ -0,0 +1,243 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef NET_CERT_INTERNAL_PARSE_OCSP_H_ |
+#define NET_CERT_INTERNAL_PARSE_OCSP_H_ |
+ |
+#include <string> |
+#include <vector> |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "net/base/hash_value.h" |
+#include "net/cert/internal/parse_certificate.h" |
+#include "net/cert/internal/signature_algorithm.h" |
+#include "net/der/input.h" |
+#include "net/der/parse_values.h" |
+#include "net/der/parser.h" |
+#include "net/der/tag.h" |
+ |
+namespace net { |
+ |
+// OCSPCertID contains a representation of a DER-encoded RFC 6960 "CertID". |
+// |
+// CertID ::= SEQUENCE { |
+// hashAlgorithm AlgorithmIdentifier, |
+// issuerNameHash OCTET STRING, -- Hash of issuer's DN |
+// issuerKeyHash OCTET STRING, -- Hash of issuer's public key |
+// serialNumber CertificateSerialNumber |
+// } |
+struct OCSPCertID { |
+ OCSPCertID(); |
+ ~OCSPCertID(); |
+ |
+ DigestAlgorithm hash_algorithm; |
+ der::Input issuer_name_hash; |
+ der::Input issuer_key_hash; |
+ der::Input serial_number; |
+}; |
+ |
+// OCSPCertStatus contains a representation of a DER-encoded RFC 6960 |
+// "CertStatus". |
+// |
+// CertStatus ::= CHOICE { |
+// good [0] IMPLICIT NULL, |
+// revoked [1] IMPLICIT RevokedInfo, |
+// unknown [2] IMPLICIT UnknownInfo |
+// } |
+// |
+// RevokedInfo ::= SEQUENCE { |
+// revocationTime GeneralizedTime, |
+// revocationReason [0] EXPLICIT CRLReason OPTIONAL |
+// } |
+// |
+// UnknownInfo ::= NULL |
+struct OCSPCertStatus { |
+ enum class Status { |
+ GOOD, |
+ REVOKED, |
+ UNKNOWN, |
+ }; |
+ |
+ enum class RevocationReason { |
eroman
2016/02/13 00:56:50
Where is this specified?
Same comment as the othe
svaldez
2016/02/16 17:25:11
Done.
|
+ UNSPECIFIED, |
+ KEY_COMPROMISE, |
+ CA_COMPROMISE, |
+ AFFILIATION_CHANGED, |
+ SUPERSEDED, |
+ CESSATION_OF_OPERATION, |
+ CERTIFICATE_HOLD, |
+ UNUSED, |
+ REMOVE_FROM_CRL, |
+ PRIVILEGE_WITHDRAWN, |
+ A_COMPROMISE, |
+ |
+ REVOCATION_REASON_MAX |
+ }; |
+ |
+ Status status; |
+ der::GeneralizedTime revocation_time; |
+ bool has_reason; |
+ RevocationReason revocation_reason; |
+}; |
+ |
+// OCSPSingleResponse contains a representation of a DER-encoded RFC 6960 |
+// "SingleResponse". The 'certID' and 'singleExtensions' fields are pointers |
eroman
2016/02/13 00:56:50
Would be clearer to reference them by name |cert_i
svaldez
2016/02/16 17:25:11
Done.
|
+// to the original object and are only valid as long as it is alive. They also |
+// aren't verified until they are parsed. |
+// |
+// SingleResponse ::= SEQUENCE { |
+// certID CertID, |
+// certStatus CertStatus, |
+// thisUpdate GeneralizedTime, |
+// nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, |
+// singleExtensions [1] EXPLICIT Extensions OPTIONAL |
+// } |
+struct OCSPSingleResponse { |
+ OCSPSingleResponse(); |
+ ~OCSPSingleResponse(); |
+ |
+ der::Input cert_id_tlv; |
+ OCSPCertStatus cert_status; |
+ der::GeneralizedTime this_update; |
+ bool has_next_update; |
+ der::GeneralizedTime next_update; |
+ bool has_extensions; |
+ der::Input extensions; |
+}; |
+ |
+// OCSPResponseData contains a representation of a DER-encoded RFC 6960 |
+// "ResponseData". The 'responses' and 'extensions' fields are pointers to the |
eroman
2016/02/13 00:56:50
Are these referring to the RFC 6960 names, or the
svaldez
2016/02/16 17:25:11
Done.
|
+// original object and are only valid as long as it is alive. They also aren't |
+// verified until they are parsed into OCSPSingleResponse and ParsedExtensions. |
+// |
+// ResponseData ::= SEQUENCE { |
+// version [0] EXPLICIT Version DEFAULT v1, |
+// responderID ResponderID, |
+// producedAt GeneralizedTime, |
+// responses SEQUENCE OF SingleResponse, |
+// responseExtensions [1] EXPLICIT Extensions OPTIONAL |
+// } |
+struct OCSPResponseData { |
+ enum class ResponderType { NAME, KEY_HASH }; |
+ |
+ struct ResponderID { |
+ ResponderType type; |
+ der::Input name; |
+ HashValue key_hash; |
+ }; |
+ |
+ OCSPResponseData(); |
+ ~OCSPResponseData(); |
+ |
+ uint8_t version; |
+ OCSPResponseData::ResponderID responder_id; |
+ der::GeneralizedTime produced_at; |
+ std::vector<der::Input> responses; |
+ bool has_extensions; |
+ der::Input extensions; |
+}; |
+ |
+// OCSPResponse contains a representation of a DER-encoded RFC 6960 |
+// "OCSPResponse" and the corresponding "BasicOCSPResponse". The 'data' field |
eroman
2016/02/13 00:56:50
'data' --> |data| ?
svaldez
2016/02/16 17:25:11
Done.
|
+// is a pointer to the original object and are only valid as long is it is |
+// alive. The 'data' field isn't verified until it is parsed into an |
eroman
2016/02/13 00:56:50
same
svaldez
2016/02/16 17:25:11
Done.
|
+// OCSPResponseData. |
+// |
+// OCSPResponse ::= SEQUENCE { |
+// responseStatus OCSPResponseStatus, |
+// responseBytes [0] EXPLICIT ResponseBytes OPTIONAL |
+// } |
+// |
+// BasicOCSPResponse ::= SEQUENCE { |
+// tbsResponseData ResponseData, |
+// signatureAlgorithm AlgorithmIdentifier, |
+// signature BIT STRING, |
+// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL |
+// } |
+struct NET_EXPORT OCSPResponse { |
+ enum class ResponseStatus { |
+ SUCCESSFUL, |
+ MALFORMED_REQUEST, |
+ INTERNAL_ERROR, |
+ TRY_LATER, |
+ SIG_REQUIRED, |
+ UNAUTHORIZED, |
+ |
+ RESPONSE_STATUS_MAX, |
eroman
2016/02/13 00:56:50
Several things here:
(1) Since this relies on th
svaldez
2016/02/16 17:25:11
Done.
|
+ }; |
+ |
+ OCSPResponse(); |
+ ~OCSPResponse(); |
+ |
+ ResponseStatus status; |
+ der::Input data; |
+ scoped_ptr<SignatureAlgorithm> signature_algorithm; |
+ der::BitString signature; |
+ std::vector<der::Input> certs; |
+}; |
+ |
+// From RFC 6960: |
+// |
+// id-pkix-ocsp OBJECT IDENTIFIER ::= { id-ad-ocsp } |
+// id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 } |
+// |
+// In dotted notation: 1.3.6.1.5.5.7.48.1.1 |
+NET_EXPORT der::Input BasicOCSPResponseOid(); |
+ |
+// Parses a DER-encoded OCSP "CertID" as specified by RFC 6960. Returns true on |
+// success and sets the results in |out|. |
+// |
+// On failure |out| has an undefined state. Some of its fields may have been |
+// updated during parsing, whereas others may not have been changed. |
+NET_EXPORT_PRIVATE bool ParseOCSPCertID(der::Input raw_tlv, OCSPCertID* out); |
+ |
+// Parses a DER-encoded OCSP "SingleResponse" as specified by RFC 6960. Returns |
+// true on success and sets the results in |out|. The resulting |out| |
+// references data from |raw_tlv| and is only valid for the lifetime of |
+// |raw_tlv|. |
+// |
+// On failure |out| has an undefined state. Some of its fields may have been |
+// updated during parsing, whereas others may not have been changed. |
+NET_EXPORT_PRIVATE bool ParseOCSPSingleResponse(der::Input raw_tlv, |
eroman
2016/02/13 00:56:50
Plz change to |const der::Input&| for consistency
svaldez
2016/02/16 17:25:11
Done.
|
+ OCSPSingleResponse* out); |
+ |
+// Parses a DER-encoded OCSP "ResponseData" as specified by RFC 6960. Returns |
+// true on success and sets the results in |out|. The resulting |out| |
+// references data from |raw_tlv| and is only valid for the lifetime of |
+// |raw_tlv|. |
+// |
+// On failure |out| has an undefined state. Some of its fields may have been |
+// updated during parsing, whereas others may not have been changed. |
+NET_EXPORT_PRIVATE bool ParseOCSPResponseData(der::Input raw_tlv, |
+ OCSPResponseData* out); |
+ |
+// Parses a DER-encoded "OCSPResponse" as specified by RFC 6960. Returns true |
+// on success and sets the results in |out|. The resulting |out| |
+// references data from |ocsp_response| and is only valid for the lifetime of |
+// |ocsp_response|. |
+// |
+// On failure |out| has an undefined state. Some of its fields may have been |
+// updated during parsing, whereas others may not have been changed. |
+NET_EXPORT_PRIVATE bool ParseOCSPResponse(der::Input ocsp_response, |
+ OCSPResponse* out); |
+ |
+// Verifies that the OCSP Response |response| is signed and has a valid trust |
+// path to the issuer |issuer_cert|. |
+NET_EXPORT_PRIVATE bool VerifyOCSPResponse( |
+ const OCSPResponse* response, |
eroman
2016/02/13 00:56:50
(1) Why pointers instead of references? What is th
svaldez
2016/02/16 17:25:11
I'll split it off to a separate CL once I'm done r
eroman
2016/02/16 23:42:25
I think there can be a logical separation between
|
+ const ParsedCertificate* issuer_cert); |
+ |
+// Checks the certificate status of |cert| based on the OCSPResponseData |
+// |response_data| and sets the results in |out|. |
+// |
+// On failure |out| has an undefined state. Some of its fields may have been |
+// updated during parsing, whereas others may not have been changed. |
+NET_EXPORT_PRIVATE bool GetOCSPCertStatus(const OCSPResponseData* response_data, |
eroman
2016/02/13 00:56:50
Why are the inputs pointers rather than references
svaldez
2016/02/16 17:25:11
Done.
|
+ const ParsedCertificate* issuer, |
+ const ParsedCertificate* cert, |
+ OCSPCertStatus* out); |
+ |
+} // namespace net |
+ |
+#endif // NET_CERT_INTERNAL_PARSE_OCSP_H_ |