Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Alexander_Naumov:SLE12
shim
shim-bnc872503-check-key-encoding.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File shim-bnc872503-check-key-encoding.patch of Package shim
From a7246827074c6c17fa15c696ad48ff1ff1a2b4d2 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin <glin@suse.com> Date: Tue, 27 May 2014 17:42:00 +0800 Subject: [PATCH] Check the first 4 bytes of the certificate A non-DER encoding x509 certificate may be mistakenly enrolled into db or MokList. This commit checks the first 4 bytes of the certificate to ensure that it's DER encoding. This commit also removes the iteration of the x509 signature list. Per UEFI SPEC, each x509 signature list contains only one x509 certificate. Besides, the size of certificate is incorrect. The size of the header must be substracted from the signature size. Signed-off-by: Gary Ching-Pang Lin <glin@suse.com> --- MokManager.c | 23 +++++++++++++++++++++-- shim.c | 45 +++++++++++++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 16 deletions(-) Index: shim-0.7/MokManager.c =================================================================== --- shim-0.7.orig/MokManager.c +++ shim-0.7/MokManager.c @@ -1701,12 +1701,31 @@ static INTN mok_pw_prompt (void *MokPW, return -1; } -static BOOLEAN verify_certificate(void *cert, UINTN size) +static BOOLEAN verify_certificate(UINT8 *cert, UINTN size) { X509 *X509Cert; - if (!cert || size == 0) + UINTN length; + if (!cert || size < 0) return FALSE; + /* + * A DER encoding x509 certificate starts with SEQUENCE(0x30), + * the number of length bytes, and the number of value bytes. + * The size of a x509 certificate is usually between 127 bytes + * and 64KB. For convenience, assume the number of value bytes + * is 2, i.e. the second byte is 0x82. + */ + if (cert[0] != 0x30 || cert[1] != 0x82) { + console_notify(L"Not a DER encoding X509 certificate"); + return FALSE; + } + + length = (cert[2]<<8 | cert[3]); + if (length != (size - 4)) { + console_notify(L"Invalid X509 certificate: Inconsistent size"); + return FALSE; + } + if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) || X509Cert == NULL) { console_notify(L"Invalid X509 certificate"); Index: shim-0.7/shim.c =================================================================== --- shim-0.7.orig/shim.c +++ shim-0.7/shim.c @@ -222,44 +222,61 @@ static EFI_STATUS relocate_coff (PE_COFF return EFI_SUCCESS; } +static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize) +{ + UINTN length; + + if (!Cert || CertSize < 4) + return FALSE; + + /* + * A DER encoding x509 certificate starts with SEQUENCE(0x30), + * the number of length bytes, and the number of value bytes. + * The size of a x509 certificate is usually between 127 bytes + * and 64KB. For convenience, assume the number of value bytes + * is 2, i.e. the second byte is 0x82. + */ + if (Cert[0] != 0x30 || Cert[1] != 0x82) + return FALSE; + + length = Cert[2]<<8 | Cert[3]; + if (length != (CertSize - 4)) + return FALSE; + + return TRUE; +} + static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, UINTN dbsize, WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash) { EFI_SIGNATURE_DATA *Cert; - UINTN CertCount, Index; + UINTN CertSize; BOOLEAN IsFound = FALSE; EFI_GUID CertType = X509_GUID; while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { if (CompareGuid (&CertList->SignatureType, &CertType) == 0) { - CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); - for (Index = 0; Index < CertCount; Index++) { + CertSize = CertList->SignatureSize - sizeof(EFI_GUID); + if (verify_x509(Cert->SignatureData, CertSize)) { IsFound = AuthenticodeVerify (data->CertData, data->Hdr.dwLength - sizeof(data->Hdr), Cert->SignatureData, - CertList->SignatureSize, + CertSize, hash, SHA256_DIGEST_SIZE); if (IsFound) - break; - - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize); + return DATA_FOUND; + } else if (verbose) { + console_notify(L"Not a DER encoding x.509 Certificate"); } - } - if (IsFound) - break; - dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); } - if (IsFound) - return DATA_FOUND; - return DATA_NOT_FOUND; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor