aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2012-12-31 14:27:56 +0000
committerJames Bottomley <JBottomley@Parallels.com>2012-12-31 14:27:56 +0000
commit2b4b624a37f2ecbf552b9a314ef8201627b56dd1 (patch)
tree956f7874622a0837204934eb1745c34dce020f30
parent20519c87fcd8030abb73ddee6cf229a977b2087f (diff)
downloadefitools-2b4b624a37f2ecbf552b9a314ef8201627b56dd1.tar.gz
KeyTool: Implement adding certificates from DER format .cer files
-rw-r--r--KeyTool.c22
-rw-r--r--include/variables.h3
-rw-r--r--lib/variables.c73
3 files changed, 47 insertions, 51 deletions
diff --git a/KeyTool.c b/KeyTool.c
index 7a71a40..01f9bd9 100644
--- a/KeyTool.c
+++ b/KeyTool.c
@@ -129,9 +129,23 @@ select_and_apply(CHAR16 **title, CHAR16 *ext, int key, UINTN options)
return;
}
} else {
- /* do something about .cer case */
- console_errorbox(L"Handling .cer files is unimplemented");
- return;
+ if (keyinfo[key].authenticated)
+ use_setsecurevariable = 1;
+ else
+ use_setsecurevariable = 0;
+ void *newesl;
+ int newsize;
+
+ status = variable_create_esl(esl, size, &X509_GUID, NULL,
+ &newesl, &newsize);
+
+ if (status != EFI_SUCCESS) {
+ console_error(L"Failed to create proper ESL", status);
+ return;
+ }
+ FreePool(esl);
+ esl = newesl;
+ size = newsize;
}
if (use_setsecurevariable) {
status = SetSecureVariable(keyinfo[key].name, esl, size,
@@ -142,7 +156,7 @@ select_and_apply(CHAR16 **title, CHAR16 *ext, int key, UINTN options)
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| options,
- size, esl);
+ size, esl);
}
if (status != EFI_SUCCESS) {
console_error(L"Failed to update variable", status);
diff --git a/include/variables.h b/include/variables.h
index aa77f97..c171bd5 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -54,3 +54,6 @@ variable_is_setupmode(void);
EFI_STATUS
variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
UINT8 hash[SHA256_DIGEST_SIZE]);
+EFI_STATUS
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
+ void **out, int *outlen);
diff --git a/lib/variables.c b/lib/variables.c
index a75e8e9..c954320 100644
--- a/lib/variables.c
+++ b/lib/variables.c
@@ -31,57 +31,33 @@
#include <errors.h>
EFI_STATUS
-CreatePkX509SignatureList (
- IN UINT8 *X509Data,
- IN UINTN X509DataSize,
- IN EFI_GUID owner,
- OUT EFI_SIGNATURE_LIST **PkCert
- )
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
+ void **out, int *outlen)
{
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_SIGNATURE_DATA *PkCertData;
+ *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
- PkCertData = NULL;
+ *out = AllocateZeroPool(*outlen);
+ if (!*out)
+ return EFI_OUT_OF_RESOURCES;
- //
- // Allocate space for PK certificate list and initialize it.
- // Create PK database entry with SignatureHeaderSize equals 0.
- //
- *PkCert = (EFI_SIGNATURE_LIST*) AllocateZeroPool (
- sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1
- + X509DataSize
- );
- if (*PkCert == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
+ EFI_SIGNATURE_LIST *sl = *out;
- (*PkCert)->SignatureListSize = (UINT32) (sizeof(EFI_SIGNATURE_LIST)
- + sizeof(EFI_SIGNATURE_DATA) - 1
- + X509DataSize);
- (*PkCert)->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
- (*PkCert)->SignatureHeaderSize = 0;
- (*PkCert)->SignatureType = EFI_CERT_X509_GUID;
-
- PkCertData = (EFI_SIGNATURE_DATA*) ((UINTN)(*PkCert)
- + sizeof(EFI_SIGNATURE_LIST)
- + (*PkCert)->SignatureHeaderSize);
- PkCertData->SignatureOwner = owner;
- //
- // Fill the PK database with PKpub data from X509 certificate file.
- //
- CopyMem (&(PkCertData->SignatureData[0]), X509Data, X509DataSize);
-
-ON_EXIT:
-
- if (EFI_ERROR(Status) && *PkCert != NULL) {
- FreePool (*PkCert);
- *PkCert = NULL;
- }
-
- return Status;
+ sl->SignatureHeaderSize = 0;
+ sl->SignatureType = *type;
+ sl->SignatureSize = cert_len + sizeof(EFI_GUID);
+ sl->SignatureListSize = *outlen;
+
+ EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST);
+
+ if (owner)
+ sd->SignatureOwner = *owner;
+
+ CopyMem(sd->SignatureData, cert, cert_len);
+
+ return EFI_SUCCESS;
}
+
EFI_STATUS
CreateTimeBasedPayload (
IN OUT UINTN *DataSize,
@@ -167,12 +143,15 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
return EFI_SECURITY_VIOLATION;
if (createtimebased) {
- efi_status = CreatePkX509SignatureList(Data, len, owner, &Cert);
+ int ds;
+ efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
+ (void **)&Cert, &ds);
if (efi_status != EFI_SUCCESS) {
Print(L"Failed to create %s certificate %d\n", var, efi_status);
return efi_status;
}
- DataSize = Cert->SignatureListSize;
+
+ DataSize = ds;
} else {
/* we expect an efi signature list rather than creating it */
Cert = (EFI_SIGNATURE_LIST *)Data;