blob: c0fc061b5e43243f39d156444df42a61f38915e5 [file] [log] [blame]
// 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.
#include "net/cert/internal/parse_ocsp.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "net/cert/internal/test_helpers.h"
#include "net/cert/x509_certificate.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
std::string GetFilePath(const std::string& file_name) {
return std::string("net/data/parse_ocsp_unittest/") + file_name;
}
enum OCSPFailure {
OCSP_SUCCESS,
PARSE_CERT,
PARSE_OCSP,
OCSP_NOT_SUCCESSFUL,
PARSE_OCSP_DATA,
PARSE_OCSP_SINGLE_RESPONSE,
VERIFY_OCSP,
OCSP_SUCCESS_REVOKED,
OCSP_SUCCESS_UNKNOWN,
};
OCSPFailure ParseOCSP(const std::string& file_name) {
std::string ocsp_data;
std::string ca_data;
std::string cert_data;
const PemBlockMapping mappings[] = {
{"OCSP RESPONSE", &ocsp_data},
{"CA CERTIFICATE", &ca_data},
{"CERTIFICATE", &cert_data},
};
if (!ReadTestDataFromPemFile(GetFilePath(file_name), mappings))
return PARSE_CERT;
der::Input ocsp_input(&ocsp_data);
der::Input ca_input(&ca_data);
der::Input cert_input(&cert_data);
der::Input issuer_tbs_certificate_tlv;
der::Input issuer_signature_algorithm_tlv;
der::BitString issuer_signature_value;
der::Input cert_tbs_certificate_tlv;
der::Input cert_signature_algorithm_tlv;
der::BitString cert_signature_value;
if (!ParseCertificate(ca_input, &issuer_tbs_certificate_tlv,
&issuer_signature_algorithm_tlv,
&issuer_signature_value))
return PARSE_CERT;
if (!ParseCertificate(cert_input, &cert_tbs_certificate_tlv,
&cert_signature_algorithm_tlv, &cert_signature_value))
return PARSE_CERT;
OCSPResponse parsed_ocsp;
OCSPResponseData parsed_ocsp_data;
if (!ParseOCSPResponse(ocsp_input, &parsed_ocsp))
return PARSE_OCSP;
if (parsed_ocsp.status != OCSPResponse::ResponseStatus::SUCCESSFUL)
return OCSP_NOT_SUCCESSFUL;
if (!ParseOCSPResponseData(parsed_ocsp.data, &parsed_ocsp_data))
return PARSE_OCSP_DATA;
OCSPCertStatus status;
if (!GetOCSPCertStatus(parsed_ocsp_data, issuer_tbs_certificate_tlv,
cert_tbs_certificate_tlv, &status))
return PARSE_OCSP_SINGLE_RESPONSE;
switch (status.status) {
case OCSPCertStatus::Status::GOOD:
return OCSP_SUCCESS;
case OCSPCertStatus::Status::REVOKED:
return OCSP_SUCCESS_REVOKED;
case OCSPCertStatus::Status::UNKNOWN:
return OCSP_SUCCESS_UNKNOWN;
}
return OCSP_SUCCESS_UNKNOWN;
}
} // namespace
TEST(ParseOCSPTest, OCSPGoodResponse) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("good_response.pem"));
}
TEST(ParseOCSPTest, OCSPNoResponse) {
ASSERT_EQ(PARSE_OCSP_SINGLE_RESPONSE, ParseOCSP("no_response.pem"));
}
TEST(ParseOCSPTest, OCSPMalformedStatus) {
ASSERT_EQ(OCSP_NOT_SUCCESSFUL, ParseOCSP("malformed_status.pem"));
}
TEST(ParseOCSPTest, OCSPBadStatus) {
ASSERT_EQ(PARSE_OCSP, ParseOCSP("bad_status.pem"));
}
TEST(ParseOCSPTest, OCSPInvalidOCSPOid) {
ASSERT_EQ(PARSE_OCSP, ParseOCSP("bad_ocsp_type.pem"));
}
TEST(ParseOCSPTest, OCSPBadSignature) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("bad_signature.pem"));
}
TEST(ParseOCSPTest, OCSPDirectSignature) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("ocsp_sign_direct.pem"));
}
TEST(ParseOCSPTest, OCSPIndirectSignature) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("ocsp_sign_indirect.pem"));
}
TEST(ParseOCSPTest, OCSPMissingIndirectSignature) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("ocsp_sign_indirect_missing.pem"));
}
TEST(ParseOCSPTest, OCSPInvalidSignature) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("ocsp_sign_bad_indirect.pem"));
}
TEST(ParseOCSPTest, OCSPExtraCerts) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("ocsp_extra_certs.pem"));
}
TEST(ParseOCSPTest, OCSPIncludesVersion) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("has_version.pem"));
}
TEST(ParseOCSPTest, OCSPResponderName) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("responder_name.pem"));
}
TEST(ParseOCSPTest, OCSPResponderKeyHash) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("responder_id.pem"));
}
TEST(ParseOCSPTest, OCSPOCSPExtension) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("has_extension.pem"));
}
TEST(ParseOCSPTest, OCSPIncludeNextUpdate) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("good_response_next_update.pem"));
}
TEST(ParseOCSPTest, OCSPRevokedResponse) {
ASSERT_EQ(OCSP_SUCCESS_REVOKED, ParseOCSP("revoke_response.pem"));
}
TEST(ParseOCSPTest, OCSPRevokedResponseWithReason) {
ASSERT_EQ(OCSP_SUCCESS_REVOKED, ParseOCSP("revoke_response_reason.pem"));
}
TEST(ParseOCSPTest, OCSPUnknownCertStatus) {
ASSERT_EQ(OCSP_SUCCESS_UNKNOWN, ParseOCSP("unknown_response.pem"));
}
TEST(ParseOCSPTest, OCSPMultipleCertStatus) {
ASSERT_EQ(OCSP_SUCCESS_UNKNOWN, ParseOCSP("multiple_response.pem"));
}
TEST(ParseOCSPTest, OCSPWrongCertResponse) {
ASSERT_EQ(PARSE_OCSP_SINGLE_RESPONSE, ParseOCSP("other_response.pem"));
}
TEST(ParseOCSPTest, OCSPOCSPSingleExtension) {
ASSERT_EQ(OCSP_SUCCESS, ParseOCSP("has_single_extension.pem"));
}
TEST(ParseOCSPTest, OCSPMissingResponse) {
ASSERT_EQ(PARSE_OCSP_SINGLE_RESPONSE, ParseOCSP("missing_response.pem"));
}
} // namespace net