예제 #1
0
파일: general.c 프로젝트: dagwieers/eid-mw
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;
}
예제 #2
0
파일: sign.c 프로젝트: Fedict/eid-mw
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;
}