CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ CK_OBJECT_HANDLE hKey) /* handle of the signature key */ { CK_BBOOL can_sign; CK_KEY_TYPE key_type; CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) }; CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hKey, (void**) &object); if (rv != CKR_OK) goto out; if (object->ops->sign == NULL_PTR) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = object->ops->get_attribute(session, object, &sign_attribute); if (rv != CKR_OK || !can_sign) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = object->ops->get_attribute(session, object, &key_type_attr); if (rv != CKR_OK) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } /* XXX: need to tell the signature algorithm that we want * to recover the signature */ sc_debug(context, "SignRecover operation initialized\n"); rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type); out: sc_debug(context, "Sign initialization returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ CK_OBJECT_HANDLE hKey) /* handle of the verification key */ { #ifndef ENABLE_OPENSSL return CKR_FUNCTION_NOT_SUPPORTED; #else #if 0 CK_BBOOL can_verify; CK_ATTRIBUTE verify_attribute = { CKA_VERIFY, &can_verify, sizeof(can_verify) }; #endif CK_KEY_TYPE key_type; CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hKey, (void**) &object); if (rv != CKR_OK) goto out; #if 0 rv = object->ops->get_attribute(session, object, &verify_attribute); if (rv != CKR_OK || !can_verify) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } #endif rv = object->ops->get_attribute(session, object, &key_type_attr); if (rv != CKR_OK) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type); out: sc_debug(context, "Verify initialization returns %d\n", rv); sc_pkcs11_unlock(); return rv; #endif }
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject) /* the object's handle */ { struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; char object_name[64]; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; snprintf(object_name, sizeof(object_name), "C_DestroyObject : Object %lu", (unsigned long) hObject); sc_debug( context, object_name ); rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find_and_delete(&session->slot->object_pool, hObject, (void**) &object); if (rv != CKR_OK) goto out; if (object->ops->destroy_object == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else rv = object->ops->destroy_object(session, object); out: sc_pkcs11_unlock(); return rv; }
CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* the signature to be verified */ CK_ULONG ulSignatureLen) /* count of bytes of signature */ { #ifndef ENABLE_OPENSSL return CKR_FUNCTION_NOT_SUPPORTED; #else struct sc_pkcs11_session *session; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen); out: sc_debug(context, "C_VerifyFinal returns %d\n", rv); sc_pkcs11_unlock(); return rv; #endif }
CK_RV C_Verify(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* plaintext data (digest) to compare */ CK_ULONG ulDataLen, /* length of data (digest) in bytes */ CK_BYTE_PTR pSignature, /* the signature to be verified */ CK_ULONG ulSignatureLen) /* count of bytes of signature */ { #ifndef ENABLE_OPENSSL return CKR_FUNCTION_NOT_SUPPORTED; #else int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = sc_pkcs11_verif_update(session, pData, ulDataLen); if (rv == CKR_OK) rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen); out: sc_debug(context, "Verify result was %d\n", rv); sc_pkcs11_unlock(); return rv; #endif }
CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSeed, /* the seed material */ CK_ULONG ulSeedLen) /* count of bytes of seed material */ { struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) { slot = session->slot; if (slot->card->framework->get_random == NULL) rv = CKR_RANDOM_NO_RNG; else if (slot->card->framework->seed_random == NULL) rv = CKR_RANDOM_SEED_NOT_SUPPORTED; else rv = slot->card->framework->seed_random(slot->card, pSeed, ulSeedLen); } sc_pkcs11_unlock(); return rv; }
CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phObject) /* receives new object's handle. */ { struct sc_pkcs11_session *session; struct sc_pkcs11_card *card; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; dump_template("C_CreateObject()", pTemplate, ulCount); rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; card = session->slot->card; if (card->framework->create_object == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else rv = card->framework->create_object(card, session->slot, pTemplate, ulCount, phObject); out: sc_pkcs11_unlock(); return rv; }
CK_RV C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* data to be digested */ CK_ULONG ulDataLen, /* bytes of data to be digested */ CK_BYTE_PTR pDigest, /* receives the message digest */ CK_ULONG_PTR pulDigestLen) /* receives byte length of digest */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = sc_pkcs11_md_update(session, pData, ulDataLen); if (rv == CKR_OK) rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen); out: sc_debug(context, "C_Digest returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ CK_OBJECT_HANDLE hKey) /* handle of the decryption key */ { CK_BBOOL can_decrypt; CK_KEY_TYPE key_type; CK_ATTRIBUTE decrypt_attribute = { CKA_DECRYPT, &can_decrypt, sizeof(can_decrypt) }; CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hKey, (void**) &object); if (rv != CKR_OK) goto out; if (object->ops->decrypt == NULL_PTR) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = object->ops->get_attribute(session, object, &decrypt_attribute); if (rv != CKR_OK || !can_decrypt) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = object->ops->get_attribute(session, object, &key_type_attr); if (rv != CKR_OK) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type); out: sc_debug(context, "Decrypt initialization returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the unwrapping mechanism */ CK_OBJECT_HANDLE hUnwrappingKey, /* handle of the unwrapping key */ CK_BYTE_PTR pWrappedKey, /* the wrapped key */ CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key */ CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */ CK_ULONG ulAttributeCount, /* # of attributes in template */ CK_OBJECT_HANDLE_PTR phKey) /* gets handle of recovered key */ { struct sc_pkcs11_session *session; struct sc_pkcs11_object *object, *result; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hUnwrappingKey, (void**) &object); if (rv != CKR_OK) goto out; if (object->ops->sign == NULL_PTR) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; } rv = object->ops->unwrap_key(session, object, pMechanism, pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, (void **) &result); sc_debug(context, "Unwrapping result was %d\n", rv); if (rv == CKR_OK) rv = pool_insert(&session->slot->object_pool, result, phKey); out: sc_pkcs11_unlock(); return rv; }
int pool_addref(pool_t *pool, void *ptr) { pool_node_t *p; if( !ptr ) return 0; p = pool_find(pool, ptr); if( p ) { p->refcount++; } return p ? p->refcount : 0; }
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes and values */ CK_ULONG ulCount) /* attributes in template */ { int rv; unsigned int i; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; dump_template("C_SetAttributeValue", pTemplate, ulCount); rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hObject, (void**) &object); if (rv != CKR_OK) goto out; if (object->ops->set_attribute == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else { for (i = 0; i < ulCount; i++) { rv = object->ops->set_attribute(session, object, &pTemplate[i]); if (rv != CKR_OK) break; } } out: sc_pkcs11_unlock(); return rv; }
static void* pool_allocate(struct caml_heap_state* local, sizeclass sz) { pool* r = pool_find(local, sz); if (!r) return 0; value* p = r->next_obj; value* next = (value*)p[1]; r->next_obj = next; Assert(p[0] == 0); if (!next) { local->avail_pools[sz] = r->next; r->next = local->full_pools[sz]; local->full_pools[sz] = r; } Assert(r->next_obj == 0 || *r->next_obj == 0); return p; }
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism) /* the digesting mechanism */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) rv = sc_pkcs11_md_init(session, pMechanism); sc_debug(context, "C_DigestInit returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* the data (digest) to be signed */ CK_ULONG ulPartLen) /* count of bytes to be signed */ { struct sc_pkcs11_session *session; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) rv = sc_pkcs11_sign_update(session, pPart, ulPartLen); sc_debug(context, "C_SignUpdate returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pDigest, /* receives the message digest */ CK_ULONG_PTR pulDigestLen) /* receives byte count of digest */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen); sc_debug(context, "C_DigestFinal returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* data to be digested */ CK_ULONG ulPartLen) /* bytes of data to be digested */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) rv = sc_pkcs11_md_update(session, pPart, ulPartLen); sc_debug(context, "C_DigestUpdate returns %d\n", rv); sc_pkcs11_unlock(); return rv; }
void pool_free(pool_t *pool, void *ptr) { pool_node_t *p; if( !ptr ) return; p = pool_find(pool, ptr); if( p ) { p->refcount--; if(p->refcount <= 0 ) { if( p->free ) { (*p->free)(p->ptr, p->arg); } else { free(p->ptr); } pool_remove(pool, ptr); } } }
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND, NULL); if (rv == CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_FIND); out: sc_pkcs11_unlock(); return rv; }
CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* the data (digest) to be signed */ CK_ULONG ulDataLen, /* count of bytes to be signed */ CK_BYTE_PTR pSignature, /* receives the signature */ CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */ { int rv; struct sc_pkcs11_session *session; CK_ULONG length; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; /* According to the pkcs11 specs, we must not do any calls that * change our crypto state if the caller is just asking for the * signature buffer size, or if the result would be * CKR_BUFFER_TOO_SMALL. Thus we cannot do the sign_update call * below. */ if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK) goto out; if (pSignature == NULL || length > *pulSignatureLen) { *pulSignatureLen = length; rv = pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK; goto out; } rv = sc_pkcs11_sign_update(session, pData, ulDataLen); if (rv == CKR_OK) rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen); out: sc_debug(context, "Signing result was %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE_PTR phObject, /* receives object handle array */ CK_ULONG ulMaxObjectCount, /* max handles to be returned */ CK_ULONG_PTR pulObjectCount) /* actual number returned */ { int rv; CK_ULONG to_return; struct sc_pkcs11_session *session; struct sc_pkcs11_find_operation *operation; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND, (sc_pkcs11_operation_t **) &operation); if (rv != CKR_OK) goto out; to_return = (CK_ULONG)operation->num_handles - operation->current_handle; if (to_return > ulMaxObjectCount) to_return = ulMaxObjectCount; *pulObjectCount = to_return; memcpy(phObject, &operation->handles[operation->current_handle], to_return * sizeof(CK_OBJECT_HANDLE)); operation->current_handle += to_return; out: sc_pkcs11_unlock(); return rv; }
CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* plaintext data (digest) to compare */ CK_ULONG ulPartLen) /* length of data (digest) in bytes */ { #ifndef ENABLE_OPENSSL return CKR_FUNCTION_NOT_SUPPORTED; #else struct sc_pkcs11_session *session; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) rv = sc_pkcs11_verif_update(session, pPart, ulPartLen); sc_debug(context, "C_VerifyUpdate returns %d\n", rv); sc_pkcs11_unlock(); return rv; #endif }
CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pEncryptedData, /* input encrypted data */ CK_ULONG ulEncryptedDataLen, /* count of bytes of input */ CK_BYTE_PTR pData, /* receives decrypted output */ CK_ULONG_PTR pulDataLen) /* receives decrypted byte count */ { int rv; struct sc_pkcs11_session *session; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = sc_pkcs11_decr(session, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen); out: sc_debug(context, "Decryption result was %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the key gen. mech. */ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* pub. attr. template */ CK_ULONG ulPublicKeyAttributeCount, /* # of pub. attrs. */ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* priv. attr. template */ CK_ULONG ulPrivateKeyAttributeCount, /* # of priv. attrs. */ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ CK_OBJECT_HANDLE_PTR phPrivateKey) /* gets priv. key handle */ { struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; dump_template("C_CreateObject(), PrivKey attrs", pPrivateKeyTemplate, ulPrivateKeyAttributeCount); dump_template("C_CreateObject(), PubKey attrs", pPublicKeyTemplate, ulPublicKeyAttributeCount); rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; slot = session->slot; if (slot->card->framework->gen_keypair == NULL) { rv = CKR_FUNCTION_NOT_SUPPORTED; } else { rv = slot->card->framework->gen_keypair(slot->card, slot, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); } out: sc_pkcs11_unlock(); return rv; }
CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR RandomData, /* receives the random data */ CK_ULONG ulRandomLen) /* number of bytes to be generated */ { struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv == CKR_OK) { slot = session->slot; if (slot->card->framework->get_random == NULL) rv = CKR_RANDOM_NO_RNG; else rv = slot->card->framework->get_random(slot->card, RandomData, ulRandomLen); } sc_pkcs11_unlock(); return rv; }
CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* receives the signature */ CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */ { struct sc_pkcs11_session *session; CK_ULONG length; int rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; /* According to the pkcs11 specs, we must not do any calls that * change our crypto state if the caller is just asking for the * signature buffer size, or if the result would be * CKR_BUFFER_TOO_SMALL. */ if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK) goto out; if (pSignature == NULL || length > *pulSignatureLen) { *pulSignatureLen = length; rv = pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK; } else { rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen); } out: sc_debug(context, "C_SignFinal returns %d\n", rv); 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_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_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */ CK_ULONG ulCount) /* attributes in template */ { static int precedence[] = { CKR_OK, CKR_BUFFER_TOO_SMALL, CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_SENSITIVE, -1 }; char object_name[64]; int j, rv; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; int res, res_type; unsigned int i; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; rv = pool_find(&session->slot->object_pool, hObject, (void**) &object); if (rv != CKR_OK) goto out; /* Debug printf */ snprintf(object_name, sizeof(object_name), "Object %lu", (unsigned long) hObject); res_type = 0; for (i = 0; i < ulCount; i++) { res = object->ops->get_attribute(session, object, &pTemplate[i]); if (res != CKR_OK) pTemplate[i].ulValueLen = (CK_ULONG) -1; dump_template(object_name, &pTemplate[i], 1); /* the pkcs11 spec has complicated rules on * what errors take precedence: * CKR_ATTRIBUTE_SENSITIVE * CKR_ATTRIBUTE_INVALID * CKR_BUFFER_TOO_SMALL * It does not exactly specify how other errors * should be handled - we give them highest * precedence */ for (j = 0; precedence[j] != -1; j++) { if (precedence[j] == res) break; } if (j > res_type) { res_type = j; rv = res; } } out: sc_pkcs11_unlock(); return rv; }