From d19b9930241207dd2ff8d197f58aab2ab89bcfff Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 3 Aug 2012 10:36:38 +0800 Subject: [PATCH] fileio: Unify key & cert loading Rather than duplicating the key & certificate loading in each tool, unify it in a fileio object. Signed-off-by: Jeremy Kerr --- Makefile.am | 4 +-- fileio.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fileio.h | 42 ++++++++++++++++++++++++++++ sbsign.c | 16 ++++------- sbvarsign.c | 56 ++++--------------------------------- sbverify.c | 28 +++---------------- 6 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 fileio.c create mode 100644 fileio.h diff --git a/Makefile.am b/Makefile.am index 699f7f0..86baa7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ bin_PROGRAMS = sbsign sbverify sbattach sbvarsign coff_headers = coff/external.h coff/pe.h coff/i386.h coff/x86_64.h -common_SOURCES = idc.c idc.h image.c image.h $(coff_headers) +common_SOURCES = idc.c idc.h image.c image.h fileio.c fileio.h $(coff_headers) common_LDADD = lib/ccan/libccan.a $(libcrypto_LIBS) common_CFLAGS = -I$(srcdir)/lib/ccan/ @@ -21,7 +21,7 @@ sbattach_SOURCES = sbattach.c $(common_SOURCES) sbattach_LDADD = $(common_LDADD) sbattach_CFLAGS = $(AM_CFLAGS) $(common_CFLAGS) -sbvarsign_SOURCES = sbvarsign.c +sbvarsign_SOURCES = sbvarsign.c $(common_SOURCES) sbvarsign_LDADD = $(common_LDADD) $(uuid_LIBS) sbvarsign_CPPFLAGS = $(EFI_CPPFLAGS) sbvarsign_CFLAGS = $(AM_CFLAGS) $(uuid_CFLAGS) $(common_CFLAGS) diff --git a/fileio.c b/fileio.c new file mode 100644 index 0000000..5d2a3f3 --- /dev/null +++ b/fileio.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012 Jeremy Kerr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the OpenSSL + * library under certain conditions as described in each individual source file, + * and distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + */ + +#include + +#include +#include +#include + +#include "fileio.h" + +EVP_PKEY *fileio_read_pkey(const char *filename) +{ + EVP_PKEY *key = NULL; + BIO *bio; + + bio = BIO_new_file(filename, "r"); + if (!bio) + goto out; + + key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + +out: + BIO_free_all(bio); + if (!key) { + fprintf(stderr, "Can't load key from file '%s'\n", filename); + ERR_print_errors_fp(stderr); + } + return key; +} + +X509 *fileio_read_cert(const char *filename) +{ + X509 *cert = NULL; + BIO *bio; + + bio = BIO_new_file(filename, "r"); + if (!bio) + goto out; + + cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + +out: + BIO_free_all(bio); + if (!cert) { + fprintf(stderr, "Can't load certificate from file '%s'\n", + filename); + ERR_print_errors_fp(stderr); + } + return cert; +} diff --git a/fileio.h b/fileio.h new file mode 100644 index 0000000..9f3a521 --- /dev/null +++ b/fileio.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Jeremy Kerr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the OpenSSL + * library under certain conditions as described in each individual source file, + * and distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + */ +#ifndef FILEIO_H +#define FILEIO_H + +#include +#include + +EVP_PKEY *fileio_read_pkey(const char *filename); +X509 *fileio_read_cert(const char *filename); + +#endif /* FILEIO_H */ + diff --git a/sbsign.c b/sbsign.c index 35bac8d..b97ce5e 100644 --- a/sbsign.c +++ b/sbsign.c @@ -53,6 +53,7 @@ #include "idc.h" #include "image.h" +#include "fileio.h" static const char *toolname = "sbsign"; @@ -185,20 +186,13 @@ int main(int argc, char **argv) OpenSSL_add_all_digests(); OpenSSL_add_all_ciphers(); - BIO *privkey_bio = BIO_new_file(keyfilename, "r"); - EVP_PKEY *pkey = PEM_read_bio_PrivateKey(privkey_bio, NULL, NULL, NULL); - if (!pkey) { - fprintf(stderr, "error reading private key %s\n", keyfilename); + EVP_PKEY *pkey = fileio_read_pkey(keyfilename); + if (!pkey) return EXIT_FAILURE; - } - BIO *cert_bio = BIO_new_file(certfilename, "r"); - X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL); - - if (!cert) { - fprintf(stderr, "error reading certificate %s\n", certfilename); + X509 *cert = fileio_read_cert(certfilename); + if (!cert) return EXIT_FAILURE; - } const EVP_MD *md = EVP_get_digestbyname("SHA256"); diff --git a/sbvarsign.c b/sbvarsign.c index ab4dabf..8e2f520 100644 --- a/sbvarsign.c +++ b/sbvarsign.c @@ -55,6 +55,7 @@ #include #include "efi-varauth.h" +#include "fileio.h" static const char *toolname = "sbvarsign"; @@ -262,55 +263,6 @@ static int set_timestamp(EFI_TIME *timestamp) return 0; } -static int load_key(struct varsign_context *ctx, const char *filename) -{ - BIO *bio; - - bio = BIO_new_file(filename, "r"); - if (!bio) - goto err; - - ctx->key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); - if (!ctx->key) - goto err; - - BIO_free_all(bio); - - return 0; - -err: - if (bio) - BIO_free_all(bio); - fprintf(stderr, "Can't load key from file '%s'\n", filename); - ERR_print_errors_fp(stderr); - return -1; -} - -static int load_cert(struct varsign_context *ctx, const char *filename) -{ - BIO *bio; - - bio = BIO_new_file(filename, "r"); - if (!bio) - goto err; - - ctx->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); - if (!ctx->cert) - goto err; - - BIO_free_all(bio); - - return 0; - -err: - if (bio) - BIO_free_all(bio); - fprintf(stderr, "Can't load certificate from file '%s'\n", filename); - ERR_print_errors_fp(stderr); - return -1; - -} - static int add_auth_descriptor(struct varsign_context *ctx) { EFI_VARIABLE_AUTHENTICATION_2 *auth; @@ -605,10 +557,12 @@ int main(int argc, char **argv) if (read_var_data(ctx)) return EXIT_FAILURE; - if (load_key(ctx, keyfilename)) + ctx->key = fileio_read_pkey(keyfilename); + if (!ctx->key) return EXIT_FAILURE; - if (load_cert(ctx, certfilename)) + ctx->cert = fileio_read_cert(certfilename); + if (!ctx->cert) return EXIT_FAILURE; /* do the signing */ diff --git a/sbverify.c b/sbverify.c index bd0b306..70bf07b 100644 --- a/sbverify.c +++ b/sbverify.c @@ -46,6 +46,7 @@ #include "image.h" #include "idc.h" +#include "fileio.h" #include #include @@ -90,34 +91,13 @@ static void version(void) int load_cert(X509_STORE *certs, const char *filename) { X509 *cert; - BIO *bio; - bio = NULL; - cert = NULL; - - bio = BIO_new_file(filename, "r"); - if (!bio) { - fprintf(stderr, "Couldn't open file %s\n", filename); - goto err; - } - - cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); - if (!cert) { - fprintf(stderr, "Couldn't read certificate file %s\n", - filename); - goto err; - } + cert = fileio_read_cert(filename); + if (!cert) + return -1; X509_STORE_add_cert(certs, cert); return 0; - -err: - ERR_print_errors_fp(stderr); - if (cert) - X509_free(cert); - if (bio) - BIO_free(bio); - return -1; } static int load_image_signature_data(struct image *image,