]> git.ozlabs.org Git - petitboot/blobdiff - lib/security/gpg.c
discover/grub2: Allow to separate the --id argument using a space char
[petitboot] / lib / security / gpg.c
index 41d1306812fa8c6c86aeb4ba97e06e29a93f3b12..e319a069036b607c1ef13eb2bb5329a7b42ca56f 100644 (file)
@@ -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
  * 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)
 {
@@ -85,22 +73,22 @@ int decrypt_file(const char *filename,
        gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
        err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: OpenPGP support not available\n", __func__);
+               pb_log_fn("OpenPGP support not available\n");
                return -1;
        }
        err = gpgme_get_engine_info(&enginfo);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG engine failed to initialize\n", __func__);
+               pb_log_fn("GPG engine failed to initialize\n");
                return -1;
        }
        err = gpgme_new(&gpg_context);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG context could not be created\n", __func__);
+               pb_log_fn("GPG context could not be created\n");
                return -1;
        }
        err = gpgme_set_protocol(gpg_context, GPGME_PROTOCOL_OpenPGP);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG protocol could not be set\n", __func__);
+               pb_log_fn("GPG protocol could not be set\n");
                return -1;
        }
        if (keyring_path)
@@ -112,7 +100,7 @@ int decrypt_file(const char *filename,
                        GPGME_PROTOCOL_OpenPGP,
                        enginfo->file_name, enginfo->home_dir);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: Could not set GPG engine information\n", __func__);
+               pb_log_fn("Could not set GPG engine information\n");
                return -1;
        }
        err = gpgme_data_new(&plaintext_data);
@@ -132,7 +120,7 @@ int decrypt_file(const char *filename,
        err = gpgme_op_decrypt_verify(gpg_context, ciphertext_data,
                plaintext_data);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: Could not decrypt file\n", __func__);
+               pb_log_fn("Could not decrypt file\n");
                return -1;
        }
        verification_result = gpgme_op_verify_result(gpg_context);
@@ -222,7 +210,7 @@ int decrypt_file(const char *filename,
        gpgme_release(gpg_context);
 
        if (!valid) {
-               pb_log("%s: Incorrect GPG signature\n", __func__);
+               pb_log_fn("Incorrect GPG signature\n");
                return -1;
        }
 
@@ -254,22 +242,22 @@ int verify_file_signature(const char *plaintext_filename,
        gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
        err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: OpenPGP support not available\n", __func__);
+               pb_log_fn("OpenPGP support not available\n");
                return -1;
        }
        err = gpgme_get_engine_info(&enginfo);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG engine failed to initialize\n", __func__);
+               pb_log_fn("GPG engine failed to initialize\n");
                return -1;
        }
        err = gpgme_new(&gpg_context);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG context could not be created\n", __func__);
+               pb_log_fn("GPG context could not be created\n");
                return -1;
        }
        err = gpgme_set_protocol(gpg_context, GPGME_PROTOCOL_OpenPGP);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: GPG protocol could not be set\n", __func__);
+               pb_log_fn("GPG protocol could not be set\n");
                return -1;
        }
        if (keyring_path)
@@ -281,7 +269,7 @@ int verify_file_signature(const char *plaintext_filename,
                        GPGME_PROTOCOL_OpenPGP, enginfo->file_name,
                        enginfo->home_dir);
        if (err != GPG_ERR_NO_ERROR) {
-               pb_log("%s: Could not set GPG engine information\n", __func__);
+               pb_log_fn("Could not set GPG engine information\n");
                return -1;
        }
        err = gpgme_data_new_from_file(&plaintext_data, plaintext_filename, 1);
@@ -352,7 +340,7 @@ int verify_file_signature(const char *plaintext_filename,
        gpgme_release(gpg_context);
 
        if (!valid) {
-               pb_log("%s: Incorrect GPG signature\n", __func__);
+               pb_log_fn("Incorrect GPG signature\n");
                return -1;
        }
 
@@ -362,185 +350,14 @@ 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"))
-               if (verify_file_signature(cmdline_template,
-                       local_cmdline_signature,
-                       authorized_signatures_handle,
-                       "/etc/gpg"))
-
-               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;
 
+#if !defined(HARD_LOCKDOWN)
        if (access(LOCKDOWN_FILE, F_OK) == -1)
                return PB_LOCKDOWN_NONE;
+#endif
 
        /* determine lockdown type */
        FILE *authorized_signatures_handle = NULL;
@@ -557,8 +374,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
@@ -569,5 +386,6 @@ int lockdown_status() {
        }
        free(auth_sig_line);
 
-       return ret;
-}
\ No newline at end of file
+    return ret;
+}
+