Chromium Code Reviews| 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..f79cd7a1d080ee63ebd140c4f772560cebe2510b |
| --- /dev/null |
| +++ b/net/cert/internal/parse_ocsp.h |
| @@ -0,0 +1,285 @@ |
| +// 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". |revocation_time| and |has_reason| are only valid when |
| +// |status| is REVOKED. |revocation_reason| is only valid when |has_reason| is |
| +// true. |
| +// |
| +// 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 |
| +// |
| +// CRLReason ::= ENUMERATED { |
| +// unspecified (0), |
| +// keyCompromise (1), |
| +// cACompromise (2), |
| +// affiliationChanged (3), |
| +// superseded (4), |
| +// cessationOfOperation (5), |
| +// certificateHold (6), |
| +// -- value 7 is not used |
| +// removeFromCRL (8), |
| +// privilegeWithdrawn (9), |
| +// aACompromise (10) |
| +// } |
| +// (from RFC 5280) |
| +struct OCSPCertStatus { |
| + enum class Status { |
| + GOOD, |
| + REVOKED, |
| + UNKNOWN, |
| + }; |
| + |
| + // Correspond to the values of CRLReason |
| + enum class RevocationReason { |
| + UNSPECIFIED = 0, |
| + KEY_COMPROMISE = 1, |
| + CA_COMPROMISE = 2, |
| + AFFILIATION_CHANGED = 3, |
| + SUPERSEDED = 4, |
| + CESSATION_OF_OPERATION = 5, |
| + CERTIFICATE_HOLD = 6, |
| + UNUSED = 7, |
| + REMOVE_FROM_CRL = 8, |
| + PRIVILEGE_WITHDRAWN = 9, |
| + A_COMPROMISE = 10, |
|
eroman
2016/02/19 02:27:33
why not AA_COMPROMISE? the aa i believe means "att
svaldez
2016/02/19 15:13:55
Done.
|
| + |
| + LAST = A_COMPROMISE, |
| + }; |
| + |
| + Status status; |
| + der::GeneralizedTime revocation_time; |
| + bool has_reason; |
| + RevocationReason revocation_reason; |
| +}; |
| + |
| +// OCSPSingleResponse contains a representation of a DER-encoded RFC 6960 |
| +// "SingleResponse". The |cert_id_tlv| and |extensions| fields are pointers to |
| +// the original object and are only valid as long as it is alive. They also |
| +// aren't verified until they are parsed. |next_update| is only valid if |
| +// |has_next_update| is true and |extensions| is only valid if |has_extensions| |
| +// is true. |
| +// |
| +// 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 |
| +// 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. |
| +// |extensions| is only valid if |has_extensions| is true. |
| +// |
| +// 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 |
| +// 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 |
| +// OCSPResponseData. |data|, |signature_algorithm|, |signature|, and |
| +// |has_certs| is only valid if |status| is SUCCESSFUL. |certs| is only valid |
| +// if |has_certs| is true. |
| +// |
| +// OCSPResponse ::= SEQUENCE { |
| +// responseStatus OCSPResponseStatus, |
| +// responseBytes [0] EXPLICIT ResponseBytes OPTIONAL |
| +// } |
| +// |
| +// ResponseBytes ::= SEQUENCE { |
| +// responseType OBJECT IDENTIFIER, |
| +// response OCTET STRING |
| +// } |
| +// |
| +// BasicOCSPResponse ::= SEQUENCE { |
| +// tbsResponseData ResponseData, |
| +// signatureAlgorithm AlgorithmIdentifier, |
| +// signature BIT STRING, |
| +// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL |
| +// } |
| +// |
| +// OCSPResponseStatus ::= ENUMERATED { |
| +// successful (0), -- Response has valid confirmations |
| +// malformedRequest (1), -- Illegal confirmation request |
| +// internalError (2), -- Internal error in issuer |
| +// tryLater (3), -- Try again later |
| +// -- (4) is not used |
| +// sigRequired (5), -- Must sign the request |
| +// unauthorized (6) -- Request unauthorized |
| +// } |
| +struct NET_EXPORT OCSPResponse { |
| + // Correspond to the values of OCSPResponseStatus |
| + enum class ResponseStatus { |
| + SUCCESSFUL = 0, |
| + MALFORMED_REQUEST = 1, |
| + INTERNAL_ERROR = 2, |
| + TRY_LATER = 3, |
| + UNUSED = 4, |
| + SIG_REQUIRED = 5, |
| + UNAUTHORIZED = 6, |
| + |
| + LAST = UNAUTHORIZED, |
| + }; |
| + |
| + OCSPResponse(); |
| + ~OCSPResponse(); |
| + |
| + ResponseStatus status; |
| + der::Input data; |
| + scoped_ptr<SignatureAlgorithm> signature_algorithm; |
| + der::BitString signature; |
| + bool has_certs; |
| + 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(const 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(const der::Input& raw_tlv, |
| + 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(const 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 |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 ParseOCSPResponse(const der::Input& raw_tlv, |
| + OCSPResponse* out); |
| + |
| +// Checks the certificate status of |cert| based on the OCSPResponseData |
| +// |response_data| and issuer |issuer| 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, |
| + const ParsedCertificate& issuer, |
| + const ParsedCertificate& cert, |
| + OCSPCertStatus* 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, |
| + const ParsedCertificate& issuer_cert); |
| + |
| +} // namespace net |
| + |
| +#endif // NET_CERT_INTERNAL_PARSE_OCSP_H_ |