#include "tpmtok_int.h"
SESSION *
session_mgr_find(CK_SESSION_HANDLE handle)
{
DL_NODE * node = NULL;
SESSION * result = NULL;
CK_RV rc;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (NULL);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if (s->handle == handle) {
result = s;
break;
}
node = node->next;
}
(void) pthread_mutex_unlock(&sess_list_mutex);
return (result);
}
CK_RV
session_mgr_new(CK_ULONG flags, SESSION **sess)
{
SESSION * new_session = NULL;
SESSION * s = NULL;
DL_NODE * node = NULL;
CK_BBOOL user_session = FALSE;
CK_BBOOL so_session = FALSE;
CK_BBOOL pkcs_locked = TRUE;
CK_BBOOL sess_locked = TRUE;
CK_RV rc;
new_session = (SESSION *)malloc(sizeof (SESSION));
if (! new_session) {
rc = CKR_HOST_MEMORY;
goto done;
}
(void) memset(new_session, 0x0, sizeof (SESSION));
rc = pthread_mutex_lock(&pkcs_mutex);
if (rc != CKR_OK) {
return (rc);
}
pkcs_locked = TRUE;
do {
s = session_mgr_find(next_session_handle);
if (s != NULL)
next_session_handle++;
else
new_session->handle = next_session_handle++;
} while (s != NULL);
(void) pthread_mutex_unlock(&pkcs_mutex);
pkcs_locked = FALSE;
new_session->session_info.slotID = 1;
new_session->session_info.flags = flags;
new_session->session_info.ulDeviceError = 0;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (rc);
}
sess_locked = TRUE;
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
so_session = TRUE;
break;
}
if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
(s->session_info.state == CKS_RW_USER_FUNCTIONS)) {
user_session = TRUE;
break;
}
node = node->next;
}
if (global_login_state == CKS_RW_SO_FUNCTIONS) {
so_session = TRUE;
}
if ((global_login_state == CKS_RO_USER_FUNCTIONS) ||
(global_login_state == CKS_RW_USER_FUNCTIONS)) {
user_session = TRUE;
}
if (user_session) {
if (new_session->session_info.flags & CKF_RW_SESSION)
new_session->session_info.state = CKS_RW_USER_FUNCTIONS;
else
new_session->session_info.state = CKS_RO_USER_FUNCTIONS;
} else if (so_session) {
new_session->session_info.state = CKS_RW_SO_FUNCTIONS;
} else {
if (new_session->session_info.flags & CKF_RW_SESSION)
new_session->session_info.state = CKS_RW_PUBLIC_SESSION;
else
new_session->session_info.state = CKS_RO_PUBLIC_SESSION;
}
sess_list = dlist_add_as_first(sess_list, new_session);
*sess = new_session;
done:
if (pkcs_locked)
(void) pthread_mutex_unlock(&pkcs_mutex);
if (sess_locked)
(void) pthread_mutex_unlock(&sess_list_mutex);
if (rc != CKR_OK && new_session != NULL) {
free(new_session);
}
return (rc);
}
CK_BBOOL
session_mgr_so_session_exists(void)
{
DL_NODE *node = NULL;
CK_RV rc;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (rc);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
rc = TRUE;
goto done;
}
node = node->next;
}
rc = FALSE;
done:
(void) pthread_mutex_unlock(&sess_list_mutex);
return (rc);
}
CK_BBOOL
session_mgr_user_session_exists(void)
{
DL_NODE *node = NULL;
CK_RV rc;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (rc);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
(s->session_info.state == CKS_RW_USER_FUNCTIONS)) {
rc = TRUE;
goto done;
}
node = node->next;
}
rc = FALSE;
done:
(void) pthread_mutex_unlock(&sess_list_mutex);
return (rc);
}
CK_BBOOL
session_mgr_public_session_exists(void)
{
DL_NODE *node = NULL;
CK_RV rc;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (rc);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if ((s->session_info.state == CKS_RO_PUBLIC_SESSION) ||
(s->session_info.state == CKS_RW_PUBLIC_SESSION)) {
rc = TRUE;
goto done;
}
node = node->next;
}
rc = FALSE;
done:
(void) pthread_mutex_unlock(&sess_list_mutex);
return (rc);
}
CK_BBOOL
session_mgr_readonly_exists(void)
{
DL_NODE *node = NULL;
CK_RV rc;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (rc);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if ((s->session_info.flags & CKF_RW_SESSION) == 0) {
rc = TRUE;
goto done;
}
node = node->next;
}
rc = FALSE;
done:
(void) pthread_mutex_unlock(&sess_list_mutex);
return (rc);
}
CK_RV
session_mgr_close_session(SESSION *sess)
{
DL_NODE * node = NULL;
CK_RV rc = CKR_OK;
if (! sess)
return (FALSE);
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (CKR_FUNCTION_FAILED);
}
node = dlist_find(sess_list, sess);
if (! node) {
rc = CKR_FUNCTION_FAILED;
goto done;
}
(void) object_mgr_purge_session_objects(sess, ALL);
if (sess->find_list)
free(sess->find_list);
if (sess->encr_ctx.context)
free(sess->encr_ctx.context);
if (sess->encr_ctx.mech.pParameter)
free(sess->encr_ctx.mech.pParameter);
if (sess->decr_ctx.context)
free(sess->decr_ctx.context);
if (sess->decr_ctx.mech.pParameter)
free(sess->decr_ctx.mech.pParameter);
if (sess->digest_ctx.context.ref)
free(sess->digest_ctx.context.ref);
if (sess->digest_ctx.mech.pParameter)
free(sess->digest_ctx.mech.pParameter);
if (sess->sign_ctx.context)
free(sess->sign_ctx.context);
if (sess->sign_ctx.mech.pParameter)
free(sess->sign_ctx.mech.pParameter);
if (sess->verify_ctx.context)
free(sess->verify_ctx.context);
if (sess->verify_ctx.mech.pParameter)
free(sess->verify_ctx.mech.pParameter);
if (sess->hContext)
(void) Tspi_Context_Close(sess->hContext);
free(sess);
sess_list = dlist_remove_node(sess_list, node);
if (sess_list == NULL) {
TSS_HCONTEXT hContext;
if (open_tss_context(&hContext) == 0) {
(void) object_mgr_purge_private_token_objects(hContext);
(void) Tspi_Context_Close(hContext);
}
global_login_state = 0;
(void) pthread_mutex_lock(&obj_list_mutex);
(void) object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE);
(void) pthread_mutex_unlock(&obj_list_mutex);
}
done:
(void) pthread_mutex_unlock(&sess_list_mutex);
return (rc);
}
CK_RV
session_mgr_close_all_sessions(void)
{
CK_RV rc = CKR_OK;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (CKR_FUNCTION_FAILED);
}
while (sess_list) {
SESSION *sess = (SESSION *)sess_list->data;
(void) object_mgr_purge_session_objects(sess, ALL);
if (sess->find_list)
free(sess->find_list);
if (sess->encr_ctx.context)
free(sess->encr_ctx.context);
if (sess->encr_ctx.mech.pParameter)
free(sess->encr_ctx.mech.pParameter);
if (sess->decr_ctx.context)
free(sess->decr_ctx.context);
if (sess->decr_ctx.mech.pParameter)
free(sess->decr_ctx.mech.pParameter);
if (sess->digest_ctx.context.ref)
free(sess->digest_ctx.context.ref);
if (sess->digest_ctx.mech.pParameter)
free(sess->digest_ctx.mech.pParameter);
if (sess->sign_ctx.context)
free(sess->sign_ctx.context);
if (sess->sign_ctx.mech.pParameter)
free(sess->sign_ctx.mech.pParameter);
if (sess->verify_ctx.context)
free(sess->verify_ctx.context);
if (sess->verify_ctx.mech.pParameter)
free(sess->verify_ctx.mech.pParameter);
if (sess->hContext)
(void) Tspi_Context_Close(sess->hContext);
free(sess);
sess_list = dlist_remove_node(sess_list, sess_list);
}
(void) pthread_mutex_unlock(&sess_list_mutex);
return (CKR_OK);
}
CK_RV
session_mgr_login_all(CK_USER_TYPE user_type) {
DL_NODE * node = NULL;
CK_RV rc = CKR_OK;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (CKR_FUNCTION_FAILED);
}
node = sess_list;
while (node) {
SESSION *s = (SESSION *)node->data;
if (s->session_info.flags & CKF_RW_SESSION) {
if (user_type == CKU_USER)
s->session_info.state = CKS_RW_USER_FUNCTIONS;
else
s->session_info.state = CKS_RW_SO_FUNCTIONS;
} else {
if (user_type == CKU_USER)
s->session_info.state = CKS_RO_USER_FUNCTIONS;
}
global_login_state = s->session_info.state;
node = node->next;
}
(void) pthread_mutex_unlock(&sess_list_mutex);
return (CKR_OK);
}
CK_RV
session_mgr_logout_all(void) {
DL_NODE * node = NULL;
SESSION * s = NULL;
CK_RV rc = CKR_OK;
rc = pthread_mutex_lock(&sess_list_mutex);
if (rc != CKR_OK) {
return (CKR_FUNCTION_FAILED);
}
node = sess_list;
while (node) {
s = (SESSION *)node->data;
(void) object_mgr_purge_session_objects(s, PRIVATE);
if (s->session_info.flags & CKF_RW_SESSION)
s->session_info.state = CKS_RW_PUBLIC_SESSION;
else
s->session_info.state = CKS_RO_PUBLIC_SESSION;
global_login_state = s->session_info.state;
node = node->next;
}
(void) pthread_mutex_unlock(&sess_list_mutex);
return (CKR_OK);
}
CK_RV
session_mgr_get_op_state(SESSION *sess,
CK_BBOOL length_only,
CK_BYTE *data,
CK_ULONG *data_len) {
OP_STATE_DATA *op_data = NULL;
CK_ULONG op_data_len = 0;
CK_ULONG offset;
void *dptr = data;
if (! sess) {
return (CKR_FUNCTION_FAILED);
}
if (sess->find_active == TRUE) {
return (CKR_STATE_UNSAVEABLE);
}
if (sess->encr_ctx.active == TRUE) {
if (op_data != NULL) {
return (CKR_STATE_UNSAVEABLE);
}
op_data_len = sizeof (OP_STATE_DATA) +
sizeof (ENCR_DECR_CONTEXT) +
sess->encr_ctx.context_len +
sess->encr_ctx.mech.ulParameterLen;
if (length_only == FALSE) {
op_data = (OP_STATE_DATA *)dptr;
op_data->data_len = op_data_len -
sizeof (OP_STATE_DATA);
op_data->session_state = sess->session_info.state;
op_data->active_operation = STATE_ENCR;
offset = sizeof (OP_STATE_DATA);
(void) (void) memcpy((CK_BYTE *)op_data + offset,
&sess->encr_ctx,
sizeof (ENCR_DECR_CONTEXT));
offset += sizeof (ENCR_DECR_CONTEXT);
if (sess->encr_ctx.context_len != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->encr_ctx.context,
sess->encr_ctx.context_len);
offset += sess->encr_ctx.context_len;
}
if (sess->encr_ctx.mech.ulParameterLen != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->encr_ctx.mech.pParameter,
sess->encr_ctx.mech.ulParameterLen);
}
}
}
if (sess->decr_ctx.active == TRUE) {
if (op_data != NULL) {
return (CKR_STATE_UNSAVEABLE);
}
op_data_len = sizeof (OP_STATE_DATA) +
sizeof (ENCR_DECR_CONTEXT) +
sess->decr_ctx.context_len +
sess->decr_ctx.mech.ulParameterLen;
if (length_only == FALSE) {
op_data = (OP_STATE_DATA *)dptr;
op_data->data_len = op_data_len -
sizeof (OP_STATE_DATA);
op_data->session_state = sess->session_info.state;
op_data->active_operation = STATE_DECR;
offset = sizeof (OP_STATE_DATA);
(void) memcpy((CK_BYTE *)op_data + offset,
&sess->decr_ctx,
sizeof (ENCR_DECR_CONTEXT));
offset += sizeof (ENCR_DECR_CONTEXT);
if (sess->decr_ctx.context_len != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->decr_ctx.context,
sess->decr_ctx.context_len);
offset += sess->decr_ctx.context_len;
}
if (sess->decr_ctx.mech.ulParameterLen != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->decr_ctx.mech.pParameter,
sess->decr_ctx.mech.ulParameterLen);
}
}
}
if (sess->digest_ctx.active == TRUE) {
if (op_data != NULL) {
return (CKR_STATE_UNSAVEABLE);
}
op_data_len = sizeof (OP_STATE_DATA) +
sizeof (DIGEST_CONTEXT) +
sess->digest_ctx.context_len +
sess->digest_ctx.mech.ulParameterLen;
if (length_only == FALSE) {
op_data = (OP_STATE_DATA *)dptr;
op_data->data_len = op_data_len -
sizeof (OP_STATE_DATA);
op_data->session_state = sess->session_info.state;
op_data->active_operation = STATE_DIGEST;
offset = sizeof (OP_STATE_DATA);
(void) memcpy((CK_BYTE *)op_data + offset,
&sess->digest_ctx, sizeof (DIGEST_CONTEXT));
offset += sizeof (DIGEST_CONTEXT);
if (sess->digest_ctx.context_len != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->digest_ctx.context.ref,
sess->digest_ctx.context_len);
offset += sess->digest_ctx.context_len;
}
if (sess->digest_ctx.mech.ulParameterLen != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->digest_ctx.mech.pParameter,
sess->digest_ctx.mech.ulParameterLen);
}
}
}
if (sess->sign_ctx.active == TRUE) {
if (op_data != NULL) {
return (CKR_STATE_UNSAVEABLE);
}
op_data_len = sizeof (OP_STATE_DATA) +
sizeof (SIGN_VERIFY_CONTEXT) +
sess->sign_ctx.context_len +
sess->sign_ctx.mech.ulParameterLen;
if (length_only == FALSE) {
op_data = (OP_STATE_DATA *)dptr;
op_data->data_len = op_data_len -
sizeof (OP_STATE_DATA);
op_data->session_state = sess->session_info.state;
op_data->active_operation = STATE_SIGN;
offset = sizeof (OP_STATE_DATA);
(void) memcpy((CK_BYTE *)op_data + offset,
&sess->sign_ctx, sizeof (SIGN_VERIFY_CONTEXT));
offset += sizeof (SIGN_VERIFY_CONTEXT);
if (sess->sign_ctx.context_len != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->sign_ctx.context,
sess->sign_ctx.context_len);
offset += sess->sign_ctx.context_len;
}
if (sess->sign_ctx.mech.ulParameterLen != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->sign_ctx.mech.pParameter,
sess->sign_ctx.mech.ulParameterLen);
}
}
}
if (sess->verify_ctx.active == TRUE) {
if (op_data != NULL) {
return (CKR_STATE_UNSAVEABLE);
}
op_data_len = sizeof (OP_STATE_DATA) +
sizeof (SIGN_VERIFY_CONTEXT) +
sess->verify_ctx.context_len +
sess->verify_ctx.mech.ulParameterLen;
if (length_only == FALSE) {
op_data = (OP_STATE_DATA *)dptr;
op_data->data_len = op_data_len -
sizeof (OP_STATE_DATA);
op_data->session_state = sess->session_info.state;
op_data->active_operation = STATE_SIGN;
offset = sizeof (OP_STATE_DATA);
(void) memcpy((CK_BYTE *)op_data + offset,
&sess->verify_ctx, sizeof (SIGN_VERIFY_CONTEXT));
offset += sizeof (SIGN_VERIFY_CONTEXT);
if (sess->verify_ctx.context_len != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->verify_ctx.context,
sess->verify_ctx.context_len);
offset += sess->verify_ctx.context_len;
}
if (sess->verify_ctx.mech.ulParameterLen != 0) {
(void) memcpy((CK_BYTE *)op_data + offset,
sess->verify_ctx.mech.pParameter,
sess->verify_ctx.mech.ulParameterLen);
}
}
}
*data_len = op_data_len;
return (CKR_OK);
}
CK_RV
session_mgr_set_op_state(
SESSION *sess,
CK_OBJECT_HANDLE encr_key,
CK_OBJECT_HANDLE auth_key,
CK_BYTE *data)
{
OP_STATE_DATA *op_data = NULL;
CK_BYTE *mech_param = NULL;
CK_BYTE *context = NULL;
CK_BYTE *ptr1 = NULL;
CK_BYTE *ptr2 = NULL;
CK_BYTE *ptr3 = NULL;
CK_ULONG len;
void *dptr = data;
if (! sess || ! data) {
return (CKR_FUNCTION_FAILED);
}
op_data = (OP_STATE_DATA *)dptr;
if (sess->session_info.state != op_data->session_state) {
return (CKR_SAVED_STATE_INVALID);
}
switch (op_data->active_operation) {
case STATE_ENCR:
case STATE_DECR:
{
void *cptr = data + sizeof (OP_STATE_DATA);
ENCR_DECR_CONTEXT *ctx = (ENCR_DECR_CONTEXT *)cptr;
len = sizeof (ENCR_DECR_CONTEXT) +
ctx->context_len + ctx->mech.ulParameterLen;
if (len != op_data->data_len) {
return (CKR_SAVED_STATE_INVALID);
}
if (auth_key != 0) {
return (CKR_KEY_NOT_NEEDED);
}
if (encr_key == 0) {
return (CKR_KEY_NEEDED);
}
ptr1 = (CK_BYTE *)ctx;
ptr2 = ptr1 + sizeof (ENCR_DECR_CONTEXT);
ptr3 = ptr2 + ctx->context_len;
if (ctx->context_len) {
context = (CK_BYTE *)malloc(ctx->context_len);
if (! context) {
return (CKR_HOST_MEMORY);
}
(void) memcpy(context, ptr2, ctx->context_len);
}
if (ctx->mech.ulParameterLen) {
mech_param = (CK_BYTE *)malloc(
ctx->mech.ulParameterLen);
if (! mech_param) {
if (context)
free(context);
return (CKR_HOST_MEMORY);
}
(void) memcpy(mech_param, ptr3,
ctx->mech.ulParameterLen);
}
}
break;
case STATE_SIGN:
case STATE_VERIFY:
{
void *cptr = data + sizeof (OP_STATE_DATA);
SIGN_VERIFY_CONTEXT *ctx = (SIGN_VERIFY_CONTEXT *)cptr;
len = sizeof (SIGN_VERIFY_CONTEXT) +
ctx->context_len + ctx->mech.ulParameterLen;
if (len != op_data->data_len) {
return (CKR_SAVED_STATE_INVALID);
}
if (auth_key == 0) {
return (CKR_KEY_NEEDED);
}
if (encr_key != 0) {
return (CKR_KEY_NOT_NEEDED);
}
ptr1 = (CK_BYTE *)ctx;
ptr2 = ptr1 + sizeof (SIGN_VERIFY_CONTEXT);
ptr3 = ptr2 + ctx->context_len;
if (ctx->context_len) {
context = (CK_BYTE *)malloc(ctx->context_len);
if (! context) {
return (CKR_HOST_MEMORY);
}
(void) memcpy(context, ptr2, ctx->context_len);
}
if (ctx->mech.ulParameterLen) {
mech_param = (CK_BYTE *)malloc(
ctx->mech.ulParameterLen);
if (! mech_param) {
if (context)
free(context);
return (CKR_HOST_MEMORY);
}
(void) memcpy(mech_param, ptr3,
ctx->mech.ulParameterLen);
}
}
break;
case STATE_DIGEST:
{
void *cptr = data + sizeof (OP_STATE_DATA);
DIGEST_CONTEXT *ctx = (DIGEST_CONTEXT *)cptr;
len = sizeof (DIGEST_CONTEXT) +
ctx->context_len + ctx->mech.ulParameterLen;
if (len != op_data->data_len) {
return (CKR_SAVED_STATE_INVALID);
}
if (auth_key != 0) {
return (CKR_KEY_NOT_NEEDED);
}
if (encr_key != 0) {
return (CKR_KEY_NOT_NEEDED);
}
ptr1 = (CK_BYTE *)ctx;
ptr2 = ptr1 + sizeof (DIGEST_CONTEXT);
ptr3 = ptr2 + ctx->context_len;
if (ctx->context_len) {
context = (CK_BYTE *)malloc(ctx->context_len);
if (! context) {
return (CKR_HOST_MEMORY);
}
(void) memcpy(context, ptr2, ctx->context_len);
}
if (ctx->mech.ulParameterLen) {
mech_param = (CK_BYTE *)malloc(
ctx->mech.ulParameterLen);
if (! mech_param) {
if (context)
free(context);
return (CKR_HOST_MEMORY);
}
(void) memcpy(mech_param, ptr3,
ctx->mech.ulParameterLen);
}
}
break;
default:
return (CKR_SAVED_STATE_INVALID);
}
if (sess->encr_ctx.active)
(void) encr_mgr_cleanup(&sess->encr_ctx);
if (sess->decr_ctx.active)
(void) decr_mgr_cleanup(&sess->decr_ctx);
if (sess->digest_ctx.active)
(void) digest_mgr_cleanup(&sess->digest_ctx);
if (sess->sign_ctx.active)
(void) sign_mgr_cleanup(&sess->sign_ctx);
if (sess->verify_ctx.active)
(void) verify_mgr_cleanup(&sess->verify_ctx);
switch (op_data->active_operation) {
case STATE_ENCR:
(void) memcpy(&sess->encr_ctx, ptr1,
sizeof (ENCR_DECR_CONTEXT));
sess->encr_ctx.key = encr_key;
sess->encr_ctx.context = context;
sess->encr_ctx.mech.pParameter = mech_param;
break;
case STATE_DECR:
(void) memcpy(&sess->decr_ctx, ptr1,
sizeof (ENCR_DECR_CONTEXT));
sess->decr_ctx.key = encr_key;
sess->decr_ctx.context = context;
sess->decr_ctx.mech.pParameter = mech_param;
break;
case STATE_SIGN:
(void) memcpy(&sess->sign_ctx, ptr1,
sizeof (SIGN_VERIFY_CONTEXT));
sess->sign_ctx.key = auth_key;
sess->sign_ctx.context = context;
sess->sign_ctx.mech.pParameter = mech_param;
break;
case STATE_VERIFY:
(void) memcpy(&sess->verify_ctx, ptr1,
sizeof (SIGN_VERIFY_CONTEXT));
sess->verify_ctx.key = auth_key;
sess->verify_ctx.context = context;
sess->verify_ctx.mech.pParameter = mech_param;
break;
case STATE_DIGEST:
(void) memcpy(&sess->digest_ctx, ptr1,
sizeof (DIGEST_CONTEXT));
sess->digest_ctx.context.ref = context;
sess->digest_ctx.mech.pParameter = mech_param;
break;
}
return (CKR_OK);
}
CK_BBOOL
pin_expired(CK_SESSION_INFO *si, CK_FLAGS flags)
{
if ((flags & CKF_SO_PIN_TO_BE_CHANGED) &&
(si->state == CKS_RW_SO_FUNCTIONS))
return (TRUE);
return ((flags & CKF_USER_PIN_TO_BE_CHANGED) &&
((si->state == CKS_RO_USER_FUNCTIONS) ||
(si->state == CKS_RW_USER_FUNCTIONS)));
}
CK_BBOOL
pin_locked(CK_SESSION_INFO *si, CK_FLAGS flags) {
if ((flags & CKF_SO_PIN_LOCKED) &&
(si->state == CKS_RW_SO_FUNCTIONS))
return (TRUE);
return ((flags & CKF_USER_PIN_LOCKED) &&
((si->state == CKS_RO_USER_FUNCTIONS) ||
(si->state == CKS_RW_USER_FUNCTIONS)));
}
void
set_login_flags(CK_USER_TYPE userType, CK_FLAGS *flags) {
if (userType == CKU_USER) {
if (*flags & CKF_USER_PIN_FINAL_TRY) {
*flags |= CKF_USER_PIN_LOCKED;
*flags &= ~(CKF_USER_PIN_FINAL_TRY);
} else if (*flags & CKF_USER_PIN_COUNT_LOW) {
*flags |= CKF_USER_PIN_FINAL_TRY;
*flags &= ~(CKF_USER_PIN_COUNT_LOW);
} else {
*flags |= CKF_USER_PIN_COUNT_LOW;
}
} else {
if (*flags & CKF_SO_PIN_FINAL_TRY) {
*flags |= CKF_SO_PIN_LOCKED;
*flags &= ~(CKF_SO_PIN_FINAL_TRY);
} else if (*flags & CKF_SO_PIN_COUNT_LOW) {
*flags |= CKF_SO_PIN_FINAL_TRY;
*flags &= ~(CKF_SO_PIN_COUNT_LOW);
} else {
*flags |= CKF_SO_PIN_COUNT_LOW;
}
}
}