summaryrefslogtreecommitdiff
path: root/Cryptlib/Pk
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/Pk')
-rw-r--r--Cryptlib/Pk/CryptAuthenticode.c20
-rw-r--r--Cryptlib/Pk/CryptPkcs7Verify.c29
-rw-r--r--Cryptlib/Pk/CryptX509.c78
3 files changed, 110 insertions, 17 deletions
diff --git a/Cryptlib/Pk/CryptAuthenticode.c b/Cryptlib/Pk/CryptAuthenticode.c
index 7b8bca53..4ce2b06b 100644
--- a/Cryptlib/Pk/CryptAuthenticode.c
+++ b/Cryptlib/Pk/CryptAuthenticode.c
@@ -9,7 +9,7 @@
AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for
data structure.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -123,7 +123,7 @@ AuthenticodeVerify (
// Un-matched SPC_INDIRECT_DATA_OBJID.
//
goto _Exit;
- }
+ }
SpcIndirectDataContent = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data);
@@ -135,16 +135,27 @@ AuthenticodeVerify (
if ((Asn1Byte & 0x80) == 0) {
//
- // Short Form of Length Encoding
+ // Short Form of Length Encoding (Length < 128)
//
ContentSize = (UINTN) (Asn1Byte & 0x7F);
//
// Skip the SEQUENCE Tag;
//
SpcIndirectDataContent += 2;
+
+ } else if ((Asn1Byte & 0x81) == 0x81) {
+ //
+ // Long Form of Length Encoding (128 <= Length < 255, Single Octet)
+ //
+ ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));
+ //
+ // Skip the SEQUENCE Tag;
+ //
+ SpcIndirectDataContent += 3;
+
} else if ((Asn1Byte & 0x82) == 0x82) {
//
- // Long Form of Length Encoding, only support two bytes.
+ // Long Form of Length Encoding (Length > 255, Two Octet)
//
ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));
ContentSize = (ContentSize << 8) + (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 3));
@@ -152,6 +163,7 @@ AuthenticodeVerify (
// Skip the SEQUENCE Tag;
//
SpcIndirectDataContent += 4;
+
} else {
goto _Exit;
}
diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c
index 05c3f877..a9665d50 100644
--- a/Cryptlib/Pk/CryptPkcs7Verify.c
+++ b/Cryptlib/Pk/CryptPkcs7Verify.c
@@ -10,7 +10,7 @@
WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated
Variable and will do basic check for data structure.
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -123,7 +123,7 @@ X509VerifyCb (
@param[in] P7Length Length of the PKCS#7 message in bytes.
@param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, otherwise
return FALSE.
- @param[out] WrapData If return status of this function is TRUE:
+ @param[out] WrapData If return status of this function is TRUE:
1) when WrapFlag is TRUE, pointer to P7Data.
2) when WrapFlag is FALSE, pointer to a new ContentInfo
structure. It's caller's responsibility to free this
@@ -227,7 +227,7 @@ WrapPkcs7Data (
@param[in] X509Stack Pointer to a X509 stack object.
@param[out] Cert Pointer to a X509 certificate.
@param[out] CertSize Length of output X509 certificate in bytes.
-
+
@retval TRUE The X509 stack pop succeeded.
@retval FALSE The pop operation failed.
@@ -359,7 +359,7 @@ Pkcs7GetSigners (
(TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX)) {
return FALSE;
}
-
+
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status) {
return Status;
@@ -410,7 +410,7 @@ Pkcs7GetSigners (
//
BufferSize = sizeof (UINT8);
OldSize = BufferSize;
-
+
for (Index = 0; ; Index++) {
Status = X509PopCertificate (Stack, &SingleCert, &SingleCertSize);
if (!Status) {
@@ -455,7 +455,7 @@ Pkcs7GetSigners (
*CertStack = CertBuf;
*StackLength = BufferSize;
Status = TRUE;
- }
+ }
_Exit:
//
@@ -485,7 +485,7 @@ _Exit:
if (OldBuf != NULL) {
free (OldBuf);
}
-
+
return Status;
}
@@ -556,11 +556,11 @@ Pkcs7Verify (
//
// Check input parameters.
//
- if (P7Data == NULL || TrustedCert == NULL || InData == NULL ||
+ if (P7Data == NULL || TrustedCert == NULL || InData == NULL ||
P7Length > INT_MAX || CertLength > INT_MAX || DataLength > INT_MAX) {
return FALSE;
}
-
+
Pkcs7 = NULL;
DataBio = NULL;
Cert = NULL;
@@ -578,18 +578,23 @@ Pkcs7Verify (
if (EVP_add_digest (EVP_sha256 ()) == 0) {
return FALSE;
}
+ if (EVP_add_digest (EVP_sha384 ()) == 0) {
+ return FALSE;
+ }
+ if (EVP_add_digest (EVP_sha512 ()) == 0) {
+ return FALSE;
+ }
if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {
return FALSE;
}
-
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status) {
return Status;
}
Status = FALSE;
-
+
//
// Retrieve PKCS#7 Data (DER encoding)
//
@@ -674,4 +679,4 @@ _Exit:
}
return Status;
-}
+} \ No newline at end of file
diff --git a/Cryptlib/Pk/CryptX509.c b/Cryptlib/Pk/CryptX509.c
index 5abe970c..29efc42b 100644
--- a/Cryptlib/Pk/CryptX509.c
+++ b/Cryptlib/Pk/CryptX509.c
@@ -1,7 +1,7 @@
/** @file
X.509 Certificate Handler Wrapper Implementation over OpenSSL.
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -484,3 +484,79 @@ _Exit:
return Status;
}
+
+/**
+ Retrieve the TBSCertificate from one given X.509 certificate.
+
+ @param[in] Cert Pointer to the given DER-encoded X509 certificate.
+ @param[in] CertSize Size of the X509 certificate in bytes.
+ @param[out] TBSCert DER-Encoded To-Be-Signed certificate.
+ @param[out] TBSCertSize Size of the TBS certificate in bytes.
+
+ If Cert is NULL, then return FALSE.
+ If TBSCert is NULL, then return FALSE.
+ If TBSCertSize is NULL, then return FALSE.
+
+ @retval TRUE The TBSCertificate was retrieved successfully.
+ @retval FALSE Invalid X.509 certificate.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetTBSCert (
+ IN CONST UINT8 *Cert,
+ IN UINTN CertSize,
+ OUT UINT8 **TBSCert,
+ OUT UINTN *TBSCertSize
+ )
+{
+ CONST UINT8 *Temp;
+ INTN Asn1Tag;
+ INTN ObjClass;
+ UINTN Length;
+
+ //
+ // Check input parameters.
+ //
+ if ((Cert == NULL) || (TBSCert == NULL) || (TBSCertSize == NULL)) {
+ return FALSE;
+ }
+
+ //
+ // An X.509 Certificate is: (defined in RFC3280)
+ // Certificate ::= SEQUENCE {
+ // tbsCertificate TBSCertificate,
+ // signatureAlgorithm AlgorithmIdentifier,
+ // signature BIT STRING }
+ //
+ // and
+ //
+ // TBSCertificate ::= SEQUENCE {
+ // version [0] Version DEFAULT v1,
+ // ...
+ // }
+ //
+ // So we can just ASN1-parse the x.509 DER-encoded data. If we strip
+ // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.
+ //
+ Temp = Cert;
+ ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);
+
+ if (Asn1Tag != V_ASN1_SEQUENCE) {
+ return FALSE;
+ }
+
+ *TBSCert = (UINT8 *)Temp;
+
+ ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
+ //
+ // Verify the parsed TBSCertificate is one correct SEQUENCE data.
+ //
+ if (Asn1Tag != V_ASN1_SEQUENCE) {
+ return FALSE;
+ }
+
+ *TBSCertSize = Length + (Temp - *TBSCert);
+
+ return TRUE;
+}