// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "parsed_certificate.h" #include <gtest/gtest.h> #include <openssl/pool.h> #include "cert_errors.h" #include "input.h" #include "parse_certificate.h" #include "test_helpers.h" // TODO(eroman): Add tests for parsing of policy mappings. BSSL_NAMESPACE_BEGIN namespace { std::string GetFilePath(const std::string &file_name) { … } // Reads and parses a certificate from the PEM file |file_name|. // // Returns nullptr if the certificate parsing failed, and verifies that any // errors match the ERRORS block in the .pem file. std::shared_ptr<const ParsedCertificate> ParseCertificateFromFile( const std::string &file_name, const ParseCertificateOptions &options) { … } der::Input DavidBenOid() { … } // Parses an Extension whose critical field is true (255). TEST(ParsedCertificateTest, ExtensionCritical) { … } // Parses an Extension whose critical field is false (omitted). TEST(ParsedCertificateTest, ExtensionNotCritical) { … } // Parses an Extension whose critical field is 0. This is in one sense FALSE, // however because critical has DEFAULT of false this is in fact invalid // DER-encoding. TEST(ParsedCertificateTest, ExtensionCritical0) { … } // Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN // values must an octet of either all zero bits, or all 1 bits, so this is not // valid. TEST(ParsedCertificateTest, ExtensionCritical3) { … } // Parses an Extensions that is an empty sequence. TEST(ParsedCertificateTest, ExtensionsEmptySequence) { … } // Parses an Extensions that is not a sequence. TEST(ParsedCertificateTest, ExtensionsNotSequence) { … } // Parses an Extensions that has data after the sequence. TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) { … } // Parses an Extensions that contains duplicated key usages. TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) { … } // Parses a certificate with a bad key usage extension (BIT STRING with zero // elements). TEST(ParsedCertificateTest, BadKeyUsage) { … } // Parses a certificate that has a PolicyQualifierInfo that is missing the // qualifier field. TEST(ParsedCertificateTest, BadPolicyQualifiers) { … } // Parses a certificate that uses an unknown signature algorithm OID (00). TEST(ParsedCertificateTest, BadSignatureAlgorithmOid) { … } // The validity encodes time as UTCTime but following the BER rules rather than // DER rules (i.e. YYMMDDHHMMZ instead of YYMMDDHHMMSSZ). TEST(ParsedCertificateTest, BadValidity) { … } // The signature algorithm contains an unexpected parameters field. TEST(ParsedCertificateTest, FailedSignatureAlgorithm) { … } // '&' is not acceptable in a printable string. TEST(ParsedCertificateTest, IssuerBadPrintableString) { … } TEST(ParsedCertificateTest, NameConstraintsBadIp) { … } TEST(ParsedCertificateTest, PolicyQualifiersEmptySequence) { … } TEST(ParsedCertificateTest, SubjectBlankSubjectAltNameNotCritical) { … } // Non-ASCII character in locality name in subject. TEST(ParsedCertificateTest, SubjectNotAscii) { … } // '&' is not acceptable in a printable string. TEST(ParsedCertificateTest, SubjectNotPrintableString) { … } TEST(ParsedCertificateTest, SubjectAltNameBadIp) { … } TEST(ParsedCertificateTest, SubjectAltNameDnsNotAscii) { … } TEST(ParsedCertificateTest, SubjectAltNameGeneralNamesEmptySequence) { … } TEST(ParsedCertificateTest, SubjectAltNameTrailingData) { … } TEST(ParsedCertificateTest, V1ExplicitVersion) { … } // Parses an Extensions that contains an extended key usages. TEST(ParsedCertificateTest, ExtendedKeyUsage) { … } // Parses an Extensions that contains a key usage. TEST(ParsedCertificateTest, KeyUsage) { … } // Parses an Extensions that contains a policies extension. TEST(ParsedCertificateTest, Policies) { … } // Parses an Extensions that contains a subjectaltname extension. TEST(ParsedCertificateTest, SubjectAltName) { … } // Parses an Extensions that contains multiple extensions, sourced from a // real-world certificate. TEST(ParsedCertificateTest, ExtensionsReal) { … } // Parses a BasicConstraints with no CA or pathlen. TEST(ParsedCertificateTest, BasicConstraintsNotCa) { … } // Parses a BasicConstraints with CA but no pathlen. TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) { … } // Parses a BasicConstraints with CA and pathlen of 9. TEST(ParsedCertificateTest, BasicConstraintsCaPath9) { … } // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). TEST(ParsedCertificateTest, BasicConstraintsPathlen255) { … } // Parses a BasicConstraints with CA and pathlen of 256 (too large). TEST(ParsedCertificateTest, BasicConstraintsPathlen256) { … } // Parses a BasicConstraints with CA and a negative pathlen. TEST(ParsedCertificateTest, BasicConstraintsNegativePath) { … } // Parses a BasicConstraints with CA and pathlen that is very large (and // couldn't fit in a 64-bit integer). TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) { … } // Parses a BasicConstraints with CA explicitly set to false. This violates // DER-encoding rules, however is commonly used, so it is accepted. TEST(ParsedCertificateTest, BasicConstraintsCaFalse) { … } // Parses a BasicConstraints with CA set to true and an unexpected NULL at // the end. TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) { … } // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. // This is valid DER for the ASN.1, however is not valid when interpreting the // BasicConstraints at a higher level. TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) { … } // Tests parsing a certificate that contains a policyConstraints // extension having requireExplicitPolicy:3. TEST(ParsedCertificateTest, PolicyConstraintsRequire) { … } // Tests parsing a certificate that contains a policyConstraints // extension having inhibitPolicyMapping:1. TEST(ParsedCertificateTest, PolicyConstraintsInhibit) { … } // Tests parsing a certificate that contains a policyConstraints // extension having requireExplicitPolicy:5,inhibitPolicyMapping:2. TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) { … } // Tests parsing a certificate that has a policyConstraints // extension with an empty sequence. TEST(ParsedCertificateTest, PolicyConstraintsEmpty) { … } // Tests a certificate with a serial number with a leading 0 padding byte in // the encoding since it is not negative. TEST(ParsedCertificateTest, SerialNumberZeroPadded) { … } // Tests a serial number where the MSB is >= 0x80, causing the encoded // length to be 21 bytes long. This is an error, as RFC 5280 specifies a // maximum of 20 bytes. TEST(ParsedCertificateTest, SerialNumberZeroPadded21BytesLong) { … } // Tests a serial number which is negative. CAs are not supposed to include // negative serial numbers, however RFC 5280 expects consumers to deal with it // anyway. TEST(ParsedCertificateTest, SerialNumberNegative) { … } // Tests a serial number which is very long. RFC 5280 specifies a maximum of 20 // bytes. TEST(ParsedCertificateTest, SerialNumber37BytesLong) { … } // Tests a serial number which is zero. RFC 5280 says they should be positive, // however also recommends supporting non-positive ones, so parsing here // is expected to succeed. TEST(ParsedCertificateTest, SerialNumberZero) { … } // Tests a serial number which not a number (NULL). TEST(ParsedCertificateTest, SerialNotNumber) { … } // Tests a serial number which uses a non-minimal INTEGER encoding TEST(ParsedCertificateTest, SerialNotMinimal) { … } // Tests parsing a certificate that has an inhibitAnyPolicy extension. TEST(ParsedCertificateTest, InhibitAnyPolicy) { … } // Tests a subjectKeyIdentifier that is not an OCTET_STRING. TEST(ParsedCertificateTest, SubjectKeyIdentifierNotOctetString) { … } // Tests an authorityKeyIdentifier that is not a SEQUENCE. TEST(ParsedCertificateTest, AuthourityKeyIdentifierNotSequence) { … } } // namespace BSSL_NAMESPACE_END