diff options
| author | Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com> | 2016-08-17 17:05:53 -0400 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2016-09-21 13:32:53 -0400 |
| commit | 6c180c6004ac464d7e83c1dc4c24047fad281b32 (patch) | |
| tree | 56132d617fff7c4f05e67024ec872d88fcafa92d | |
| parent | 8af6e22814dc5a4de5fd93b65071a141112aaa49 (diff) | |
| download | efi-boot-shim-6c180c6004ac464d7e83c1dc4c24047fad281b32.tar.gz efi-boot-shim-6c180c6004ac464d7e83c1dc4c24047fad281b32.zip | |
shim: verify Extended Key Usage flags
For starters; don't allow the "module signing" OID; which ought to
only ever be used for signing kernel modules, not signing EFI binaries.
Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
| -rw-r--r-- | shim.c | 54 |
1 files changed, 47 insertions, 7 deletions
@@ -52,9 +52,15 @@ #include "console.h" #include "version.h" +#include <stdarg.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + #define FALLBACK L"\\fb" EFI_ARCH L".efi" #define MOK_MANAGER L"\\mm" EFI_ARCH L".efi" +#define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2" + static EFI_SYSTEM_TABLE *systab; static EFI_HANDLE image_handle; static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table); @@ -389,6 +395,38 @@ static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize) return TRUE; } +static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize) +{ + X509 *x509; + CONST UINT8 *Temp = Cert; + EXTENDED_KEY_USAGE *eku; + ASN1_OBJECT *module_signing; + + module_signing = OBJ_nid2obj(OBJ_create(OID_EKU_MODSIGN, NULL, NULL)); + + x509 = d2i_X509 (NULL, &Temp, (long) CertSize); + if (x509 != NULL) { + eku = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL); + + if (eku) { + int i = 0; + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + ASN1_OBJECT *key_usage = sk_ASN1_OBJECT_value(eku, i); + + if (OBJ_cmp(module_signing, key_usage) == 0) + return FALSE; + } + EXTENDED_KEY_USAGE_free(eku); + } + + X509_free(x509); + } + + OBJ_cleanup(); + + return TRUE; +} + static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, UINTN dbsize, WIN_CERTIFICATE_EFI_PKCS *data, @@ -404,13 +442,15 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); CertSize = CertList->SignatureSize - sizeof(EFI_GUID); if (verify_x509(Cert->SignatureData, CertSize)) { - IsFound = AuthenticodeVerify (data->CertData, - data->Hdr.dwLength - sizeof(data->Hdr), - Cert->SignatureData, - CertSize, - hash, SHA256_DIGEST_SIZE); - if (IsFound) - return DATA_FOUND; + if (verify_eku(Cert->SignatureData, CertSize)) { + IsFound = AuthenticodeVerify (data->CertData, + data->Hdr.dwLength - sizeof(data->Hdr), + Cert->SignatureData, + CertSize, + hash, SHA256_DIGEST_SIZE); + if (IsFound) + return DATA_FOUND; + } } else if (verbose) { console_notify(L"Not a DER encoding x.509 Certificate"); } |
