13#include "InternalCryptLib.h"
14#include <openssl/x509v3.h>
15#include <openssl/asn1.h>
16#include <openssl/x509.h>
17#include <openssl/bio.h>
18#include <crypto/x509.h>
19#include <openssl/pkcs7.h>
20#include <openssl/bn.h>
21#include <openssl/x509_vfy.h>
22#include <openssl/pem.h>
23#include <openssl/evp.h>
24#include <crypto/asn1.h>
74 STACK_OF (X509) *Signers;
81 if ((CertChain ==
NULL) || (SignerCert ==
NULL)) {
82 Status = EFI_INVALID_PARAMETER;
89 Signers = PKCS7_get0_signers ((
PKCS7 *)CertChain,
NULL, PKCS7_BINARY);
90 if (Signers ==
NULL) {
94 Status = EFI_INVALID_PARAMETER;
101 NumberSigners = sk_X509_num (Signers);
102 if (NumberSigners != 1) {
106 Status = EFI_NOT_FOUND;
110 *SignerCert = sk_X509_value (Signers, 0);
116 if (Signers !=
NULL) {
117 sk_X509_free (Signers);
140 IN ASN1_OBJECT *Asn1ToFind
145 X509_EXTENSION *Extension;
146 EXTENDED_KEY_USAGE *Eku;
147 INT32 ExtensionIndex;
149 ASN1_OBJECT *Asn1InCert;
152 Status = EFI_NOT_FOUND;
160 if ((Cert ==
NULL) || (Asn1ToFind ==
NULL)) {
161 Status = EFI_INVALID_PARAMETER;
169 ClonedCert = X509_dup ((X509 *)Cert);
170 if (ClonedCert ==
NULL) {
174 Status = EFI_INVALID_PARAMETER;
181 ExtensionIndex = X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -1);
183 if (ExtensionIndex < 0) {
190 Extension = X509_get_ext (ClonedCert, ExtensionIndex);
191 if (Extension ==
NULL) {
198 Eku = (EXTENDED_KEY_USAGE *)X509V3_EXT_d2i (Extension);
206 NumExtensions = sk_ASN1_OBJECT_num (Eku);
211 for (Index = 0; Index < NumExtensions; Index++) {
212 Asn1InCert = sk_ASN1_OBJECT_value (Eku, (INT32)Index);
213 if (Asn1InCert ==
NULL) {
220 if ((Asn1InCert->length == Asn1ToFind->length) &&
221 (
CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length) == 0))
236 if (ClonedCert !=
NULL) {
237 X509_free (ClonedCert);
241 sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);
264 IN CONST CHAR8 *RequiredEKUs[],
265 IN CONST UINT32 RequiredEKUsSize,
266 IN BOOLEAN RequireAllPresent
270 ASN1_OBJECT *Asn1ToFind;
278 if ((SignerCert ==
NULL) || (RequiredEKUs ==
NULL) || (RequiredEKUsSize == 0)) {
279 Status = EFI_INVALID_PARAMETER;
283 for (Index = 0; Index < RequiredEKUsSize; Index++) {
287 if (Asn1ToFind !=
NULL) {
288 ASN1_OBJECT_free (Asn1ToFind);
292 Asn1ToFind = OBJ_txt2obj (RequiredEKUs[Index], 0);
293 if (Asn1ToFind ==
NULL) {
297 Status = EFI_INVALID_PARAMETER;
304 if (!RequireAllPresent) {
319 if (Asn1ToFind !=
NULL) {
320 ASN1_OBJECT_free (Asn1ToFind);
323 if (RequireAllPresent &&
324 (NumEkusFound == RequiredEKUsSize))
368 IN CONST UINT8 *Pkcs7Signature,
370 IN CONST CHAR8 *RequiredEKUs[],
371 IN CONST UINT32 RequiredEKUsSize,
372 IN BOOLEAN RequireAllPresent
378 STACK_OF (X509) *CertChain;
380 INT32 NumberCertsInSignature;
384 UINTN SignedDataSize;
392 NumberCertsInSignature = 0;
402 if ((Pkcs7Signature ==
NULL) ||
403 (SignatureSize == 0) ||
404 (RequiredEKUs ==
NULL) ||
405 (RequiredEKUsSize == 0))
407 Status = EFI_INVALID_PARAMETER;
411 if (RequiredEKUsSize == 1) {
412 RequireAllPresent =
TRUE;
429 Status = EFI_INVALID_PARAMETER;
438 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&Temp, (INT32)SignedDataSize);
443 Status = EFI_INVALID_PARAMETER;
450 SignatureType = OBJ_obj2nid (Pkcs7->type);
451 switch (SignatureType) {
452 case NID_pkcs7_signed:
453 if (Pkcs7->d.sign !=
NULL) {
454 CertChain = Pkcs7->d.sign->cert;
458 case NID_pkcs7_signedAndEnveloped:
459 if (Pkcs7->d.signed_and_enveloped !=
NULL) {
460 CertChain = Pkcs7->d.signed_and_enveloped->cert;
471 if (CertChain ==
NULL) {
475 Status = EFI_INVALID_PARAMETER;
482 NumberCertsInSignature = sk_X509_num (CertChain);
484 if (NumberCertsInSignature == 0) {
488 Status = EFI_INVALID_PARAMETER;
500 Status = EFI_INVALID_PARAMETER;
504 Status =
CheckEKUs (SignerCert, RequiredEKUs, RequiredEKUsSize, RequireAllPresent);
517 if (!IsWrapped && SignedData) {
BOOLEAN WrapPkcs7Data(IN CONST UINT8 *P7Data, IN UINTN P7Length, OUT BOOLEAN *WrapFlag, OUT UINT8 **WrapData, OUT UINTN *WrapDataSize)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
STATIC EFI_STATUS CheckEKUs(IN CONST X509 *SignerCert, IN CONST CHAR8 *RequiredEKUs[], IN CONST UINT32 RequiredEKUsSize, IN BOOLEAN RequireAllPresent)
STATIC EFI_STATUS GetSignerCertificate(IN CONST PKCS7 *CertChain, OUT X509 **SignerCert)
STATIC EFI_STATUS IsEkuInCertificate(IN CONST X509 *Cert, IN ASN1_OBJECT *Asn1ToFind)
EFI_STATUS EFIAPI VerifyEKUsInPkcs7Signature(IN CONST UINT8 *Pkcs7Signature, IN CONST UINT32 SignatureSize, IN CONST CHAR8 *RequiredEKUs[], IN CONST UINT32 RequiredEKUsSize, IN BOOLEAN RequireAllPresent)
VOID EFIAPI Exit(IN EFI_STATUS Status)