summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com5
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c101
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeys.h6
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c69
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c12
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.c45
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h52
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c88
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c11
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softSession.h7
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softSessionUtil.c33
11 files changed, 273 insertions, 156 deletions
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com b/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
index a3d76fd04e..39fc82a46a 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
@@ -22,9 +22,8 @@
# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
#
# Copyright 2010 Nexenta Systems, Inc. All rights reserved.
-# Copyright 2018, Joyent, Inc.
+# Copyright 2020 Joyent, Inc.
#
-# Copyright (c) 2018, Joyent, Inc.
LIBRARY = pkcs11_softtoken.a
VERS= .1
@@ -121,7 +120,7 @@ SRCS = \
# libelfsign needs a static pkcs11_softtoken
LIBS = $(DYNLIB)
-LDLIBS += -lc -lmd -lcryptoutil -lsoftcrypto -lgen
+LDLIBS += -lc -lmd -lcryptoutil -lsoftcrypto -lgen -lavl
CSTD = $(CSTD_GNU99)
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
index c44cbcb2a2..f52cc26ba0 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
@@ -23,6 +23,8 @@
* Use is subject to license terms.
*
* Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#include <strings.h>
@@ -30,7 +32,9 @@
#include <cryptoutil.h>
#include <unistd.h> /* for pid_t */
#include <pthread.h>
+#include <stddef.h>
#include <security/cryptoki.h>
+#include <sys/debug.h>
#include "softGlobal.h"
#include "softSession.h"
#include "softObject.h"
@@ -118,9 +122,31 @@ boolean_t softtoken_initialized = B_FALSE;
static pid_t softtoken_pid = 0;
-/* This mutex protects soft_session_list, all_sessions_closing */
+/*
+ * Lock ordering in pkcs11_softtoken is as follows:
+ * soft_giant_mutex
+ * soft_sessionlist_mutex
+ * soft_slot.slot_mutex
+ * soft_slot.keystore_mutex
+ * token session mutexes
+ * soft_session_t->session_mutex
+ * soft_object_mutex
+ * soft_object_t->object_mutex
+ * obj_delay_freed.obj_to_be_free_mutex
+ * ses_delay_freed.ses_to_br_free_mutex
+ */
+
+/*
+ * This mutex protects soft_session_list, all_sessions_closing,
+ * and soft_session_tree
+ */
pthread_mutex_t soft_sessionlist_mutex;
soft_session_t *soft_session_list = NULL;
+avl_tree_t soft_session_tree;
+
+/* This protects soft_object_tree */
+pthread_mutex_t soft_object_mutex;
+avl_tree_t soft_object_tree;
int all_sessions_closing = 0;
@@ -132,15 +158,17 @@ ses_to_be_freed_list_t ses_delay_freed;
pthread_mutex_t soft_giant_mutex = PTHREAD_MUTEX_INITIALIZER;
static CK_RV finalize_common(boolean_t force, CK_VOID_PTR pReserved);
-static void softtoken_init();
-static void softtoken_fini();
-static void softtoken_fork_prepare();
-static void softtoken_fork_after();
+static void softtoken_init(void);
+static void softtoken_fini(void);
+static void softtoken_fork_prepare(void);
+static void softtoken_fork_after(void);
+static int session_compare(const void *a, const void *b);
+static int object_compare(const void *a, const void *b);
CK_RV
C_Initialize(CK_VOID_PTR pInitArgs)
{
-
+ pthread_mutexattr_t attr = { 0 };
int initialize_pid;
boolean_t supplied_ok;
CK_RV rv;
@@ -211,12 +239,28 @@ C_Initialize(CK_VOID_PTR pInitArgs)
}
}
+ if (pthread_mutexattr_init(&attr) != 0) {
+ (void) pthread_mutex_unlock(&soft_giant_mutex);
+ return (CKR_HOST_MEMORY);
+ }
+
+ VERIFY0(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
+
/* Initialize the session list lock */
- if (pthread_mutex_init(&soft_sessionlist_mutex, NULL) != 0) {
+ if (pthread_mutex_init(&soft_sessionlist_mutex, &attr) != 0) {
+ (void) pthread_mutexattr_destroy(&attr);
(void) pthread_mutex_unlock(&soft_giant_mutex);
return (CKR_CANT_LOCK);
}
+ if (pthread_mutex_init(&soft_object_mutex, &attr) != 0) {
+ (void) pthread_mutexattr_destroy(&attr);
+ (void) pthread_mutex_unlock(&soft_giant_mutex);
+ return (CKR_CANT_LOCK);
+ }
+
+ VERIFY0(pthread_mutexattr_destroy(&attr));
+
/*
* token object related initialization
*/
@@ -322,8 +366,8 @@ C_Finalize(CK_VOID_PTR pReserved)
* must be held before calling this function.
*/
static CK_RV
-finalize_common(boolean_t force, CK_VOID_PTR pReserved) {
-
+finalize_common(boolean_t force, CK_VOID_PTR pReserved)
+{
CK_RV rv = CKR_OK;
struct object *delay_free_obj, *tmpo;
struct session *delay_free_ses, *tmps;
@@ -363,6 +407,8 @@ finalize_common(boolean_t force, CK_VOID_PTR pReserved) {
* two also prevent deadlocks and other artificial dependencies.
*/
+ (void) pthread_mutex_destroy(&soft_object_mutex);
+
/* Destroy the session list lock here */
(void) pthread_mutex_destroy(&soft_sessionlist_mutex);
@@ -404,6 +450,12 @@ finalize_common(boolean_t force, CK_VOID_PTR pReserved) {
static void
softtoken_init()
{
+ avl_create(&soft_session_tree, session_compare, sizeof (soft_session_t),
+ offsetof(soft_session_t, node));
+
+ avl_create(&soft_object_tree, object_compare, sizeof (soft_object_t),
+ offsetof(soft_object_t, node));
+
/* Children inherit parent's atfork handlers */
(void) pthread_atfork(softtoken_fork_prepare,
softtoken_fork_after, softtoken_fork_after);
@@ -426,6 +478,9 @@ softtoken_fini()
(void) finalize_common(B_TRUE, NULL_PTR);
+ avl_destroy(&soft_object_tree);
+ avl_destroy(&soft_session_tree);
+
(void) pthread_mutex_unlock(&soft_giant_mutex);
}
@@ -510,6 +565,7 @@ softtoken_fork_prepare()
(void) pthread_mutex_lock(&soft_slot.keystore_mutex);
soft_acquire_all_session_mutexes(&token_session);
soft_acquire_all_session_mutexes(soft_session_list);
+ VERIFY0(pthread_mutex_lock(&soft_object_mutex));
(void) pthread_mutex_lock(
&obj_delay_freed.obj_to_be_free_mutex);
(void) pthread_mutex_lock(
@@ -529,6 +585,7 @@ softtoken_fork_after()
&ses_delay_freed.ses_to_be_free_mutex);
(void) pthread_mutex_unlock(
&obj_delay_freed.obj_to_be_free_mutex);
+ VERIFY0(pthread_mutex_unlock(&soft_object_mutex));
soft_release_all_session_mutexes(soft_session_list);
soft_release_all_session_mutexes(&token_session);
(void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
@@ -537,3 +594,29 @@ softtoken_fork_after()
}
(void) pthread_mutex_unlock(&soft_giant_mutex);
}
+
+static int
+session_compare(const void *a, const void *b)
+{
+ const soft_session_t *l = a;
+ const soft_session_t *r = b;
+
+ if (l->handle < r->handle)
+ return (-1);
+ if (l->handle > r->handle)
+ return (1);
+ return (0);
+}
+
+static int
+object_compare(const void *a, const void *b)
+{
+ const soft_object_t *l = a;
+ const soft_object_t *r = b;
+
+ if (l->handle < r->handle)
+ return (-1);
+ if (l->handle > r->handle)
+ return (1);
+ return (0);
+}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeys.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeys.h
index 82af35991f..7bb9fa2c88 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeys.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeys.h
@@ -22,13 +22,13 @@
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#ifndef _SOFTKEYS_H
#define _SOFTKEYS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -55,7 +55,7 @@ CK_RV soft_derivekey(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *,
void soft_derive_enforce_flags(soft_object_t *, soft_object_t *);
CK_RV soft_gen_keyobject(CK_ATTRIBUTE_PTR, CK_ULONG,
- CK_ULONG *, soft_session_t *, CK_OBJECT_CLASS, CK_KEY_TYPE,
+ soft_object_t **, soft_session_t *, CK_OBJECT_CLASS, CK_KEY_TYPE,
CK_ULONG, CK_ULONG, boolean_t);
CK_RV soft_generate_pkcs5_pbkdf2_key(soft_session_t *, CK_MECHANISM_PTR,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c
index b3c48663aa..67bb1f7a24 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c
@@ -21,7 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright (c) 2018, Joyent, Inc.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#include <pthread.h>
@@ -61,11 +62,10 @@ soft_pkcs12_pbe(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *);
*/
CK_RV
soft_gen_keyobject(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_ULONG *objecthandle_p, soft_session_t *sp,
+ soft_object_t **objp, soft_session_t *sp,
CK_OBJECT_CLASS class, CK_KEY_TYPE key_type, CK_ULONG keylen, CK_ULONG mode,
boolean_t internal)
{
-
CK_RV rv;
soft_object_t *new_objp = NULL;
@@ -109,24 +109,22 @@ soft_gen_keyobject(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
/* Write the new token object to the keystore */
if (IS_TOKEN_OBJECT(new_objp)) {
new_objp->version = 1;
- new_objp->session_handle = (CK_SESSION_HANDLE)NULL;
+ new_objp->session_handle = CK_INVALID_HANDLE;
soft_add_token_object_to_slot(new_objp);
- /*
- * Type casting the address of an object struct to
- * an object handle.
- */
- *objecthandle_p = (CK_ULONG)new_objp;
+
+ set_objecthandle(new_objp);
+ *objp = new_objp;
return (CKR_OK);
}
- new_objp->session_handle = (CK_SESSION_HANDLE)sp;
+ new_objp->session_handle = sp->handle;
/* Add the new object to the session's object list. */
soft_add_object_to_session(new_objp, sp);
- /* Type casting the address of an object struct to an object handle. */
- *objecthandle_p = (CK_ULONG)new_objp;
+ set_objecthandle(new_objp);
+ *objp = new_objp;
return (CKR_OK);
@@ -258,16 +256,13 @@ soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
}
/* Create a new object for secret key. */
- rv = soft_gen_keyobject(pTemplate, ulCount, phKey, session_p,
+ rv = soft_gen_keyobject(pTemplate, ulCount, &secret_key, session_p,
CKO_SECRET_KEY, key_type, keylen, SOFT_GEN_KEY, B_FALSE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)*phKey;
-
switch (pMechanism->mechanism) {
case CKM_DES_KEY_GEN:
/*
@@ -410,6 +405,7 @@ soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
}
+ *phKey = secret_key->handle;
return (rv);
}
@@ -448,19 +444,16 @@ soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
/* Create a new object for public key. */
rv = soft_gen_keyobject(pPublicKeyTemplate, ulPublicAttrCount,
- phPublicKey, session_p, CKO_PUBLIC_KEY, key_type, 0,
+ &public_key, session_p, CKO_PUBLIC_KEY, key_type, 0,
SOFT_GEN_KEY, B_FALSE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the public object pointer. */
- public_key = (soft_object_t *)*phPublicKey;
-
/* Create a new object for private key. */
rv = soft_gen_keyobject(pPrivateKeyTemplate, ulPrivateAttrCount,
- phPrivateKey, session_p, CKO_PRIVATE_KEY, key_type, 0,
+ &private_key, session_p, CKO_PRIVATE_KEY, key_type, 0,
SOFT_GEN_KEY, B_FALSE);
if (rv != CKR_OK) {
@@ -475,9 +468,6 @@ soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
return (rv);
}
- /* Obtain the private object pointer. */
- private_key = (soft_object_t *)*phPrivateKey;
-
/*
* At this point, both public key and private key objects
* are settled with the application specified attributes.
@@ -542,6 +532,9 @@ soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
}
}
+ *phPublicKey = public_key->handle;
+ *phPrivateKey = private_key->handle;
+
return (rv);
}
@@ -851,16 +844,13 @@ soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
* be provided in the template.
*/
rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
- phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
- SOFT_DERIVE_KEY_DH, B_FALSE);
+ &secret_key, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL,
+ 0, SOFT_DERIVE_KEY_DH, B_FALSE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)*phKey;
-
rv = soft_dh_key_derive(basekey_p, secret_key,
(CK_BYTE *)pMechanism->pParameter,
pMechanism->ulParameterLen);
@@ -883,16 +873,13 @@ soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
* be provided in the template.
*/
rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
- phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
- SOFT_DERIVE_KEY_DH, B_FALSE);
+ &secret_key, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL,
+ 0, SOFT_DERIVE_KEY_DH, B_FALSE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)*phKey;
-
rv = soft_ec_key_derive(basekey_p, secret_key,
(CK_BYTE *)pMechanism->pParameter,
pMechanism->ulParameterLen);
@@ -951,7 +938,7 @@ common:
* the template, the default is CKK_GENERIC_SECRET.
*/
rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
- phKey, session_p, CKO_SECRET_KEY,
+ &secret_key, session_p, CKO_SECRET_KEY,
(CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
SOFT_DERIVE_KEY_OTHER, B_FALSE);
@@ -959,8 +946,7 @@ common:
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)*phKey;
+ *phKey = secret_key->handle;
/* Validate the key type and key length */
rv = soft_key_derive_check_length(secret_key, hash_size);
@@ -1249,6 +1235,8 @@ soft_create_hmac_key(soft_session_t *session_p, CK_BYTE *passwd,
CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
CK_BBOOL True = TRUE;
CK_ATTRIBUTE keytemplate[4];
+ soft_object_t *keyobj;
+
/*
* We must initialize each template member individually
* because at the time of initial coding for ON10, the
@@ -1277,10 +1265,13 @@ soft_create_hmac_key(soft_session_t *session_p, CK_BYTE *passwd,
* mechanism parameter structure.
*/
rv = soft_gen_keyobject(keytemplate,
- sizeof (keytemplate)/sizeof (CK_ATTRIBUTE), phKey, session_p,
+ sizeof (keytemplate)/sizeof (CK_ATTRIBUTE), &keyobj, session_p,
CKO_SECRET_KEY, (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
SOFT_CREATE_OBJ, B_TRUE);
+ if (keyobj != NULL)
+ *phKey = keyobj->handle;
+
return (rv);
}
@@ -1675,7 +1666,7 @@ soft_unwrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
/* Create a new object based on the attribute template. */
rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
- (CK_ULONG *)&new_objp, session_p, (CK_OBJECT_CLASS)~0UL,
+ &new_objp, session_p, (CK_OBJECT_CLASS)~0UL,
(CK_KEY_TYPE)~0UL, 0, SOFT_UNWRAP_KEY, B_FALSE);
if (rv != CKR_OK)
return (rv);
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
index 72e16bfe29..2524678a01 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2018, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
*/
#include <crypt.h>
@@ -2004,7 +2004,6 @@ soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
CK_KEY_TYPE keytype = CKK_AES;
static CK_BBOOL truevalue = TRUE;
soft_object_t *secret_key;
- CK_OBJECT_HANDLE hKey;
CK_ULONG passwd_size;
if (pPIN == NULL)
@@ -2062,15 +2061,13 @@ soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
params.ulPasswordLen = &passwd_size;
- rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
+ rv = soft_gen_keyobject(tmpl, attrs, &secret_key, &token_session,
CKO_SECRET_KEY, CKK_AES, 0, SOFT_GEN_KEY, B_TRUE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)hKey;
keylen = OBJ_SEC_VALUE_LEN(secret_key);
if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
soft_delete_object(&token_session, secret_key,
@@ -2129,7 +2126,6 @@ soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
static CK_BBOOL truevalue = TRUE;
soft_object_t *secret_key;
- CK_OBJECT_HANDLE hKey;
CK_ULONG passwd_size;
if (pPIN == NULL)
@@ -2187,15 +2183,13 @@ soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
params.ulPasswordLen = &passwd_size;
- rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
+ rv = soft_gen_keyobject(tmpl, attrs, &secret_key, &token_session,
CKO_SECRET_KEY, CKK_GENERIC_SECRET, 0, SOFT_GEN_KEY, B_TRUE);
if (rv != CKR_OK) {
return (rv);
}
- /* Obtain the secret object pointer. */
- secret_key = (soft_object_t *)hKey;
keylen = OBJ_SEC_VALUE_LEN(secret_key);
if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
soft_delete_object(&token_session, secret_key,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.c
index d5aae80910..27a3d95a08 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.c
@@ -21,8 +21,9 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
-
#include <pthread.h>
#include <stdlib.h>
#include <security/cryptoki.h>
@@ -165,7 +166,7 @@ C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
goto fail;
}
- new_object->session_handle = (CK_SESSION_HANDLE)NULL;
+ new_object->session_handle = CK_INVALID_HANDLE;
/*
* Add the newly created token object to the global
* token object list in the slot struct.
@@ -173,11 +174,13 @@ C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
soft_add_token_object_to_slot(new_object);
OBJ_REFRELE(old_object);
SES_REFRELE(session_p, lock_held);
- *phNewObject = (CK_ULONG)new_object;
+ *phNewObject = set_objecthandle(new_object);
return (CKR_OK);
}
+ *phNewObject = set_objecthandle(new_object);
+
/* Insert new object into this session's object list */
soft_add_object_to_session(new_object, session_p);
@@ -188,9 +191,6 @@ C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
OBJ_REFRELE(old_object);
SES_REFRELE(session_p, lock_held);
- /* set handle of the new object */
- *phNewObject = (CK_ULONG)new_object;
-
return (rv);
fail:
@@ -210,7 +210,7 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
CK_RV rv;
soft_object_t *object_p;
- soft_session_t *session_p = (soft_session_t *)(hSession);
+ soft_session_t *session_p;
boolean_t lock_held = B_FALSE;
CK_SESSION_HANDLE creating_session;
@@ -218,21 +218,14 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
if (!softtoken_initialized)
return (CKR_CRYPTOKI_NOT_INITIALIZED);
- /*
- * The reason that we don't call handle2session is because
- * the argument hSession may not be the creating_session of
- * the object to be destroyed, and we want to avoid the lock
- * contention. The handle2session will be called later for
- * the creating_session.
- */
- if ((session_p == NULL) ||
- (session_p->magic_marker != SOFTTOKEN_SESSION_MAGIC)) {
- return (CKR_SESSION_HANDLE_INVALID);
- }
+ rv = handle2session(hSession, &session_p);
+ if (rv != CKR_OK)
+ return (rv);
/* Obtain the object pointer. */
HANDLE2OBJECT_DESTROY(hObject, object_p, rv);
if (rv != CKR_OK) {
+ SES_REFRELE(session_p, lock_held);
return (rv);
}
@@ -247,12 +240,7 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
*/
rv = soft_pin_expired_check(object_p);
if (rv != CKR_OK) {
- return (rv);
- }
-
- /* Obtain the session pointer just for validity check. */
- rv = handle2session(hSession, &session_p);
- if (rv != CKR_OK) {
+ SES_REFRELE(session_p, lock_held);
return (rv);
}
@@ -287,15 +275,6 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
}
/*
- * Obtain the session pointer. Also, increment the session
- * reference count.
- */
- rv = handle2session(creating_session, &session_p);
- if (rv != CKR_OK) {
- return (rv);
- }
-
- /*
* Set OBJECT_IS_DELETING flag so any access to this
* object will be rejected.
*/
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
index ea73e1a58d..8179497b29 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
*/
#ifndef _SOFTOBJECT_H
@@ -32,6 +33,7 @@ extern "C" {
#include <pthread.h>
#include <security/pkcs11t.h>
+#include <sys/avl.h>
#include "softKeystoreUtil.h"
#include "softSession.h"
@@ -272,8 +274,8 @@ typedef struct x509_attr_cert {
typedef struct certificate_obj {
CK_CERTIFICATE_TYPE certificate_type;
union {
- x509_cert_t x509;
- x509_attr_cert_t x509_attr;
+ x509_cert_t x509;
+ x509_attr_cert_t x509_attr;
} cert_type_u;
} certificate_obj_t;
@@ -293,9 +295,11 @@ typedef attribute_info_t *CK_ATTRIBUTE_INFO_PTR;
* This is the main structure of the Objects.
*/
typedef struct object {
+ avl_node_t node;
+ CK_OBJECT_HANDLE handle;
/* Generic common fields. Always present */
uint_t version; /* for token objects only */
- CK_OBJECT_CLASS class;
+ CK_OBJECT_CLASS class;
CK_KEY_TYPE key_type;
CK_CERTIFICATE_TYPE cert_type;
ulong_t magic_marker;
@@ -745,38 +749,11 @@ typedef enum {
#define OBJECT_REFCNT_WAITING 2 /* Waiting for object reference */
/* count to become zero */
-/*
- * This macro is used to type cast an object handle to a pointer to
- * the object struct. Also, it checks to see if the object struct
- * is tagged with an object magic number. This is to detect when an
- * application passes a bogus object pointer.
- * Also, it checks to see if the object is in the deleting state that
- * another thread is performing. If not, increment the object reference
- * count by one. This is to prevent this object from being deleted by
- * other thread.
- */
-#define HANDLE2OBJECT_COMMON(hObject, object_p, rv, REFCNT_CODE) { \
- object_p = (soft_object_t *)(hObject); \
- if ((object_p == NULL) || \
- (object_p->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {\
- rv = CKR_OBJECT_HANDLE_INVALID; \
- } else { \
- (void) pthread_mutex_lock(&object_p->object_mutex); \
- if (!(object_p->obj_delete_sync & OBJECT_IS_DELETING)) { \
- REFCNT_CODE; \
- rv = CKR_OK; \
- } else { \
- rv = CKR_OBJECT_HANDLE_INVALID; \
- } \
- (void) pthread_mutex_unlock(&object_p->object_mutex); \
- } \
-}
-
#define HANDLE2OBJECT(hObject, object_p, rv) \
- HANDLE2OBJECT_COMMON(hObject, object_p, rv, object_p->obj_refcnt++)
+ rv = handle2object(hObject, &(object_p), B_TRUE);
#define HANDLE2OBJECT_DESTROY(hObject, object_p, rv) \
- HANDLE2OBJECT_COMMON(hObject, object_p, rv, /* no refcnt increment */)
+ rv = handle2object(hObject, &(object_p), B_FALSE);
#define OBJ_REFRELE(object_p) { \
@@ -788,13 +765,22 @@ typedef enum {
(void) pthread_mutex_unlock(&object_p->object_mutex); \
}
+extern pthread_mutex_t soft_object_mutex;
+extern avl_tree_t soft_object_tree;
+
/*
* Function Prototypes.
*/
+
+CK_RV handle2object(CK_OBJECT_HANDLE hObject, soft_object_t **object_p,
+ boolean_t refhold);
+
+CK_ULONG set_objecthandle(soft_object_t *obj);
+
void soft_cleanup_object(soft_object_t *objp);
CK_RV soft_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_ULONG *objecthandle_p, soft_session_t *sp);
+ CK_OBJECT_HANDLE_PTR objecthandle_p, soft_session_t *sp);
void soft_delete_object(soft_session_t *sp, soft_object_t *objp,
boolean_t force, boolean_t lock_held);
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
index 9794565299..021ae200ed 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
*/
#include <pthread.h>
@@ -28,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <security/cryptoki.h>
+#include <sys/debug.h>
#include "softGlobal.h"
#include "softObject.h"
#include "softSession.h"
@@ -159,7 +161,7 @@ soft_copy_object(soft_object_t *old_object, soft_object_t **new_object,
* Save the session handle of the C_CopyObject function
* in the new copy of the session object.
*/
- new_objp->session_handle = (CK_SESSION_HANDLE)sp;
+ new_objp->session_handle = sp->handle;
break;
}
@@ -220,13 +222,72 @@ soft_merge_object(soft_object_t *old_object, soft_object_t *new_object)
old_object->extra_attrlistp = new_object->extra_attrlistp;
}
+/*
+ * Sets *object_p to the soft_object_t corresponding to hObject. If
+ * hObject is valid, and not in the deleting state, CKR_OK is returned,
+ * otherwise an error is returned. If hObject is valid and refhold is B_TRUE,
+ * the object is also held.
+ */
+CK_RV
+handle2object(CK_OBJECT_HANDLE hObject, soft_object_t **object_p,
+ boolean_t refhold)
+{
+ soft_object_t *obj;
+ soft_object_t node;
+
+ (void) memset(&node, 0, sizeof (node));
+ node.handle = hObject;
+
+ VERIFY0(pthread_mutex_lock(&soft_object_mutex));
+ if ((obj = avl_find(&soft_object_tree, &node, NULL)) == NULL ||
+ obj->magic_marker != SOFTTOKEN_OBJECT_MAGIC) {
+ VERIFY0(pthread_mutex_unlock(&soft_object_mutex));
+ return (CKR_OBJECT_HANDLE_INVALID);
+ }
+
+ (void) pthread_mutex_lock(&obj->object_mutex);
+ VERIFY0(pthread_mutex_unlock(&soft_object_mutex));
+
+ if (obj->obj_delete_sync & OBJECT_IS_DELETING) {
+ (void) pthread_mutex_unlock(&obj->object_mutex);
+ return (CKR_OBJECT_HANDLE_INVALID);
+ }
+
+ if (refhold)
+ obj->obj_refcnt++;
+
+ (void) pthread_mutex_unlock(&obj->object_mutex);
+
+ *object_p = obj;
+ return (CKR_OK);
+}
+
+CK_ULONG
+set_objecthandle(soft_object_t *obj)
+{
+ avl_index_t where;
+
+ (void) pthread_mutex_lock(&soft_object_mutex);
+
+ do {
+ arc4random_buf(&obj->handle, sizeof (obj->handle));
+ if (obj->handle == CK_INVALID_HANDLE)
+ continue;
+ } while (avl_find(&soft_object_tree, obj, &where) != NULL);
+
+ avl_insert(&soft_object_tree, obj, where);
+
+ (void) pthread_mutex_unlock(&soft_object_mutex);
+
+ return (obj->handle);
+}
/*
* Create a new object struct, and add it to the session's object list.
*/
CK_RV
soft_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_ULONG *objecthandle_p, soft_session_t *sp)
+ CK_OBJECT_HANDLE_PTR objecthandle_p, soft_session_t *sp)
{
CK_RV rv = CKR_OK;
@@ -278,24 +339,20 @@ soft_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
(void) pthread_mutex_destroy(&new_objp->object_mutex);
goto fail_cleanup2;
}
- new_objp->session_handle = (CK_SESSION_HANDLE)NULL;
+ new_objp->session_handle = CK_INVALID_HANDLE;
soft_add_token_object_to_slot(new_objp);
- /*
- * Type casting the address of an object struct to
- * an object handle.
- */
- *objecthandle_p = (CK_ULONG)new_objp;
+
+ *objecthandle_p = set_objecthandle(new_objp);
return (CKR_OK);
}
- new_objp->session_handle = (CK_SESSION_HANDLE)sp;
+ new_objp->session_handle = sp->handle;
/* Add the new object to the session's object list. */
soft_add_object_to_session(new_objp, sp);
- /* Type casting the address of an object struct to an object handle. */
- *objecthandle_p = (CK_ULONG)new_objp;
+ *objecthandle_p = set_objecthandle(new_objp);
return (CKR_OK);
@@ -470,6 +527,10 @@ soft_delete_object_cleanup(soft_object_t *objp, boolean_t force)
*/
soft_cleanup_object(objp);
+ (void) pthread_mutex_lock(&soft_object_mutex);
+ avl_remove(&soft_object_tree, objp);
+ (void) pthread_mutex_unlock(&soft_object_mutex);
+
/* Reset OBJECT_IS_DELETING flag. */
objp->obj_delete_sync &= ~OBJECT_IS_DELETING;
@@ -506,7 +567,7 @@ soft_delete_object_cleanup(soft_object_t *objp, boolean_t force)
*/
void
soft_delete_object(soft_session_t *sp, soft_object_t *objp,
- boolean_t force, boolean_t lock_held)
+ boolean_t force, boolean_t lock_held)
{
/*
@@ -801,8 +862,7 @@ soft_find_objects(soft_session_t *sp, CK_OBJECT_HANDLE *obj_found,
(void) pthread_mutex_lock(&obj->object_mutex);
/* a sanity check to make sure the obj is still valid */
if (obj->magic_marker == SOFTTOKEN_OBJECT_MAGIC) {
- obj_found[num_obj_found] =
- (CK_OBJECT_HANDLE)obj;
+ obj_found[num_obj_found] = obj->handle;
num_obj_found++;
}
(void) pthread_mutex_unlock(&obj->object_mutex);
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c
index f836ddc009..6e22ad745b 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.c
@@ -21,7 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2018, Joyent, Inc.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#include <fcntl.h>
@@ -999,23 +1000,23 @@ soft_add_derived_key(CK_ATTRIBUTE_PTR tmpl, CK_ULONG attrcount,
/* ... and, if it needs to persist, write on the token */
if (IS_TOKEN_OBJECT(secret_key)) {
- secret_key->session_handle = (CK_SESSION_HANDLE)NULL;
+ secret_key->session_handle = CK_INVALID_HANDLE;
soft_add_token_object_to_slot(secret_key);
rv = soft_put_object_to_keystore(secret_key);
if (rv != CKR_OK) {
soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
return (rv);
}
- *phKey = (CK_OBJECT_HANDLE)secret_key;
+ *phKey = set_objecthandle(secret_key);
return (CKR_OK);
}
/* Add the new object to the session's object list. */
soft_add_object_to_session(secret_key, sp);
- secret_key->session_handle = (CK_SESSION_HANDLE)sp;
+ secret_key->session_handle = sp->handle;
- *phKey = (CK_OBJECT_HANDLE)secret_key;
+ *phKey = set_objecthandle(secret_key);
return (rv);
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSession.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSession.h
index cede49858f..c8f22781f8 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSession.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSession.h
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#ifndef _SOFTSESSION_H
@@ -32,7 +34,7 @@ extern "C" {
#include <pthread.h>
#include <security/pkcs11t.h>
-
+#include <sys/avl.h>
#define SOFTTOKEN_SESSION_MAGIC 0xECF00002
@@ -71,6 +73,8 @@ typedef struct crypto_active_op {
#define CRYPTO_KEY_DIGESTED 3 /* A C_DigestKey() was called */
typedef struct session {
+ avl_node_t node;
+ CK_SESSION_HANDLE handle;
ulong_t magic_marker; /* magic # be validated for integrity */
pthread_mutex_t session_mutex; /* session's mutex lock */
pthread_cond_t ses_free_cond; /* cond variable for signal and wait */
@@ -168,6 +172,7 @@ typedef struct ses_to_be_freed_list {
extern pthread_mutex_t soft_sessionlist_mutex;
extern soft_session_t *soft_session_list;
+extern avl_tree_t soft_session_tree;
extern int all_sessions_closing;
extern CK_ULONG soft_session_cnt; /* the number of opened sessions */
extern CK_ULONG soft_session_rw_cnt; /* the number of opened R/W sessions */
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSessionUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSessionUtil.c
index a1302a1649..254f6438e6 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSessionUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSessionUtil.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2020 Joyent, Inc.
*/
#include <md5.h>
@@ -95,7 +97,6 @@ soft_delete_all_sessions(boolean_t force)
}
-
/*
* Create a new session struct, and add it to the session linked list.
*
@@ -104,9 +105,8 @@ soft_delete_all_sessions(boolean_t force)
*/
CK_RV
soft_add_session(CK_FLAGS flags, CK_VOID_PTR pApplication,
- CK_NOTIFY notify, CK_ULONG *sessionhandle_p)
+ CK_NOTIFY notify, CK_ULONG *sessionhandle_p)
{
-
soft_session_t *new_sp = NULL;
/* Allocate a new session struct */
@@ -152,6 +152,16 @@ soft_add_session(CK_FLAGS flags, CK_VOID_PTR pApplication,
/* Acquire the global session list lock */
(void) pthread_mutex_lock(&soft_sessionlist_mutex);
+ /* Generate a unique session handle. */
+ do {
+ arc4random_buf(&new_sp->handle, sizeof (new_sp->handle));
+ if (new_sp->handle == CK_INVALID_HANDLE)
+ continue;
+ } while (avl_find(&soft_session_tree, new_sp, NULL) != NULL);
+
+ avl_add(&soft_session_tree, new_sp);
+ *sessionhandle_p = new_sp->handle;
+
/* Insert the new session in front of session list */
if (soft_session_list == NULL) {
soft_session_list = new_sp;
@@ -164,8 +174,6 @@ soft_add_session(CK_FLAGS flags, CK_VOID_PTR pApplication,
soft_session_list = new_sp;
}
- /* Type casting the address of a session struct to a session handle */
- *sessionhandle_p = (CK_ULONG)new_sp;
++soft_session_cnt;
if (flags & CKF_RW_SESSION)
++soft_session_rw_cnt;
@@ -276,6 +284,8 @@ soft_delete_session(soft_session_t *session_p,
}
}
+ avl_remove(&soft_session_tree, session_p);
+
--soft_session_cnt;
if (session_p->flags & CKF_RW_SESSION)
--soft_session_rw_cnt;
@@ -379,7 +389,7 @@ soft_delete_session(soft_session_t *session_p,
free(fcontext);
}
- /* Reset SESSION_IS_CLOSIN flag. */
+ /* Reset SESSION_IS_CLOSING flag. */
session_p->ses_close_sync &= ~SESSION_IS_CLOSING;
(void) pthread_mutex_unlock(&session_p->session_mutex);
@@ -410,7 +420,8 @@ CK_RV
handle2session(CK_SESSION_HANDLE hSession, soft_session_t **session_p)
{
- soft_session_t *sp = (soft_session_t *)(hSession);
+ soft_session_t *sp;
+ soft_session_t node;
/*
* No need to hold soft_sessionlist_mutex as we are
@@ -420,11 +431,19 @@ handle2session(CK_SESSION_HANDLE hSession, soft_session_t **session_p)
return (CKR_SESSION_CLOSED);
}
+ (void) memset(&node, 0, sizeof (node));
+ node.handle = hSession;
+
+ (void) pthread_mutex_lock(&soft_sessionlist_mutex);
+
+ sp = avl_find(&soft_session_tree, &node, NULL);
if ((sp == NULL) ||
(sp->magic_marker != SOFTTOKEN_SESSION_MAGIC)) {
+ (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
return (CKR_SESSION_HANDLE_INVALID);
}
(void) pthread_mutex_lock(&sp->session_mutex);
+ (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
if (sp->ses_close_sync & SESSION_IS_CLOSING) {
(void) pthread_mutex_unlock(&sp->session_mutex);