Beispiel #1
0
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */
{
	P11_SESSION *pSession = NULL;
	P11_FIND_DATA *pData = NULL;
	int ret;
	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_FindObjectsFinal(session %d)", hSession);

	ret = p11_get_session(hSession, &pSession);
	if (pSession == NULL || ret != CKR_OK)
		//omit error card removed here since FireFox has a problem with it.
		// if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	if (pSession->Operation[P11_OPERATION_FIND].active == 0)
	{
		log_trace(WHERE, "I: For this session no search operation is active");
		//we return without problem
		ret = CKR_OPERATION_NOT_INITIALIZED;
		goto cleanup;
	}

	//get search template
	pData = (P11_FIND_DATA *) pSession->Operation[P11_OPERATION_FIND].pData;
	if (pData == NULL)
	{
		log_trace(WHERE, "I: For this session no search operation is active");
		//we return without problem
		ret = CKR_OK;
		goto cleanup;
	}
	//free search template
	p11_clean_finddata(pData);	

	//free find operation data
	free(pData);
	pSession->Operation[P11_OPERATION_FIND].pData = NULL;

	pSession->Operation[P11_OPERATION_FIND].active = 0;

	ret = CKR_OK;

cleanup:
	p11_unlock();
	return ret;
}
Beispiel #2
0
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,   /* the session's handle */
                   CK_MECHANISM_PTR  pMechanism) /* the digesting mechanism */
{
   int ret;
   P11_SESSION *pSession = NULL;
   P11_DIGEST_DATA *pDigestData = NULL;

	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, "I: enter, hSession = %i",hSession);

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active digest operation for this session
   if (pSession->Operation[P11_OPERATION_DIGEST].active)
      {
      log_trace(WHERE, "W: Session %d: digest operation allready exists", hSession);
      ret = CKR_OPERATION_ACTIVE;
      goto cleanup;
      }

   /* init search operation */
   if((pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData) == NULL)
      {
      pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData = (P11_DIGEST_DATA *) malloc (sizeof(P11_DIGEST_DATA));
      if (pDigestData == NULL)
         {
         log_trace( WHERE, "E: error allocating memory");
         ret = CKR_HOST_MEMORY;
         }
      }

   memset(pDigestData, 0, sizeof(P11_DIGEST_DATA));
   ret = hash_init(pMechanism, &(pDigestData->phash), &(pDigestData->l_hash));
   if(ret)
      {
      log_trace(WHERE, "E: could not initialize hash()");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }
   pSession->Operation[P11_OPERATION_DIGEST].active = 1;

cleanup:
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);
   return ret;
}
Beispiel #3
0
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE_PTR pMechanismList,
	CK_ULONG_PTR pulCount)
{
	CK_RV ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_GetMechanismList(slot %d)", slotID);

	ret = cal_get_mechanism_list(slotID, pMechanismList,pulCount);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: cal_get_mechanism_list(slotid=%d) returns %s", slotID, log_map_error(ret));
		goto cleanup;
	}

cleanup:

	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #4
0
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 ret;
   P11_SESSION *pSession = NULL;
   P11_DIGEST_DATA *pDigestData = NULL;

	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, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_DIGEST].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no digest operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get digest operation */
   if((pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData) == NULL)
      {
      log_trace( WHERE, "E: no digest operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   ret = hash_update(pDigestData->phash, (char*)pPart, ulPartLen);
   if(ret)
      {
      log_trace(WHERE, "E: hash_update failed()");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

cleanup:
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Beispiel #5
0
CK_RV C_Finalize(CK_VOID_PTR pReserved)
{
	CK_RV ret = CKR_OK;
	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);
	}		

	if (pReserved != NULL)
	{
		log_trace(WHERE, "I: leave, CKR_ARGUMENTS_BAD");
		return (CKR_ARGUMENTS_BAD);
	}

	ret = p11_lock();
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	//g_final = 0; /* Belpic */
	p11_set_init(BEIDP11_DEINITIALIZING);

	//ret = cal_close();
    if (g_aseP11Handle == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - g_aseP11Handle is NULL");
        ret =  CKR_ARGUMENTS_BAD;
    }
    else
    {
        ret = (pFunctions->C_Finalize) (&pReserved);
        if (g_aseP11Handle != NULL)
		{
			dlclose(g_aseP11Handle);
		}

    }

	/* Release and destroy the mutex */
	// mutex might still be in use by C_waitforslotlist

	p11_free_lock();

	p11_set_init(BEIDP11_NOT_INITIALIZED);
	// util_clean_lock(&logmutex);
	log_trace(WHERE, "I: p11_free_lock()");
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #6
0
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
	CK_CHAR_PTR pOldPin,
	CK_ULONG ulOldLen,
	CK_CHAR_PTR pNewPin,
	CK_ULONG ulNewLen)
{
	int ret;
	//P11_SESSION *pSession = NULL;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_SetPIN(session %d)", hSession);

	/*ret = p11_get_session(hSession, &pSession);
	if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	ret = cal_change_pin(pSession->hslot, ulOldLen, pOldPin, ulNewLen, pNewPin);
	*/
    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_SetPIN");
        ret = (pFunctions->C_SetPIN) (hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
    }

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #7
0
CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE type,
	CK_MECHANISM_INFO_PTR pInfo)
{
	CK_RV ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_GetMechanismInfo(slot %d)", slotID);

	if (pInfo == NULL_PTR)
	{
		CLEANUP(CKR_ARGUMENTS_BAD);
	}

	/*ret = cal_get_mechanism_info(slotID, type, pInfo);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: p11_get_mechanism_info(slotid=%d) returns %d", slotID, ret);
		goto cleanup;
	}*/
    if (g_aseP11Handle == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - g_aseP11Handle is NULL");
        CLEANUP(CKR_ARGUMENTS_BAD);
    }

    ret = (pFunctions->C_GetMechanismInfo) ( slotID,  type, pInfo);


cleanup:        
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #8
0
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE_PTR pMechanismList,
	CK_ULONG_PTR pulCount)
{
	CK_RV ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_GetMechanismList(slot %d)", slotID);

	/*ret = cal_get_mechanism_list(slotID, pMechanismList,pulCount);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: cal_get_mechanism_list(slotid=%d) returns %s", slotID, log_map_error(ret));
		goto cleanup;
	}*/
    if (g_aseP11Handle == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - g_aseP11Handle is NULL");
        CLEANUP(CKR_ARGUMENTS_BAD);
    }

    ret = (pFunctions->C_GetMechanismList) ( slotID,  pMechanismList, pulCount);


cleanup:

	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #9
0
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
{
	CK_RV ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_GetTokenInfo(slot %d)", slotID);
	if (pInfo == NULL_PTR) 
	{
		log_trace(WHERE, "E: pInfo = NULL");
		CLEANUP(CKR_ARGUMENTS_BAD);
	}

	ret = cal_get_token_info(slotID, pInfo);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: p11_get_token_info returns %d", ret);
		goto cleanup;
	}

cleanup:        
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #10
0
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */
{
	int ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_CloseAllSessions(slot %d)", slotID);

	//ret = p11_close_all_sessions(slotID);
    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_CloseAllSessions");
        ret = (pFunctions->C_CloseAllSessions) (slotID);
    }

	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #11
0
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 */
{
   CK_RV ret;
   P11_SESSION *pSession = NULL;
   P11_SIGN_DATA *pSignData = NULL;
   char* oldBuf = NULL;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();
	
   log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no sign operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      log_trace( WHERE, "E: no sign operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if (pSignData->phash == NULL)
      {
      if ( (ulPartLen + pSignData->lbuf) > pSignData->l_sign)
         {
         log_trace(WHERE, "E: size not possible for signing");
         ret = CKR_DATA_LEN_RANGE;
         goto cleanup;
         }
	  oldBuf = pSignData->pbuf;
	  pSignData->pbuf = (char*)realloc(pSignData->pbuf, pSignData->lbuf + ulPartLen);

      if (pSignData->pbuf == NULL)
         {
         log_trace(WHERE, "E: memory allocation problem for host");
         ret = CKR_HOST_MEMORY;
		 //old location has not been freed, so do that now
		 if (oldBuf != NULL)
			free(oldBuf);
         goto cleanup;
         }
      //add data
      memcpy(pSignData->pbuf+pSignData->lbuf, pPart, ulPartLen);
      pSignData->lbuf += ulPartLen;
      }
   else
      {
      ret = hash_update(pSignData->phash, (char*)pPart, ulPartLen);
      if (ret)
         {
         log_trace(WHERE, "E: hash_update failed");
         ret = CKR_FUNCTION_FAILED;
         goto cleanup;
         }
      }

cleanup:

   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);
return ret;
}
Beispiel #12
0
CK_RV C_Sign(CK_SESSION_HANDLE hSession,        /* the session's handle */
             CK_BYTE_PTR       pData,           /* the data 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 */
{
   CK_RV ret                  = CKR_OK;
   P11_SESSION*   pSession    = NULL;
   P11_SIGN_DATA* pSignData   = NULL;
   unsigned char* pDigest     = NULL;
   unsigned long  ulDigestLen = 0;
// unsigned int ulSignatureLen = *pulSignatureLen;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no sign operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      log_trace( WHERE, "E: no sign operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if(pSignData->update)
      {
      log_trace(WHERE, "E: C_Sign() cannot be used to finalize a C_SignUpdate() function");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   if (pSignature == NULL)
      {
      /* just return the signature size */
      *pulSignatureLen = pSignData->l_sign;
      ret = CKR_OK;
      goto cleanup;
      }

   if (pSignData->l_sign > *pulSignatureLen)
      {
      *pulSignatureLen = pSignData->l_sign;
      ret = CKR_BUFFER_TOO_SMALL;
      goto cleanup;
      }

   /* do we have to hash first? */
   if (pSignData->phash)
      {
      /* reserve space for data to sign */
      pDigest = (unsigned char*) malloc(pSignData->l_hash);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      ret = hash_update(pSignData->phash, (char*)pData, ulDataLen);
      if(ret == 0)
         ret = hash_final(pSignData->phash, pDigest, &ulDigestLen);
      if(ret)
         {
         log_trace(WHERE, "E: hash failed()");
         ret = CKR_FUNCTION_FAILED;
         goto terminate;
         }
      }
   else
      {
      /* reserve space for data to sign */
      pDigest = (unsigned char*) malloc(ulDataLen);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      memcpy(pDigest, pData, ulDataLen);
      ulDigestLen = ulDataLen;
      }

   /* do the signing (and add pkcs headers first if needed) */
   ret = cal_sign(pSession->hslot, pSignData, pDigest, ulDigestLen, pSignature, pulSignatureLen);
   if (ret != CKR_OK)
      log_trace(WHERE, "E: cal_sign() returned %s", log_map_error(ret));

terminate:
   //terminate sign operation
   free(pSignData);
   pSession->Operation[P11_OPERATION_SIGN].pData = NULL;
   pSession->Operation[P11_OPERATION_SIGN].active = 0;

cleanup:        
   if (pDigest)
      free(pDigest);
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);
return ret;
}
Beispiel #13
0
CK_RV C_SignInit(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_RV ret;
   P11_SESSION *pSession = NULL;
   P11_SLOT    *pSlot = NULL;
   P11_SIGN_DATA *pSignData = NULL;
   P11_OBJECT  *pObject = NULL;

   CK_BBOOL       *pcan_sign = NULL;
   CK_KEY_TYPE    *pkeytype = NULL;
   CK_ULONG       *pmodsize = NULL;
   CK_ULONG       *pid = NULL;
   CK_ULONG       *pclass = NULL;
   CK_ULONG len = 0;
   CK_MECHANISM_TYPE_PTR  pMechanismsSupported = NULL;
   CK_ULONG ulSupportedMechLen = 0;
   CK_ULONG ulcounter = 0;
   int ihash;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active sign operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active)
      {
      log_trace(WHERE, "W: Session %d: sign operation allready exists", hSession);
      ret = CKR_OPERATION_ACTIVE;
      goto cleanup;
      }

   pSlot = p11_get_slot(pSession->hslot);
   if (pSlot == NULL)
      {
      log_trace(WHERE, "E: Slot not found for session %d", hSession);
      ret = CKR_SESSION_HANDLE_INVALID;
      goto cleanup;
      }

   if(!(pSlot->ulCardDataCached & CACHED_DATA_TYPE_CDF))
   {
	   log_trace(WHERE, "E: Key handle but no CDF read yet!");
	   ret = CKR_KEY_HANDLE_INVALID;
	   goto cleanup;
   }

#ifndef PKCS11_FF
   ret = cal_init_objects(pSlot);
   if(ret != CKR_OK)
   {
	   log_trace(WHERE, "E: cal_init_objects() returns %s_", log_map_error(ret));
   }
#endif

   //check mechanism
   //since this module is only for BEID, we check for RSA here and we do not check the device capabilities
   //check mechanism table for signing depending on token in slot

	 //get number of mechanisms
		ret = cal_get_mechanism_list(pSession->hslot, pMechanismsSupported, &ulSupportedMechLen);
		if (ret != CKR_OK)
   {
			log_trace(WHERE, "E: cal_get_mechanism_list(slotid=%d) returns %s", pSession->hslot, log_map_error(ret));
			goto cleanup;
   }

		//get the mechanisms list
		pMechanismsSupported = (CK_MECHANISM_TYPE_PTR) malloc (sizeof(CK_MECHANISM_TYPE)*ulSupportedMechLen);
		if(pMechanismsSupported != NULL)
		{
			ret = cal_get_mechanism_list(pSession->hslot, pMechanismsSupported, &ulSupportedMechLen);
			if (ret != CKR_OK)
			{
				log_trace(WHERE, "E: cal_get_mechanism_list(slotid=%d) returns %s", pSession->hslot, log_map_error(ret));
				free(pMechanismsSupported);
				goto cleanup;
			}

			ret = CKR_MECHANISM_INVALID;

			for(ulcounter = 0; ulcounter < ulSupportedMechLen ; ulcounter++)
			{
				if(pMechanismsSupported[ulcounter] == pMechanism->mechanism)
				{
					ret = CKR_OK;
					break;
				}
			}
			if(ret == CKR_MECHANISM_INVALID)
			{
				free(pMechanismsSupported);
				goto cleanup;  
			}
			free(pMechanismsSupported);
		}

   switch(pMechanism->mechanism)
      {
      case CKM_MD5_RSA_PKCS:
      case CKM_SHA1_RSA_PKCS:
      case CKM_RIPEMD160_RSA_PKCS:
      case CKM_SHA256_RSA_PKCS:
      case CKM_SHA384_RSA_PKCS:
      case CKM_SHA512_RSA_PKCS: 
      case CKM_SHA1_RSA_PKCS_PSS:
      case CKM_SHA256_RSA_PKCS_PSS:
      case CKM_ECDSA_SHA256:
      case CKM_ECDSA_SHA384:
      case CKM_ECDSA_SHA512:
      	ihash = 1; break;
      case CKM_RSA_PKCS:
      case CKM_ECDSA:
      	ihash = 0; break;
      default: 
         ret = CKR_MECHANISM_INVALID;
         goto cleanup;            
      }

   //can we use the object for signing?
   pObject = p11_get_slot_object(pSlot, hKey);
   if (pObject == NULL || pObject->count == 0)
      {
      log_trace(WHERE, "E: invalid key handle");
      ret = CKR_KEY_HANDLE_INVALID;
      goto cleanup;
      }

   //check class, keytype and sign attribute CKO_PRIV_KEY
   /* CKR_KEY_TYPE_INCONSISTENT has higher rank than CKR_KEY_FUNCTION_NOT_PERMITTED */
   ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_KEY_TYPE, (CK_VOID_PTR*) &pkeytype, &len);
   if (ret || (len != sizeof(CK_KEY_TYPE)) || (*pkeytype != CKK_RSA))
      {
      log_trace(WHERE, "E: Wrong keytype");
      ret = CKR_KEY_TYPE_INCONSISTENT;
      goto cleanup;
      }

   ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_CLASS, (CK_VOID_PTR*) &pclass, &len);
   if (ret || (len != sizeof(CK_ULONG)) || (*pclass != CKO_PRIVATE_KEY))
      {
      log_trace(WHERE, "E: Key is not CKO_PRIVATE_KEY");
      ret = CKR_KEY_FUNCTION_NOT_PERMITTED;
      goto cleanup;
      }

   ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_SIGN, (CK_VOID_PTR*) &pcan_sign, &len);
   if (ret || (len != sizeof(CK_BBOOL)) || (*pcan_sign != CK_TRUE))
      {
      log_trace(WHERE, "E: Key cannot be used for signing");
      ret = CKR_KEY_FUNCTION_NOT_PERMITTED;
      goto cleanup;
      }

   ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_MODULUS_BITS, (CK_VOID_PTR*) &pmodsize, &len);
   if (ret || (len != sizeof(CK_ULONG)) )
      {
      log_trace(WHERE, "E: Lengh not defined for modulus bits for private key");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   /* get ID to identify signature key */
   /* at this time, id should be available, otherwise, device is not connected and objects are not initialized */
   ret = p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_ID, (CK_VOID_PTR*) &pid, &len);
   if (ret || (len != sizeof(CK_ULONG)))
      {
      log_trace(WHERE, "E: ID missing for key");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   /* init sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      pSignData = pSession->Operation[P11_OPERATION_SIGN].pData = (P11_SIGN_DATA *) malloc (sizeof(P11_SIGN_DATA));
      if (pSignData == NULL)
         {
         log_trace( WHERE, "E: error allocating memory");
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      }

   memset(pSignData, 0, sizeof(P11_SIGN_DATA));

   pSignData->mechanism = pMechanism->mechanism;
   pSignData->hKey = hKey;
   pSignData->l_sign = (*pmodsize+7)/8;
   pSignData->id = *pid;

   if (ihash)
      {
      ret = hash_init(pMechanism, &(pSignData->phash), &(pSignData->l_hash));
      if(ret)
         {
         log_trace(WHERE, "E: could not initialize hash()");
         ret = CKR_FUNCTION_FAILED;
         goto cleanup;
         }
      }
   pSession->Operation[P11_OPERATION_SIGN].active = 1;

cleanup:       
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Beispiel #14
0
CK_RV C_WaitForSlotEvent(CK_FLAGS flags,   /* blocking/nonblocking flag */
	CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
	CK_VOID_PTR pReserved) /* reserved.  Should be NULL_PTR */

{
	CK_RV ret = CKR_OK;
	int h;
	P11_SLOT *p11Slot = NULL;
	int i = 0;
	CK_BBOOL locked = CK_FALSE;
#ifdef PKCS11_FF
	CK_BBOOL bRunning = CK_TRUE;
	long error = 0;
#endif

	log_trace(WHERE, "I: enter");

	//need to check initialization before lock, as lock might be in progress of being set up
	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}	

#ifdef PKCS11_FF
	/*error = cal_check_pcsc(&bRunning);
	if(bRunning == CK_FALSE)
	{
		while( (error == 0) && (bRunning == CK_FALSE) )
		{
			cal_wait (500);
			error = cal_check_pcsc(&bRunning);

			//check if pkcs11 isn't finalizing
			if (p11_get_init() != BEIDP11_INITIALIZED)
			{
				log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NO_LONGER_INITIALIZED");
				return (CKR_CRYPTOKI_NOT_INITIALIZED);
			}	
		}
		//pcsc just got launched, so establish a new context
		ret = p11_lock();
		if (ret != CKR_OK)
		{
			log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
			return ret;
		}
		//check if nowhere else the context has been reestablished
		//TODO : if()
		cal_re_establish_context();
		p11_unlock();
	}*/
#endif

	ret = p11_lock();
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	//check again, in case c_finalize got the lock right before we did
	//(then c_finalize will give us a chance to fall through, right before he resets the lock))
	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		p11_unlock();
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}	

	locked = CK_TRUE;

	log_trace(WHERE, "S: C_WaitForSlotEvent(flags = 0x%0x)", flags);

	// Doesn't seem to work on Linux: if you insert a card then Mozilla freezes
	// until you remove the card. This function however seems to work fine.
#ifndef _WIN32
	CLEANUP(CKR_FUNCTION_NOT_SUPPORTED);
#endif

	//first check if no events are set for slots in previous run
	//this could happen if more cards are inserted/removed at the same time
	for (i=0; i < p11_get_nreaders(); i++)
	{
		p11Slot = p11_get_slot(i);
		if(p11Slot == NULL)
			CLEANUP(CKR_FUNCTION_FAILED);
		if (p11Slot->ievent != P11_EVENT_NONE)
		{
#ifdef PKCS11_FF
			//in case the upnp reader caused the event, return a new slotnumber
			if( (i+1) == p11_get_nreaders())
			{
				if(cal_getgnFFReaders() == 0)
				{
					cal_setgnFFReaders(p11_get_nreaders()+1);
				}
				else
				{
					cal_incgnFFReaders();
				}
				i = (cal_getgnFFReaders()-1);
			}
#endif
			*pSlot = i;
			//clear event
			p11Slot->ievent = P11_EVENT_NONE;
			CLEANUP(CKR_OK);
		}
	}

	if (flags & CKF_DONT_BLOCK)
	{
		ret = cal_wait_for_slot_event(0);//0 means don't block
	}
	else
	{
		ret = cal_wait_for_slot_event(1);//1 means block, lock will get released here

		//ret is 0x30 when SCardGetStatusChange gets cancelled 
		if ((p11_get_init() == BEIDP11_NOT_INITIALIZED ) || 
			(p11_get_init() == BEIDP11_DEINITIALIZING) || 
			(ret == CKR_CRYPTOKI_NOT_INITIALIZED) )
		{
			log_trace(WHERE, "I: CKR_CRYPTOKI_NOT_INITIALIZED");
			p11_unlock();
			return(CKR_CRYPTOKI_NOT_INITIALIZED);
		}
	}
	if(ret != CKR_OK)
		goto cleanup;

	ret = cal_get_slot_changes(&h);

	if (ret == CKR_OK)
		*pSlot = h;

	//else CKR_NO_EVENT

	/* Firefox 1.5 tries to call this function (with the blocking flag)
	* in a separate thread; and this causes the pkcs11 lib to hang on Linux
	* So we might have to return "not supported" in which case Ff 1.5 defaults
	* to polling in the main thread, like before. */

cleanup:
	if(locked == CK_TRUE)
		p11_unlock();

	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #15
0
CK_RV C_Initialize(CK_VOID_PTR pReserved)
{
	int ret = CKR_OK;
	CK_C_INITIALIZE_ARGS_PTR p_args;
	unsigned char initial_state = p11_get_init();

#if _DEBUG
	log_init(DEFAULT_LOG_FILE, LOG_LEVEL_PKCS11_INFO);
#else
	log_init(DEFAULT_LOG_FILE, LOG_LEVEL_PKCS11_NONE);
#endif
	log_trace(WHERE, "I: enter pReserved = %p",pReserved);
	if (p11_get_init() != BEIDP11_NOT_INITIALIZED)
	{
		ret = CKR_CRYPTOKI_ALREADY_INITIALIZED;
		log_trace(WHERE, "I: Module is allready initialized");
	}
	else
	{
		//g_init = BEIDP11_INITIALIZED;
		p11_set_init(BEIDP11_INITIALIZING);
		if (pReserved != NULL)
		{
			p_args = (CK_C_INITIALIZE_ARGS *)pReserved;

			if(p_args->pReserved != NULL)
			{
				ret = CKR_ARGUMENTS_BAD;
				goto cleanup;
			}
			if(	(p_args->CreateMutex == NULL) || (p_args->DestroyMutex == NULL) || \
				(p_args->LockMutex == NULL) || (p_args->UnlockMutex == NULL)	)
			{
				log_trace(WHERE, "S: use supplied locking mechanism");
				//If some, but not all, of the supplied function pointers to C_Initialize are non-NULL_PTR, 
				//then C_Initialize should return with the value CKR_ARGUMENTS_BAD.
				if(!((p_args->CreateMutex == NULL) && (p_args->DestroyMutex == NULL) && \
					(p_args->LockMutex == NULL) && (p_args->UnlockMutex == NULL)))
				{
					ret = CKR_ARGUMENTS_BAD;
					goto cleanup;
				}
			}
			log_trace(WHERE, "S: p11_init_lock");
			p11_init_lock(p_args);
		}
		cal_init();
		p11_set_init(BEIDP11_INITIALIZED);
		log_trace(WHERE, "S: Initialize this PKCS11 Module");
		log_trace(WHERE, "S: =============================");
/*#ifdef PKCS11_FF
	cal_init_pcsc();
#endif*/
	}

cleanup:
	log_trace(WHERE, "I: leave, ret = %i",ret);
	if (ret != CKR_OK) {
		p11_set_init(initial_state);
	}
	return ret;
}
Beispiel #16
0
CK_RV C_Initialize(CK_VOID_PTR pReserved)
{
	int ret = CKR_OK;
	CK_RV retVal = CKR_OK;
	CK_C_INITIALIZE_ARGS_PTR p_args;

#if _DEBUG
	log_init(DEFAULT_LOG_FILE, LOG_LEVEL_PKCS11_INFO);
#else
	log_init(DEFAULT_LOG_FILE, LOG_LEVEL_PKCS11_NONE);
#endif
	log_trace(WHERE, "I: enter pReserved = %p",pReserved);
	if (p11_get_init() != BEIDP11_NOT_INITIALIZED)
	{
		ret = CKR_CRYPTOKI_ALREADY_INITIALIZED;
		log_trace(WHERE, "I: Module is allready initialized");
	}
	else
	{
		//g_init = BEIDP11_INITIALIZED;
		p11_set_init(BEIDP11_INITIALIZING);
		if (pReserved != NULL)
		{
			p_args = (CK_C_INITIALIZE_ARGS *)pReserved;

			if(p_args->pReserved != NULL)
			{
				ret = CKR_ARGUMENTS_BAD;
				goto cleanup;
			}
			if(	(p_args->CreateMutex == NULL) || (p_args->DestroyMutex == NULL) || \
				(p_args->LockMutex == NULL) || (p_args->UnlockMutex == NULL)	)
			{
				log_trace(WHERE, "S: use supplied locking mechanism");
				//If some, but not all, of the supplied function pointers to C_Initialize are non-NULL_PTR, 
				//then C_Initialize should return with the value CKR_ARGUMENTS_BAD.
				if(!((p_args->CreateMutex == NULL) && (p_args->DestroyMutex == NULL) && \
					(p_args->LockMutex == NULL) && (p_args->UnlockMutex == NULL)))
				{
					ret = CKR_ARGUMENTS_BAD;
					goto cleanup;
				}
			}
			log_trace(WHERE, "S: p11_init_lock");
			p11_init_lock(p_args);
		}
		//cal_init();
		g_aseP11Handle = dlopen(ASEP11_LIB, RTLD_LAZY); // RTLD_NOW is slower
		log_trace(WHERE, "S: dlopen(ASEP11_LIB");
		if (g_aseP11Handle != NULL)
		{
		    // get function pointer to C_GetFunctionList
            pC_GetFunctionList = (CK_C_GetFunctionList)dlsym(g_aseP11Handle, "C_GetFunctionList");
            if (pC_GetFunctionList != NULL)
            {
                // invoke C_GetFunctionList to get the list of pkcs11 function pointers
                retVal = (*pC_GetFunctionList) (&pFunctions);
                if (retVal == CKR_OK)
                {
                    // initialize Cryptoki
                    retVal = (pFunctions->C_Initialize) (NULL);
                }
            }
		}
		if (retVal == CKR_OK)
        {
            p11_set_init(BEIDP11_INITIALIZED);
            log_trace(WHERE, "S: Initialize this PKCS11 Module");
            log_trace(WHERE, "S: =============================");
        }
		else
		{
			log_trace(WHERE, "E: Not Initialized this PKCS11 Module");
            ret = CKR_ARGUMENTS_BAD;
            goto cleanup;
		}

	}

cleanup:
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #17
0
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;
}
Beispiel #18
0
CK_RV C_Logout(CK_SESSION_HANDLE hSession) /* the session's handle */
{
	int ret = CKR_OK;
	//P11_SESSION *pSession = NULL;
	//P11_SLOT *pSlot = NULL;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	} 

	log_trace(WHERE, "S: Logout (session %d)", hSession);

	/*ret = p11_get_session(hSession, &pSession);
	if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: Slot not found for session %d", hSession);
		ret = CKR_SESSION_HANDLE_INVALID;
		goto cleanup;
	}

	if (pSlot->login_type >= 0)
	{
		pSlot->login_type = -1;
		ret = cal_logout(pSession->hslot);
	}
	else
		ret = CKR_USER_NOT_LOGGED_IN;
	*/
	/* TODO  cleanup all active operations (see standard) */
	/* TODO: invalidate all private objects */
	/* TODO: destroy all private session objects (we only have private token objects and they are unreadable anyway) */

    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_Logout");
        ret = (pFunctions->C_Logout) (hSession);
    }


cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #19
0
CK_RV C_Login(CK_SESSION_HANDLE hSession,  /* the session's handle */
	CK_USER_TYPE      userType,  /* the user type */
	CK_CHAR_PTR       pPin,      /* the user's PIN */
	CK_ULONG          ulPinLen)  /* the length of the PIN */
{
	int ret;
	//P11_SESSION *pSession = NULL;
	//P11_SLOT *pSlot = NULL;
	CK_TOKEN_INFO tokeninfo;

	//return(CKR_OK);
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	memset(&tokeninfo, 0, sizeof(CK_TOKEN_INFO));

	log_trace(WHERE, "S: Login (session %d)", hSession);

	if (userType != CKU_USER && userType != CKU_SO)
	{
		ret = CKR_USER_TYPE_INVALID;
		goto cleanup;
	}

	/*ret = p11_get_session(hSession, &pSession);
	if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: Slot not found for session %d", hSession);
		ret = CKR_SESSION_HANDLE_INVALID;
		goto cleanup;
	}

	if (pSlot->login_type >= 0)
	{
		// Needed for Acrobat, in case you want to sign with a 2nd card
		ret = CKR_OK; //CKR_USER_ALREADY_LOGGED_IN;
		goto cleanup;
	}

	/*   ret = cal_get_token_info(pSlot, &tokeninfo);
	if (ret != CKR_OK)
	{
	log_trace(WHERE, "E: could not find tokeninfo for slot %d", pSession->hslot);
	goto cleanup;
	}

	if ( !(tokeninfo.flags & CKF_USER_PIN_INITIALIZED) )
	{
	ret = CKR_USER_PIN_NOT_INITIALIZED;
	goto cleanup;
	}*/

	/*ret = cal_logon(pSession->hslot, ulPinLen, pPin, 0);
	if (ret == CKR_OK)
		pSlot->login_type = userType;*/
    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_Login");
        ret = (pFunctions->C_Login) (hSession, userType, pPin, ulPinLen);
    }

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #20
0
CK_RV C_OpenSession(CK_SLOT_ID            slotID,        /* the slot's ID */
	CK_FLAGS              flags,         /* defined in CK_SESSION_INFO */
	CK_VOID_PTR           pApplication,  /* pointer passed to callback */
	CK_NOTIFY             Notify,        /* notification callback function */
	CK_SESSION_HANDLE_PTR phSession)     /* receives new session handle */
{
	int ret;
	//P11_SLOT* pSlot = NULL;
	//P11_SESSION *pSession = NULL;

	//   CAutoMutex(&g_oSlotMutex);
	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(slotID);   /* mutex per slot slot 0 tot 9 FF=global slot*/
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_OpenSession (slot %d)", slotID);

	if (!(flags & CKF_SERIAL_SESSION)) 
	{
		ret = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
		goto cleanup;
	}

	//XXX check this
	/*   if (flags & ~(CKF_SERIAL_SESSION | CKF_RW_SESSION))
	{
	ret = CKR_ARGUMENTS_BAD;
	goto cleanup;
	}*/

	/*pSlot = p11_get_slot(slotID);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: p11_get_slot(%d) returns null", slotID);
		ret = CKR_SLOT_ID_INVALID;
		goto cleanup;
	}

	/* Check that no conflictions sessions exist */
	/* RO session when SO session exists is not allowed */
	/*if ( !(flags & CKF_RW_SESSION) && (pSlot->login_type == CKU_SO))
	{
		log_trace(WHERE, "E: R/W Session exists", slotID);
		ret = CKR_SESSION_READ_WRITE_SO_EXISTS;
		goto cleanup;
	}

	//get a free session object reserve it by setting inuse flag
	ret = p11_get_free_session(phSession, &pSession);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: p11_get_free_session() returns %d", ret);
		goto cleanup;
	}

	//connect to card if present
	ret = cal_connect(slotID);
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "E: cal_connect(slot %d) failed", slotID);
		//release session so it can be reused
		pSession->inuse = 0;
		goto cleanup;
	}

	pSession->hslot = slotID;
	pSession->flags = flags;
	pSession->pdNotify = pApplication;
	pSession->pfNotify = Notify;
	//initial state 
	pSession->state = P11_CARD_STILL_PRESENT;
	pSession->bReadDataAllowed = P11_READDATA_ASK;
	pSession->bCardDataCashed = FALSE;

	/* keep the nr of sessions for this slot */
	/*pSlot->nsessions++;*/
    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_OpenSession");
        ret = (pFunctions->C_OpenSession) (slotID, flags, pApplication, Notify, phSession );
    }

	log_trace(WHERE, "S: Open session (slot %d: hsession = %d )", slotID, *phSession);

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #21
0
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession,  /* the session's handle */
	CK_SESSION_INFO_PTR pInfo)   /* receives session information */
{
	int ret;
	//P11_SESSION *pSession = NULL;
	//P11_SLOT *pSlot = NULL;
	//CK_TOKEN_INFO tokeninfo;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_GetSessionInfo(session %d)", hSession);

	if (pInfo == NULL_PTR) 
	{
		ret = CKR_ARGUMENTS_BAD;
		goto cleanup;
	}

	/*ret = p11_get_session(hSession, &pSession);
	if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d) (%s)", hSession, log_map_error(ret));
		goto cleanup;
	}

	pInfo->slotID = pSession->hslot;
	pInfo->flags = pSession->flags;
	pInfo->ulDeviceError = 0;

	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: slot not found for session %d", hSession);
		ret = CKR_SESSION_HANDLE_INVALID;
		goto cleanup;
	}

	//SO only can create RW_SO sessions
	if (pSlot->login_type == CKU_SO) 
	{
		pInfo->state = CKS_RW_SO_FUNCTIONS;
	}
	//USER can create RW or RO sessions
	else if (pSlot->login_type == CKU_USER) 
	{
		pInfo->state = (pSession->flags & CKF_RW_SESSION)? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS;
	} 
	//if login not required => we can also get USER sessions without being logged on
	else 
	{
		ret = cal_get_token_info(pSession->hslot, &tokeninfo);
		if ( (ret == CKR_OK) && !(tokeninfo.flags & CKF_LOGIN_REQUIRED) )
			pInfo->state = (pSession->flags & CKF_RW_SESSION)? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS;
		else
			pInfo->state = (pSession->flags & CKF_RW_SESSION) ? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
	}*/
	
    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_CloseSession");
        ret = (pFunctions->C_CloseSession) (hSession);
    }

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #22
0
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 */
{
   CK_RV ret;
   P11_SESSION *pSession = NULL;
   P11_SIGN_DATA *pSignData = NULL;
   unsigned char *pDigest = NULL;
   unsigned long ulDigestLen = 0;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter");
 
   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);      
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no sign operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      log_trace( WHERE, "E: no sign operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

	 if(pSignature == NULL)
	 {
		*pulSignatureLen = pSignData->l_sign;
		ret = CKR_OK;
		goto cleanup;
	 }

	 if(*pulSignatureLen < pSignData->l_sign)
	 {
		*pulSignatureLen = pSignData->l_sign;
		ret = CKR_BUFFER_TOO_SMALL;
		goto cleanup;
	 }

   if (pSignData->phash)
      {
      /* get hash */
      pDigest = (unsigned char*) malloc(pSignData->l_hash);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      
      ret = hash_final(pSignData->phash, pDigest, &ulDigestLen);
      if(ret)
         {
         log_trace(WHERE, "E: hash_final failed()");
         ret = CKR_FUNCTION_FAILED;
         goto cleanup;
         }
      }
   else
      {
      /* no hash: get buffer to sign directly */
      pDigest = (unsigned char*) malloc(pSignData->lbuf);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      memcpy(pDigest, pSignData->pbuf, pSignData->lbuf);
      ulDigestLen = pSignData->lbuf;
      }

   ret = cal_sign(pSession->hslot, pSignData, pDigest, ulDigestLen, pSignature, pulSignatureLen);
   if (ret != CKR_OK)
      log_trace(WHERE, "E: cal_sign() returned %s", log_map_error(ret));

   //terminate sign operation
   free(pSignData);
   pSession->Operation[P11_OPERATION_SIGN].pData = NULL;
   pSession->Operation[P11_OPERATION_SIGN].active = 0;

cleanup:
   if (pDigest)
      free(pDigest);

   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Beispiel #23
0
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 */
{
   CK_RV ret;
   P11_SESSION *pSession = NULL;
   P11_DIGEST_DATA *pDigestData = NULL;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter, hSession = %i",hSession);

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if ((pSession->Operation[P11_OPERATION_DIGEST].active) == 0)
      {
      log_trace(WHERE, "E: Session %d: no digest operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get digest operation */
   if((pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData) == NULL)
      {
      log_trace(WHERE, "E: no digest operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if(pDigestData->update)
      {
      log_trace(WHERE, "E: C_Digest() cannot be used to finalize C_DigestUpdate()");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   if (pDigest == NULL)
      {
      *pulDigestLen = pDigestData->l_hash;
      /* return ok without terminating digest params */
      ret = CKR_OK;   
      goto cleanup;
      }

   if (*pulDigestLen < pDigestData->l_hash)
      {
      *pulDigestLen = pDigestData->l_hash;
      ret = CKR_BUFFER_TOO_SMALL;
      goto cleanup;
      }

   ret = hash_update(pDigestData->phash, (char*)pData, ulDataLen);
   if(ret == 0)
      ret = hash_final(pDigestData->phash, pDigest, pulDigestLen);
   if(ret)
      {
      log_trace(WHERE, "E: hash failed()");
      ret = CKR_FUNCTION_FAILED;
      //don't goto cleanup here
      }

   /* terminate digest operation */
   free(pDigestData);
   pSession->Operation[P11_OPERATION_DIGEST].pData = NULL;
   pSession->Operation[P11_OPERATION_DIGEST].active = 0;

cleanup:
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Beispiel #24
0
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
{
	//P11_SESSION *pSession = NULL;
	//P11_SLOT *pSlot = NULL;
	CK_RV ret;
	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	log_trace(WHERE, "S: C_CloseSession (session %d)", hSession);

	//get session, of pSession is found, regardless the ret value, we can clean it up
	/*ret = p11_get_session(hSession, &pSession);
	if (pSession == NULL)
	{
		ret = CKR_SESSION_HANDLE_INVALID;
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	//get slot, if not exist, we allow to close session anyway
	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "W: Invalid slot (%d) for session (%d)", pSession->hslot, hSession);
		//ret = CKR_OK;
	}
	else
	{
		//
		if (pSlot->nsessions > 0)
			pSlot->nsessions--;

		if ((pSlot->nsessions < 1) && (pSlot->login_type >= 0) )
		{
			//TODO what to do if no session longer exists?
			//      cal_logout(pSlot);
			pSlot->login_type = -1;
		}

		//disconnect this session to device
		ret = cal_disconnect(pSession->hslot);
	}

	//clear data so it can be reused
	pSession->state = 0;
	pSession->inuse = 0;
	pSession->flags = 0;
	pSession->hslot = 0;
	pSession->pdNotify = NULL;
	pSession->pfNotify = NULL;*/

    if (pFunctions == NULL)
    {
        log_trace(WHERE, "E: leave, CKR_CRYPTOKI_NOT_INITIALIZED - pFunctions is NULL");
        ret =  CKR_ARGUMENTS_BAD;
        goto cleanup;
    }
    else
    {
		log_trace(WHERE, "I: leave, ASE C_CloseSession");
        ret = (pFunctions->C_CloseSession) (hSession);
    }

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #25
0
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 */
{
	/*

	this function finds handles to objects but does not actually reads them.
	this function returns handles to objects that exist on the token.
	PKCS15 defines existance of attributes that should be readable from token

	*/

	int ret = 0;
	P11_SESSION   *pSession = NULL;
	P11_SLOT      *pSlot = NULL;
	P11_FIND_DATA *pData = NULL;
	P11_OBJECT    *pObject = NULL;
	CK_BBOOL      *pbToken = NULL;
	void          *p = NULL;
	CK_ULONG      *pclass = NULL;
	int           match = 0;
	unsigned int           h,j = 0;

	CK_ULONG len = 0;

	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_FindObjects(session %d)", hSession);

	ret = p11_get_session(hSession, &pSession);
	if (pSession == NULL || ret != CKR_OK)
		// if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	if (pSession->Operation[P11_OPERATION_FIND].active == 0)
	{
		log_trace(WHERE, "E: For this session no search operation is initiated");
		ret = CKR_OPERATION_NOT_INITIALIZED;
		goto cleanup;
	}

	//get search template
	pData = (P11_FIND_DATA *) pSession->Operation[P11_OPERATION_FIND].pData;
	if (pData == NULL)
	{
		log_trace(WHERE, "E: Session (%d): search data not initialized correctly", hSession);
		ret = CKR_OPERATION_NOT_INITIALIZED;
		goto cleanup;
	}

	/* VSC this code was moved to here since Sun-PKCS11 cannot handle CKR_Attribute_value_invalid in C_FindObjectsInit() properly!!! */
	/* here we just return 0 objects in case of class type that is not supported */
	ret = p11_get_attribute_value(pData->pSearch, pData->size, CKA_CLASS, (CK_VOID_PTR *) &pclass, &len);
	if ( (ret == 0) && (len == sizeof(CK_ULONG) ) )
	{
		if ( (*pclass != CKO_CERTIFICATE) && (*pclass != CKO_PRIVATE_KEY) && (*pclass != CKO_PUBLIC_KEY) && (*pclass != CKO_DATA) )
		{
			ret = CKR_OK; //ret = CKR_ATTRIBUTE_VALUE_INVALID;
			*pulObjectCount = 0;
			goto cleanup;
		}
	}

	//check if we have a TOKEN attribute to look for
	//in case of null search template we search for all objects
	//Firefox does not set TOKEN object for CKO_PRIVATE_KEY objects so for the moment we allow looking for them, id has to match anyway.
	len = sizeof(CK_BBOOL);
	if (pData->size > 0)
	{
		ret = p11_get_attribute_value(pData->pSearch, pData->size, CKA_TOKEN, (CK_VOID_PTR *) &pbToken, &len);
		//if ((ret != CKR_OK) || ( (len == sizeof(CK_BBOOL) ) && (*pbToken == CK_FALSE) ) )
		//for the moment if CKA_TOKEN is specified and set to false, we reply that only token objects can be searched for and continue with ok
		if ((ret == CKR_OK) && (len == sizeof(CK_BBOOL)) && (*pbToken == CK_FALSE) ) 
		{
			log_trace(WHERE, "W: only token objects can be searched for");
			*pulObjectCount = 0;
			ret = CKR_OK;
			goto cleanup;
		}
	}

	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: p11_get_slot(%d) returns null", pSession->hslot);
		ret = CKR_SLOT_ID_INVALID;
		goto cleanup;
	}

	*pulObjectCount = 0;

	//for all objects in token, match with search template as long as we need, keep handle to current token object
	for (h = pData->hCurrent; h <= (pSlot->nobjects) && (*pulObjectCount < ulMaxObjectCount); h++, pData->hCurrent++)
	{
		pObject = p11_get_slot_object(pSlot, h);
		if (pObject == NULL)
		{
			log_trace(WHERE, "E: invalid object handle, call C_FindObjectsInit() first");
			ret = CKR_OPERATION_NOT_INITIALIZED;
			goto cleanup;
		}
		if (pObject->inuse == 0)
			continue; //this object is not in use by the token()

		//if not logged in, objects with missing CKA_PRIVATE or CKA_PRIVATE set to false will be ignored
#if 0 //TODO
		if (pSlot->login_type < 0) //CKU_SO=0; CKU_USER=1
		{
			if (p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_PRIVATE, (CK_VOID_PTR *) &pbPrivate, &len) != CKR_OK)
			{
				log_trace(WHERE, "E: missing CKA_PRIVATE attribute in our object: bad implementation");
				continue;
			}

			if ( (len == sizeof(CK_BBOOL)) && (*pbPrivate == CK_TRUE) )
			{
				log_trace(WHERE, "E: Not allowed to retrieve private objects");
				continue;
			}
		}
#endif
		// Try to match every attribute
		match = 1;
		//if pData->size = 0 => this means that we will search for every object!!! match = 1 so for() is skipped and object is returned
		for (j = 0; j < pData->size; j++)
		{
			//get the value of the attribute from the token object and compare with the search attribute
			if (p11_get_attribute_value(pObject->pAttr, pObject->count, pData->pSearch[j].type, &p, &len) != CKR_OK)
			{
				match = 0;
				break;
			}

			// printf("pData->pSearch[%d].ulValueLen=%d <> len=%d\n",j,pData->pSearch[j].ulValueLen,len);

			if (pData->pSearch[j].ulValueLen != len)
			{
				match = 0;
				break;
			}

			if (memcmp(pData->pSearch[j].pValue, p, len) != 0)
			{
				match = 0;
				break;
			}
		}

		if (match)
		{
			log_trace(WHERE, "I: Slot %d: Object %d matches", pSession->hslot, h);
			//put handle to object in list
			phObject[*pulObjectCount] = (CK_OBJECT_HANDLE) h;
			*pulObjectCount +=1;
		}
		else
			log_trace(WHERE, "I: Slot %d: Object %d no match with search template", pSession->hslot, h);
	}

	ret = CKR_OK;

cleanup: 
	p11_unlock();
	return ret;
}
Beispiel #26
0
CK_RV C_GetSlotList(CK_BBOOL       tokenPresent,  /* only slots with token present */
	CK_SLOT_ID_PTR pSlotList,     /* receives the array of slot IDs */
	CK_ULONG_PTR   pulCount)      /* receives the number of slots */
{

	P11_SLOT *pSlot;
	CK_RV ret = CKR_OK;
	int h;
	CK_ULONG c = 0; 
	static int l=0;

	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();
	log_trace(WHERE, "I: p11_lock() acquiered");
	if (ret != CKR_OK)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return (ret);
	}

	if (++l<LOG_MAX_REC)
		log_trace(WHERE, "S: C_GetSlotList()");

	if (pulCount == NULL_PTR)
	{
		ret = CKR_ARGUMENTS_BAD;
		goto cleanup;
	}

#ifdef PKCS11_V2_20
	if(pSlotList == NULL){
		ret = cal_refresh_readers();
	}
#endif
	//init slots allready done
	//update info on tokens in slot, could be removed if thread keeps track of these token states
	//BUG in Adobe Acrobat reader: adobe asks for slots with pSlotList = NULL, so only nr of slots will be returned. This is ok.
	//a second time Adobe calls this, pSlotList still is NULL, so the array with SlotIDs cannot be returned, again, nr of slots is returned.
	//Adobe just assumes that the first slot has ID=0 !!! and uses this ID=0 for all further actions.
	//to overcome this problem, we start our SlotIDs from 0 and not 1 !!!

	log_trace(WHERE, "I: h=0");
	//Do not show the virtual reader (used to capture the reader connect events)
	//for (h=0; h < (p11_get_nreaders()-1); h++)
	for (h=0; h < p11_get_nreaders(); h++)
	{
		log_trace(WHERE, "I: h=%i",h);
		pSlot = p11_get_slot(h);

		if (l < LOG_MAX_REC) 
			log_trace(WHERE, "I: slot[%d]: %s", h, pSlot->name);

		if (tokenPresent == CK_TRUE)
		{
			int pPresent = 0;
			ret = cal_token_present(h, &pPresent);
			if(ret != CKR_OK && ret != CKR_TOKEN_NOT_RECOGNIZED)
			{
				goto cleanup;
			}
			if (pPresent)
			{
				log_trace(WHERE, "I: cal_token_present");
				c++;
				if ((pSlotList != NULL_PTR) && (c <= *pulCount) )
					pSlotList[c-1] =  h;
			}
			continue;
		}
		else
		{
			//get all slots
			c++;
			if ((pSlotList != NULL_PTR) && (c <= *pulCount) )
			{
				pSlotList[c-1] =  h;
			}
			continue;
		}
	} //end for

#ifdef PKCS11_FF
	//return the fake slotID for the attached/removed reader
	if (cal_getgnFFReaders()!= 0)
	{
		//return a higher number of slots, so FF starts waiting for slotchanges again
		if(pSlotList == NULL)
		{
			c = cal_getgnFFReaders();
		}
		else
		{
			for(; h < cal_getgnFFReaders(); h++)
			{
				log_trace(WHERE, "I: h=%i",h);
				c++;
				if (c <= *pulCount )
					pSlotList[c-1] = h;
			}
		}
	}

#endif

	//if more slots are found than can be returned in slotlist, return buffer too smal 
	if ((c > *pulCount) && (pSlotList != NULL_PTR) )
		ret = CKR_BUFFER_TOO_SMALL;

	//number of slots should always be returned.
	*pulCount = c;

cleanup:   
	log_trace(WHERE, "I: p11_unlock()");
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}
Beispiel #27
0
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 */
{
	/*
	This function returns the values from the object.
	Object is cached so objects are read only once and remain valid until new session is setup with token.
	Objects are allready initialized (but not read) during connection with token.
	*/

	int status, ret = 0;
	P11_SESSION *pSession = NULL;
	P11_SLOT    *pSlot    = NULL;
	P11_OBJECT  *pObject  = NULL;
	unsigned int j = 0;
	void  *pValue    = NULL;
	CK_ULONG len = 0;
	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_GetAttributeValue(hObject=%d)",hObject);

	ret = p11_get_session(hSession, &pSession);
	if (ret)
	{
		log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
		goto cleanup;
	}

	pSlot = p11_get_slot(pSession->hslot);
	if (pSlot == NULL)
	{
		log_trace(WHERE, "E: p11_get_slot(%d) returns null", pSession->hslot);
		ret = CKR_SLOT_ID_INVALID;
		goto cleanup;
	}

	pObject = p11_get_slot_object(pSlot, hObject);
	if (pObject == NULL)
	{
		log_trace(WHERE, "E: slot %d: object %d does not exist", pSession->hslot, hObject);
		ret = CKR_OBJECT_HANDLE_INVALID;
		goto cleanup;
	}

	//read object from token if not cached allready
	if (pObject->state != P11_CACHED)
	{
		ret = cal_read_object(pSession->hslot, pObject);
		if (ret != 0)
		{
			log_trace(WHERE, "E: p11_read_object() returned %d", ret);
			goto cleanup;
		}
	}

	/*   if (pSlot->login_type < 0) //CKU_SO=0; CKU_USER=1
	{
	if (p11_get_attribute_value(pObject->pAttr, pObject->count, CKA_PRIVATE, (CK_VOID_PTR *) &pbPrivate, &len) != CKR_OK)
	{
	log_trace(WHERE, "E: missing CKA_PRIVATE attribute in our object: bad implementation");
	continue;
	}

	if ( (len == sizeof(CK_BBOOL)) && (*pbPrivate == CK_TRUE) )
	{
	log_trace(WHERE, "E: Not allowed to retrieve private objects");
	continue;
	}
	}*/

	//retrieve all objects as listed in template and fill the template
	//action is done for all attributes, even if some attributes give errors or buffer is too small
	//there is however only one return code to return so we have to keep the most important return code.
	for (j = 0; j < ulCount; j++)
	{
		status = p11_get_attribute_value(pObject->pAttr, pObject->count, pTemplate[j].type, (CK_VOID_PTR *) &pValue, &len);
		if (status != CKR_OK)
		{
			log_template("E: C_GetAttributeValue status != CKR_OK", &pTemplate[j], 1);
			log_trace(WHERE, "E: p11_get_attribute_value (object=%d) returned %s", hObject, log_map_error(status));
			pTemplate[j].ulValueLen = (CK_ULONG) -1;
			ret = status;
			continue;
		}

		if (pTemplate[j].pValue == NULL)
		{
			/* in this case we return the real length of the value */
			pTemplate[j].ulValueLen = len;
			continue;
		}

		if (len > pTemplate[j].ulValueLen)
		{
			pTemplate[j].ulValueLen = (CK_ULONG) -1;
			ret = CKR_BUFFER_TOO_SMALL;
			continue;
		}

		pTemplate[j].ulValueLen = len;
		memcpy(pTemplate[j].pValue, pValue, len);
	}

	if (ulCount != 0)
		log_template("I: Template out:", pTemplate, ulCount);

cleanup:
	p11_unlock();
	return ret;
}
Beispiel #28
0
CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{         
	CK_RV ret;
	P11_SLOT *slot;
	static int l=0;
	int isPresent = 0;

	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)
	{
		log_trace(WHERE, "I: leave, p11_lock failed with %i",ret);
		return ret;
	}

	if (++l < LOG_MAX_REC)  
		log_trace(WHERE, "S: C_GetSlotInfo(slot %d)", slotID);

	if (pInfo == NULL_PTR) 
	{
		log_trace(WHERE, "E: pInfo = NULL");
		CLEANUP(CKR_ARGUMENTS_BAD);
	}

	slot = p11_get_slot(slotID);
	if (slot == NULL)
	{
		log_trace(WHERE, "E: p11_get_slot(%d) returns null", slotID);
		CLEANUP(CKR_SLOT_ID_INVALID);
	}

	//fill in slot info
	strcpy_n(pInfo->slotDescription, slot->name, 64, ' ');
	strcpy_n(pInfo->manufacturerID, "_ID_", 32, ' ');
	pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
	pInfo->hardwareVersion.major = 1;
	pInfo->hardwareVersion.minor = 0;
	pInfo->firmwareVersion.major = 1;
	pInfo->firmwareVersion.minor = 0;

	//check if token is present
	ret = (cal_token_present(slotID, &isPresent));
	if(ret != CKR_OK)
		goto cleanup;
	if (isPresent)
	{
		pInfo->flags |= CKF_TOKEN_PRESENT;
	}

cleanup:
	p11_unlock();
	log_trace(WHERE, "I: leave, ret = %i",ret);
	return ret;
}