|
|
e97c83 |
From 5f18e2e3643524c6b6b38c44c6ce4eabdcfd59d1 Mon Sep 17 00:00:00 2001
|
|
|
e97c83 |
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
|
e97c83 |
Date: Tue, 27 May 2014 17:42:00 +0800
|
|
|
e97c83 |
Subject: [PATCH 30/74] Check the first 4 bytes of the certificate
|
|
|
e97c83 |
|
|
|
e97c83 |
A non-DER encoding x509 certificate may be mistakenly enrolled into
|
|
|
e97c83 |
db or MokList. This commit checks the first 4 bytes of the certificate
|
|
|
e97c83 |
to ensure that it's DER encoding.
|
|
|
e97c83 |
|
|
|
e97c83 |
This commit also removes the iteration of the x509 signature list.
|
|
|
e97c83 |
Per UEFI SPEC, each x509 signature list contains only one x509 certificate.
|
|
|
e97c83 |
Besides, the size of certificate is incorrect. The size of the header must
|
|
|
e97c83 |
be substracted from the signature size.
|
|
|
e97c83 |
|
|
|
e97c83 |
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
|
e97c83 |
---
|
|
|
e97c83 |
MokManager.c | 23 +++++++++++++++++++++--
|
|
|
e97c83 |
shim.c | 45 +++++++++++++++++++++++++++++++--------------
|
|
|
e97c83 |
2 files changed, 52 insertions(+), 16 deletions(-)
|
|
|
e97c83 |
|
|
|
e97c83 |
diff --git a/MokManager.c b/MokManager.c
|
|
|
e97c83 |
index 3da61f4..c9fbbac 100644
|
|
|
e97c83 |
--- a/MokManager.c
|
|
|
e97c83 |
+++ b/MokManager.c
|
|
|
e97c83 |
@@ -1306,11 +1306,30 @@ static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
|
|
e97c83 |
return -1;
|
|
|
e97c83 |
}
|
|
|
e97c83 |
|
|
|
e97c83 |
-static BOOLEAN verify_certificate(void *cert, UINTN size)
|
|
|
e97c83 |
+static BOOLEAN verify_certificate(UINT8 *cert, UINTN size)
|
|
|
e97c83 |
{
|
|
|
e97c83 |
X509 *X509Cert;
|
|
|
e97c83 |
- if (!cert || size == 0)
|
|
|
e97c83 |
+ UINTN length;
|
|
|
e97c83 |
+ if (!cert || size < 0)
|
|
|
e97c83 |
+ return FALSE;
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ /*
|
|
|
e97c83 |
+ * A DER encoding x509 certificate starts with SEQUENCE(0x30),
|
|
|
e97c83 |
+ * the number of length bytes, and the number of value bytes.
|
|
|
e97c83 |
+ * The size of a x509 certificate is usually between 127 bytes
|
|
|
e97c83 |
+ * and 64KB. For convenience, assume the number of value bytes
|
|
|
e97c83 |
+ * is 2, i.e. the second byte is 0x82.
|
|
|
e97c83 |
+ */
|
|
|
e97c83 |
+ if (cert[0] != 0x30 || cert[1] != 0x82) {
|
|
|
e97c83 |
+ console_notify(L"Not a DER encoding X509 certificate");
|
|
|
e97c83 |
return FALSE;
|
|
|
e97c83 |
+ }
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ length = (cert[2]<<8 | cert[3]);
|
|
|
e97c83 |
+ if (length != (size - 4)) {
|
|
|
e97c83 |
+ console_notify(L"Invalid X509 certificate: Inconsistent size");
|
|
|
e97c83 |
+ return FALSE;
|
|
|
e97c83 |
+ }
|
|
|
e97c83 |
|
|
|
e97c83 |
if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) ||
|
|
|
e97c83 |
X509Cert == NULL) {
|
|
|
e97c83 |
diff --git a/shim.c b/shim.c
|
|
|
e97c83 |
index d8699f9..cd26ce6 100644
|
|
|
e97c83 |
--- a/shim.c
|
|
|
e97c83 |
+++ b/shim.c
|
|
|
e97c83 |
@@ -226,44 +226,61 @@ static EFI_STATUS relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
|
|
e97c83 |
return EFI_SUCCESS;
|
|
|
e97c83 |
}
|
|
|
e97c83 |
|
|
|
e97c83 |
+static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
|
|
|
e97c83 |
+{
|
|
|
e97c83 |
+ UINTN length;
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ if (!Cert || CertSize < 4)
|
|
|
e97c83 |
+ return FALSE;
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ /*
|
|
|
e97c83 |
+ * A DER encoding x509 certificate starts with SEQUENCE(0x30),
|
|
|
e97c83 |
+ * the number of length bytes, and the number of value bytes.
|
|
|
e97c83 |
+ * The size of a x509 certificate is usually between 127 bytes
|
|
|
e97c83 |
+ * and 64KB. For convenience, assume the number of value bytes
|
|
|
e97c83 |
+ * is 2, i.e. the second byte is 0x82.
|
|
|
e97c83 |
+ */
|
|
|
e97c83 |
+ if (Cert[0] != 0x30 || Cert[1] != 0x82)
|
|
|
e97c83 |
+ return FALSE;
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ length = Cert[2]<<8 | Cert[3];
|
|
|
e97c83 |
+ if (length != (CertSize - 4))
|
|
|
e97c83 |
+ return FALSE;
|
|
|
e97c83 |
+
|
|
|
e97c83 |
+ return TRUE;
|
|
|
e97c83 |
+}
|
|
|
e97c83 |
+
|
|
|
e97c83 |
static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
|
|
|
e97c83 |
UINTN dbsize,
|
|
|
e97c83 |
WIN_CERTIFICATE_EFI_PKCS *data,
|
|
|
e97c83 |
UINT8 *hash)
|
|
|
e97c83 |
{
|
|
|
e97c83 |
EFI_SIGNATURE_DATA *Cert;
|
|
|
e97c83 |
- UINTN CertCount, Index;
|
|
|
e97c83 |
+ UINTN CertSize;
|
|
|
e97c83 |
BOOLEAN IsFound = FALSE;
|
|
|
e97c83 |
EFI_GUID CertType = X509_GUID;
|
|
|
e97c83 |
|
|
|
e97c83 |
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
|
|
|
e97c83 |
if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
|
|
|
e97c83 |
- CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
|
|
|
e97c83 |
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
|
|
e97c83 |
- for (Index = 0; Index < CertCount; Index++) {
|
|
|
e97c83 |
+ CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
|
|
|
e97c83 |
+ if (verify_x509(Cert->SignatureData, CertSize)) {
|
|
|
e97c83 |
IsFound = AuthenticodeVerify (data->CertData,
|
|
|
e97c83 |
data->Hdr.dwLength - sizeof(data->Hdr),
|
|
|
e97c83 |
Cert->SignatureData,
|
|
|
e97c83 |
- CertList->SignatureSize,
|
|
|
e97c83 |
+ CertSize,
|
|
|
e97c83 |
hash, SHA256_DIGEST_SIZE);
|
|
|
e97c83 |
if (IsFound)
|
|
|
e97c83 |
- break;
|
|
|
e97c83 |
-
|
|
|
e97c83 |
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
|
|
e97c83 |
+ return DATA_FOUND;
|
|
|
e97c83 |
+ } else if (verbose) {
|
|
|
e97c83 |
+ console_notify(L"Not a DER encoding x.509 Certificate");
|
|
|
e97c83 |
}
|
|
|
e97c83 |
-
|
|
|
e97c83 |
}
|
|
|
e97c83 |
|
|
|
e97c83 |
- if (IsFound)
|
|
|
e97c83 |
- break;
|
|
|
e97c83 |
-
|
|
|
e97c83 |
dbsize -= CertList->SignatureListSize;
|
|
|
e97c83 |
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
|
|
|
e97c83 |
}
|
|
|
e97c83 |
|
|
|
e97c83 |
- if (IsFound)
|
|
|
e97c83 |
- return DATA_FOUND;
|
|
|
e97c83 |
-
|
|
|
e97c83 |
return DATA_NOT_FOUND;
|
|
|
e97c83 |
}
|
|
|
e97c83 |
|
|
|
e97c83 |
--
|
|
|
e97c83 |
1.9.3
|
|
|
e97c83 |
|