예제 #1
0
파일: dcrypt-gnutls.c 프로젝트: bdraco/core
static
int dcrypt_gnutls_store_private_key(struct dcrypt_private_key *key, const char *cipher, buffer_t *destination, dcrypt_password_cb *cb, void *ctx, const char **error_r)
{
	gnutls_privkey_t priv = (gnutls_privkey_t)key;
	gnutls_x509_privkey_t xkey;
	gnutls_privkey_export_x509(priv, &xkey);
	/* then export PEM */
	size_t outl = 0;
	gnutls_x509_privkey_export_pkcs8(xkey, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, &outl);
	char buffer[outl];
	gnutls_x509_privkey_export_pkcs8(xkey, GNUTLS_X509_FMT_PEM, NULL, 0, buffer, &outl);
	buffer_append(destination, buffer, outl);
	memset(buffer, 0, sizeof(buffer));
	return 0;
}
예제 #2
0
void
print_private_key(FILE *outfile, common_info_st * cinfo, gnutls_x509_privkey_t key)
{
	int ret;
	size_t size;

	if (!key)
		return;

	if (!cinfo->pkcs8) {
		/* Only print private key parameters when an unencrypted
		 * format is used */
		if (cinfo->outcert_format == GNUTLS_X509_FMT_PEM)
			privkey_info_int(outfile, cinfo, key);

		size = lbuffer_size;
		ret = gnutls_x509_privkey_export(key, cinfo->outcert_format,
						 lbuffer, &size);
		if (ret < 0) {
			fprintf(stderr, "privkey_export: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (cinfo->no_compat == 0 && gnutls_x509_privkey_get_seed(key, NULL, NULL, 0) != GNUTLS_E_INVALID_REQUEST) {
			gnutls_x509_privkey_set_flags(key, GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT);

			fwrite(lbuffer, 1, size, outfile);

			size = lbuffer_size;
			ret = gnutls_x509_privkey_export(key, cinfo->outcert_format,
						 lbuffer, &size);
			if (ret < 0) {
				fprintf(stderr, "privkey_export: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}
		}

	} else {
		unsigned int flags = 0;
		const char *pass;

		pass = get_password(cinfo, &flags, 0);
		flags |= cipher_to_flags(cinfo->pkcs_cipher);

		size = lbuffer_size;
		ret =
		    gnutls_x509_privkey_export_pkcs8(key, cinfo->outcert_format,
						     pass, flags, lbuffer,
						     &size);
		if (ret < 0) {
			fprintf(stderr, "privkey_export_pkcs8: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	}

	fwrite(lbuffer, 1, size, outfile);
}
예제 #3
0
파일: pem.c 프로젝트: gitter-badger/knot
static int try_export_pem(gnutls_x509_privkey_t key, dnssec_binary_t *pem)
{
	assert(key);

	gnutls_x509_crt_fmt_t format = GNUTLS_X509_FMT_PEM;
	char *password = NULL;
	int flags = 0;

	return gnutls_x509_privkey_export_pkcs8(key, format, password, flags,
						pem->data, &pem->size);
}
예제 #4
0
파일: crypto.cpp 프로젝트: mrobado/opendht
Blob
PrivateKey::serialize() const
{
    if (!x509_key)
        return {};
    size_t buf_sz = 8192;
    Blob buffer;
    buffer.resize(buf_sz);
    int err = gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, buffer.data(), &buf_sz);
    if (err != GNUTLS_E_SUCCESS) {
        std::cerr << "Could not export private key - " << gnutls_strerror(err) << std::endl;
        return {};
    }
    buffer.resize(buf_sz);
    return buffer;
}
예제 #5
0
void    Plugin::_loadPrivateKey()
{
    QFile           file(this->keyFile);
    int             bits;
    size_t          size;
    QByteArray      data;
    gnutls_datum_t  datum;
    int             error;

    if (!file.open(QIODevice::ReadWrite))
        throw Properties("error", "Unable to open the private key file").add("file", this->keyFile);
    ASSERT_INIT(gnutls_x509_privkey_init(&this->key), "privkey");
    // Checks that the private key is valid
    if (file.size() > 0)
    {
        data = file.readAll();
        datum.size = data.size();
        datum.data = (unsigned char *)data.data();
        if ((error = gnutls_x509_privkey_import_pkcs8(this->key, &datum, GNUTLS_X509_FMT_PEM, this->keyPassword.data(), 0)) != GNUTLS_E_SUCCESS)
        {
            LOG_ERROR("Invalid private key", Properties("error", gnutls_strerror(error)).toMap(), "Plugin", "_generatePrivateKey");
            file.resize(0);
        }
        else if (gnutls_x509_privkey_sec_param(this->key) != this->secParam)
            file.resize(0);
    }
    // Generates the private key
    if (file.size() == 0)
    {
        bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, this->secParam);
        LOG_INFO("Generating a new private key", Properties("secParam", gnutls_sec_param_get_name(this->secParam)).add("bits", bits).toMap(), "Plugin", "_generatePrivateKey");
        ASSERT(gnutls_x509_privkey_generate(this->key, GNUTLS_PK_RSA, bits, 0));
        ASSERT(gnutls_x509_privkey_verify_params(this->key));
        size = bits;
        data.resize((int)size);
        ASSERT(gnutls_x509_privkey_export_pkcs8(this->key, GNUTLS_X509_FMT_PEM, this->keyPassword.data(), GNUTLS_PKCS_USE_PBES2_AES_256, data.data(), &size));
        data.resize((int)size);
        file.write(data);
    }
}
예제 #6
0
/**
 * ntfs_pkcs12_extract_rsa_key
 */
static ntfs_rsa_private_key ntfs_pkcs12_extract_rsa_key(u8 *pfx, int pfx_size,
        char *password, char *thumbprint, int thumbprint_size,
        NTFS_DF_TYPES *df_type)
{
    int err, bag_index, flags;
    gnutls_datum_t dpfx, dkey;
    gnutls_pkcs12_t pkcs12 = NULL;
    gnutls_pkcs12_bag_t bag = NULL;
    gnutls_x509_privkey_t pkey = NULL;
    gnutls_x509_crt_t crt = NULL;
    ntfs_rsa_private_key rsa_key = NULL;
    char purpose_oid[100];
    size_t purpose_oid_size = sizeof(purpose_oid);
    size_t tp_size = thumbprint_size;
    BOOL have_thumbprint = FALSE;

    *df_type = DF_TYPE_UNKNOWN;
    /* Create a pkcs12 structure. */
    err = gnutls_pkcs12_init(&pkcs12);
    if (err) {
        ntfs_log_error("Failed to initialize PKCS#12 structure: %s\n",
                       gnutls_strerror(err));
        return NULL;
    }
    /* Convert the PFX file (DER format) to native pkcs12 format. */
    dpfx.data = pfx;
    dpfx.size = pfx_size;
    err = gnutls_pkcs12_import(pkcs12, &dpfx, GNUTLS_X509_FMT_DER, 0);
    if (err) {
        ntfs_log_error("Failed to convert the PFX file from DER to "
                       "native PKCS#12 format: %s\n",
                       gnutls_strerror(err));
        goto err;
    }
    /*
     * Verify that the password is correct and that the key file has not
     * been tampered with.  Note if the password has zero length and the
     * verification fails, retry with password set to NULL.  This is needed
     * to get passwordless .pfx files generated with Windows XP SP1 (and
     * probably earlier versions of Windows) to work.
     */
retry_verify:
    err = gnutls_pkcs12_verify_mac(pkcs12, password);
    if (err) {
        if (err == GNUTLS_E_MAC_VERIFY_FAILED &&
                password && !strlen(password)) {
            password = NULL;
            goto retry_verify;
        }
        ntfs_log_error("Failed to verify the MAC: %s  Is the "
                       "password correct?\n", gnutls_strerror(err));
        goto err;
    }
    for (bag_index = 0; ; bag_index++) {
        err = gnutls_pkcs12_bag_init(&bag);
        if (err) {
            ntfs_log_error("Failed to initialize PKCS#12 Bag "
                           "structure: %s\n",
                           gnutls_strerror(err));
            goto err;
        }
        err = gnutls_pkcs12_get_bag(pkcs12, bag_index, bag);
        if (err) {
            if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
                err = 0;
                break;
            }
            ntfs_log_error("Failed to obtain Bag from PKCS#12 "
                           "structure: %s\n",
                           gnutls_strerror(err));
            goto err;
        }
check_again:
        err = gnutls_pkcs12_bag_get_count(bag);
        if (err < 0) {
            ntfs_log_error("Failed to obtain Bag count: %s\n",
                           gnutls_strerror(err));
            goto err;
        }
        err = gnutls_pkcs12_bag_get_type(bag, 0);
        if (err < 0) {
            ntfs_log_error("Failed to determine Bag type: %s\n",
                           gnutls_strerror(err));
            goto err;
        }
        flags = 0;
        switch (err) {
        case GNUTLS_BAG_PKCS8_KEY:
            flags = GNUTLS_PKCS_PLAIN;
        case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
            err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey);
            if (err < 0) {
                ntfs_log_error("Failed to obtain Bag data: "
                               "%s\n", gnutls_strerror(err));
                goto err;
            }
            err = gnutls_x509_privkey_init(&pkey);
            if (err) {
                ntfs_log_error("Failed to initialized "
                               "private key structure: %s\n",
                               gnutls_strerror(err));
                goto err;
            }
            /* Decrypt the private key into GNU TLS format. */
            err = gnutls_x509_privkey_import_pkcs8(pkey, &dkey,
                                                   GNUTLS_X509_FMT_DER, password, flags);
            if (err) {
                ntfs_log_error("Failed to convert private "
                               "key from DER to GNU TLS "
                               "format: %s\n",
                               gnutls_strerror(err));
                goto err;
            }
#if 0
            /*
             * Export the key again, but unencrypted, and output it
             * to stderr.  Note the output has an RSA header so to
             * compare to openssl pkcs12 -nodes -in myfile.pfx
             * output need to ignore the part of the key between
             * the first "MII..." up to the second "MII...".  The
             * actual RSA private key begins at the second "MII..."
             * and in my testing at least was identical to openssl
             * output and was also identical both on big and little
             * endian so gnutls should be endianness safe.
             */
            char *buf = malloc(8192);
            size_t bufsize = 8192;
            err = gnutls_x509_privkey_export_pkcs8(pkey,
                                                   GNUTLS_X509_FMT_PEM, "", GNUTLS_PKCS_PLAIN, buf,
                                                   &bufsize);
            if (err) {
                ntfs_log_error("eek1\n");
                exit(1);
            }
            ntfs_log_error("%s\n", buf);
            free(buf);
#endif
            /* Convert the private key to our internal format. */
            rsa_key = ntfs_rsa_private_key_import_from_gnutls(pkey);
            if (!rsa_key)
                goto err;
            break;
        case GNUTLS_BAG_ENCRYPTED:
            err = gnutls_pkcs12_bag_decrypt(bag, password);
            if (err) {
                ntfs_log_error("Failed to decrypt Bag: %s\n",
                               gnutls_strerror(err));
                goto err;
            }
            goto check_again;
        case GNUTLS_BAG_CERTIFICATE:
            err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey);
            if (err < 0) {
                ntfs_log_error("Failed to obtain Bag data: "
                               "%s\n", gnutls_strerror(err));
                goto err;
            }
            err = gnutls_x509_crt_init(&crt);
            if (err) {
                ntfs_log_error("Failed to initialize "
                               "certificate structure: %s\n",
                               gnutls_strerror(err));
                goto err;
            }
            err = gnutls_x509_crt_import(crt, &dkey,
                                         GNUTLS_X509_FMT_DER);
            if (err) {
                ntfs_log_error("Failed to convert certificate "
                               "from DER to GNU TLS format: "
                               "%s\n", gnutls_strerror(err));
                goto err;
            }
            err = gnutls_x509_crt_get_key_purpose_oid(crt, 0,
                    purpose_oid, &purpose_oid_size, NULL);
            if (err) {
                ntfs_log_error("Failed to get key purpose "
                               "OID: %s\n",
                               gnutls_strerror(err));
                goto err;
            }
            purpose_oid[purpose_oid_size - 1] = '\0';
            if (!strcmp(purpose_oid,
                        NTFS_EFS_CERT_PURPOSE_OID_DRF))
                *df_type = DF_TYPE_DRF;
            else if (!strcmp(purpose_oid,
                             NTFS_EFS_CERT_PURPOSE_OID_DDF))
                *df_type = DF_TYPE_DDF;
            else {
                ntfs_log_error("Certificate has unknown "
                               "purpose OID %s.\n",
                               purpose_oid);
                err = EINVAL;
                goto err;
            }
            /* Return the thumbprint to the caller. */
            err = gnutls_x509_crt_get_fingerprint(crt,
                                                  GNUTLS_DIG_SHA1, thumbprint, &tp_size);
            if (err) {
                ntfs_log_error("Failed to get thumbprint: "
                               "%s\n", gnutls_strerror(err));
                goto err;
            }
            if (tp_size != NTFS_SHA1_THUMBPRINT_SIZE) {
                ntfs_log_error("Invalid thumbprint size %zd.  "
                               "Should be %d.\n", tp_size,
                               thumbprint_size);
                err = EINVAL;
                goto err;
            }
            have_thumbprint = TRUE;
            gnutls_x509_crt_deinit(crt);
            crt = NULL;
            break;
        default:
            /* We do not care about other types. */
            break;
        }
        gnutls_pkcs12_bag_deinit(bag);
    }
err:
    if (rsa_key && (err || *df_type == DF_TYPE_UNKNOWN ||
                    !have_thumbprint)) {
        if (!err)
            ntfs_log_error("Key type or thumbprint not found, "
                           "aborting.\n");
        ntfs_rsa_private_key_release(rsa_key);
        rsa_key = NULL;
    }
    if (crt)
        gnutls_x509_crt_deinit(crt);
    if (pkey)
        gnutls_x509_privkey_deinit(pkey);
    if (bag)
        gnutls_pkcs12_bag_deinit(bag);
    if (pkcs12)
        gnutls_pkcs12_deinit(pkcs12);
    return rsa_key;
}