summaryrefslogtreecommitdiffstats
path: root/lib/security/gpg.c
diff options
context:
space:
mode:
authorBrett Grandbois <brett.grandbois@opengear.com>2018-05-15 10:55:49 +1000
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2018-05-30 14:23:39 +1000
commit8b214b9d1c51f49d977e93b66378ed4f73790c8b (patch)
tree94bdcbd19c82e7d45a970e7cf6c80a2b20627f8d /lib/security/gpg.c
parentb1234ac9dd09c9ceaf929c9d4d738fd556525291 (diff)
downloadtalos-petitboot-8b214b9d1c51f49d977e93b66378ed4f73790c8b.tar.gz
talos-petitboot-8b214b9d1c51f49d977e93b66378ed4f73790c8b.zip
lib/security: add in openssl support
Refactor to export a generic API rather than specific gpg_ prefixes by changing gpg.h to security.h and renaming some of the exports. Break out the common and specific functionality into common.c and none.c/gpg.c/openssl.c for no/gpgme/openssl modes respectively. gpgme should work as before OpenSSL support works like this: The pb-lockdown file is a PKCS12 file or X509 certificate or PEM-encoded raw public key. To follow the current conventions the presence of a PKCS12 file as a lockdown signals decrypt mode because of the presence of the private key, anything else signals signature verification mode. The keyring path is currently ignored but in the future could be used to point to an X509 certificate chain for validity checking. Because of this self-signed certificates are currently supported and really just used as a public key container. Signature verification mode supports: * Cryptographic Message Syntax (CMS) as detached S/MIME, this is really more for consistency for the encryption mode (see below). This mode requires the lockdown file to be an X509 certificate. A sample creation command would be: openssl cms -sign -in (infile) -out (outfile) -binary -nocerts \ -inkey (private key) -signer (recipient certificate) * Raw signature digest as output from openssl dgst -sign command. This mode can have the lockdown file be an X509 certificate or a PEM raw public key but the digest algorithm must be pre-defined by the VERIFY_DIGEST configure argument. The default is SHA256. A sample creation command would be: openssl dgst -sign (private key) -out (outfile) -(digest mode) \ (infile) Decryption mode supports: * CMS signed-envelope as attached S/MIME. This is for consistency with the current expectation of no external file for decryption. Some future enhancement could be to come up with some proprietary external file format containing the cipher used, the encrypted cipher key, and the IV (if necessary). A sample creation command would be: openssl cms -sign -in (infile) -signer (recipient certificate) \ -binary -nocerts -nodetach -inkey (private key) | \ openssl cms -encrypt -(cipher mode) -out (outfile) \ (recipient certificate) The PKCS12 file is expecting the private key to have password of NULL or "" as there is currently no mechanism to supply a custom one. Signed-off-by: Brett Grandbois <brett.grandbois@opengear.com> Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Diffstat (limited to 'lib/security/gpg.c')
-rw-r--r--lib/security/gpg.c202
1 files changed, 8 insertions, 194 deletions
diff --git a/lib/security/gpg.c b/lib/security/gpg.c
index 76e2c6c..761d6ce 100644
--- a/lib/security/gpg.c
+++ b/lib/security/gpg.c
@@ -25,6 +25,7 @@
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
+#include <locale.h>
#include <sys/types.h>
#include <log/log.h>
@@ -34,7 +35,9 @@
#include <util/util.h>
#include <i18n/i18n.h>
-#include "gpg.h"
+#include <gpgme.h>
+
+#include "security.h"
/*
* If --with-signed-boot is enabled lib/security provides the ability to handle
@@ -45,21 +48,6 @@
* to guarantee secure boot by itself.
*/
-struct pb_url * gpg_get_signature_url(void *ctx, struct pb_url *base_file)
-{
- struct pb_url *signature_file = NULL;
-
- signature_file = pb_url_copy(ctx, base_file);
- talloc_free(signature_file->file);
- signature_file->file = talloc_asprintf(signature_file,
- "%s.sig", base_file->file);
- talloc_free(signature_file->path);
- signature_file->path = talloc_asprintf(signature_file,
- "%s.sig", base_file->path);
-
- return signature_file;
-}
-
int decrypt_file(const char *filename,
FILE *authorized_signatures_handle, const char *keyring_path)
{
@@ -362,181 +350,6 @@ int verify_file_signature(const char *plaintext_filename,
return 0;
}
-int gpg_validate_boot_files(struct boot_task *boot_task) {
- int result = 0;
- char *kernel_filename = NULL;
- char *initrd_filename = NULL;
- char *dtb_filename = NULL;
-
- FILE *authorized_signatures_handle = NULL;
-
- char cmdline_template[] = "/tmp/petitbootXXXXXX";
- int cmdline_fd = mkstemp(cmdline_template);
- FILE *cmdline_handle = NULL;
-
- const char* local_initrd_signature = (boot_task->verify_signature) ?
- boot_task->local_initrd_signature : NULL;
- const char* local_dtb_signature = (boot_task->verify_signature) ?
- boot_task->local_dtb_signature : NULL;
- const char* local_image_signature = (boot_task->verify_signature) ?
- boot_task->local_image_signature : NULL;
- const char* local_cmdline_signature =
- (boot_task->verify_signature || boot_task->decrypt_files) ?
- boot_task->local_cmdline_signature : NULL;
-
- if ((!boot_task->verify_signature) && (!boot_task->decrypt_files))
- return result;
-
- /* Load authorized signatures file */
- authorized_signatures_handle = fopen(LOCKDOWN_FILE, "r");
- if (!authorized_signatures_handle) {
- pb_log("%s: unable to read lockdown file\n", __func__);
- return KEXEC_LOAD_SIG_SETUP_INVALID;
- }
-
- /* Copy files to temporary directory for verification / boot */
- result = copy_file_secure_dest(boot_task,
- boot_task->local_image,
- &kernel_filename);
- if (result) {
- pb_log("%s: image copy failed: (%d)\n",
- __func__, result);
- return result;
- }
- if (boot_task->local_initrd) {
- result = copy_file_secure_dest(boot_task,
- boot_task->local_initrd,
- &initrd_filename);
- if (result) {
- pb_log("%s: initrd copy failed: (%d)\n",
- __func__, result);
- return result;
- }
- }
- if (boot_task->local_dtb) {
- result = copy_file_secure_dest(boot_task,
- boot_task->local_dtb,
- &dtb_filename);
- if (result) {
- pb_log("%s: dtb copy failed: (%d)\n",
- __func__, result);
- return result;
- }
- }
- boot_task->local_image_override = talloc_strdup(boot_task,
- kernel_filename);
- if (boot_task->local_initrd)
- boot_task->local_initrd_override = talloc_strdup(boot_task,
- initrd_filename);
- if (boot_task->local_dtb)
- boot_task->local_dtb_override = talloc_strdup(boot_task,
- dtb_filename);
-
- /* Write command line to temporary file for verification */
- if (cmdline_fd < 0) {
- /* mkstemp failed */
- pb_log("%s: failed: unable to create command line"
- " temporary file for verification\n",
- __func__);
- result = -1;
- }
- else {
- cmdline_handle = fdopen(cmdline_fd, "w");
- }
- if (!cmdline_handle) {
- /* Failed to open file */
- pb_log("%s: failed: unable to write command line"
- " temporary file for verification\n",
- __func__);
- result = -1;
- }
- else {
- fwrite(boot_task->args, sizeof(char),
- strlen(boot_task->args), cmdline_handle);
- fflush(cmdline_handle);
- }
-
- if (boot_task->verify_signature) {
- /* Check signatures */
- if (verify_file_signature(kernel_filename,
- local_image_signature,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_SIGNATURE_FAILURE;
- if (verify_file_signature(cmdline_template,
- local_cmdline_signature,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_SIGNATURE_FAILURE;
-
- if (boot_task->local_initrd_signature)
- if (verify_file_signature(initrd_filename,
- local_initrd_signature,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_SIGNATURE_FAILURE;
- if (boot_task->local_dtb_signature)
- if (verify_file_signature(dtb_filename,
- local_dtb_signature,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_SIGNATURE_FAILURE;
-
- /* Clean up */
- if (cmdline_handle) {
- fclose(cmdline_handle);
- unlink(cmdline_template);
- }
- fclose(authorized_signatures_handle);
- } else if (boot_task->decrypt_files) {
- /* Decrypt files */
- if (decrypt_file(kernel_filename,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_DECRYPTION_FALURE;
- if (verify_file_signature(cmdline_template,
- local_cmdline_signature,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_SIGNATURE_FAILURE;
- if (boot_task->local_initrd)
- if (decrypt_file(initrd_filename,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_DECRYPTION_FALURE;
- if (boot_task->local_dtb)
- if (decrypt_file(dtb_filename,
- authorized_signatures_handle,
- "/etc/gpg"))
- result = KEXEC_LOAD_DECRYPTION_FALURE;
-
- /* Clean up */
- if (cmdline_handle) {
- fclose(cmdline_handle);
- unlink(cmdline_template);
- }
- fclose(authorized_signatures_handle);
- }
-
- return result;
-}
-
-void gpg_validate_boot_files_cleanup(struct boot_task *boot_task) {
- if ((boot_task->verify_signature) || (boot_task->decrypt_files)) {
- unlink(boot_task->local_image_override);
- if (boot_task->local_initrd_override)
- unlink(boot_task->local_initrd_override);
- if (boot_task->local_dtb_override)
- unlink(boot_task->local_dtb_override);
-
- talloc_free(boot_task->local_image_override);
- if (boot_task->local_initrd_override)
- talloc_free(boot_task->local_initrd_override);
- if (boot_task->local_dtb_override)
- talloc_free(boot_task->local_dtb_override);
- }
-}
-
int lockdown_status() {
/* assume most restrictive lockdown type */
int ret = PB_LOCKDOWN_SIGN;
@@ -559,8 +372,8 @@ int lockdown_status() {
authorized_signatures_handle)) != -1) {
auth_sig_len = strlen(auth_sig_line);
while ((auth_sig_line[auth_sig_len-1] == '\n')
- || (auth_sig_line[auth_sig_len-1] == '\r'))
- auth_sig_len--;
+ || (auth_sig_line[auth_sig_len-1] == '\r'))
+ auth_sig_len--;
auth_sig_line[auth_sig_len] = 0;
if (strcmp(auth_sig_line, "ENCRYPTED") == 0) {
/* first line indicates encrypted files
@@ -571,5 +384,6 @@ int lockdown_status() {
}
free(auth_sig_line);
- return ret;
+ return ret;
}
+
OpenPOWER on IntegriCloud