// BasicOCSPResponse ::= SEQUENCE { // tbsResponseData ResponseData, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING, // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } Result BasicResponse(Reader& input, Context& context) { Reader tbsResponseData; SignedDataWithSignature signedData; Result rv = der::SignedData(input, tbsResponseData, signedData); if (rv != Success) { if (rv == Result::ERROR_BAD_SIGNATURE) { return Result::ERROR_OCSP_BAD_SIGNATURE; } return rv; } // Parse certificates, if any NonOwningDERArray certs; if (!input.AtEnd()) { // We ignore the lengths of the wrappers because we'll detect bad lengths // during parsing--too short and we'll run out of input for parsing a cert, // and too long and we'll have leftover data that won't parse as a cert. // [0] wrapper Reader wrapped; rv = der::ExpectTagAndGetValue( input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0, wrapped); if (rv != Success) { return rv; } rv = der::End(input); if (rv != Success) { return rv; } // SEQUENCE wrapper Reader certsSequence; rv = der::ExpectTagAndGetValue(wrapped, der::SEQUENCE, certsSequence); if (rv != Success) { return rv; } rv = der::End(wrapped); if (rv != Success) { return rv; } // sequence of certificates while (!certsSequence.AtEnd()) { Input cert; rv = der::ExpectTagAndGetTLV(certsSequence, der::SEQUENCE, cert); if (rv != Success) { return rv; } rv = certs.Append(cert); if (rv != Success) { return rv; } } } return ResponseData(tbsResponseData, context, signedData, certs); }
Result MultiLogCTVerifier::VerifySCTs(Input encodedSctList, const LogEntry& expectedEntry, SignedCertificateTimestamp::Origin origin, uint64_t time, CTVerifyResult& result) { Reader listReader; Result rv = DecodeSCTList(encodedSctList, listReader); if (rv != Success) { result.decodingErrors++; return Success; } while (!listReader.AtEnd()) { Input encodedSct; rv = ReadSCTListItem(listReader, encodedSct); if (rv != Success) { result.decodingErrors++; return Success; } Reader encodedSctReader(encodedSct); SignedCertificateTimestamp sct; rv = DecodeSignedCertificateTimestamp(encodedSctReader, sct); if (rv != Success) { result.decodingErrors++; continue; } sct.origin = origin; rv = VerifySingleSCT(Move(sct), expectedEntry, time, result); if (rv != Success) { return rv; } } return Success; }
Result CheckKeyUsage(EndEntityOrCA endEntityOrCA, const Input* encodedKeyUsage, KeyUsage requiredKeyUsageIfPresent) { if (!encodedKeyUsage) { // TODO(bug 970196): Reject certificates that are being used to verify // certificate signatures unless the certificate is a trust anchor, to // reduce the chances of an end-entity certificate being abused as a CA // certificate. // if (endEntityOrCA == EndEntityOrCA::MustBeCA && !isTrustAnchor) { // return Result::ERROR_INADEQUATE_KEY_USAGE; // } // // TODO: Users may configure arbitrary certificates as trust anchors, not // just roots. We should only allow a certificate without a key usage to be // used as a CA when it is self-issued and self-signed. return Success; } Reader input(*encodedKeyUsage); Reader value; if (der::ExpectTagAndGetValue(input, der::BIT_STRING, value) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } uint8_t numberOfPaddingBits; if (value.Read(numberOfPaddingBits) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } if (numberOfPaddingBits > 7) { return Result::ERROR_INADEQUATE_KEY_USAGE; } uint8_t bits; if (value.Read(bits) != Success) { // Reject empty bit masks. return Result::ERROR_INADEQUATE_KEY_USAGE; } // The most significant bit is numbered 0 (digitalSignature) and the least // significant bit is numbered 7 (encipherOnly), and the padding is in the // least significant bits of the last byte. The numbering of bits in a byte // is backwards from how we usually interpret them. // // For example, let's say bits is encoded in one byte with of value 0xB0 and // numberOfPaddingBits == 4. Then, bits is 10110000 in binary: // // bit 0 bit 3 // | | // v v // 10110000 // ^^^^ // | // 4 padding bits // // Since bits is the last byte, we have to consider the padding by ensuring // that the least significant 4 bits are all zero, since DER rules require // all padding bits to be zero. Then we have to look at the bit N bits to the // right of the most significant bit, where N is a value from the KeyUsage // enumeration. // // Let's say we're interested in the keyCertSign (5) bit. We'd need to look // at bit 5, which is zero, so keyCertSign is not asserted. (Since we check // that the padding is all zeros, it is OK to read from the padding bits.) // // Let's say we're interested in the digitalSignature (0) bit. We'd need to // look at the bit 0 (the most significant bit), which is set, so that means // digitalSignature is asserted. Similarly, keyEncipherment (2) and // dataEncipherment (3) are asserted. // // Note that since the KeyUsage enumeration is limited to values 0-7, we // only ever need to examine the first byte test for // requiredKeyUsageIfPresent. if (requiredKeyUsageIfPresent != KeyUsage::noParticularKeyUsageRequired) { // Check that the required key usage bit is set. if ((bits & KeyUsageToBitMask(requiredKeyUsageIfPresent)) == 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } if (endEntityOrCA != EndEntityOrCA::MustBeCA) { // RFC 5280 says "The keyCertSign bit is asserted when the subject public // key is used for verifying signatures on public key certificates. If the // keyCertSign bit is asserted, then the cA bit in the basic constraints // extension (Section 4.2.1.9) MUST also be asserted." if ((bits & KeyUsageToBitMask(KeyUsage::keyCertSign)) != 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } // The padding applies to the last byte, so skip to the last byte. while (!value.AtEnd()) { if (value.Read(bits) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } // All of the padding bits must be zero, according to DER rules. uint8_t paddingMask = static_cast<uint8_t>((1 << numberOfPaddingBits) - 1); if ((bits & paddingMask) != 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } return Success; }
// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation Result CheckCertificatePolicies(EndEntityOrCA endEntityOrCA, const Input* encodedCertificatePolicies, const Input* encodedInhibitAnyPolicy, TrustLevel trustLevel, const CertPolicyId& requiredPolicy) { if (requiredPolicy.numBytes == 0 || requiredPolicy.numBytes > sizeof requiredPolicy.bytes) { return Result::FATAL_ERROR_INVALID_ARGS; } bool requiredPolicyFound = requiredPolicy.IsAnyPolicy(); if (requiredPolicyFound) { return Success; } // Bug 989051. Until we handle inhibitAnyPolicy we will fail close when // inhibitAnyPolicy extension is present and we are validating for a policy. if (!requiredPolicyFound && encodedInhibitAnyPolicy) { return Result::ERROR_POLICY_VALIDATION_FAILED; } // The root CA certificate may omit the policies that it has been // trusted for, so we cannot require the policies to be present in those // certificates. Instead, the determination of which roots are trusted for // which policies is made by the TrustDomain's GetCertTrust method. if (trustLevel == TrustLevel::TrustAnchor && endEntityOrCA == EndEntityOrCA::MustBeCA) { requiredPolicyFound = true; } Input requiredPolicyDER; if (requiredPolicyDER.Init(requiredPolicy.bytes, requiredPolicy.numBytes) != Success) { return Result::FATAL_ERROR_INVALID_ARGS; } if (encodedCertificatePolicies) { Reader extension(*encodedCertificatePolicies); Reader certificatePolicies; Result rv = der::ExpectTagAndGetValue(extension, der::SEQUENCE, certificatePolicies); if (rv != Success) { return Result::ERROR_POLICY_VALIDATION_FAILED; } if (!extension.AtEnd()) { return Result::ERROR_POLICY_VALIDATION_FAILED; } do { // PolicyInformation ::= SEQUENCE { // policyIdentifier CertPolicyId, // policyQualifiers SEQUENCE SIZE (1..MAX) OF // PolicyQualifierInfo OPTIONAL } Reader policyInformation; rv = der::ExpectTagAndGetValue(certificatePolicies, der::SEQUENCE, policyInformation); if (rv != Success) { return Result::ERROR_POLICY_VALIDATION_FAILED; } Reader policyIdentifier; rv = der::ExpectTagAndGetValue(policyInformation, der::OIDTag, policyIdentifier); if (rv != Success) { return rv; } if (policyIdentifier.MatchRest(requiredPolicyDER)) { requiredPolicyFound = true; } else if (endEntityOrCA == EndEntityOrCA::MustBeCA && policyIdentifier.MatchRest(anyPolicy)) { requiredPolicyFound = true; } // RFC 5280 Section 4.2.1.4 says "Optional qualifiers, which MAY be // present, are not expected to change the definition of the policy." Also, // it seems that Section 6, which defines validation, does not require any // matching of qualifiers. Thus, doing anything with the policy qualifiers // would be a waste of time and a source of potential incompatibilities, so // we just ignore them. } while (!requiredPolicyFound && !certificatePolicies.AtEnd()); } if (!requiredPolicyFound) { return Result::ERROR_POLICY_VALIDATION_FAILED; } return Success; }