/* * Copyright 2012 * * see COPYING file * * Read and dump all the secure variables */ #include #include #include #include #include #include #include #include #include "efiauthenticated.h" void parse_db(UINT8 *data, UINTN len, EFI_HANDLE image, CHAR16 *name, int save_file) { EFI_SIGNATURE_LIST *CertList = (EFI_SIGNATURE_LIST *)data; EFI_SIGNATURE_DATA *Cert; UINTN count = 0, DataSize = len; EFI_FILE *file; CHAR16 *buf = AllocatePool(StrSize(name) + 4 + 2 + 4 + 8 +100); CHAR16 *ext; EFI_STATUS status; int size; certlist_for_each_certentry(CertList, data, size, DataSize) { int Index = 0; count++; if (CompareGuid(&CertList->SignatureType, &X509_GUID) == 0) { ext = L"X509"; } else if (CompareGuid(&CertList->SignatureType, &RSA2048_GUID) == 0) { ext = L"RSA2048"; } else if (CompareGuid(&CertList->SignatureType, &PKCS7_GUID) == 0) { ext = L"PKCS7"; } else if (CompareGuid(&CertList->SignatureType, &EFI_CERT_SHA256_GUID) == 0) { ext = L"SHA256"; } else { ext = L"Unknown"; } Print(L"%s: List %d, type %s\n", name, count, ext); certentry_for_each_cert(Cert, CertList) { Print(L" Signature %d, size %d, owner %g\n", Index++, CertList->SignatureSize, &Cert->SignatureOwner); if (StrCmp(ext, L"X509") == 0) { CHAR16 buf1[4096]; x509_to_str(Cert->SignatureData, CertList->SignatureSize, X509_OBJ_SUBJECT, buf1, sizeof(buf1)); Print(L" Subject: %s\n", buf1); x509_to_str(Cert->SignatureData, CertList->SignatureSize, X509_OBJ_ISSUER, buf1, sizeof(buf1)); Print(L" Issuer: %s\n", buf1); } else if (StrCmp(ext, L"SHA256") == 0) { CHAR16 buf1[256]; StrCpy(buf1, L"Hash: "); sha256_StrCat_hash(buf1, Cert->SignatureData); Print(L" %s\n", buf1); } if (save_file) { SPrint(buf, 0, L"%s-%d-%d-%s-%g", name, count, Index, ext, &Cert->SignatureOwner); Print(L"Writing to file %s\n", buf); status = simple_file_open(image, buf, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); if (status != EFI_SUCCESS) { Print(L"Failed to open file %s: %d\n", buf, status); continue; } status = simple_file_write_all(file, CertList->SignatureSize-sizeof(EFI_GUID), Cert->SignatureData); simple_file_close(file); if (status != EFI_SUCCESS) { Print(L"Failed to write signature to file %s: %d\n", buf, status); continue; } } } } FreePool(buf); } EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_STATUS status; CHAR16 **variables; EFI_GUID *owners; CHAR16 **ARGV, *progname; UINT8 *data; UINTN len; int i, argc, save_keys = 0, no_print = 0; InitializeLib(image, systab); if (GetOSIndications() & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION) { variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", L"dbt", L"MokList" , NULL}; owners = (EFI_GUID []){ GV_GUID, GV_GUID, SIG_DB, SIG_DB, SIG_DB, MOK_OWNER }; } else { variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", L"MokList" , NULL}; owners = (EFI_GUID []){ GV_GUID, GV_GUID, SIG_DB, SIG_DB, MOK_OWNER }; } status = argsplit(image, &argc, &ARGV); if (status != EFI_SUCCESS) { Print(L"Failed to parse arguments: %d\n", status); return status; } progname = ARGV[0]; while (argc > 1 && ARGV[1][0] == L'-') { if (StrCmp(ARGV[1], L"-s") == 0) { save_keys = 1; ARGV += 1; argc -= 1; } else if (StrCmp(ARGV[1], L"-n") == 0) { no_print = 1; ARGV += 1; argc -= 1; } else { /* unrecognised option */ break; } } if ((argc != 2 && argc != 1) || (argc != 1 && no_print)) { Print(L"Usage: %s: [-s|-n] [var]\n", progname); return EFI_INVALID_PARAMETER; } if (argc == 1) { for (i = 0; variables[i] != NULL; i++) { status = get_variable(variables[i], &data, &len, owners[i]); if (status == EFI_NOT_FOUND) { Print(L"Variable %s has no entries\n", variables[i]); } else if (status != EFI_SUCCESS) { Print(L"Failed to get %s: %d\n", variables[i], status); } else { Print(L"Variable %s length %d\n", variables[i], len); parse_db(data, len, image, variables[i], save_keys); FreePool(data); } } } else { CHAR16 *var = ARGV[1]; for(i = 0; variables[i] != NULL; i++) { if (StrCmp(var, variables[i]) == 0) { break; } } if (variables[i]== NULL) { Print(L"Invalid Variable %s\nVariable must be one of: ", var); for (i = 0; variables[i] != NULL; i++) Print(L"%s ", variables[i]); Print(L"\n"); return EFI_INVALID_PARAMETER; } status = get_variable(variables[i], &data, &len, owners[i]); if (status == EFI_NOT_FOUND) { Print(L"Variable %s has no entries\n", variables[i]); } else if (status != EFI_SUCCESS) { Print(L"Failed to get %s: %d\n", variables[i], status); } else { Print(L"Variable %s length %d\n", variables[i], len); parse_db(data, len, image, variables[i], save_keys); FreePool(data); parse_db(data, len, image, variables[i], save_keys); } } return EFI_SUCCESS; }