Пример #1
0
/*
 * Create an EVP_PKEY OpenSSL object for a given key
 * Returns private or public key depending on isPrivate
 */
EVP_PKEY *pkcs11_get_key(PKCS11_KEY *key, int isPrivate)
{
	if (key->isPrivate != isPrivate)
		key = pkcs11_find_key_from_key(key);
	if (key == NULL)
		return NULL;
	if (key->evp_key == NULL) {
		PKCS11_KEY_private *kpriv = PRIVKEY(key);
		key->evp_key = kpriv->ops->get_evp_key(key);
		if (key->evp_key == NULL)
			return NULL;
		kpriv->always_authenticate = CK_FALSE;
		if(isPrivate) {
			if(key_getattr_val(key, CKA_ALWAYS_AUTHENTICATE,
					&kpriv->always_authenticate, sizeof(CK_BBOOL)))
				fprintf(stderr, "Missing CKA_ALWAYS_AUTHENTICATE attribute\n");
		}
	}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	EVP_PKEY_up_ref(key->evp_key);
#else
	CRYPTO_add(&key->evp_key->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
	return key->evp_key;
}
Пример #2
0
static EC_KEY *pkcs11_get_ec(PKCS11_KEY *key)
{
	EC_KEY *ec;
	int no_params, no_point;

	ec = EC_KEY_new();
	if (ec == NULL)
		return NULL;

	/* For OpenSSL req we need at least the
	 * EC_KEY_get0_group(ec_key)) to return the group.
	 * Continue even if it fails, as the sign operation does not need
	 * it if the PKCS#11 module or the hardware can figure this out
	 */
	no_params = pkcs11_get_params(ec, key);
	no_point = pkcs11_get_point_key(ec, key);
	if (no_point && key->isPrivate) /* Retry with the public key */
		no_point = pkcs11_get_point_key(ec, pkcs11_find_key_from_key(key));
	if (no_point && key->isPrivate) /* Retry with the certificate */
		no_point = pkcs11_get_point_cert(ec, pkcs11_find_certificate(key));

	if (key->isPrivate && EC_KEY_get0_private_key(ec) == NULL) {
		BIGNUM *bn = BN_new();
		EC_KEY_set_private_key(ec, bn);
		BN_free(bn);
	}

	/* A public keys requires both the params and the point to be present */
	if (!key->isPrivate && (no_params || no_point)) {
		EC_KEY_free(ec);
		return NULL;
	}

	return ec;
}
Пример #3
0
static EC_KEY *pkcs11_get_ec(PKCS11_KEY *key)
{
	EC_KEY *ec, *found_params = NULL, *found_point = NULL;
	CK_BYTE *params, *point;
	size_t params_len = 0, point_len = 0;
	PKCS11_KEY *pubkey;

	ec = EC_KEY_new();
	if (ec == NULL)
		return NULL;

	/* For OpenSSL req we need at least the
	 * EC_KEY_get0_group(ec_key)) to return the group.
	 * Continue even if it fails, as the sign operation does not need
	 * it if the PKCS#11 module or the hardware can figure this out
	 */
	if (!key_getattr_alloc(key, CKA_EC_PARAMS, &params, &params_len)) {
		const unsigned char *a = params;

		/* Convert to OpenSSL parmas */
		found_params = d2i_ECParameters(&ec, &a, (long)params_len);
		OPENSSL_free(params);
	}

	/* Now retrieve the point */
	pubkey = key->isPrivate ? pkcs11_find_key_from_key(key) : key;
	if (pubkey == NULL)
		return ec;
	if (!key_getattr_alloc(pubkey, CKA_EC_POINT, &point, &point_len)) {
		const unsigned char *a;
		ASN1_OCTET_STRING *os;

		/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */
		a = point;
		os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)point_len);
		if (os) {
			a = os->data;
			found_point = o2i_ECPublicKey(&ec, &a, os->length);
			ASN1_STRING_free(os);
		}
		if (found_point == NULL) { /* Workaround for broken PKCS#11 modules */
			a = point;
			found_point = o2i_ECPublicKey(&ec, &a, point_len);
		}
		OPENSSL_free(point);
	}

	/* A public keys requires both the params and the point to be present */
	if (!key->isPrivate && (found_params == NULL || found_point == NULL)) {
		EC_KEY_free(ec);
		return NULL;
	}

	return ec;
}