int p11_add_slot_object(P11_SLOT *pSlot, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_BBOOL bToken, CK_ULONG type, CK_ULONG id, CK_BBOOL bPrivate, CK_ULONG *phObject) { int ret = CKR_OK; P11_OBJECT *pObject = NULL; //unsigned int hObject = 0; *phObject = 0; ret = p11_new_slot_object(pSlot, phObject); if ((ret != 0) || (*phObject == 0)) { log_trace(WHERE, "E: could not add new slot object during init of objects"); return(ret); } pObject = p11_get_slot_object(pSlot, *phObject); //add room for attributes as in template pObject->pAttr = (CK_ATTRIBUTE_PTR) malloc(ulCount * sizeof(CK_ATTRIBUTE)); if (pObject->pAttr == NULL) { log_trace(WHERE, "E: alloc error for attribute"); return (CKR_HOST_MEMORY); } //set the size of the object attributes pObject->count = ulCount; //copy the template to the new object ret = p11_copy_object(pTemplate, ulCount, pObject->pAttr); if (ret) { log_trace(WHERE, "E: p11_copy_object() returned %d", ret); goto cleanup; } //CKA_TOKEN ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_TOKEN, (CK_VOID_PTR) &bToken, sizeof(CK_BBOOL)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_TOKEN) returned %d", ret); goto cleanup; } //CKA_CLASS ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_CLASS, (CK_VOID_PTR) &type, sizeof(CK_ULONG)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_CLASS) returned %d", ret); goto cleanup; } //CKA_ID ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_ID, (CK_VOID_PTR) &id, sizeof(CK_ULONG)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_ID) returned %d", ret); goto cleanup; } //CKA_PRIVATE ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_PRIVATE, (CK_VOID_PTR) &bPrivate, sizeof(CK_BBOOL)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_PRIVATE) returned %d", ret); goto cleanup; } cleanup: return (ret); }
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 */ { P11_SESSION *pSession = NULL; P11_FIND_DATA *pData = NULL; int ret; CK_ULONG *pclass = NULL; CK_ULONG len = 0; CK_BBOOL addIdObjects = CK_FALSE; CK_BYTE filesToCacheFlag = CACHED_DATA_TYPE_ALL; CK_BYTE allowCardRead = P11_DISPLAY_NO; log_trace(WHERE, "I: enter"); if (p11_get_init() != BEIDP11_INITIALIZED) { log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED"); return (CKR_CRYPTOKI_NOT_INITIALIZED); } ret = p11_lock(); if (ret != CKR_OK) return ret; log_trace(WHERE, "S: C_FindObjectsInit(session %d)", hSession); if (ulCount == 0) log_trace(WHERE, "I: empty template => search all objects"); else log_template("I: Search template:", pTemplate, ulCount); /* add check here to avoid useless calls to C_FindObjects() */ /* reason to add this is that e.g. Firefox for every certificate in its store starts a find operation with CKA_CLASS_TYPE */ /* that is unknown by this implementation */ /* CKA_CLASS_TYPE we support is only CKO_CERTIFICATE, CKO_PRIVATE_KEY and CKO_PUBLIC_KEY */ /* Sun-PKCS11 cannot handle CKR_ATTRIBUTE_VALUE_INVALID properly so => initialize search and findObjects will just return 0 matching objects in case of CKO_DATA */ if (ulCount) { ret = p11_get_attribute_value(pTemplate, ulCount, CKA_CLASS, (CK_VOID_PTR *) &pclass, &len); if ( (ret == 0) && (len == sizeof(CK_ULONG) ) ) { //CKO_SECRET_KEY is not supported but for SUN-PKCS11 we allow a search that will result in 0 objects if ( (*pclass != CKO_CERTIFICATE) && (*pclass != CKO_PRIVATE_KEY) && (*pclass != CKO_PUBLIC_KEY) && (*pclass != CKO_SECRET_KEY) && (*pclass != CKO_DATA)) { log_trace(WHERE, "I: CKA_CLASS (%0x) not supported by this PKCS11 module", *pclass); ret = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } else if (*pclass == CKO_DATA) { addIdObjects = CK_TRUE; } } //We only return the CKO_DATA objects when specifically asked for, this to prevent webbrowsers //to read the entire carddata, while they only need the certificates. //(e.g. we saw firefox do a C_FindObjectsInit with only the auth cert's CKA_VALUE and its value // in the template) //else if (len == 0)// no CKA_CLASS attribute in the template //{ // addIdObjects = CK_TRUE; //} } //see comment above, We only return the CKO_DATA objects when specifically asked for //else //{ // addIdObjects = CK_TRUE; //} ret = p11_get_session(hSession, &pSession); // if (pSession == NULL) if (ret) { log_trace(WHERE, "E: Invalid session (%d) (%s)", hSession, log_map_error(ret)); //if (ret == CKR_DEVICE_REMOVED) //ret = CKR_SESSION_HANDLE_INVALID; //ret = CKR_FUNCTION_FAILED; goto cleanup; } //is there an active search operation for this session if (pSession->Operation[P11_OPERATION_FIND].active) { log_trace(WHERE, "W: Session %d: search operation allready exists", hSession); ret = CKR_OPERATION_ACTIVE; goto cleanup; } if(addIdObjects == CK_TRUE) { //parse the search template CK_UTF8CHAR* pLabel; CK_UTF8CHAR* pObjectID; ret = p11_get_attribute_value(pTemplate, ulCount, CKA_OBJECT_ID, (CK_VOID_PTR *) &pObjectID, &len); if ( (ret == 0) && (len > 0 ) ) { SetParseFlagByObjectID(&filesToCacheFlag,pObjectID,len); } else { ret = p11_get_attribute_value(pTemplate, ulCount, CKA_LABEL, (CK_VOID_PTR *) &pLabel, &len); if ( (ret == 0) && (len > 0 ) ) { SetParseFlagByLabel(&filesToCacheFlag,pLabel,len); } } if((filesToCacheFlag != CACHED_DATA_TYPE_CARDDATA) && (filesToCacheFlag != CACHED_DATA_TYPE_RNCERT)) { if ((pSession->bReadDataAllowed == P11_READDATA_ASK) & (eidmw_readpermission != P11_READDATA_ALWAYS)) { allowCardRead = AllowCardReading(); switch(allowCardRead) { case P11_DISPLAY_YES: pSession->bReadDataAllowed = P11_READDATA_ALLOWED; break; case P11_DISPLAY_ALWAYS: pSession->bReadDataAllowed = P11_READDATA_ALLOWED; eidmw_readpermission = P11_READDATA_ALWAYS; //allowed for as long as this pkcs11 instance exists, put it in some variable log_trace(WHERE, "I: Al reading from the card"); break; case P11_DISPLAY_NO: //keep asking //case P11_DISPLAY_NEVER: //pSession->bReadDataAllowed = P11_READDATA_REFUSED; default: log_trace(WHERE, "I: User does not allow reading from the card"); ret = CKR_FUNCTION_FAILED; goto cleanup; break; } } else if (pSession->bReadDataAllowed == P11_READDATA_REFUSED) { log_trace(WHERE, "I: User did not allow reading from the card during this session"); ret = CKR_FUNCTION_FAILED; goto cleanup; } } } /* init search operation */ pData = (P11_FIND_DATA *)pSession->Operation[P11_OPERATION_FIND].pData; if(pData == NULL) { pSession->Operation[P11_OPERATION_FIND].pData = (P11_FIND_DATA *) malloc (sizeof(P11_FIND_DATA)); pData = (P11_FIND_DATA *)pSession->Operation[P11_OPERATION_FIND].pData; if (pData == NULL) { log_trace( WHERE, "E: error allocating memory"); ret = CKR_HOST_MEMORY; goto cleanup; } } //first handle = 1 pData->hCurrent = 1; pData->pSearch = NULL; pData->size = 0; //keep search template if at least one entry in the search template if (ulCount > 0) { pData->pSearch = (CK_ATTRIBUTE_PTR) malloc(sizeof(CK_ATTRIBUTE)*ulCount); if (pData->pSearch == NULL) { log_trace(WHERE, "E: error allocating memory for object search template()"); ret = CKR_HOST_MEMORY; goto cleanup; } memset(pData->pSearch,0,sizeof(CK_ATTRIBUTE)*ulCount); ret = p11_copy_object(pTemplate, ulCount, pData->pSearch); if (ret) { log_trace(WHERE, "E: p11_copy_object() returned %d", ret); goto cleanup; } } pData->size = ulCount; //set search operation to active state since there can be only one pSession->Operation[P11_OPERATION_FIND].active = 1; if ( addIdObjects ) { //check if the data isn't cached already if( ((filesToCacheFlag != CACHED_DATA_TYPE_ALL) && ((pSession->bCardDataCashed & filesToCacheFlag) == FALSE)) || ((filesToCacheFlag == CACHED_DATA_TYPE_ALL) && (pSession->bCardDataCashed != CACHED_DATA_TYPE_ALL)) ) { CK_ULONG counter = 0; CK_ULONG flagsToCheckListLen = 6; CK_BYTE flagsToCheckList[6] = {CACHED_DATA_TYPE_ID,CACHED_DATA_TYPE_ADDRESS,CACHED_DATA_TYPE_PHOTO, CACHED_DATA_TYPE_RNCERT,CACHED_DATA_TYPE_SIGN_DATA_FILE,CACHED_DATA_TYPE_SIGN_ADDRESS_FILE}; switch(filesToCacheFlag) { case CACHED_DATA_TYPE_ALL: //cache and parse whatever isn't cached already //first check if carddata is cashed already, if not parse and cache it if( (pSession->bCardDataCashed & CACHED_DATA_TYPE_CARDDATA) == 0){ ret = cal_get_card_data(pSession->hslot); if (ret != 0){ log_trace(WHERE, "E: cal_read_ID_files() returned %d", ret); goto cleanup; } } //check which other files are cached already, parse and cache those that aren't while(counter < flagsToCheckListLen){ ret = cal_read_ID_files(pSession->hslot,flagsToCheckList[counter]); if (ret != 0){ log_trace(WHERE, "E: cal_read_ID_files() returned %d", ret); goto cleanup; } counter++; } break; case CACHED_DATA_TYPE_CARDDATA: //cache and parse only the carddata ret = cal_get_card_data(pSession->hslot); if (ret != 0){ log_trace(WHERE, "E: cal_read_ID_files() returned %d", ret); goto cleanup; } break; default: //cache and parse only the requested file type ret = cal_read_ID_files(pSession->hslot,filesToCacheFlag); if (ret != 0){ log_trace(WHERE, "E: cal_read_ID_files() returned %d", ret); goto cleanup; } } //remember the file(s) we cashed pSession->bCardDataCashed |= filesToCacheFlag; } } ret = CKR_OK; cleanup: p11_unlock(); return ret; }
CK_RV p11_add_slot_ID_object(P11_SLOT *pSlot, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_BBOOL bToken, CK_ULONG type, CK_BBOOL bPrivate, CK_ULONG *phObject, CK_VOID_PTR plabel, CK_ULONG labelLen, CK_VOID_PTR pvalue, CK_ULONG valueLen, CK_VOID_PTR pobjectID, CK_ULONG objectIDLen) { CK_RV ret = CKR_OK; P11_OBJECT *pObject = NULL; //unsigned int hObject = 0; *phObject = 0; ret = p11_new_slot_object(pSlot, phObject); if ((ret != CKR_OK) || (*phObject == 0)) { log_trace(WHERE, "E: could not add new slot object during init of objects"); return(ret); } pObject = p11_get_slot_object(pSlot, *phObject); //add room for attributes as in template pObject->pAttr = (CK_ATTRIBUTE_PTR) malloc(ulCount * sizeof(CK_ATTRIBUTE)); if (pObject->pAttr == NULL) { log_trace(WHERE, "E: alloc error for attribute"); return (CKR_HOST_MEMORY); } memset(pObject->pAttr, 0, ulCount * sizeof(CK_ATTRIBUTE)); //set the size of the object attributes pObject->count = ulCount; //copy the template to the new object ret = p11_copy_object(pTemplate, ulCount, pObject->pAttr); if (ret) { log_trace(WHERE, "E: p11_copy_object() returned %d", ret); goto cleanup; } //CKA_TOKEN ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_TOKEN, (CK_VOID_PTR) &bToken, sizeof(CK_BBOOL)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_TOKEN) returned %d", ret); goto cleanup; } //CKA_CLASS ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_CLASS, (CK_VOID_PTR) &type, sizeof(CK_ULONG)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_CLASS) returned %d", ret); goto cleanup; } //CKA_PRIVATE ret = p11_set_attribute_value(pObject->pAttr, ulCount, CKA_PRIVATE, (CK_VOID_PTR) &bPrivate, sizeof(CK_BBOOL)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_PRIVATE) returned %d", ret); goto cleanup; } //CKA_LABEL ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_LABEL, plabel, labelLen); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_LABEL) returned %d", ret); goto cleanup; } //CKA_VALUE ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_VALUE, pvalue, valueLen); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_VALUE) returned %d", ret); goto cleanup; } //CKA_VALUE_LEN ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_VALUE_LEN, &valueLen, sizeof(CK_ULONG)); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_VALUE_LEN) returned %d", ret); goto cleanup; } //CKA_OBJECT_ID ret = p11_set_attribute_value(pObject->pAttr, pObject->count, CKA_OBJECT_ID, pobjectID, objectIDLen); if (ret) { log_trace(WHERE, "E: p11_set_attribute_value(CKA_OBJECT_ID) returned %d", ret); goto cleanup; } pObject->state=P11_CACHED; cleanup: return (ret); }