Skip to content

Commit 3a798cb

Browse files
committed
Add KEYMGMT implementation for PKCS#11 provider
1 parent 21f1c6b commit 3a798cb

File tree

8 files changed

+457
-11
lines changed

8 files changed

+457
-11
lines changed

src/libp11-int.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct pkcs11_object_private {
111111
unsigned int forkid;
112112
int refcnt;
113113
pthread_mutex_t lock;
114+
PKCS11_KEY *public; /* our current public object */
114115
};
115116
#define PRIVKEY(_key) ((PKCS11_OBJECT_private *) (_key)->_private)
116117
#define PRIVCERT(_cert) ((PKCS11_OBJECT_private *) (_cert)->_private)
@@ -304,6 +305,9 @@ extern PKCS11_CERT *pkcs11_find_certificate(PKCS11_OBJECT_private *key);
304305
/* Find the corresponding key (if any) */
305306
extern PKCS11_KEY *pkcs11_find_key(PKCS11_OBJECT_private *cert);
306307

308+
/* Returns the PKCS11_KEY handle associated with the given EVP_PKEY */
309+
extern PKCS11_KEY *pkcs11_get_pkcs11_key(const EVP_PKEY *pk);
310+
307311
/* Get a list of all certificates matching with template associated with this token */
308312
extern int pkcs11_enumerate_certs(PKCS11_SLOT_private *,
309313
const PKCS11_CERT *cert_template, PKCS11_CERT **certs, unsigned int *ncerts);

src/libp11.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ PKCS11_get_public_key
2626
PKCS11_get_slotid_from_slot
2727
PKCS11_find_certificate
2828
PKCS11_find_key
29+
pkcs11_get_pkcs11_key
2930
PKCS11_enumerate_certs
3031
PKCS11_enumerate_certs_ext
3132
PKCS11_remove_certificate

src/libp11.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,16 @@ extern PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *);
342342
/* Find the corresponding key (if any) */
343343
extern PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *);
344344

345+
/**
346+
* Returns a PKCS11_KEY object referencing the private key associated
347+
* with the given EVP_PKEY.
348+
*
349+
* @param pk EVP_PKEY object referring to a PKCS#11 private key
350+
* @retval !=NULL reference to the PKCS11_KEY object
351+
* @retval NULL error or EVP_PKEY does not reference a private key
352+
*/
353+
extern PKCS11_KEY *PKCS11_get_pkcs11_key(const EVP_PKEY *pk);
354+
345355
/* Get a list of all certificates associated with this token */
346356
extern int PKCS11_enumerate_certs(PKCS11_TOKEN *, PKCS11_CERT **, unsigned int *);
347357

src/p11_front.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,15 @@ PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *pcert)
279279
return pkcs11_find_key(cert);
280280
}
281281

282+
PKCS11_KEY *PKCS11_get_pkcs11_key(const EVP_PKEY *pk)
283+
{
284+
PKCS11_KEY *pkey = pkcs11_get_pkcs11_key(pk);
285+
PKCS11_OBJECT_private *key = PRIVKEY(pkey);
286+
if (check_object_fork(key) < 0)
287+
return NULL;
288+
return pkey;
289+
}
290+
282291
int PKCS11_enumerate_certs_ext(PKCS11_TOKEN *token, const PKCS11_CERT *cert_template,
283292
PKCS11_CERT **certs, unsigned int *ncerts)
284293
{

src/p11_key.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ static const unsigned char STR_ED448[] = {
4444
# endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
4545
#endif /* OPENSSL_NO_EC */
4646

47+
static int pkey_ex_index = 0;
48+
4749
static int pkcs11_find_keys(PKCS11_SLOT_private *, CK_SESSION_HANDLE, unsigned int,
4850
PKCS11_TEMPLATE *);
4951
static int pkcs11_init_key(PKCS11_SLOT_private *, CK_SESSION_HANDLE session,
@@ -58,6 +60,35 @@ static void pkcs11_common_pubkey_attr(PKCS11_TEMPLATE *, const char *,
5860
static void pkcs11_common_privkey_attr(PKCS11_TEMPLATE *, const char *,
5961
const unsigned char *, size_t, const PKCS11_params *);
6062

63+
static void alloc_pkey_ex_index(void)
64+
{
65+
if (pkey_ex_index == 0) {
66+
while (pkey_ex_index == 0) /* Workaround for OpenSSL RT3710 */
67+
pkey_ex_index = EVP_PKEY_get_ex_new_index(0, "libp11 EVP_PKEY",
68+
NULL, NULL, NULL);
69+
if (pkey_ex_index < 0)
70+
pkey_ex_index = 0; /* Fallback to app_data */
71+
}
72+
}
73+
74+
static void free_pkey_ex_index(void)
75+
{
76+
if (pkey_ex_index > 0) {
77+
CRYPTO_free_ex_index(CRYPTO_EX_INDEX_EVP_PKEY, pkey_ex_index);
78+
pkey_ex_index = 0;
79+
}
80+
}
81+
82+
static void pkcs11_set_ex_data_evp_pkey(EVP_PKEY *pkey, PKCS11_KEY *key)
83+
{
84+
EVP_PKEY_set_ex_data(pkey, pkey_ex_index, key);
85+
}
86+
87+
static PKCS11_KEY *pkcs11_get_ex_data_evp_pkey(const EVP_PKEY *pkey)
88+
{
89+
return EVP_PKEY_get_ex_data(pkey, pkey_ex_index);
90+
}
91+
6192
/* Helper to acquire object handle from given template */
6293
static CK_OBJECT_HANDLE pkcs11_handle_from_template(PKCS11_SLOT_private *slot,
6394
CK_SESSION_HANDLE session, PKCS11_TEMPLATE *tmpl)
@@ -708,12 +739,21 @@ EVP_PKEY *pkcs11_get_key(PKCS11_OBJECT_private *key0, CK_OBJECT_CLASS object_cla
708739
default:
709740
pkcs11_log(key0->slot->ctx, LOG_DEBUG, "Unsupported key type\n");
710741
}
742+
alloc_pkey_ex_index();
743+
pkcs11_set_ex_data_evp_pkey(ret, key->public);
744+
711745
err:
712746
if (key != key0)
713747
pkcs11_object_free(key);
714748
return ret;
715749
}
716750

751+
/* Returns the PKCS11_KEY handle associated with the given EVP_PKEY */
752+
PKCS11_KEY *pkcs11_get_pkcs11_key(const EVP_PKEY *pk)
753+
{
754+
return pkcs11_get_ex_data_evp_pkey(pk);
755+
}
756+
717757
/*
718758
* Authenticate a private the key operation if needed
719759
* This function *only* handles CKU_CONTEXT_SPECIFIC logins.
@@ -912,6 +952,9 @@ static int pkcs11_init_key(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session,
912952
key->label = kpriv->label;
913953
key->isPrivate = (type == CKO_PRIVATE_KEY);
914954

955+
/* Link back */
956+
kpriv->public = key;
957+
915958
if (ret)
916959
*ret = key;
917960
return 0;
@@ -981,6 +1024,7 @@ void pkcs11_destroy_keys(PKCS11_SLOT_private *slot, unsigned int type)
9811024
OPENSSL_free(keys->keys);
9821025
keys->keys = NULL;
9831026
keys->num = 0;
1027+
free_pkey_ex_index();
9841028
}
9851029

9861030
/* vim: set noexpandtab: */

0 commit comments

Comments
 (0)