1 /** @file -- Pkcs7EkuVerify.c
2 * Copyright (c) Microsoft Corporation.
3 * SPDX-License-Identifier: BSD-2-Clause-Patent
5 This is an test code which verifies specified
6 Enhanced Key Usages (EKU)'s are present in the leaf signer
7 of a PKCS7 formatted signature.
10 A typical signing certificate chain looks like this: (Could be RSA or ECC).
12 ------------------------------------------
13 | | // Root of trust. ECDSA P521 curve
14 | TestEKUParsingRoot | // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
15 | | // CERT_KEY_CERT_SIGN_KEY_USAGE | CERT_CRL_SIGN_KEY_USAGE
16 ------------------------------------------
19 ------------------------------------------
20 | | // Policy CA. Issues subordinate CAs. ECC P384 curve.
21 | TestEKUParsingPolicyCA | // SHA 256 Key Usage:
22 | | // CERT_KEY_CERT_SIGN_KEY_USAGE | CERT_CRL_SIGN_KEY_USAGE
23 ------------------------------------------
26 ------------------------------------------
27 | | // Issues end-entity (leaf) signers. ECC P256 curve.
28 | TestEKUParsingIssuingCA | // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
29 | | // Enhanced Key Usage:
30 ------------------------------------------ // 1.3.6.1.4.1.311.76.9.21.1 (Surface firmware signing)
33 --------------------------------------
34 / TestEKUParsingLeafSigner && / // Leaf signer, ECC P256 curve.
35 / TestEKUParsingLeafSignerPid12345 / // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
36 / / // Enhanced Key usages:
37 -------------------------------------- // 1.3.6.1.4.1.311.76.9.21.1 (Surface firmware signing)
38 // 1.3.6.1.4.1.311.76.9.21.1.N, N == Product ID.
46 #include "TestBaseCryptLib.h"
48 #include "Pkcs7EkuTestSignatures.h"
52 VerifyEKUsInPkcs7Signature (
53 IN CONST UINT8
*Pkcs7Signature
,
54 IN CONST UINT32 SignatureSize
,
55 IN CONST CHAR8
*RequiredEKUs
[],
56 IN CONST UINT32 RequiredEKUsSize
,
57 IN BOOLEAN RequireAllPresent
60 /// ================================================================================================
61 /// ================================================================================================
65 /// ================================================================================================
66 /// ================================================================================================
68 CONST CHAR8 FIRMWARE_SIGNER_EKU
[] = "1.3.6.1.4.1.311.76.9.21.1";
71 TestVerifyEKUsInSignature()
73 Verify that "1.3.6.1.4.1.311.76.9.21.1" (Firmware signature) is in the
74 leaf signer certificate.
77 @param[in] Framework - Unit-test framework handle.
78 @param[in] Context - Optional context pointer for this test.
80 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
81 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
86 TestVerifyEKUsInSignature (
87 IN UNIT_TEST_CONTEXT Context
90 EFI_STATUS Status
= EFI_SUCCESS
;
92 CONST CHAR8
*RequiredEKUs
[] = { FIRMWARE_SIGNER_EKU
};
94 Status
= VerifyEKUsInPkcs7Signature (
95 ProductionECCSignature
,
96 ARRAY_SIZE (ProductionECCSignature
),
97 (CONST CHAR8
**)RequiredEKUs
,
98 ARRAY_SIZE (RequiredEKUs
),
101 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
103 return UNIT_TEST_PASSED
;
104 }// TestVerifyEKUsInSignature()
107 TestVerifyEKUsWith3CertsInSignature()
109 This PKCS7 signature has 3 certificates in it. (Policy CA, Issuing CA
110 and leaf signer). It has one firmware signing EKU in it.
111 "1.3.6.1.4.1.311.76.9.21.1"
113 @param[in] Framework - Unit-test framework handle.
114 @param[in] Context - Optional context pointer for this test.
116 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
117 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
122 TestVerifyEKUsWith3CertsInSignature (
123 IN UNIT_TEST_CONTEXT Context
126 EFI_STATUS Status
= EFI_SUCCESS
;
128 CONST CHAR8
*RequiredEKUs
[] = { FIRMWARE_SIGNER_EKU
};
130 Status
= VerifyEKUsInPkcs7Signature (
131 TestSignEKUsWith3CertsInSignature
,
132 ARRAY_SIZE (TestSignEKUsWith3CertsInSignature
),
133 (CONST CHAR8
**)RequiredEKUs
,
134 ARRAY_SIZE (RequiredEKUs
),
137 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
139 return UNIT_TEST_PASSED
;
140 }// TestVerifyEKUsWith3CertsInSignature()
143 TestVerifyEKUsWith2CertsInSignature()
145 This PKCS7 signature has 2 certificates in it. (Issuing CA and leaf signer).
146 It has one firmware signing EKU in it. "1.3.6.1.4.1.311.76.9.21.1"
148 @param[in] Framework - Unit-test framework handle.
149 @param[in] Context - Optional context pointer for this test.
151 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
152 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
157 TestVerifyEKUsWith2CertsInSignature (
158 IN UNIT_TEST_CONTEXT Context
161 EFI_STATUS Status
= EFI_SUCCESS
;
163 CONST CHAR8
*RequiredEKUs
[] = { FIRMWARE_SIGNER_EKU
};
165 Status
= VerifyEKUsInPkcs7Signature (
166 TestSignEKUsWith2CertsInSignature
,
167 ARRAY_SIZE (TestSignEKUsWith2CertsInSignature
),
168 (CONST CHAR8
**)RequiredEKUs
,
169 ARRAY_SIZE (RequiredEKUs
),
172 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
174 return UNIT_TEST_PASSED
;
175 }// TestVerifyEKUsWith2CertsInSignature()
178 TestVerifyEKUsWith1CertInSignature()
180 This PKCS7 signature only has the leaf signer in it.
181 It has one firmware signing EKU in it. "1.3.6.1.4.1.311.76.9.21.1"
183 @param[in] Framework - Unit-test framework handle.
184 @param[in] Context - Optional context pointer for this test.
186 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
187 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
192 TestVerifyEKUsWith1CertInSignature (
193 IN UNIT_TEST_CONTEXT Context
196 EFI_STATUS Status
= EFI_SUCCESS
;
198 CONST CHAR8
*RequiredEKUs
[] = { FIRMWARE_SIGNER_EKU
};
200 Status
= VerifyEKUsInPkcs7Signature (
201 TestSignEKUsWith1CertInSignature
,
202 ARRAY_SIZE (TestSignEKUsWith1CertInSignature
),
203 (CONST CHAR8
**)RequiredEKUs
,
204 ARRAY_SIZE (RequiredEKUs
),
207 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
209 return UNIT_TEST_PASSED
;
210 }// TestVerifyEKUsWith1CertInSignature()
213 TestVerifyEKUsWithMultipleEKUsInCert()
216 This signature has two EKU's in it:
217 "1.3.6.1.4.1.311.76.9.21.1"
218 "1.3.6.1.4.1.311.76.9.21.2"
219 We verify that both EKU's were present in the leaf signer.
221 @param[in] Framework - Unit-test framework handle.
222 @param[in] Context - Optional context pointer for this test.
224 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
225 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
230 TestVerifyEKUsWithMultipleEKUsInCert (
231 IN UNIT_TEST_CONTEXT Context
234 EFI_STATUS Status
= EFI_SUCCESS
;
236 CONST CHAR8
*RequiredEKUs
[] = {
237 "1.3.6.1.4.1.311.76.9.21.1",
238 "1.3.6.1.4.1.311.76.9.21.1.2"
241 Status
= VerifyEKUsInPkcs7Signature (
242 TestSignedWithMultipleEKUsInCert
,
243 ARRAY_SIZE (TestSignedWithMultipleEKUsInCert
),
244 (CONST CHAR8
**)RequiredEKUs
,
245 ARRAY_SIZE (RequiredEKUs
),
248 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
250 return UNIT_TEST_PASSED
;
251 }// TestVerifyEKUsWithMultipleEKUsInCert()
254 TestEkusNotPresentInSignature()
256 This test verifies that if we send an EKU that is not in the signature,
257 that we get back an error.
259 @param[in] Framework - Unit-test framework handle.
260 @param[in] Context - Optional context pointer for this test.
262 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
263 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
268 TestEkusNotPresentInSignature (
269 IN UNIT_TEST_CONTEXT Context
272 EFI_STATUS Status
= EFI_SUCCESS
;
275 // This EKU is not in the signature.
277 CONST CHAR8
*RequiredEKUs
[] = { "1.3.6.1.4.1.311.76.9.21.3" };
279 Status
= VerifyEKUsInPkcs7Signature (
280 TestSignedWithMultipleEKUsInCert
,
281 ARRAY_SIZE (TestSignedWithMultipleEKUsInCert
),
282 (CONST CHAR8
**)RequiredEKUs
,
283 ARRAY_SIZE (RequiredEKUs
),
286 UT_ASSERT_NOT_EQUAL (Status
, EFI_SUCCESS
);
288 return UNIT_TEST_PASSED
;
289 }// TestEkusNotPresentInSignature()
292 TestEkusNotPresentInSignature()
294 This test signature has two EKU's in it: (Product ID is 10001)
295 "1.3.6.1.4.1.311.76.9.21.1"
296 "1.3.6.1.4.1.311.76.9.21.1.10001"
298 @param[in] Framework - Unit-test framework handle.
299 @param[in] Context - Optional context pointer for this test.
301 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
302 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
307 TestProductId10001PresentInSignature (
308 IN UNIT_TEST_CONTEXT Context
311 EFI_STATUS Status
= EFI_SUCCESS
;
314 // These EKU's are present in the leaf signer certificate.
316 CONST CHAR8
*RequiredEKUs
[] = {
317 "1.3.6.1.4.1.311.76.9.21.1",
318 "1.3.6.1.4.1.311.76.9.21.1.10001"
321 Status
= VerifyEKUsInPkcs7Signature (
322 TestSignedWithProductId10001
,
323 ARRAY_SIZE (TestSignedWithProductId10001
),
324 (CONST CHAR8
**)RequiredEKUs
,
325 ARRAY_SIZE (RequiredEKUs
),
328 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
330 return UNIT_TEST_PASSED
;
331 }// TestProductId10001PresentInSignature()
334 TestOnlyOneEkuInListRequired()
336 This test will check the BOOLEAN RequireAllPresent parameter in the
337 call to VerifyEKUsInPkcs7Signature() behaves properly. The signature
340 "1.3.6.1.4.1.311.76.9.21.1"
341 "1.3.6.1.4.1.311.76.9.21.1.10001"
343 but we only pass in one of them, and set RequireAllPresent to FALSE.
345 @param[in] Framework - Unit-test framework handle.
346 @param[in] Context - Optional context pointer for this test.
348 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
349 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
354 TestOnlyOneEkuInListRequired (
355 IN UNIT_TEST_CONTEXT Context
358 EFI_STATUS Status
= EFI_SUCCESS
;
361 // This will test the flag that specifies it is OK to succeed if
362 // any one of the EKU's passed in is found.
364 CONST CHAR8
*RequiredEKUs
[] = { "1.3.6.1.4.1.311.76.9.21.1.10001" };
366 Status
= VerifyEKUsInPkcs7Signature (
367 TestSignedWithProductId10001
,
368 ARRAY_SIZE (TestSignedWithProductId10001
),
369 (CONST CHAR8
**)RequiredEKUs
,
370 ARRAY_SIZE (RequiredEKUs
),
373 UT_ASSERT_STATUS_EQUAL (Status
, EFI_SUCCESS
);
375 return UNIT_TEST_PASSED
;
376 }// TestOnlyOneEkuInListRequired()
379 TestNoEKUsInSignature()
381 This test uses a signature that was signed with a certificate that does
382 not contain any EKUs.
385 @param[in] Framework - Unit-test framework handle.
386 @param[in] Context - Optional context pointer for this test.
388 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
389 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
394 TestNoEKUsInSignature (
395 IN UNIT_TEST_CONTEXT Context
398 EFI_STATUS Status
= EFI_SUCCESS
;
401 // This EKU is not in the certificate, so it should fail.
403 CONST CHAR8
*RequiredEKUs
[] = { "1.3.6.1.4.1.311.76.9.21.1" };
405 Status
= VerifyEKUsInPkcs7Signature (
406 TestSignatureWithNoEKUsPresent
,
407 ARRAY_SIZE (TestSignatureWithNoEKUsPresent
),
408 (CONST CHAR8
**)RequiredEKUs
,
409 ARRAY_SIZE (RequiredEKUs
),
412 UT_ASSERT_NOT_EQUAL (Status
, EFI_SUCCESS
);
414 return UNIT_TEST_PASSED
;
415 }// TestNoEKUsInSignature()
418 TestInvalidParameters()
420 Passes the API invalid parameters, and ensures that it does not succeed.
422 @param[in] Framework - Unit-test framework handle.
423 @param[in] Context - Optional context pointer for this test.
425 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
426 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
431 TestInvalidParameters (
432 IN UNIT_TEST_CONTEXT Context
435 EFI_STATUS Status
= EFI_SUCCESS
;
437 CONST CHAR8
*RequiredEKUs
[] = { "1.3.6.1.4.1.311.76.9.21.1" };
440 // Check bad signature.
442 Status
= VerifyEKUsInPkcs7Signature (
445 (CONST CHAR8
**)RequiredEKUs
,
446 ARRAY_SIZE (RequiredEKUs
),
449 UT_ASSERT_STATUS_EQUAL (Status
, EFI_INVALID_PARAMETER
);
452 // Check invalid EKU's
454 Status
= VerifyEKUsInPkcs7Signature (
455 TestSignatureWithNoEKUsPresent
,
456 ARRAY_SIZE (TestSignatureWithNoEKUsPresent
),
457 (CONST CHAR8
**)NULL
,
461 UT_ASSERT_STATUS_EQUAL (Status
, EFI_INVALID_PARAMETER
);
463 return UNIT_TEST_PASSED
;
464 }// TestInvalidParameters()
467 TestEKUSubStringFails()
469 Pass the API a sub set and super set of an EKU and ensure that they
472 @param[in] Framework - Unit-test framework handle.
473 @param[in] Context - Optional context pointer for this test.
475 @retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
476 @retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
481 TestEKUSubsetSupersetFails (
482 IN UNIT_TEST_CONTEXT Context
485 EFI_STATUS Status
= EFI_SUCCESS
;
488 // This signature has an EKU of:
489 // "1.3.6.1.4.1.311.76.9.21.1.10001"
491 // "1.3.6.1.4.1.311.76.9.21"
494 CONST CHAR8
*RequiredEKUs1
[] = { "1.3.6.1.4.1.311.76.9.21" };
496 Status
= VerifyEKUsInPkcs7Signature (
497 TestSignedWithProductId10001
,
498 ARRAY_SIZE (TestSignedWithProductId10001
),
499 (CONST CHAR8
**)RequiredEKUs1
,
500 ARRAY_SIZE (RequiredEKUs1
),
503 UT_ASSERT_NOT_EQUAL (Status
, EFI_SUCCESS
);
506 // This signature has an EKU of:
507 // "1.3.6.1.4.1.311.76.9.21.1.10001"
508 // so ensure that a super set
509 // "1.3.6.1.4.1.311.76.9.21.1.10001.1"
512 CONST CHAR8
*RequiredEKUs2
[] = { "1.3.6.1.4.1.311.76.9.21.1.10001.1" };
514 Status
= VerifyEKUsInPkcs7Signature (
515 TestSignedWithProductId10001
,
516 ARRAY_SIZE (TestSignedWithProductId10001
),
517 (CONST CHAR8
**)RequiredEKUs2
,
518 ARRAY_SIZE (RequiredEKUs2
),
521 UT_ASSERT_NOT_EQUAL (Status
, EFI_SUCCESS
);
523 return UNIT_TEST_PASSED
;
524 }// TestEKUSubsetSupersetFails()
526 TEST_DESC mPkcs7EkuTest
[] = {
528 // -----Description--------------------------------Class----------------------------Function------------------------------Pre---Post--Context
530 { "TestVerifyEKUsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsInSignature
, NULL
, NULL
, NULL
},
531 { "TestVerifyEKUsWith3CertsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith3CertsInSignature
, NULL
, NULL
, NULL
},
532 { "TestVerifyEKUsWith2CertsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith2CertsInSignature
, NULL
, NULL
, NULL
},
533 { "TestVerifyEKUsWith1CertInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith1CertInSignature
, NULL
, NULL
, NULL
},
534 { "TestVerifyEKUsWithMultipleEKUsInCert()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWithMultipleEKUsInCert
, NULL
, NULL
, NULL
},
535 { "TestEkusNotPresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestEkusNotPresentInSignature
, NULL
, NULL
, NULL
},
536 { "TestProductId10001PresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestProductId10001PresentInSignature
, NULL
, NULL
, NULL
},
537 { "TestOnlyOneEkuInListRequired()", "CryptoPkg.BaseCryptLib.Eku", TestOnlyOneEkuInListRequired
, NULL
, NULL
, NULL
},
538 { "TestNoEKUsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestNoEKUsInSignature
, NULL
, NULL
, NULL
},
539 { "TestInvalidParameters()", "CryptoPkg.BaseCryptLib.Eku", TestInvalidParameters
, NULL
, NULL
, NULL
},
540 { "TestEKUSubsetSupersetFails()", "CryptoPkg.BaseCryptLib.Eku", TestEKUSubsetSupersetFails
, NULL
, NULL
, NULL
},
543 UINTN mPkcs7EkuTestNum
= ARRAY_SIZE (mPkcs7EkuTest
);