-
Notifications
You must be signed in to change notification settings - Fork 11
/
cert-to-efi-sig-list.c
118 lines (95 loc) · 2.8 KB
/
cert-to-efi-sig-list.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Copyright 2012 <[email protected]>
*
* see COPYING file
*/
#include <stdint.h>
#define __STDC_VERSION__ 199901L
#include <efi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <guid.h>
#include <variables.h>
#include <version.h>
static void
usage(const char *progname)
{
printf("Usage: %s [-g <guid>] <crt file> <efi sig list file>\n", progname);
}
static void
help(const char * progname)
{
usage(progname);
printf("Take an input X509 certificate (in PEM format) and convert it to an EFI\n"
"signature list file containing only that single certificate\n\n"
"Options:\n"
"\t-g <guid> Use <guid> as the owner of the signature. If this is not\n"
"\t supplied, an all zero guid will be used\n"
);
}
int
main(int argc, char *argv[])
{
char *certfile, *efifile;
const char *progname = argv[0];
EFI_GUID owner = { 0 };
while (argc > 1) {
if (strcmp("--version", argv[1]) == 0) {
version(progname);
exit(0);
} else if (strcmp("--help", argv[1]) == 0) {
help(progname);
exit(0);
} else if (strcmp("-g", argv[1]) == 0) {
str_to_guid(argv[2], &owner);
argv += 2;
argc -= 2;
} else {
break;
}
}
if (argc != 3) {
exit(1);
}
certfile = argv[1];
efifile = argv[2];
ERR_load_crypto_strings();
OpenSSL_add_all_digests();
OpenSSL_add_all_ciphers();
/* here we may get highly unlikely failures or we'll get a
* complaint about FIPS signatures (usually becuase the FIPS
* module isn't present). In either case ignore the errors
* (malloc will cause other failures out lower down */
ERR_clear_error();
BIO *cert_bio = BIO_new_file(certfile, "r");
X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL);
int PkCertLen = i2d_X509(cert, NULL);
PkCertLen += sizeof(EFI_SIGNATURE_LIST) + OFFSET_OF(EFI_SIGNATURE_DATA, SignatureData);
EFI_SIGNATURE_LIST *PkCert = malloc (PkCertLen);
if (!PkCert) {
fprintf(stderr, "failed to malloc cert\n");
exit(1);
}
unsigned char *tmp = (unsigned char *)PkCert + sizeof(EFI_SIGNATURE_LIST) + OFFSET_OF(EFI_SIGNATURE_DATA, SignatureData);
i2d_X509(cert, &tmp);
PkCert->SignatureListSize = PkCertLen;
PkCert->SignatureSize = (UINT32) (PkCertLen - sizeof(EFI_SIGNATURE_LIST));
PkCert->SignatureHeaderSize = 0;
PkCert->SignatureType = EFI_CERT_X509_GUID;
EFI_SIGNATURE_DATA *PkCertData = (void *)PkCert + sizeof(EFI_SIGNATURE_LIST);
PkCertData->SignatureOwner = owner;
FILE *f = fopen(efifile, "w");
if (!f) {
fprintf(stderr, "failed to open efi file %s: ", efifile);
perror("");
exit(1);
}
if (fwrite(PkCert, 1, PkCertLen, f) != PkCertLen) {
perror("Did not write enough bytes to efi file");
exit(1);
}
return 0;
}