예제 #1
0
파일: p11.c 프로젝트: 12019/svn.gov.pt
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);
}
예제 #2
0
파일: object.c 프로젝트: Frederikus/eid-mw
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;
}
예제 #3
0
파일: p11.c 프로젝트: Frederikus/eid-mw
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);
}