tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pkixocsp_VerifyEncodedOCSPResponse.cpp (48005B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This code is made available to you under your choice of the following sets
      4 * of licensing terms:
      5 */
      6 /* This Source Code Form is subject to the terms of the Mozilla Public
      7 * License, v. 2.0. If a copy of the MPL was not distributed with this
      8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 */
     10 /* Copyright 2014 Mozilla Contributors
     11 *
     12 * Licensed under the Apache License, Version 2.0 (the "License");
     13 * you may not use this file except in compliance with the License.
     14 * You may obtain a copy of the License at
     15 *
     16 *     http://www.apache.org/licenses/LICENSE-2.0
     17 *
     18 * Unless required by applicable law or agreed to in writing, software
     19 * distributed under the License is distributed on an "AS IS" BASIS,
     20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     21 * See the License for the specific language governing permissions and
     22 * limitations under the License.
     23 */
     24 
     25 #include "pkixgtest.h"
     26 
     27 #include "mozpkix/pkixder.h"
     28 
     29 #include "secoid.h"
     30 
     31 using namespace mozilla::pkix;
     32 using namespace mozilla::pkix::test;
     33 
     34 const uint16_t END_ENTITY_MAX_LIFETIME_IN_DAYS = 10;
     35 
     36 // Note that CheckRevocation is never called for OCSP signing certificates.
     37 class OCSPTestTrustDomain : public DefaultCryptoTrustDomain
     38 {
     39 public:
     40  OCSPTestTrustDomain() { }
     41 
     42  Result GetCertTrust(EndEntityOrCA endEntityOrCA, const CertPolicyId&,
     43                      Input, /*out*/ TrustLevel& trustLevel)
     44                      /*non-final*/ override
     45  {
     46    EXPECT_EQ(endEntityOrCA, EndEntityOrCA::MustBeEndEntity);
     47    trustLevel = TrustLevel::InheritsTrust;
     48    return Success;
     49  }
     50 
     51  virtual void NoteAuxiliaryExtension(AuxiliaryExtension extension,
     52                                      Input extensionData) override
     53  {
     54    if (extension == AuxiliaryExtension::SCTListFromOCSPResponse) {
     55      signedCertificateTimestamps = InputToByteString(extensionData);
     56    } else {
     57      // We do not currently expect to receive any other extension here.
     58      ADD_FAILURE();
     59    }
     60  }
     61 
     62  ByteString signedCertificateTimestamps;
     63 };
     64 
     65 namespace {
     66 char const* const rootName = "Test CA 1";
     67 } // namespace
     68 
     69 class pkixocsp_VerifyEncodedResponse : public ::testing::Test
     70 {
     71 public:
     72  static void SetUpTestSuite()
     73  {
     74    rootKeyPair.reset(GenerateKeyPair());
     75    if (!rootKeyPair) {
     76      abort();
     77    }
     78  }
     79 
     80  void SetUp()
     81  {
     82    rootNameDER = CNToDERName(rootName);
     83    if (ENCODING_FAILED(rootNameDER)) {
     84      abort();
     85    }
     86    Input rootNameDERInput;
     87    if (rootNameDERInput.Init(rootNameDER.data(), rootNameDER.length())
     88          != Success) {
     89      abort();
     90    }
     91 
     92    serialNumberDER =
     93      CreateEncodedSerialNumber(static_cast<long>(++rootIssuedCount));
     94    if (ENCODING_FAILED(serialNumberDER)) {
     95      abort();
     96    }
     97    Input serialNumberDERInput;
     98    if (serialNumberDERInput.Init(serialNumberDER.data(),
     99                                  serialNumberDER.length()) != Success) {
    100      abort();
    101    }
    102 
    103    Input rootSPKIDER;
    104    if (rootSPKIDER.Init(rootKeyPair->subjectPublicKeyInfo.data(),
    105                         rootKeyPair->subjectPublicKeyInfo.length())
    106          != Success) {
    107      abort();
    108    }
    109    endEntityCertID.reset(new (std::nothrow) CertID(rootNameDERInput, rootSPKIDER,
    110                                                    serialNumberDERInput));
    111    if (!endEntityCertID) {
    112      abort();
    113    }
    114  }
    115 
    116  static ScopedTestKeyPair rootKeyPair;
    117  static uint32_t rootIssuedCount;
    118  OCSPTestTrustDomain trustDomain;
    119 
    120  // endEntityCertID references rootKeyPair, rootNameDER, and serialNumberDER.
    121  ByteString rootNameDER;
    122  ByteString serialNumberDER;
    123  // endEntityCertID references rootKeyPair, rootNameDER, and serialNumberDER.
    124  ScopedCertID endEntityCertID;
    125 };
    126 
    127 /*static*/ ScopedTestKeyPair pkixocsp_VerifyEncodedResponse::rootKeyPair;
    128 /*static*/ uint32_t pkixocsp_VerifyEncodedResponse::rootIssuedCount = 0;
    129 
    130 ///////////////////////////////////////////////////////////////////////////////
    131 // responseStatus
    132 
    133 struct WithoutResponseBytes
    134 {
    135  uint8_t responseStatus;
    136  Result expectedError;
    137 };
    138 
    139 static const WithoutResponseBytes WITHOUT_RESPONSEBYTES[] = {
    140  { OCSPResponseContext::successful, Result::ERROR_OCSP_MALFORMED_RESPONSE },
    141  { OCSPResponseContext::malformedRequest, Result::ERROR_OCSP_MALFORMED_REQUEST },
    142  { OCSPResponseContext::internalError, Result::ERROR_OCSP_SERVER_ERROR },
    143  { OCSPResponseContext::tryLater, Result::ERROR_OCSP_TRY_SERVER_LATER },
    144  { 4/*unused*/, Result::ERROR_OCSP_UNKNOWN_RESPONSE_STATUS },
    145  { OCSPResponseContext::sigRequired, Result::ERROR_OCSP_REQUEST_NEEDS_SIG },
    146  { OCSPResponseContext::unauthorized, Result::ERROR_OCSP_UNAUTHORIZED_REQUEST },
    147  { OCSPResponseContext::unauthorized + 1,
    148    Result::ERROR_OCSP_UNKNOWN_RESPONSE_STATUS
    149  },
    150 };
    151 
    152 class pkixocsp_VerifyEncodedResponse_WithoutResponseBytes
    153  : public pkixocsp_VerifyEncodedResponse
    154  , public ::testing::WithParamInterface<WithoutResponseBytes>
    155 {
    156 protected:
    157  ByteString CreateEncodedOCSPErrorResponse(uint8_t status)
    158  {
    159    static const Input EMPTY;
    160    OCSPResponseContext context(CertID(EMPTY, EMPTY, EMPTY),
    161                                oneDayBeforeNow);
    162    context.responseStatus = status;
    163    context.skipResponseBytes = true;
    164    return CreateEncodedOCSPResponse(context);
    165  }
    166 };
    167 
    168 TEST_P(pkixocsp_VerifyEncodedResponse_WithoutResponseBytes, CorrectErrorCode)
    169 {
    170  ByteString
    171    responseString(CreateEncodedOCSPErrorResponse(GetParam().responseStatus));
    172  Input response;
    173  ASSERT_EQ(Success,
    174            response.Init(responseString.data(), responseString.length()));
    175  bool expired;
    176  ASSERT_EQ(GetParam().expectedError,
    177            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    178                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    179                                      response, expired));
    180 }
    181 
    182 INSTANTIATE_TEST_SUITE_P(pkixocsp_VerifyEncodedResponse_WithoutResponseBytes,
    183                        pkixocsp_VerifyEncodedResponse_WithoutResponseBytes,
    184                        testing::ValuesIn(WITHOUT_RESPONSEBYTES));
    185 
    186 ///////////////////////////////////////////////////////////////////////////////
    187 // "successful" responses
    188 
    189 namespace {
    190 
    191 // Alias for nullptr to aid readability in the code below.
    192 static const char* byKey = nullptr;
    193 
    194 } // namespace
    195 
    196 class pkixocsp_VerifyEncodedResponse_successful
    197  : public pkixocsp_VerifyEncodedResponse
    198 {
    199 public:
    200  void SetUp()
    201  {
    202    pkixocsp_VerifyEncodedResponse::SetUp();
    203  }
    204 
    205  static void SetUpTestSuite()
    206  {
    207    pkixocsp_VerifyEncodedResponse::SetUpTestSuite();
    208  }
    209 
    210  ByteString CreateEncodedOCSPSuccessfulResponse(
    211                    OCSPResponseContext::CertStatus certStatus,
    212                    const CertID& certID,
    213       /*optional*/ const char* signerName,
    214                    const TestKeyPair& signerKeyPair,
    215                    time_t producedAt, time_t thisUpdate,
    216       /*optional*/ const time_t* nextUpdate,
    217                    const TestSignatureAlgorithm& signatureAlgorithm,
    218       /*optional*/ const ByteString* certs = nullptr,
    219       /*optional*/ OCSPResponseExtension* singleExtensions = nullptr,
    220       /*optional*/ OCSPResponseExtension* responseExtensions = nullptr,
    221       /*optional*/ const ByteString* trailingResponseData = nullptr,
    222       /*optional*/ DigestAlgorithm certIDHashAlgorithm = DigestAlgorithm::sha1,
    223       /*optional*/ ByteString certIDHashAlgorithmEncoded = ByteString())
    224  {
    225    OCSPResponseContext context(certID, producedAt);
    226    context.certIDHashAlgorithm = certIDHashAlgorithm;
    227    context.certIDHashAlgorithmEncoded = certIDHashAlgorithmEncoded;
    228    if (signerName) {
    229      context.signerNameDER = CNToDERName(signerName);
    230      EXPECT_FALSE(ENCODING_FAILED(context.signerNameDER));
    231    }
    232    context.signerKeyPair.reset(signerKeyPair.Clone());
    233    EXPECT_TRUE(context.signerKeyPair.get());
    234    context.responseStatus = OCSPResponseContext::successful;
    235    context.producedAt = producedAt;
    236    context.signatureAlgorithm = signatureAlgorithm;
    237    context.certs = certs;
    238    context.singleExtensions = singleExtensions;
    239    context.responseExtensions = responseExtensions;
    240    context.trailingResponseData = trailingResponseData;
    241 
    242    context.certStatus = static_cast<uint8_t>(certStatus);
    243    context.thisUpdate = thisUpdate;
    244    context.nextUpdate = nextUpdate ? *nextUpdate : 0;
    245    context.includeNextUpdate = nextUpdate != nullptr;
    246 
    247    return CreateEncodedOCSPResponse(context);
    248  }
    249 };
    250 
    251 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey)
    252 {
    253  ByteString responseString(
    254               CreateEncodedOCSPSuccessfulResponse(
    255                         OCSPResponseContext::good, *endEntityCertID, byKey,
    256                         *rootKeyPair, oneDayBeforeNow,
    257                         oneDayBeforeNow, &oneDayAfterNow,
    258                         sha256WithRSAEncryption()));
    259  Input response;
    260  ASSERT_EQ(Success,
    261            response.Init(responseString.data(), responseString.length()));
    262  bool expired;
    263  ASSERT_EQ(Success,
    264            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    265                                      Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    266                                      response, expired));
    267  ASSERT_FALSE(expired);
    268 }
    269 
    270 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byName)
    271 {
    272  ByteString responseString(
    273               CreateEncodedOCSPSuccessfulResponse(
    274                         OCSPResponseContext::good, *endEntityCertID, rootName,
    275                         *rootKeyPair, oneDayBeforeNow,
    276                         oneDayBeforeNow, &oneDayAfterNow,
    277                         sha256WithRSAEncryption()));
    278  Input response;
    279  ASSERT_EQ(Success,
    280            response.Init(responseString.data(), responseString.length()));
    281  bool expired;
    282  ASSERT_EQ(Success,
    283            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    284                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    285                                      response, expired));
    286  ASSERT_FALSE(expired);
    287 }
    288 
    289 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey_without_nextUpdate)
    290 {
    291  ByteString responseString(
    292               CreateEncodedOCSPSuccessfulResponse(
    293                         OCSPResponseContext::good, *endEntityCertID, byKey,
    294                         *rootKeyPair, oneDayBeforeNow,
    295                         oneDayBeforeNow, nullptr,
    296                         sha256WithRSAEncryption()));
    297  Input response;
    298  ASSERT_EQ(Success,
    299            response.Init(responseString.data(), responseString.length()));
    300  bool expired;
    301  ASSERT_EQ(Success,
    302            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    303                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    304                                      response, expired));
    305  ASSERT_FALSE(expired);
    306 }
    307 
    308 TEST_F(pkixocsp_VerifyEncodedResponse_successful, revoked)
    309 {
    310  ByteString responseString(
    311               CreateEncodedOCSPSuccessfulResponse(
    312                         OCSPResponseContext::revoked, *endEntityCertID, byKey,
    313                         *rootKeyPair, oneDayBeforeNow,
    314                         oneDayBeforeNow, &oneDayAfterNow,
    315                         sha256WithRSAEncryption()));
    316  Input response;
    317  ASSERT_EQ(Success,
    318            response.Init(responseString.data(), responseString.length()));
    319  bool expired;
    320  ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE,
    321            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    322                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    323                                      response, expired));
    324  ASSERT_FALSE(expired);
    325 }
    326 
    327 TEST_F(pkixocsp_VerifyEncodedResponse_successful, unknown)
    328 {
    329  ByteString responseString(
    330               CreateEncodedOCSPSuccessfulResponse(
    331                         OCSPResponseContext::unknown, *endEntityCertID, byKey,
    332                         *rootKeyPair, oneDayBeforeNow,
    333                         oneDayBeforeNow, &oneDayAfterNow,
    334                         sha256WithRSAEncryption()));
    335  Input response;
    336  ASSERT_EQ(Success,
    337            response.Init(responseString.data(), responseString.length()));
    338  bool expired;
    339  ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT,
    340            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    341                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    342                                      response, expired));
    343  ASSERT_FALSE(expired);
    344 }
    345 
    346 TEST_F(pkixocsp_VerifyEncodedResponse_successful,
    347       good_unsupportedSignatureAlgorithm)
    348 {
    349  PRUint32 policyMd5;
    350  ASSERT_EQ(SECSuccess,NSS_GetAlgorithmPolicy(SEC_OID_MD5, &policyMd5));
    351 
    352  /* our encode won't work if MD5 isn't allowed by policy */
    353  ASSERT_EQ(SECSuccess,
    354            NSS_SetAlgorithmPolicy(SEC_OID_MD5, NSS_USE_ALG_IN_SIGNATURE, 0));
    355  ByteString responseString(
    356               CreateEncodedOCSPSuccessfulResponse(
    357                         OCSPResponseContext::good, *endEntityCertID, byKey,
    358                         *rootKeyPair, oneDayBeforeNow,
    359                         oneDayBeforeNow, &oneDayAfterNow,
    360                         md5WithRSAEncryption()));
    361  Input response;
    362  ASSERT_EQ(Success,
    363            response.Init(responseString.data(), responseString.length()));
    364  /* now restore the existing policy */
    365  ASSERT_EQ(SECSuccess,
    366           NSS_SetAlgorithmPolicy(SEC_OID_MD5, policyMd5, NSS_USE_ALG_IN_SIGNATURE));
    367  bool expired;
    368  ASSERT_EQ(Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED,
    369            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    370                                      Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    371                                      response, expired));
    372  ASSERT_FALSE(expired);
    373 }
    374 
    375 // Added for bug 1079436. The output variable validThrough represents the
    376 // latest time for which VerifyEncodedOCSPResponse will succeed, which is
    377 // different from the nextUpdate time in the OCSP response due to the slop we
    378 // add for time comparisons to deal with clock skew.
    379 TEST_F(pkixocsp_VerifyEncodedResponse_successful, check_validThrough)
    380 {
    381  ByteString responseString(
    382               CreateEncodedOCSPSuccessfulResponse(
    383                         OCSPResponseContext::good, *endEntityCertID, byKey,
    384                         *rootKeyPair, oneDayBeforeNow,
    385                         oneDayBeforeNow, &oneDayAfterNow,
    386                         sha256WithRSAEncryption()));
    387  Time validThrough(Time::uninitialized);
    388  {
    389    Input response;
    390    ASSERT_EQ(Success,
    391              response.Init(responseString.data(), responseString.length()));
    392    bool expired;
    393    ASSERT_EQ(Success,
    394              VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    395                                        Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    396                                        response, expired, nullptr,
    397                                        &validThrough));
    398    ASSERT_FALSE(expired);
    399    // The response was created to be valid until one day after now, so the
    400    // value we got for validThrough should be after that.
    401    Time oneDayAfterNowAsPKIXTime(
    402          TimeFromEpochInSeconds(static_cast<uint64_t>(oneDayAfterNow)));
    403    ASSERT_TRUE(validThrough > oneDayAfterNowAsPKIXTime);
    404  }
    405  {
    406    Input response;
    407    ASSERT_EQ(Success,
    408              response.Init(responseString.data(), responseString.length()));
    409    bool expired;
    410    // Given validThrough from a previous verification, this response should be
    411    // valid through that time.
    412    ASSERT_EQ(Success,
    413              VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    414                                        validThrough, END_ENTITY_MAX_LIFETIME_IN_DAYS,
    415                                        response, expired));
    416    ASSERT_FALSE(expired);
    417  }
    418  {
    419    Time noLongerValid(validThrough);
    420    ASSERT_EQ(Success, noLongerValid.AddSeconds(1));
    421    Input response;
    422    ASSERT_EQ(Success,
    423              response.Init(responseString.data(), responseString.length()));
    424    bool expired;
    425    // The verification time is now after when the response will be considered
    426    // valid.
    427    ASSERT_EQ(Result::ERROR_OCSP_OLD_RESPONSE,
    428              VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    429                                        noLongerValid, END_ENTITY_MAX_LIFETIME_IN_DAYS,
    430                                        response, expired));
    431    ASSERT_TRUE(expired);
    432  }
    433 }
    434 
    435 // python DottedOIDToCode.py --tlv
    436 //   id_ocsp_singleExtensionSctList 1.3.6.1.4.1.11129.2.4.5
    437 static const uint8_t tlv_id_ocsp_singleExtensionSctList[] = {
    438  0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x05
    439 };
    440 static const uint8_t dummySctList[] = {
    441  0x01, 0x02, 0x03, 0x04, 0x05
    442 };
    443 
    444 TEST_F(pkixocsp_VerifyEncodedResponse_successful, ct_extension)
    445 {
    446  OCSPResponseExtension ctExtension;
    447  ctExtension.id = BytesToByteString(tlv_id_ocsp_singleExtensionSctList);
    448  // SignedCertificateTimestampList structure is encoded as an OCTET STRING
    449  // within the extension value (see RFC 6962 section 3.3).
    450  // pkix decodes it internally and returns the actual structure.
    451  ctExtension.value = TLV(der::OCTET_STRING, BytesToByteString(dummySctList));
    452 
    453  ByteString responseString(
    454               CreateEncodedOCSPSuccessfulResponse(
    455                         OCSPResponseContext::good, *endEntityCertID, byKey,
    456                         *rootKeyPair, oneDayBeforeNow,
    457                         oneDayBeforeNow, &oneDayAfterNow,
    458                         sha256WithRSAEncryption(),
    459                         /*certs*/ nullptr,
    460                         &ctExtension));
    461  Input response;
    462  ASSERT_EQ(Success,
    463            response.Init(responseString.data(), responseString.length()));
    464 
    465  bool expired;
    466  ASSERT_EQ(Success,
    467            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    468                                      Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    469                                      response, expired));
    470  ASSERT_FALSE(expired);
    471  ASSERT_EQ(BytesToByteString(dummySctList),
    472            trustDomain.signedCertificateTimestamps);
    473 }
    474 
    475 TEST_F(pkixocsp_VerifyEncodedResponse_successful, trailingResponseData)
    476 {
    477  OCSPResponseExtension ctExtension;
    478  ctExtension.id = BytesToByteString(tlv_id_ocsp_singleExtensionSctList);
    479  // SignedCertificateTimestampList structure is encoded as an OCTET STRING
    480  // within the extension value (see RFC 6962 section 3.3).
    481  // pkix decodes it internally and returns the actual structure.
    482  ctExtension.value = TLV(der::OCTET_STRING, BytesToByteString(dummySctList));
    483  ByteString trailingResponseData(3, 0x20);
    484  ByteString responseString(
    485               CreateEncodedOCSPSuccessfulResponse(
    486                         OCSPResponseContext::good, *endEntityCertID, byKey,
    487                         *rootKeyPair, oneDayBeforeNow,
    488                         oneDayBeforeNow, &oneDayAfterNow,
    489                         sha256WithRSAEncryption(),
    490                         /*certs*/ nullptr,
    491                         &ctExtension,
    492                         /*responseExtensions*/ nullptr,
    493                         &trailingResponseData));
    494  Input response;
    495  ASSERT_EQ(Success,
    496            response.Init(responseString.data(), responseString.length()));
    497  bool expired;
    498  ASSERT_EQ(Result::ERROR_OCSP_MALFORMED_RESPONSE,
    499            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    500                                      Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    501                                      response, expired));
    502 }
    503 
    504 struct CertIDHashAlgorithm
    505 {
    506  DigestAlgorithm hashAlgorithm;
    507  ByteString encodedHashAlgorithm;
    508  Result expectedResult;
    509 };
    510 
    511 // python DottedOIDToCode.py --alg id-sha1 1.3.14.3.2.26
    512 static const uint8_t alg_id_sha1[] = {
    513  0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
    514 };
    515 // python DottedOIDToCode.py --alg id-sha256 2.16.840.1.101.3.4.2.1
    516 static const uint8_t alg_id_sha256[] = {
    517  0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
    518 };
    519 static const uint8_t not_an_encoded_hash_oid[] = {
    520  0x01, 0x02, 0x03, 0x04
    521 };
    522 
    523 static const CertIDHashAlgorithm CERTID_HASH_ALGORITHMS[] = {
    524  { DigestAlgorithm::sha1, ByteString(), Success },
    525  { DigestAlgorithm::sha256, ByteString(), Success },
    526  { DigestAlgorithm::sha384, ByteString(), Success },
    527  { DigestAlgorithm::sha512, ByteString(), Success },
    528  { DigestAlgorithm::sha256, BytesToByteString(alg_id_sha1),
    529    Result::ERROR_OCSP_MALFORMED_RESPONSE },
    530  { DigestAlgorithm::sha1, BytesToByteString(alg_id_sha256),
    531    Result::ERROR_OCSP_MALFORMED_RESPONSE },
    532  { DigestAlgorithm::sha1, BytesToByteString(not_an_encoded_hash_oid),
    533    Result::ERROR_OCSP_MALFORMED_RESPONSE },
    534 };
    535 
    536 class pkixocsp_VerifyEncodedResponse_CertIDHashAlgorithm
    537  : public pkixocsp_VerifyEncodedResponse_successful
    538  , public ::testing::WithParamInterface<CertIDHashAlgorithm>
    539 {
    540 };
    541 
    542 TEST_P(pkixocsp_VerifyEncodedResponse_CertIDHashAlgorithm, CertIDHashAlgorithm)
    543 {
    544  ByteString responseString(
    545               CreateEncodedOCSPSuccessfulResponse(
    546                         OCSPResponseContext::good, *endEntityCertID, byKey,
    547                         *rootKeyPair, oneDayBeforeNow,
    548                         oneDayBeforeNow, &oneDayAfterNow,
    549                         sha256WithRSAEncryption(),
    550                         nullptr,
    551                         nullptr,
    552                         nullptr,
    553                         nullptr,
    554                         GetParam().hashAlgorithm,
    555                         GetParam().encodedHashAlgorithm));
    556  Input response;
    557  ASSERT_EQ(Success,
    558            response.Init(responseString.data(), responseString.length()));
    559  bool expired;
    560  ASSERT_EQ(GetParam().expectedResult,
    561            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
    562                                      Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
    563                                      response, expired));
    564  ASSERT_FALSE(expired);
    565 }
    566 
    567 INSTANTIATE_TEST_SUITE_P(pkixocsp_VerifyEncodedResponse_CertIDHashAlgorithm,
    568                        pkixocsp_VerifyEncodedResponse_CertIDHashAlgorithm,
    569                        testing::ValuesIn(CERTID_HASH_ALGORITHMS));
    570 
    571 ///////////////////////////////////////////////////////////////////////////////
    572 // indirect responses (signed by a delegated OCSP responder cert)
    573 
    574 class pkixocsp_VerifyEncodedResponse_DelegatedResponder
    575  : public pkixocsp_VerifyEncodedResponse_successful
    576 {
    577 protected:
    578  // certSubjectName should be unique for each call. This way, we avoid any
    579  // issues with NSS caching the certificates internally. For the same reason,
    580  // we generate a new keypair on each call. Either one of these should be
    581  // sufficient to avoid issues with the NSS cache, but we do both to be
    582  // cautious.
    583  //
    584  // signerName should be byKey to use the byKey ResponderID construction, or
    585  // another value (usually equal to certSubjectName) to use the byName
    586  // ResponderID construction.
    587  //
    588  // certSignatureAlgorithm specifies the signature algorithm that the
    589  // certificate will be signed with, not the OCSP response.
    590  //
    591  // If signerEKU is omitted, then the certificate will have the
    592  // id-kp-OCSPSigning EKU. If signerEKU is SEC_OID_UNKNOWN then it will not
    593  // have any EKU extension. Otherwise, the certificate will have the given
    594  // EKU.
    595  ByteString CreateEncodedIndirectOCSPSuccessfulResponse(
    596               const char* certSubjectName,
    597               OCSPResponseContext::CertStatus certStatus,
    598               const char* signerName,
    599               const TestSignatureAlgorithm& certSignatureAlgorithm,
    600               /*optional*/ const Input* signerEKUDER = &OCSPSigningEKUDER,
    601               /*optional, out*/ ByteString* signerDEROut = nullptr)
    602  {
    603    assert(certSubjectName);
    604 
    605    const ByteString extensions[] = {
    606      signerEKUDER
    607        ? CreateEncodedEKUExtension(*signerEKUDER, Critical::No)
    608        : ByteString(),
    609      ByteString()
    610    };
    611    ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
    612    ByteString signerDER(CreateEncodedCertificate(
    613                           ++rootIssuedCount, certSignatureAlgorithm,
    614                           rootName, oneDayBeforeNow, oneDayAfterNow,
    615                           certSubjectName, *signerKeyPair,
    616                           signerEKUDER ? extensions : nullptr,
    617                           *rootKeyPair));
    618    EXPECT_FALSE(ENCODING_FAILED(signerDER));
    619    if (signerDEROut) {
    620      *signerDEROut = signerDER;
    621    }
    622 
    623    ByteString signerNameDER;
    624    if (signerName) {
    625      signerNameDER = CNToDERName(signerName);
    626      EXPECT_FALSE(ENCODING_FAILED(signerNameDER));
    627    }
    628    ByteString certs[] = { signerDER, ByteString() };
    629    return CreateEncodedOCSPSuccessfulResponse(certStatus, *endEntityCertID,
    630                                               signerName, *signerKeyPair,
    631                                               oneDayBeforeNow,
    632                                               oneDayBeforeNow,
    633                                               &oneDayAfterNow,
    634                                               sha256WithRSAEncryption(),
    635                                               certs);
    636  }
    637 
    638  static ByteString CreateEncodedCertificate(uint32_t serialNumber,
    639                                             const TestSignatureAlgorithm& signatureAlg,
    640                                             const char* issuer,
    641                                             time_t notBefore,
    642                                             time_t notAfter,
    643                                             const char* subject,
    644                                             const TestKeyPair& subjectKeyPair,
    645                                /*optional*/ const ByteString* extensions,
    646                                             const TestKeyPair& signerKeyPair)
    647  {
    648    ByteString serialNumberDER(CreateEncodedSerialNumber(
    649                                 static_cast<long>(serialNumber)));
    650    if (ENCODING_FAILED(serialNumberDER)) {
    651      return ByteString();
    652    }
    653    ByteString issuerDER(CNToDERName(issuer));
    654    if (ENCODING_FAILED(issuerDER)) {
    655      return ByteString();
    656    }
    657    ByteString subjectDER(CNToDERName(subject));
    658    if (ENCODING_FAILED(subjectDER)) {
    659      return ByteString();
    660    }
    661    return ::mozilla::pkix::test::CreateEncodedCertificate(
    662                                    v3, signatureAlg, serialNumberDER,
    663                                    issuerDER, notBefore, notAfter,
    664                                    subjectDER, subjectKeyPair, extensions,
    665                                    signerKeyPair, signatureAlg);
    666  }
    667 
    668  static const Input OCSPSigningEKUDER;
    669 };
    670 
    671 /*static*/ const Input pkixocsp_VerifyEncodedResponse_DelegatedResponder::
    672  OCSPSigningEKUDER(tlv_id_kp_OCSPSigning);
    673 
    674 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byKey)
    675 {
    676  ByteString responseString(
    677               CreateEncodedIndirectOCSPSuccessfulResponse(
    678                         "good_indirect_byKey", OCSPResponseContext::good,
    679                         byKey, sha256WithRSAEncryption()));
    680  Input response;
    681  ASSERT_EQ(Success,
    682            response.Init(responseString.data(), responseString.length()));
    683  bool expired;
    684  ASSERT_EQ(Success,
    685            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    686                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    687                                      response, expired));
    688  ASSERT_FALSE(expired);
    689 }
    690 
    691 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byName)
    692 {
    693  ByteString responseString(
    694               CreateEncodedIndirectOCSPSuccessfulResponse(
    695                         "good_indirect_byName", OCSPResponseContext::good,
    696                         "good_indirect_byName", sha256WithRSAEncryption()));
    697  Input response;
    698  ASSERT_EQ(Success,
    699            response.Init(responseString.data(), responseString.length()));
    700  bool expired;
    701  ASSERT_EQ(Success,
    702            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    703                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    704                                      response, expired));
    705  ASSERT_FALSE(expired);
    706 }
    707 
    708 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
    709       good_byKey_missing_signer)
    710 {
    711  ScopedTestKeyPair missingSignerKeyPair(GenerateKeyPair());
    712  ASSERT_TRUE(missingSignerKeyPair.get());
    713 
    714  ByteString responseString(
    715               CreateEncodedOCSPSuccessfulResponse(
    716                         OCSPResponseContext::good, *endEntityCertID, byKey,
    717                         *missingSignerKeyPair, oneDayBeforeNow,
    718                         oneDayBeforeNow, nullptr,
    719                         sha256WithRSAEncryption()));
    720  Input response;
    721  ASSERT_EQ(Success,
    722            response.Init(responseString.data(), responseString.length()));
    723  bool expired;
    724  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    725            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    726                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    727                                      response, expired));
    728  ASSERT_FALSE(expired);
    729 }
    730 
    731 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
    732       good_byName_missing_signer)
    733 {
    734  ScopedTestKeyPair missingSignerKeyPair(GenerateKeyPair());
    735  ASSERT_TRUE(missingSignerKeyPair.get());
    736  ByteString responseString(
    737               CreateEncodedOCSPSuccessfulResponse(
    738                         OCSPResponseContext::good, *endEntityCertID,
    739                         "missing", *missingSignerKeyPair,
    740                         oneDayBeforeNow, oneDayBeforeNow, nullptr,
    741                         sha256WithRSAEncryption()));
    742  Input response;
    743  ASSERT_EQ(Success,
    744            response.Init(responseString.data(), responseString.length()));
    745  bool expired;
    746  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    747            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    748                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    749                                      response, expired));
    750  ASSERT_FALSE(expired);
    751 }
    752 
    753 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired)
    754 {
    755  static const char* signerName = "good_indirect_expired";
    756 
    757  const ByteString extensions[] = {
    758    CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No),
    759    ByteString()
    760  };
    761 
    762  ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
    763  ByteString signerDER(CreateEncodedCertificate(
    764                          ++rootIssuedCount, sha256WithRSAEncryption(),
    765                          rootName,
    766                          tenDaysBeforeNow,
    767                          twoDaysBeforeNow,
    768                          signerName, *signerKeyPair, extensions,
    769                          *rootKeyPair));
    770  ASSERT_FALSE(ENCODING_FAILED(signerDER));
    771 
    772  ByteString certs[] = { signerDER, ByteString() };
    773  ByteString responseString(
    774               CreateEncodedOCSPSuccessfulResponse(
    775                         OCSPResponseContext::good, *endEntityCertID,
    776                         signerName, *signerKeyPair, oneDayBeforeNow,
    777                         oneDayBeforeNow, &oneDayAfterNow,
    778                         sha256WithRSAEncryption(), certs));
    779  Input response;
    780  ASSERT_EQ(Success,
    781            response.Init(responseString.data(), responseString.length()));
    782  bool expired;
    783  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    784            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    785                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    786                                      response, expired));
    787 }
    788 
    789 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future)
    790 {
    791  static const char* signerName = "good_indirect_future";
    792 
    793  const ByteString extensions[] = {
    794    CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No),
    795    ByteString()
    796  };
    797 
    798  ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
    799  ByteString signerDER(CreateEncodedCertificate(
    800                         ++rootIssuedCount, sha256WithRSAEncryption(),
    801                         rootName,
    802                         twoDaysAfterNow,
    803                         tenDaysAfterNow,
    804                         signerName, *signerKeyPair, extensions,
    805                         *rootKeyPair));
    806  ASSERT_FALSE(ENCODING_FAILED(signerDER));
    807 
    808  ByteString certs[] = { signerDER, ByteString() };
    809  ByteString responseString(
    810               CreateEncodedOCSPSuccessfulResponse(
    811                         OCSPResponseContext::good, *endEntityCertID,
    812                         signerName, *signerKeyPair, oneDayBeforeNow,
    813                         oneDayBeforeNow, &oneDayAfterNow,
    814                         sha256WithRSAEncryption(), certs));
    815  Input response;
    816  ASSERT_EQ(Success,
    817            response.Init(responseString.data(), responseString.length()));
    818  bool expired;
    819  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    820            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    821                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    822                                      response, expired));
    823  ASSERT_FALSE(expired);
    824 }
    825 
    826 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_no_eku)
    827 {
    828  ByteString responseString(
    829               CreateEncodedIndirectOCSPSuccessfulResponse(
    830                         "good_indirect_wrong_eku",
    831                         OCSPResponseContext::good, byKey,
    832                         sha256WithRSAEncryption(), nullptr));
    833  Input response;
    834  ASSERT_EQ(Success,
    835            response.Init(responseString.data(), responseString.length()));
    836  bool expired;
    837  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    838            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    839                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    840                                      response, expired));
    841  ASSERT_FALSE(expired);
    842 }
    843 
    844 static const Input serverAuthEKUDER(tlv_id_kp_serverAuth);
    845 
    846 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
    847       good_indirect_wrong_eku)
    848 {
    849  ByteString responseString(
    850               CreateEncodedIndirectOCSPSuccessfulResponse(
    851                        "good_indirect_wrong_eku",
    852                        OCSPResponseContext::good, byKey,
    853                        sha256WithRSAEncryption(), &serverAuthEKUDER));
    854  Input response;
    855  ASSERT_EQ(Success,
    856            response.Init(responseString.data(), responseString.length()));
    857  bool expired;
    858  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    859            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    860                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    861                                      response, expired));
    862  ASSERT_FALSE(expired);
    863 }
    864 
    865 // Test that signature of OCSP response signer cert is verified
    866 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_tampered_eku)
    867 {
    868  ByteString tamperedResponse(
    869               CreateEncodedIndirectOCSPSuccessfulResponse(
    870                         "good_indirect_tampered_eku",
    871                         OCSPResponseContext::good, byKey,
    872                         sha256WithRSAEncryption(), &serverAuthEKUDER));
    873  ASSERT_EQ(Success,
    874            TamperOnce(tamperedResponse,
    875                       ByteString(tlv_id_kp_serverAuth,
    876                                  sizeof(tlv_id_kp_serverAuth)),
    877                       ByteString(tlv_id_kp_OCSPSigning,
    878                                  sizeof(tlv_id_kp_OCSPSigning))));
    879  Input tamperedResponseInput;
    880  ASSERT_EQ(Success, tamperedResponseInput.Init(tamperedResponse.data(),
    881                                                tamperedResponse.length()));
    882  bool expired;
    883  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    884            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    885                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    886                                      tamperedResponseInput, expired));
    887  ASSERT_FALSE(expired);
    888 }
    889 
    890 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer)
    891 {
    892  static const char* subCAName = "good_indirect_unknown_issuer sub-CA";
    893  static const char* signerName = "good_indirect_unknown_issuer OCSP signer";
    894 
    895  // unknown issuer
    896  ScopedTestKeyPair unknownKeyPair(GenerateKeyPair());
    897  ASSERT_TRUE(unknownKeyPair.get());
    898 
    899  // Delegated responder cert signed by unknown issuer
    900  const ByteString extensions[] = {
    901    CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No),
    902    ByteString()
    903  };
    904  ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
    905  ByteString signerDER(CreateEncodedCertificate(
    906                         1, sha256WithRSAEncryption(), subCAName,
    907                         oneDayBeforeNow, oneDayAfterNow, signerName,
    908                         *signerKeyPair, extensions, *unknownKeyPair));
    909  ASSERT_FALSE(ENCODING_FAILED(signerDER));
    910 
    911  // OCSP response signed by that delegated responder
    912  ByteString certs[] = { signerDER, ByteString() };
    913  ByteString responseString(
    914               CreateEncodedOCSPSuccessfulResponse(
    915                         OCSPResponseContext::good, *endEntityCertID,
    916                         signerName, *signerKeyPair, oneDayBeforeNow,
    917                         oneDayBeforeNow, &oneDayAfterNow,
    918                         sha256WithRSAEncryption(), certs));
    919  Input response;
    920  ASSERT_EQ(Success,
    921            response.Init(responseString.data(), responseString.length()));
    922  bool expired;
    923  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    924            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    925                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    926                                      response, expired));
    927  ASSERT_FALSE(expired);
    928 }
    929 
    930 // The CA that issued the OCSP responder cert is a sub-CA of the issuer of
    931 // the certificate that the OCSP response is for. That sub-CA cert is included
    932 // in the OCSP response before the OCSP responder cert.
    933 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
    934       good_indirect_subca_1_first)
    935 {
    936  static const char* subCAName = "good_indirect_subca_1_first sub-CA";
    937  static const char* signerName = "good_indirect_subca_1_first OCSP signer";
    938  static const long zero = 0;
    939 
    940  // sub-CA of root (root is the direct issuer of endEntity)
    941  const ByteString subCAExtensions[] = {
    942    CreateEncodedBasicConstraints(true, &zero, Critical::No),
    943    ByteString()
    944  };
    945  ScopedTestKeyPair subCAKeyPair(GenerateKeyPair());
    946  ByteString subCADER(CreateEncodedCertificate(
    947                        ++rootIssuedCount, sha256WithRSAEncryption(), rootName,
    948                        oneDayBeforeNow, oneDayAfterNow, subCAName,
    949                        *subCAKeyPair, subCAExtensions, *rootKeyPair));
    950  ASSERT_FALSE(ENCODING_FAILED(subCADER));
    951 
    952  // Delegated responder cert signed by that sub-CA
    953  const ByteString extensions[] = {
    954    CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No),
    955    ByteString(),
    956  };
    957  ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
    958  ByteString signerDER(CreateEncodedCertificate(
    959                         1, sha256WithRSAEncryption(), subCAName,
    960                         oneDayBeforeNow, oneDayAfterNow, signerName,
    961                         *signerKeyPair, extensions, *subCAKeyPair));
    962  ASSERT_FALSE(ENCODING_FAILED(signerDER));
    963 
    964  // OCSP response signed by the delegated responder issued by the sub-CA
    965  // that is trying to impersonate the root.
    966  ByteString certs[] = { subCADER, signerDER, ByteString() };
    967  ByteString responseString(
    968               CreateEncodedOCSPSuccessfulResponse(
    969                         OCSPResponseContext::good, *endEntityCertID,
    970                         signerName, *signerKeyPair, oneDayBeforeNow,
    971                         oneDayBeforeNow, &oneDayAfterNow,
    972                         sha256WithRSAEncryption(), certs));
    973  Input response;
    974  ASSERT_EQ(Success,
    975            response.Init(responseString.data(), responseString.length()));
    976  bool expired;
    977  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
    978            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
    979                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
    980                                      response, expired));
    981  ASSERT_FALSE(expired);
    982 }
    983 
    984 // The CA that issued the OCSP responder cert is a sub-CA of the issuer of
    985 // the certificate that the OCSP response is for. That sub-CA cert is included
    986 // in the OCSP response after the OCSP responder cert.
    987 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
    988       good_indirect_subca_1_second)
    989 {
    990  static const char* subCAName = "good_indirect_subca_1_second sub-CA";
    991  static const char* signerName = "good_indirect_subca_1_second OCSP signer";
    992  static const long zero = 0;
    993 
    994  // sub-CA of root (root is the direct issuer of endEntity)
    995  const ByteString subCAExtensions[] = {
    996    CreateEncodedBasicConstraints(true, &zero, Critical::No),
    997    ByteString()
    998  };
    999  ScopedTestKeyPair subCAKeyPair(GenerateKeyPair());
   1000  ByteString subCADER(CreateEncodedCertificate(++rootIssuedCount,
   1001                                               sha256WithRSAEncryption(),
   1002                                               rootName,
   1003                                               oneDayBeforeNow, oneDayAfterNow,
   1004                                               subCAName, *subCAKeyPair,
   1005                                               subCAExtensions, *rootKeyPair));
   1006  ASSERT_FALSE(ENCODING_FAILED(subCADER));
   1007 
   1008  // Delegated responder cert signed by that sub-CA
   1009  const ByteString extensions[] = {
   1010    CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No),
   1011    ByteString()
   1012  };
   1013  ScopedTestKeyPair signerKeyPair(GenerateKeyPair());
   1014  ByteString signerDER(CreateEncodedCertificate(
   1015                         1, sha256WithRSAEncryption(), subCAName,
   1016                         oneDayBeforeNow, oneDayAfterNow, signerName,
   1017                         *signerKeyPair, extensions, *subCAKeyPair));
   1018  ASSERT_FALSE(ENCODING_FAILED(signerDER));
   1019 
   1020  // OCSP response signed by the delegated responder issued by the sub-CA
   1021  // that is trying to impersonate the root.
   1022  ByteString certs[] = { signerDER, subCADER, ByteString() };
   1023  ByteString responseString(
   1024                 CreateEncodedOCSPSuccessfulResponse(
   1025                         OCSPResponseContext::good, *endEntityCertID,
   1026                         signerName, *signerKeyPair, oneDayBeforeNow,
   1027                         oneDayBeforeNow, &oneDayAfterNow,
   1028                         sha256WithRSAEncryption(), certs));
   1029  Input response;
   1030  ASSERT_EQ(Success,
   1031            response.Init(responseString.data(), responseString.length()));
   1032  bool expired;
   1033  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
   1034            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
   1035                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
   1036                                      response, expired));
   1037  ASSERT_FALSE(expired);
   1038 }
   1039 
   1040 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
   1041       good_unsupportedSignatureAlgorithmOnResponder)
   1042 {
   1043  // Note that the algorithm ID (md5WithRSAEncryption) identifies the signature
   1044  // algorithm that will be used to sign the certificate that issues the OCSP
   1045  // responses, not the responses themselves.
   1046  PRUint32 policyMd5;
   1047  ASSERT_EQ(SECSuccess,NSS_GetAlgorithmPolicy(SEC_OID_MD5, &policyMd5));
   1048 
   1049  /* our encode won't work if MD5 isn't allowed by policy */
   1050  ASSERT_EQ(SECSuccess,
   1051            NSS_SetAlgorithmPolicy(SEC_OID_MD5, NSS_USE_ALG_IN_SIGNATURE, 0));
   1052  ByteString responseString(
   1053               CreateEncodedIndirectOCSPSuccessfulResponse(
   1054                         "good_indirect_unsupportedSignatureAlgorithm",
   1055                         OCSPResponseContext::good, byKey,
   1056                         md5WithRSAEncryption()));
   1057  Input response;
   1058  /* now restore the existing policy */
   1059  ASSERT_EQ(Success,
   1060            response.Init(responseString.data(), responseString.length()));
   1061  ASSERT_EQ(SECSuccess,
   1062            NSS_SetAlgorithmPolicy(SEC_OID_MD5, policyMd5, NSS_USE_ALG_IN_SIGNATURE));
   1063  bool expired;
   1064  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
   1065            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
   1066                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
   1067                                      response, expired));
   1068 }
   1069 
   1070 class pkixocsp_VerifyEncodedResponse_GetCertTrust
   1071  : public pkixocsp_VerifyEncodedResponse_DelegatedResponder {
   1072 public:
   1073  void SetUp()
   1074  {
   1075    pkixocsp_VerifyEncodedResponse_DelegatedResponder::SetUp();
   1076 
   1077    responseString =
   1078        CreateEncodedIndirectOCSPSuccessfulResponse(
   1079          "OCSPGetCertTrustTest Signer", OCSPResponseContext::good,
   1080          byKey, sha256WithRSAEncryption(), &OCSPSigningEKUDER,
   1081          &signerCertDER);
   1082    if (ENCODING_FAILED(responseString)) {
   1083      abort();
   1084    }
   1085    if (response.Init(responseString.data(), responseString.length())
   1086          != Success) {
   1087      abort();
   1088    }
   1089    if (signerCertDER.length() == 0) {
   1090      abort();
   1091    }
   1092  }
   1093 
   1094  class TrustDomain final : public OCSPTestTrustDomain
   1095  {
   1096  public:
   1097    TrustDomain()
   1098      : certTrustLevel(TrustLevel::InheritsTrust)
   1099    {
   1100    }
   1101 
   1102    bool SetCertTrust(const ByteString& aCertDER, TrustLevel aCertTrustLevel)
   1103    {
   1104      this->certDER = aCertDER;
   1105      this->certTrustLevel = aCertTrustLevel;
   1106      return true;
   1107    }
   1108  private:
   1109    Result GetCertTrust(EndEntityOrCA endEntityOrCA, const CertPolicyId&,
   1110                        Input candidateCert, /*out*/ TrustLevel& trustLevel)
   1111                        override
   1112    {
   1113      EXPECT_EQ(endEntityOrCA, EndEntityOrCA::MustBeEndEntity);
   1114      EXPECT_FALSE(certDER.empty());
   1115      Input certDERInput;
   1116      EXPECT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length()));
   1117      EXPECT_TRUE(InputsAreEqual(certDERInput, candidateCert));
   1118      trustLevel = certTrustLevel;
   1119      return Success;
   1120    }
   1121 
   1122    ByteString certDER;
   1123    TrustLevel certTrustLevel;
   1124  };
   1125 
   1126 // trustDomain deliberately shadows the inherited field so that it isn't used
   1127 // by accident. See bug 1339921.
   1128 // Unfortunately GCC can't parse __has_warning("-Wshadow-field") even if it's
   1129 // the latter part of a conjunction that would evaluate to false, so we have to
   1130 // wrap it in a separate preprocessor conditional rather than using &&.
   1131 #if defined(__clang__)
   1132  #if __has_warning("-Wshadow-field")
   1133    #pragma clang diagnostic push
   1134    #pragma clang diagnostic ignored "-Wshadow-field"
   1135  #endif
   1136 #endif
   1137  TrustDomain trustDomain;
   1138 #if defined(__clang__)
   1139  #if __has_warning("-Wshadow-field")
   1140    #pragma clang diagnostic pop
   1141  #endif
   1142 #endif
   1143  ByteString signerCertDER;
   1144  ByteString responseString;
   1145  Input response; // references data in responseString
   1146 };
   1147 
   1148 TEST_F(pkixocsp_VerifyEncodedResponse_GetCertTrust, InheritTrust)
   1149 {
   1150  ASSERT_TRUE(trustDomain.SetCertTrust(signerCertDER,
   1151                                       TrustLevel::InheritsTrust));
   1152  bool expired;
   1153  ASSERT_EQ(Success,
   1154            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
   1155                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
   1156                                      response, expired));
   1157  ASSERT_FALSE(expired);
   1158 }
   1159 
   1160 TEST_F(pkixocsp_VerifyEncodedResponse_GetCertTrust, TrustAnchor)
   1161 {
   1162  ASSERT_TRUE(trustDomain.SetCertTrust(signerCertDER,
   1163                                       TrustLevel::TrustAnchor));
   1164  bool expired;
   1165  ASSERT_EQ(Success,
   1166            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
   1167                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
   1168                                      response, expired));
   1169  ASSERT_FALSE(expired);
   1170 }
   1171 
   1172 TEST_F(pkixocsp_VerifyEncodedResponse_GetCertTrust, ActivelyDistrusted)
   1173 {
   1174  ASSERT_TRUE(trustDomain.SetCertTrust(signerCertDER,
   1175                                       TrustLevel::ActivelyDistrusted));
   1176  Input responseInput;
   1177  ASSERT_EQ(Success,
   1178            responseInput.Init(responseString.data(),
   1179                               responseString.length()));
   1180  bool expired;
   1181  ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
   1182            VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
   1183                                      END_ENTITY_MAX_LIFETIME_IN_DAYS,
   1184                                      responseInput, expired));
   1185  ASSERT_FALSE(expired);
   1186 }