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 */ CK_RV rv; struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; if (pMechanism == NULL_PTR || (pPublicKeyTemplate == NULL_PTR && ulPublicKeyAttributeCount > 0) || (pPrivateKeyTemplate == NULL_PTR && ulPrivateKeyAttributeCount > 0)) return CKR_ARGUMENTS_BAD; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; dump_template(SC_LOG_DEBUG_NORMAL, "C_GenerateKeyPair(), PrivKey attrs", pPrivateKeyTemplate, ulPrivateKeyAttributeCount); dump_template(SC_LOG_DEBUG_NORMAL, "C_GenerateKeyPair(), PubKey attrs", pPublicKeyTemplate, ulPublicKeyAttributeCount); rv = get_session(hSession, &session); if (rv != CKR_OK) goto out; if (!(session->flags & CKF_RW_SESSION)) { rv = CKR_SESSION_READ_ONLY; goto out; } slot = session->slot; if (slot->p11card->framework->gen_keypair == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else { rv = restore_login_state(slot); if (rv == CKR_OK) rv = slot->p11card->framework->gen_keypair(slot, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); rv = reset_login_state(session->slot, rv); } out: 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; }
/* * Helper function to compare attributes on any sort of object */ int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK_ATTRIBUTE_PTR attr) { struct sc_pkcs11_object *object; u8 temp1[1024]; u8 *temp2 = NULL; /* dynamic allocation for large attributes */ CK_ATTRIBUTE temp_attr; int rv, res; object = (struct sc_pkcs11_object *) ptr; temp_attr.type = attr->type; temp_attr.pValue = NULL; temp_attr.ulValueLen = 0; /* Get the length of the attribute */ rv = object->ops->get_attribute(session, object, &temp_attr); if (rv != CKR_OK || temp_attr.ulValueLen != attr->ulValueLen) return 0; if (temp_attr.ulValueLen <= sizeof(temp1)) temp_attr.pValue = temp1; else { temp2 = (u8 *) malloc(temp_attr.ulValueLen); if (temp2 == NULL) return 0; temp_attr.pValue = temp2; } /* Get the attribute */ rv = object->ops->get_attribute(session, object, &temp_attr); if (rv != CKR_OK) { res = 0; goto done; } #ifdef DEBUG { char foo[64]; snprintf(foo, sizeof(foo), "Object %p (slot %d)", object, session->slot->id); dump_template(foo, &temp_attr, 1); } #endif res = temp_attr.ulValueLen == attr->ulValueLen && !memcmp(temp_attr.pValue, attr->pValue, attr->ulValueLen); done: if (temp2 != NULL) free(temp2); return res; }
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; }
/* C_CreateObject can be called from C_DeriveKey * which is holding the sc_pkcs11_lock * So dont get the lock again. */ static CK_RV sc_create_object_int(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. */ int use_lock) { CK_RV rv = CKR_OK; struct sc_pkcs11_session *session; struct sc_pkcs11_card *card; LOG_FUNC_CALLED(context); if (pTemplate == NULL_PTR || ulCount == 0) return CKR_ARGUMENTS_BAD; if (use_lock) { rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; } dump_template(SC_LOG_DEBUG_NORMAL, "C_CreateObject()", pTemplate, ulCount); session = list_seek(&sessions, &hSession); if (!session) { rv = CKR_SESSION_HANDLE_INVALID; goto out; } #if 0 /* TODO DEE what should we check here */ if (!(session->flags & CKF_RW_SESSION)) { rv = CKR_SESSION_READ_ONLY; goto out; } #endif card = session->slot->card; if (card->framework->create_object == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else rv = card->framework->create_object(session->slot, pTemplate, ulCount, phObject); out: if (use_lock) sc_pkcs11_unlock(); LOG_FUNC_RETURN(context, rv); }
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 */ { CK_RV rv; unsigned int i; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; if (pTemplate == NULL_PTR || ulCount == 0) return CKR_ARGUMENTS_BAD; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; dump_template(SC_LOG_DEBUG_NORMAL, "C_SetAttributeValue", pTemplate, ulCount); rv = get_object_from_session(hSession, hObject, &session, &object); if (rv != CKR_OK) goto out; if (!(session->flags & CKF_RW_SESSION)) { rv = CKR_SESSION_READ_ONLY; 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; }
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; }
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; }
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; }
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; CK_RV rv; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; int res, res_type; unsigned int i; if (pTemplate == NULL_PTR || ulCount == 0) return CKR_ARGUMENTS_BAD; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = get_object_from_session(hSession, hObject, &session, &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(SC_LOG_DEBUG_NORMAL, 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_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s", hSession, hObject, lookup_enum ( RV_T, rv )); sc_pkcs11_unlock(); return rv; }
/************************************************************************* Name: ias_parm_provide_help Purpose: print out the template or help info Returns: ERROR if an error happens 0 if no help was provided 1 if help was provided *************************************************************************/ int ias_parm_provide_help ( const char *option, /* I: parameter to show help or template */ IAS_PARM_PARAMETER_DEFINITION **params, /* I/O : pointer to list of items to read from the ODL file */ int count, /* I: number of items */ IAS_PARAMETER_SOURCE file_source_type /* I: Type of file source, OMF and Parameter File */ ) { int i; /* Verify the parameter descriptions aren't larger than IAS_PARM_MAX_DESC_LENGTH characters */ for(i = 0; i < count; i++) { if (strlen(params[i]->description) > IAS_PARM_MAX_DESC_LENGTH) { IAS_LOG_ERROR("Parameter description larger than %d characters " "for %s", IAS_PARM_MAX_DESC_LENGTH, params[i]->name); return ERROR; } } /* Output the template data. this data is in the form of an ODL file */ if(strcmp(option, "--template") == 0) { if (file_source_type == IAS_INPUT_PARAMETERS) printf("OBJECT = PARAMETERS\n"); else if (file_source_type == IAS_OMF_PARAMETERS) printf("OBJECT = OMF\n"); else { IAS_LOG_ERROR("Invalid parameter source"); return ERROR; } for(i = 0; i < count; i++) dump_template(params[i]); if (file_source_type == IAS_INPUT_PARAMETERS) printf("END_OBJECT = PARAMETERS\n"); else if (file_source_type == IAS_OMF_PARAMETERS) printf("END_OBJECT = OMF\n"); printf("END\n"); return 1; } /* output from loadtable represents the data to be entered in the database to support a script */ else if(strcmp(option, "--loadtable") == 0) { /* No action if this is OMF */ if (file_source_type == IAS_OMF_PARAMETERS) { return 1; } /* in the loadtable case, there is no need to check the output type */ for(i = 0; i < count; i++) { if (dump_loadtable_parameters(params[i],i) != SUCCESS) { IAS_LOG_ERROR("An error occurred writing load table output " "for the PARAMETERS table"); return ERROR; } } printf("\n"); for(i = 0; i < count; i++) { if (dump_loadtable_parm_edits(params[i],i) != SUCCESS) { IAS_LOG_ERROR("An error occurred writing load table output " "for the PARM_EDITS table"); return ERROR; } } printf("\n"); for(i = 0; i < count; i++) { if (dump_loadtable_parm_list(params[i],i) != SUCCESS) { IAS_LOG_ERROR("An error occurred writing load table output " "for the PARM_LIST table"); return ERROR; } } printf("\n"); for(i = 0; i < count; i++) { if (dump_loadtable_def_parms(params[i],i) != SUCCESS) { IAS_LOG_ERROR("An error occurred writing load table output " "for the DEF_PARMS table"); return ERROR; } } printf("\n"); return 1; } /* The output from help is in a general format desribing the parameters */ else if(strcmp(option, "--help") == 0) { if (file_source_type == IAS_INPUT_PARAMETERS) printf("\n### Application Input Parameters ###\n\n"); else if (file_source_type == IAS_OMF_PARAMETERS) printf("\n### OMF Parameters ###\n\n"); else { IAS_LOG_ERROR("Invalid parameter source"); return ERROR; } for(i = 0; i < count; i++) dump_parameter_definition(params[i]); printf("\n"); return 1; } return 0; }