Coverage Report

Created: 2018-09-25 14:53

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