CK_RV sc_pkcs11_md_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; if (!session || !session->slot || !(p11card = session->slot->card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_DIGEST); if (mt == NULL) return CKR_MECHANISM_INVALID; rv = session_start_operation(session, SC_PKCS11_OPERATION_DIGEST, mt, &operation); if (rv != CKR_OK) return rv; memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->md_init(operation); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST); return rv; }
/* * Initialize a verify context. When we get here, we know * the key object is capable of verifying _something_ */ CK_RV sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; if (!session || !session->slot || !(p11card = session->slot->card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_VERIFY); if (mt == NULL) return CKR_MECHANISM_INVALID; /* See if compatible with key type */ if (mt->key_type != key_type) return CKR_KEY_TYPE_INCONSISTENT; rv = session_start_operation(session, SC_PKCS11_OPERATION_VERIFY, mt, &operation); if (rv != CKR_OK) return rv; memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->verif_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_VERIFY); return rv; }
/* * Initialize a signing context. When we get here, we know * the key object is capable of signing _something_ */ CK_RV sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; LOG_FUNC_CALLED(context); if (!session || !session->slot || !(p11card = session->slot->card)) LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); /* See if we support this mechanism type */ sc_log(context, "mechanism 0x%X, key-type 0x%X", pMechanism->mechanism, key_type); mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_SIGN); if (mt == NULL) LOG_FUNC_RETURN(context, CKR_MECHANISM_INVALID); /* See if compatible with key type */ if (mt->key_type != key_type) LOG_FUNC_RETURN(context, CKR_KEY_TYPE_INCONSISTENT); rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); if (rv != CKR_OK) LOG_FUNC_RETURN(context, rv); memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->sign_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); LOG_FUNC_RETURN(context, rv); }
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ CK_ULONG ulCount) /* attributes in search template */ { CK_BBOOL is_private = TRUE; CK_ATTRIBUTE private_attribute = { CKA_PRIVATE, &is_private, sizeof(is_private) }; int rv, match, hide_private; unsigned int j; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; struct sc_pkcs11_find_operation *operation; struct sc_pkcs11_pool_item *item; struct sc_pkcs11_slot *slot; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; sc_debug(context, "C_FindObjectsInit(slot = %d)\n", session->slot->id); dump_template("C_FindObjectsInit()", pTemplate, ulCount); rv = session_start_operation(session, SC_PKCS11_OPERATION_FIND, &find_mechanism, (struct sc_pkcs11_operation**) &operation); if (rv != CKR_OK) goto out; operation->current_handle = 0; operation->num_handles = 0; slot = session->slot; /* Check whether we should hide private objects */ hide_private = 0; if (slot->login_user != CKU_USER && (slot->token_info.flags & CKF_LOGIN_REQUIRED)) hide_private = 1; /* For each object in token do */ for (item = slot->object_pool.head; item != NULL; item = item->next) { object = (struct sc_pkcs11_object*) item->item; /* User not logged in and private object? */ if (hide_private) { if (object->ops->get_attribute(session, object, &private_attribute) != CKR_OK) continue; if (is_private) { sc_debug(context, "Object %d/%d: Private object and not logged in.\n", slot->id, item->handle); continue; } } /* Try to match every attribute */ match = 1; for (j = 0; j < ulCount; j++) { rv = object->ops->cmp_attribute(session, object, &pTemplate[j]); if (rv == 0) { if (context->debug >= 4) { sc_debug(context, "Object %d/%d: Attribute 0x%x does NOT match.\n", slot->id, item->handle, pTemplate[j].type); } match = 0; break; } if (context->debug >= 4) { sc_debug(context, "Object %d/%d: Attribute 0x%x matches.\n", slot->id, item->handle, pTemplate[j].type); } } if (match) { sc_debug(context, "Object %d/%d matches\n", slot->id, item->handle); /* Avoid buffer overflow --okir */ if (operation->num_handles >= SC_PKCS11_FIND_MAX_HANDLES) { sc_debug(context, "Too many matching objects\n"); break; } operation->handles[operation->num_handles++] = item->handle; } } rv = CKR_OK; sc_debug(context, "%d matching objects\n", operation->num_handles); out: sc_pkcs11_unlock(); return rv; }
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ CK_ULONG ulCount) /* attributes in search template */ { CK_RV rv; CK_BBOOL is_private = TRUE; CK_ATTRIBUTE private_attribute = { CKA_PRIVATE, &is_private, sizeof(is_private) }; int match, hide_private; unsigned int i, j; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; struct sc_pkcs11_find_operation *operation; struct sc_pkcs11_slot *slot; if (pTemplate == NULL_PTR && ulCount > 0) return CKR_ARGUMENTS_BAD; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = get_session(hSession, &session); if (rv != CKR_OK) goto out; sc_log(context, "C_FindObjectsInit(slot = %d)\n", session->slot->id); dump_template(SC_LOG_DEBUG_NORMAL, "C_FindObjectsInit()", pTemplate, ulCount); rv = session_start_operation(session, SC_PKCS11_OPERATION_FIND, &find_mechanism, (struct sc_pkcs11_operation **)&operation); if (rv != CKR_OK) goto out; operation->current_handle = 0; operation->num_handles = 0; operation->allocated_handles = 0; operation->handles = NULL; slot = session->slot; /* Check whether we should hide private objects */ hide_private = 0; if (slot->login_user != CKU_USER && (slot->token_info.flags & CKF_LOGIN_REQUIRED)) hide_private = 1; /* For each object in token do */ for (i=0; i<list_size(&slot->objects); i++) { object = (struct sc_pkcs11_object *)list_get_at(&slot->objects, i); sc_log(context, "Object with handle 0x%lx", object->handle); /* User not logged in and private object? */ if (hide_private) { if (object->ops->get_attribute(session, object, &private_attribute) != CKR_OK) continue; if (is_private) { sc_log(context, "Object %d/%d: Private object and not logged in.", slot->id, object->handle); continue; } } /* Try to match every attribute */ match = 1; for (j = 0; j < ulCount; j++) { rv = object->ops->cmp_attribute(session, object, &pTemplate[j]); if (rv == 0) { sc_log(context, "Object %d/%d: Attribute 0x%x does NOT match.", slot->id, object->handle, pTemplate[j].type); match = 0; break; } if (context->debug >= 4) { sc_log(context, "Object %d/%d: Attribute 0x%x matches.", slot->id, object->handle, pTemplate[j].type); } } if (match) { sc_log(context, "Object %d/%d matches\n", slot->id, object->handle); /* Realloc handles - remove restriction on only 32 matching objects -dee */ if (operation->num_handles >= operation->allocated_handles) { operation->allocated_handles += SC_PKCS11_FIND_INC_HANDLES; sc_log(context, "realloc for %d handles", operation->allocated_handles); operation->handles = realloc(operation->handles, sizeof(CK_OBJECT_HANDLE) * operation->allocated_handles); if (operation->handles == NULL) { rv = CKR_HOST_MEMORY; goto out; } } operation->handles[operation->num_handles++] = object->handle; } } rv = CKR_OK; sc_log(context, "%d matching objects\n", operation->num_handles); out: sc_pkcs11_unlock(); return rv; }