Esempio n. 1
0
int main()
{
	int fd;
	char* buffer_w="where are you";
	char* buffer_r;
	size_t length=13;
	size_t* len;
	fd=write_temp_file(buffer_w,length);	
	buffer_r=read_temp_file(fd,len);
	printf("buffer_w is %s\n",buffer_w);
	printf("buffer_r is %s\n",buffer_r);
}
Esempio n. 2
0
int main(int argc, char const* argv[])
{
    char buffer[]="this is a test";
    char *pRead = NULL;
    size_t rLength = 0;
    temp_file_handle fd;

    fd = write_temp_file(buffer, sizeof(buffer));

    pRead = read_temp_file(fd, &rLength);
    printf("%s\n", pRead);
    free(pRead);

    return 0;
}
static int assisted_module_signing(Options *op, Package *p)
{
    int generate_keys = FALSE, do_sign = FALSE, secureboot, i;

    secureboot = secure_boot_enabled();

    if (secureboot < 0) {
        ui_log(op, "Unable to determine if Secure Boot is enabled: %s",
               strerror(-secureboot));
    }

    if (op->kernel_module_signed) {
        /* The kernel module is already signed, e.g. from linking a precompiled
         * interface + appending a detached signature */
        return TRUE;
    }

    if (test_kernel_config_option(op, p, "CONFIG_DUMMY_OPTION") ==
        KERNEL_CONFIG_OPTION_UNKNOWN) {
        /* Unable to test kernel configuration options, possibly due to
         * missing kernel headers. Since we might be installing on a
         * system that doesn't have the headers, bail out. */
        return TRUE;
    }

    if (op->module_signing_secret_key && op->module_signing_public_key) {
        /* If the user supplied signing keys, sign the module, regardless of
         * whether or not we actually need to. */
        do_sign = TRUE;
    } else if (test_kernel_config_option(op, p, "CONFIG_MODULE_SIG_FORCE") ==
               KERNEL_CONFIG_OPTION_DEFINED) {
        /* If CONFIG_MODULE_SIG_FORCE is set, we must sign. */
        ui_message(op, "The target kernel has CONFIG_MODULE_SIG_FORCE set, "
                   "which means that it requires that kernel modules be "
                   "cryptographically signed by a trusted key.");
        do_sign = TRUE;
    } else if (secureboot != 1 && !op->expert) {
        /* If this is a non-UEFI system, or a UEFI system with secure boot
         * disabled, or we are unable to determine whether the system has
         * secure boot enabled, bail out unless in expert mode. */
        return TRUE;
    } else if (test_kernel_config_option(op, p, "CONFIG_MODULE_SIG") ==
               KERNEL_CONFIG_OPTION_DEFINED){
        /* The kernel may or may not enforce module signatures; ask the user
         * whether to sign the module. */

        const char *choices[2] = {
            "Sign the kernel module",
            "Install without signing"
        };

        const char* sb_message = (secureboot == 1) ?
                                     "This system also has UEFI Secure Boot "
                                     "enabled; many distributions enforce "
                                     "module signature verification on UEFI "
                                     "systems when Secure Boot is enabled. " :
                                     "";

        do_sign = (ui_multiple_choice(op, choices, 2, 1, "The target kernel "
                                      "has CONFIG_MODULE_SIG set, which means "
                                      "that it supports cryptographic "
                                      "signatures on kernel modules. On some "
                                      "systems, the kernel may refuse to load "
                                      "modules without a valid signature from "
                                      "a trusted key. %sWould you like to sign "
                                      "the NVIDIA kernel module?",
                                      sb_message) == 0);
    }

    if (!do_sign) {
        /* The user explicitly opted out of module signing, or the kernel does
         * not support module signatures, and no signing keys were provided;
         * there is nothing for us to do here. */
        return TRUE;
    }

    /* If we're missing either key, we need to get both from the user. */
    if (!op->module_signing_secret_key || !op->module_signing_public_key) {

        const char *choices[2] = {
            "Use an existing key pair",
            "Generate a new key pair"
        };

        generate_keys = (ui_multiple_choice(op, choices, 2, 1, "Would you like "
                                            "to sign the NVIDIA kernel module "
                                            "with an existing key pair, or "
                                            "would you like to generate a new "
                                            "one?") == 1);

        if (generate_keys) {
            char *cmdline, *x509_hash, *private_key_path, *public_key_path;
            int ret, generate_failed = FALSE;

            if (!op->utils[OPENSSL]) {
                ui_error(op, "Unable to generate key pair: openssl not "
                         "found!");
                return FALSE;
            }

            /* Determine what hashing algorithm to use for the generated X.509
             * certificate. XXX The default is to use the same hash that is
             * used for signing modules; the two hashes are actually orthognal
             * to each other, but by choosing the module signing hash we are
             * guaranteed that the chosen hash will be built into the kernel.
             */
            if (op->module_signing_x509_hash) {
                x509_hash = nvstrdup(op->module_signing_x509_hash);
            } else {
                char *guess, *guess_trimmed, *warn = NULL;

                char *no_guess = "Unable to guess the module signing hash.";
                char *common_warn = "The module signing certificate generated "
                                    "by nvidia-installer will be signed with "
                                    "sha256 as a fallback. If the resulting "
                                    "certificate fails to import into your "
                                    "kernel's trusted keyring, please run the "
                                    "installer again, and either use a pre-"
                                    "generated key pair, or set the "
                                    "--module-signing-x509-hash option if you "
                                    "plan to generate a new key pair with "
                                    "nvidia-installer.";

                guess = guess_module_signing_hash(op,
                                                  p->kernel_module_build_directory);

                if (guess == NULL) {
                    warn = no_guess;
                    goto guess_fail;
                }

                guess_trimmed = nv_trim_space(guess);
                guess_trimmed = nv_trim_char_strict(guess_trimmed, '"');

                if (guess_trimmed) {
                    if (strlen(guess_trimmed) == 0) {
                        warn = no_guess;
                        goto guess_fail;
                    }

                    x509_hash = nvstrdup(guess_trimmed);
                } else {
                    warn = "Error while parsing the detected module signing "
                           "hash.";
                    goto guess_fail;
                }

guess_fail:
                nvfree(guess);

                if (warn) {
                    ui_warn(op, "%s %s", warn, common_warn);
                    x509_hash = nvstrdup("sha256");
                }
            }

            log_printf(op, NULL, "Generating key pair for module signing...");

            /* Generate temporary files for the signing key and certificate */

            private_key_path = write_temp_file(op, 0, NULL, 0600);
            public_key_path = write_temp_file(op, 0, NULL, 0644);

            if (!private_key_path || !public_key_path) {
                ui_error(op, "Failed to create one or more temporary files for "
                         "the module signing keys.");
                generate_failed = TRUE;
                goto generate_done;
            }

            /* Generate a key pair using openssl.
             * XXX We assume that sign-file requires the X.509 certificate
             * in DER format; if this changes in the future we will need
             * to be able to accommodate the actual required format. */

            cmdline = nvstrcat("cd ", p->kernel_module_build_directory, "; ",
                               op->utils[OPENSSL], " req -new -x509 -newkey "
                               "rsa:2048 -days 7300 -nodes -subj "
                               "\"/CN=nvidia-installer generated signing key/\""
                               " -keyout ", private_key_path,
                               " -outform DER -out ", public_key_path,
                               " -", x509_hash, NULL);
            nvfree(x509_hash);

            ret = run_command(op, cmdline, NULL, TRUE, 8, TRUE);

            nvfree(cmdline);

            if (ret != 0) {
                ui_error(op, "Failed to generate key pair!");
                generate_failed = TRUE;
                goto generate_done;
            }

            log_printf(op, NULL, "Signing keys generated successfully.");

            /* Set the signing keys to the newly generated pair. */

            op->module_signing_secret_key = nvstrdup(private_key_path);
            op->module_signing_public_key = nvstrdup(public_key_path);

generate_done:
            nvfree(private_key_path);
            nvfree(public_key_path);

            if (generate_failed) {
                return FALSE;
            }
        } else {
            /* The user already has keys; prompt for their locations. */
            op->module_signing_secret_key =
                get_filename(op, op->module_signing_secret_key,
                             "Please provide the path to the private key");
            op->module_signing_public_key =
                get_filename(op, op->module_signing_public_key,
                             "Please provide the path to the public key");
        }
    }

    /* Now that we have keys (user-supplied or installer-generated),
     * sign the kernel module/s which we built earlier. */

    for (i = 0; i < p->num_kernel_modules; i++) {
        if (!sign_kernel_module(op, p->kernel_module_build_directory,
                                p->kernel_modules[i].module_filename, TRUE)) {
            return FALSE;
        }
    }

    if (generate_keys) {

        /* If keys were generated, we should install the verification cert
         * so that the user can make the kernel trust it, and either delete
         * or install the private signing key. */
        char *name, *result = NULL, *fingerprint, *cmdline;
        char short_fingerprint[9];
        int ret, delete_secret_key;

        delete_secret_key = ui_yes_no(op, TRUE, "The NVIDIA kernel module was "
                                      "successfully signed with a newly "
                                      "generated key pair. Would you like to "
                                      "delete the private signing key?");

        /* Get the fingerprint of the X.509 certificate. We already used 
           openssl to create a keypair at this point, so we know we have it;
           otherwise, we would have already returned by now. */
        cmdline = nvstrcat(op->utils[OPENSSL], " x509 -noout -fingerprint ",
                           "-inform DER -in ", op->module_signing_public_key,
                           NULL);
        ret = run_command(op, cmdline, &result, FALSE, 0, FALSE);
        nvfree(cmdline);

        /* Format: "SHA1 Fingerprint=00:00:00:00:..." */
        fingerprint = strchr(result, '=') + 1;

        if (ret != 0 || !fingerprint || strlen(fingerprint) < 40) {
            char *sha1sum = find_system_util("sha1sum");

            if (sha1sum) {
                /* the openssl command failed, or we parsed its output
                 * incorrectly; try to get a sha1sum of the DER certificate */
                cmdline = nvstrcat(sha1sum, " ", op->module_signing_public_key,
                                   NULL);
                ret = run_command(op, cmdline, &result, FALSE, 0, FALSE);
                nvfree(sha1sum);
                nvfree(cmdline);

                fingerprint = result;
            }

            if (!sha1sum || ret != 0 || !fingerprint ||
                strlen(fingerprint) < 40) {
                /* Unable to determine fingerprint */
                fingerprint = "UNKNOWN";
            } else {
                char *end = strchr(fingerprint, ' ');
                *end = '\0';
            }
        } else {
            /* Remove any ':' characters from fingerprint and truncate */
            char *tmp = nv_strreplace(fingerprint, ":", "");
            strncpy(short_fingerprint, tmp, sizeof(short_fingerprint));
            nvfree(tmp);
        }
        short_fingerprint[sizeof(short_fingerprint) - 1] = '\0';

        /* Add the public key to the package */

        /* XXX name will be leaked when freeing package */
        name = nvstrcat("nvidia-modsign-crt-", short_fingerprint, ".der", NULL);

        add_package_entry(p,
                          nvstrdup(op->module_signing_public_key),
                          NULL, /* path */
                          name,
                          NULL, /* target */
                          NULL, /* dst */
                          FILE_TYPE_MODULE_SIGNING_KEY,
                          FILE_TLS_CLASS_NONE,
                          FILE_COMPAT_ARCH_NONE,
                          0444);

        ui_message(op, "An X.509 certificate containing the public signing "
                    "key will be installed to %s/%s. The SHA1 fingerprint of "
                    "this certificate is: %s.\n\nThis certificate must be "
                    "added to a key database which is trusted by your kernel "
                    "in order for the kernel to be able to verify the module "
                    "signature.", op->module_signing_key_path, name,
                    fingerprint);

        nvfree(result);

        /* Delete or install the private key */

        if (delete_secret_key) {
            secure_delete(op, op->module_signing_secret_key);
        } else {

            /* Add the private key to the package */

            name = nvstrcat("nvidia-modsign-key-", short_fingerprint, ".key",
                            NULL);

            add_package_entry(p,
                              nvstrdup(op->module_signing_secret_key),
                              NULL, /* path */
                              name,
                              NULL, /* target */
                              NULL, /* dst */
                              FILE_TYPE_MODULE_SIGNING_KEY,
                              FILE_TLS_CLASS_NONE,
                              FILE_COMPAT_ARCH_NONE,
                              0400);

            ui_message(op, "The private signing key will be installed to %s/%s. "
                       "After the public key is added to a key database which "
                       "is trusted by your kernel, you may reuse the saved "
                       "public/private key pair to sign additional kernel "
                       "modules, without needing to re-enroll the public key. "
                       "Please take some reasonable precautions to secure the "
                       "private key: see the README for suggestions.",
                       op->module_signing_key_path, name);
        }
    } /* if (generate_keys) */

    return TRUE;
} /* assisted_module_signing() */