Example #1
0
int find_slot(CK_BBOOL with_token, CK_SLOT_ID_PTR slot) {
	CK_RV rv;
	CK_ULONG count = 0;
	CK_SLOT_ID_PTR list = NULL;

	ckrv_mod m[] = { CKR_BUFFER_TOO_SMALL, TEST_RV_OK };
	check_rv_long(C_GetSlotList(with_token, NULL_PTR, &count), m);
	printf("slots %sfound: %lu\n", with_token ? "with token " : "", count);
	if(count == 0 && with_token) {
		if(have_robot()) {
			robot_insert_card();
			return find_slot(with_token, slot);
		}
		printf("Need at least one token to run this test\n");
		return TEST_RV_SKIP;
	}

	do {
		list = (CK_SLOT_ID_PTR)realloc(list, sizeof(CK_SLOT_ID) * count);
	} while((rv = C_GetSlotList(with_token, list, &count) == CKR_BUFFER_TOO_SMALL));
	check_rv_late("C_GetSlotList");

	if(count > 1) {
		printf("INFO: multiple slots found, using slot %lu\n", list[0]);
	}

	*slot = list[0];
	free(list);

	return TEST_RV_OK;
}
Example #2
0
File: pkcs.c Project: 274914765/C
/*
 * initialize the Cryptoki library.
 */
int pkcs_init (void)
{
    CK_RV rv;

    CK_ULONG slotcount;

    CK_SLOT_ID_PTR pSlotList = NULL;

    netsnmp_pkcs_slot_session *tmp;

    int i, rval = SNMPERR_SUCCESS;

    /* Initialize pkcs */
    if ((rv = C_Initialize (NULL)) != CKR_OK)
    {
        DEBUGMSGTL (("pkcs_init", "C_Initialize failed: %s", pkcserr_string (rv)));
        return SNMPERR_SC_NOT_CONFIGURED;
    }

    /* Get slot count */
    rv = C_GetSlotList (1, NULL_PTR, &slotcount);
    if (rv != CKR_OK || slotcount == 0)
    {
        DEBUGMSGTL (("pkcs_init", "C_GetSlotList failed: %s", pkcserr_string (rv)));
        QUITFUN (SNMPERR_GENERR, pkcs_init_quit);
    }

    /* Found at least one slot, allocate memory for slot list */
    pSlotList = malloc (slotcount * sizeof (CK_SLOT_ID));
    pSlot = malloc (sizeof (netsnmp_pkcs_slot_info));
    pSlot->pSession = malloc (slotcount * sizeof (netsnmp_pkcs_slot_session));

    if (pSlotList == NULL_PTR || pSlot == NULL_PTR || pSlot->pSession == NULL_PTR)
    {
        DEBUGMSGTL (("pkcs_init", "malloc failed."));
        QUITFUN (SNMPERR_GENERR, pkcs_init_quit);
    }

    /* Get the list of slots */
    if ((rv = C_GetSlotList (1, pSlotList, &slotcount)) != CKR_OK)
    {
        DEBUGMSGTL (("pkcs_init", "C_GetSlotList failed: %s", pkcserr_string (rv)));
        QUITFUN (SNMPERR_GENERR, pkcs_init_quit);
    }

    /* initialize Slots structure */
    pSlot->count = slotcount;
    for (i = 0, tmp = pSlot->pSession; i < slotcount; i++, tmp++)
    {
        tmp->sid = pSlotList[i];
        tmp->hdl = NULL;
    }

    snmp_register_callback (SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN, free_slots, NULL);

  pkcs_init_quit:
    SNMP_FREE (pSlotList);
    return rval;
}
Example #3
0
void CPKCSDemoDlg::OnBtnConnect() 
{
	if(m_hSession)
		return;

	::SetCursor(::LoadCursor(NULL, IDC_WAIT));

	StartOP();

	CK_RV rv;
	CK_ULONG ulCount = 0;
	rv = C_GetSlotList(TRUE, NULL_PTR, &ulCount);
	if(CKR_OK != rv )
	{
		ShowErr(NEWLINE"Can't acquire information of slot, ErrorCode: 0x%08X."NEWLINE, rv);
		return;
	}
	if(0 >= ulCount)
	{
		ShowMsg(NEWLINE"Can't connect to token, make sure one token has been inserted."NEWLINE);
		return;
	}

	m_pSlotList = (CK_SLOT_ID_PTR)new CK_SLOT_ID[ulCount];
	if (! m_pSlotList) 
	{
		ShowMsg(NEWLINE"Not enough memory!"NEWLINE);
		return;
	}

	rv = C_GetSlotList(TRUE, m_pSlotList, &ulCount);
	if(CKR_OK != rv )
	{
		ShowErr(NEWLINE"Can't acquire information of slot, ErrorCode: 0x%08X."NEWLINE, rv);
		return;
	}
	if(0 >= ulCount)
	{
		ShowMsg(NEWLINE"Can't connect to token, make sure one token has been inserted."NEWLINE);
		return;
	}

	rv = C_OpenSession(
		m_pSlotList[0],  CKF_RW_SESSION | CKF_SERIAL_SESSION,
		&m_pApplication, NULL_PTR, &m_hSession);
	if(CKR_OK != rv )
	{
		ShowErr(NEWLINE"Can't Acquire information of slot, ErrorCode: 0x%08X."NEWLINE, rv);
		delete[] m_pSlotList;
		m_pSlotList = NULL_PTR;
	}
	else
	{
		ShowMsg(NEWLINE"Connect to token Successfully !"NEWLINE);
		m_btnConnect.EnableWindow(FALSE);
		ShowMsg(NEWLINE"Before next test step, need to generate RSA key pair!"NEWLINE);
		m_btnKeyPairGen.EnableWindow(TRUE);
	}
}
Example #4
0
KMF_RETURN
kmf_create_pk11_session(CK_SESSION_HANDLE *sessionp,
	CK_MECHANISM_TYPE wanted_mech,
	CK_FLAGS wanted_flags)
{
	CK_RV rv;
	KMF_RETURN ret;
	KMF_RETURN kmf_rv = KMF_OK;
	CK_SLOT_ID_PTR pSlotList;
	CK_ULONG pulCount;
	CK_MECHANISM_INFO info;
	int i;

	ret = init_pk11();

	if (ret != KMF_OK)
		return (ret);

	rv = C_GetSlotList(0, NULL, &pulCount);
	if (rv != CKR_OK) {
		kmf_rv = KMF_ERR_UNINITIALIZED;
		goto out;
	}

	pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID));
	if (pSlotList == NULL) {
		kmf_rv = KMF_ERR_MEMORY;
		goto out;
	}

	rv = C_GetSlotList(0, pSlotList, &pulCount);
	if (rv != CKR_OK) {
		kmf_rv = KMF_ERR_UNINITIALIZED;
		goto out;
	}

	for (i = 0; i < pulCount; i++) {
		rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info);
		if (rv == CKR_OK &&
		    (info.flags & wanted_flags) == wanted_flags)
			break;
	}
	if (i < pulCount) {
		rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION,
		    NULL, NULL, sessionp);

		if (rv != CKR_OK) {
			kmf_rv = KMF_ERR_UNINITIALIZED;
		}
	} else {
		kmf_rv = KMF_ERR_UNINITIALIZED;
	}

out:
	if (pSlotList != NULL)
		free(pSlotList);
	return (kmf_rv);

}
/* Solaris Kerberos */
krb5_error_code
krb5_open_pkcs11_session(CK_SESSION_HANDLE *hSession)
{
	krb5_error_code retval = 0;
	CK_RV rv; 
	CK_SLOT_ID_PTR slotlist = NULL_PTR; 
	CK_ULONG slotcount; 
	CK_ULONG i;

	/* List of all Slots */
	rv = C_GetSlotList(FALSE, NULL_PTR, &slotcount);
	if (rv != CKR_OK) {
		KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x.", rv);
		retval = PKCS_ERR;
		goto cleanup;
	}

	if (slotcount == 0) {
		KRB5_LOG0(KRB5_ERR, "No slot is found in PKCS11.");
		retval = PKCS_ERR;
		goto cleanup;
	}

	slotlist = (CK_SLOT_ID_PTR)malloc(slotcount * sizeof(CK_SLOT_ID));	
	if (slotlist == NULL) {
		KRB5_LOG0(KRB5_ERR, "malloc failed for slotcount.");
		retval = PKCS_ERR;
		goto cleanup;
	}
	
	rv = C_GetSlotList(FALSE, slotlist, &slotcount);
	if (rv != CKR_OK) {
		KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x", rv);
		retval = PKCS_ERR;
		goto cleanup;
	}
	for (i = 0; i < slotcount; i++) {
		if (slot_supports_krb5(slotlist + i))
			break;
	}
	if (i == slotcount){
		KRB5_LOG0(KRB5_ERR, "Could not find slot which supports "
		   "Kerberos");
		retval = PKCS_ERR;
		goto cleanup;
	}
	rv = C_OpenSession(slotlist[i], CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR,
	    hSession);
	if (rv != CKR_OK) {
		retval = PKCS_ERR;
	}
cleanup:
	if (slotlist != NULL)
		free(slotlist);
	return(retval);
}
void InfoTests::testGetSlotList()
{
	CK_RV rv;
	CK_ULONG ulSlotCount = 0;
	CK_SLOT_ID_PTR pSlotList;

	// Just make sure that we finalize any previous failed tests
	C_Finalize(NULL_PTR);

	rv = C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);

	rv = C_Initialize(NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_GetSlotList(CK_FALSE, NULL_PTR, NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_ARGUMENTS_BAD);

	// Get the size of the buffer
	rv = C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_OK);
	pSlotList = (CK_SLOT_ID_PTR)malloc(ulSlotCount * sizeof(CK_SLOT_ID));

	// Check if we have a too small buffer
	ulSlotCount = 0;
	rv = C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);

	// Get the slot list
	rv = C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_OK);
	free(pSlotList);

	// Get the number of slots with tokens
	rv = C_GetSlotList(CK_TRUE, NULL_PTR, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_OK);
	pSlotList = (CK_SLOT_ID_PTR)malloc(ulSlotCount * sizeof(CK_SLOT_ID));

	// Check if we have a too small buffer
	ulSlotCount = 0;
	rv = C_GetSlotList(CK_TRUE, pSlotList, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);

	// Get the slot list
	rv = C_GetSlotList(CK_TRUE, pSlotList, &ulSlotCount);
	CPPUNIT_ASSERT(rv == CKR_OK);
	free(pSlotList);

	C_Finalize(NULL_PTR);
}
Example #7
0
CK_SLOT_ID
get_slot() {
    CK_RV rv;
    CK_SLOT_ID slotId;
    CK_ULONG slotCount = 10;
    CK_SLOT_ID *slotIds = malloc(sizeof(CK_SLOT_ID) * slotCount);

    rv = C_GetSlotList(CK_TRUE, slotIds, &slotCount);
    check_return_value(rv, "get slot list");

    if (slotCount < 1) {
        free(slotIds);
        fprintf(stderr, "Error; could not find any slots\n");
        exit(1);
    }

    slotId = slotIds[0];
    free(slotIds);
    printf("slot count: %d\n", (int) slotCount);
    return slotId;
}
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Cryptoki::GetSlotsInternal___STATIC__SZARRAY_MicrosoftSPOTCryptokiSlot( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CK_ULONG                i;
    CK_SLOT_ID              slots[NETMF_CRYPTOKI_MAX_SLOTS];
    CK_ULONG                count = NETMF_CRYPTOKI_MAX_SLOTS;
    CLR_RT_HeapBlock_Array* pSlots;
    CLR_RT_HeapBlock        ref;
    CLR_RT_HeapBlock*       pSlotRef;

    CRYPTOKI_CHECK_RESULT(stack, C_GetSlotList(CK_FALSE, slots, &count));

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(ref, (CLR_UINT32)count, g_CLR_RT_WellKnownTypes.m_CryptokiSlot));

    pSlots = ref.DereferenceArray();

    pSlotRef = (CLR_RT_HeapBlock*)pSlots->GetFirstElement();
            
    for(i=0; i<count; i++)
    {
        CLR_RT_HeapBlock* pSlot;
        
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( pSlotRef[i], g_CLR_RT_WellKnownTypes.m_CryptokiSlot ));

        pSlot = pSlotRef[i].Dereference();
      
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotIndex    ].SetInteger        ((CLR_INT32)slots[i]);
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_disposed     ].SetBoolean        (false              );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_evtDispatcher].SetObjectReference(NULL               );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotEvent    ].SetObjectReference(NULL               );
        pSlot[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Slot::FIELD__m_slotInfo     ].SetObjectReference(NULL               );
    }

    stack.SetResult_Object(pSlots);

    TINYCLR_NOCLEANUP();
}
Example #9
0
/* C_Finalize indicates that an application is done with the
 * Cryptoki library. */
CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(
        CK_VOID_PTR pReserved
)
{
  CK_RV rv = CKR_OK;
  CK_SLOT_ID_PTR slot_list =NULL_PTR;
  CK_ULONG slot_num =0;
  CK_ULONG i;

  CI_LogEntry("C_Finalize", "starting...", rv, 1);

    /* make sure we are initialized */
  if (!(CK_I_global_flags & CK_IGF_INITIALIZED)) 
    return CKR_CRYPTOKI_NOT_INITIALIZED;

  if(pReserved != NULL_PTR)
    return CKR_ARGUMENTS_BAD;

  /* there can only be sessions on slot that have token */
  rv = C_GetSlotList(TRUE,NULL_PTR,&slot_num);
  if(rv != CKR_OK)
    {
      CI_LogEntry("C_Finalize", "getting count of slots", rv, 0);
      return rv;
    }

  slot_list = TC_malloc(slot_num*sizeof(CK_SLOT_ID_PTR));
  if( slot_list == NULL_PTR)
    {
      rv = CKR_HOST_MEMORY;
      CI_LogEntry("C_Finalize", "getting space for slot list", rv, 0);
      return rv;
    }

  rv = C_GetSlotList(TRUE,slot_list,&slot_num);
  if(rv != CKR_OK)
    {
      CI_LogEntry("C_Finalize", "getting slots list", rv, 0);
      return rv;
    }
  
  for(i =0 ; i< slot_num ; i++)
    {
      /* Deallocate all Sessions */
      rv = C_CloseAllSessions(slot_list[i]);
      if(rv != CKR_OK)
	{
	  CI_VarLogEntry("C_Finalize", "removing all sessions in slot %i", rv, 0,
			 slot_list[i]);
	  return rv;
	}

      /* Call CI_FinalizeToken in all Tokens */
      rv = CI_RemoveToken(slot_list[i]);
      if(rv != CKR_OK)
	{
	  CI_VarLogEntry("C_Finalize", "finalizing token in slot %i", rv, 0,
			 slot_list[i]);
	  return rv;
	}
    }
  TC_free(slot_list);

  //CI_DestroyHashtable(CK_I_app_table.session_table);
  if (CK_I_app_table.session_table != NULL_PTR)
  {
  CI_DestroyHashtable(CK_I_app_table.session_table);
  CK_I_app_table.session_table = NULL_PTR;
  }

  /**** assert that there are no remaining objects ****/
  rv = CI_ObjFinalize();
  if(rv != CKR_OK) 
    {
       CI_LogEntry("CI_InternalCloseSession",
		  "failed to clear objects",rv,0);
      return rv;
    }

#ifdef CK_GENERIC
  /* The call for the Win32 code will be done from DllMain() */
  rv = CI_UnloadDlls();
  if(rv != CKR_OK) 
    {
       CI_LogEntry("C_Finalize",
		  "failed to unload Dlls",rv,0);
      return rv;
    }
#endif  

  CK_I_global_flags ^= CK_IGF_INITIALIZED;
  CI_LogEntry("C_Finalize", "...complete", rv, 1);
  return rv;
}
Example #10
0
static int initFunction( DEVICE_INFO *deviceInfo, const char *name,
						 const int nameLength )
	{
	CK_SESSION_HANDLE hSession;
	CK_SLOT_ID slotList[ MAX_PKCS11_SLOTS + 8 ];
	CK_ULONG slotCount = MAX_PKCS11_SLOTS;
	CK_SLOT_INFO slotInfo;
	CK_TOKEN_INFO tokenInfo;
	CK_RV status;
	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
	const PKCS11_MECHANISM_INFO *mechanismInfoPtr;
	char *labelPtr;
	int tokenSlot = DEFAULT_SLOT, i, labelLength, mechanismInfoSize;
	int cryptStatus, cryptStatus2;

	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
	assert( isReadPtr( name, nameLength ) );

	/* Get information on all available slots */
	memset( slotList, 0, sizeof( slotList ) );
	status = C_GetSlotList( TRUE, slotList, &slotCount );
	if( status != CKR_OK )
		return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) );
	if( slotCount <= 0 )
		{
		/* There are token slots present but no tokens in the slots */
		return( CRYPT_ERROR_OPEN );
		}

	/* Check whether a token name (used to select the slot) has been 
	   specified */
	for( i = 1; i < nameLength - 1; i++ )
		{
		if( name[ i ] == ':' && name[ i + 1 ] == ':' )
			break;
		}
	if( i < nameLength - 1 )
		{
		const char *tokenName = name + i + 2;	/* Skip '::' */
		const int tokenNameLength = nameLength - ( i + 2 );

		if( tokenNameLength <= 0 )
			return( CRYPT_ARGERROR_STR1 );

		/* Some tokens don't implement named slots, so we also allow them to 
		   be specified using slot counts */
		if( tokenNameLength == 1 && isDigit( *tokenName ) )
			{
			tokenSlot = *tokenName - '0';
			if( tokenSlot < 0 || tokenSlot > 9 )
				return( CRYPT_ARGERROR_STR1 );
			if( tokenSlot > slotCount - 1 )	/* Slots numbered from zero */
				return( CRYPT_ERROR_NOTFOUND );
			status = C_GetTokenInfo( slotList[ tokenSlot ], &tokenInfo );
			if( status != CKR_OK )
				return( CRYPT_ERROR_NOTFOUND );
			}
		else
			{
			/* Check each (named) slot for a token matching the given name */
			for( tokenSlot = 0; tokenSlot < slotCount && \
								tokenSlot < FAILSAFE_ITERATIONS_MED; 
				 tokenSlot++ )
				{
				status = C_GetTokenInfo( slotList[ tokenSlot ], &tokenInfo );
				if( status == CKR_OK && \
					!strCompare( tokenName, tokenInfo.label, tokenNameLength ) )
					break;
				}
			ENSURES( tokenSlot < FAILSAFE_ITERATIONS_MED );
			if( tokenSlot >= slotCount )
				return( CRYPT_ERROR_NOTFOUND );
			}
		}
	pkcs11Info->slotID = slotList[ tokenSlot ];

	/* Get information on device-specific capabilities */
	status = C_GetSlotInfo( pkcs11Info->slotID, &slotInfo );
	if( status != CKR_OK )
		{
		shutdownFunction( deviceInfo );
		return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) );
		}
	if( slotInfo.flags & CKF_REMOVABLE_DEVICE )
		{
		/* The device is removable */
		deviceInfo->flags |= DEVICE_REMOVABLE;
		}
	status = C_GetTokenInfo( pkcs11Info->slotID, &tokenInfo );
	if( status != CKR_OK )
		{
		shutdownFunction( deviceInfo );
		return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) );
		}
	if( tokenInfo.flags & CKF_RNG )
		{
		/* The device has an onboard RNG that we can use */
		deviceInfo->getRandomFunction = getRandomFunction;
		}
#if 0	/* The Spyrus driver for pre-Lynks-II cards returns the local system 
		   time (with a GMT/localtime offset), ignoring the fact that the 
		   token has an onboard clock, so having the CKF_CLOCK_ON_TOKEN not 
		   set is accurate, although having it ignore the presence of the 
		   clock isn't very valid */
	if( !( tokenInfo.flags & CKF_CLOCK_ON_TOKEN ) && \
		( !strCompare( tokenInfo.label, "Lynks Token", 11 ) || \
		  !strCompare( tokenInfo.model, "Rosetta", 7 ) ) )
		{
		/* Fix buggy Spyrus PKCS #11 drivers which claim that the token
		   doesn't have a RTC even though it does (the Rosetta (smart card) 
		   form of the token is even worse, it returns garbage in the label 
		   and manufacturer fields, but the model field is OK).  There is a 
		   chance that there's a genuine problem with the clock (there are 
		   batches of tokens with bad clocks) but the time check that  
		   follows below will catch those */
		tokenInfo.flags |= CKF_CLOCK_ON_TOKEN;
		}
#endif /* 0 */
	if( tokenInfo.flags & CKF_CLOCK_ON_TOKEN )
		{
		const time_t theTime = getTokenTime( &tokenInfo );
		const time_t currentTime = getTime();

		/* The token claims to have an onboard clock that we can use.  Since
		   this could be arbitrarily inaccurate we compare it with the 
		   system time and only rely on it if it's within +/- 1 day of the
		   system time.
		   
		   There is a second check that we should make to catch drivers that
		   claim to read the time from the token but actually use the local
		   computer's time, but this isn't easy to do.  The most obvious way
		   is to set the system time to a bogus value and check whether this
		   matches the returned time, but this is somewhat drastic and 
		   requires superuser privs on most systems.  An alternative is to 
		   check whether the claimed token time exactly matches the system 
		   time, but this will produce false positives if (for example) the
		   token has been recently synchronised to the system time.  For now
		   all we can do is throw an exception if it appears that the token
		   time is faked */
		if( theTime > MIN_TIME_VALUE && \
			theTime >= currentTime - 86400 && \
			theTime <= currentTime + 86400 )
			deviceInfo->flags |= DEVICE_TIME;

		/* If this check is triggered then the token time may be faked since 
		   it's identical to the host system time, see the comment above for 
		   details.  We make an exception for soft-tokens (if we can detect 
		   them), which will (by definition) have the same time as the 
		   system time */
		if( !( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name[ 0 ] && \
			   !strCompare( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name, 
							"Software", 8 ) ) && \
			theTime == currentTime )
			{
			DEBUG_DIAG(( "PKCS #11 token time is the same as the host "
						 "system time, token time may be faked by the "
						 "driver." ));
			assert( DEBUG_WARN );
			}
		}
	if( tokenInfo.flags & CKF_WRITE_PROTECTED )
		{
		/* The device can't have data on it changed */
		deviceInfo->flags |= DEVICE_READONLY;
		}
	if( ( tokenInfo.flags & CKF_LOGIN_REQUIRED ) || \
		!( tokenInfo.flags & CKF_USER_PIN_INITIALIZED ) )
		{
		/* The user needs to log in before using various device functions.
		   We check for the absence of CKF_USER_PIN_INITIALIZED as well as 
		   the more obvious CKF_LOGIN_REQUIRED because if we've got an 
		   uninitialised device there's no PIN set so some devices will 
		   report that there's no login required (or at least none is 
		   possible).  We need to introduce some sort of pipeline stall if 
		   this is the case because otherwise the user could successfully 
		   perform some functions that don't require a login (where the 
		   exact details of what's allowed without a login are device-
		   specific) before running into mysterious failures when they get 
		   to functions that do require a login.  To avoid this, we make an 
		   uninitialised device look like a login-required device, so the 
		   user gets an invalid-PIN error if they try and proceed */
		deviceInfo->flags |= DEVICE_NEEDSLOGIN;
		}
	if( ( pkcs11Info->minPinSize = ( int ) tokenInfo.ulMinPinLen ) < 4 )
		{
		/* Some devices report silly PIN sizes */
		DEBUG_DIAG(( "Driver reports suspicious minimum PIN size %lu, "
					 "using 4", tokenInfo.ulMinPinLen ));
		pkcs11Info->minPinSize = 4;
		}
	if( ( pkcs11Info->maxPinSize = ( int ) tokenInfo.ulMaxPinLen ) < 4 )
		{
		/* Some devices report silly PIN sizes (setting this to ULONG_MAX or
		   4GB, which becomes -1 as an int, counts as silly).  Since we can't
		   differentiate between 0xFFFFFFFF = bogus value and 0xFFFFFFFF = 
		   ULONG_MAX we play it safe and set the limit to 8 bytes, which most
		   devices should be able to handle */
		DEBUG_DIAG(( "Driver reports suspicious maximum PIN size %lu, "
					 "using 8", tokenInfo.ulMinPinLen ));
		pkcs11Info->maxPinSize = 8;
		}
	labelPtr = ( char * ) tokenInfo.label;
	for( labelLength = 32;
		 labelLength > 0 && \
		 ( labelPtr[ labelLength - 1 ] == ' ' || \
		   !labelPtr[ labelLength - 1 ] ); 
		  labelLength-- );	/* Strip trailing blanks/nulls */
	while( labelLength > 0 && *labelPtr == ' ' )
		{
		/* Strip leading blanks */
		labelPtr++;
		labelLength--;
		}
	if( labelLength > 0 )
		{
		memcpy( pkcs11Info->label, labelPtr, labelLength );
		pkcs11Info->labelLen = labelLength;
		sanitiseString( pkcs11Info->label, CRYPT_MAX_TEXTSIZE, 
						labelLength );
		}
	else
		{
		/* There's no label for the token, use the device label instead */
		if( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name[ 0 ] )
			{
			labelLength = \
				min( strlen( pkcs11InfoTbl[ pkcs11Info->deviceNo ].name ),
					 CRYPT_MAX_TEXTSIZE );
			memcpy( pkcs11Info->label, 
					pkcs11InfoTbl[ pkcs11Info->deviceNo ].name, labelLength );
			}
		}
	pkcs11Info->hActiveSignObject = CK_OBJECT_NONE;
	deviceInfo->label = pkcs11Info->label;
	deviceInfo->labelLen = pkcs11Info->labelLen;

	/* Open a session with the device.  This gets a bit awkward because we 
	   can't tell whether a R/W session is OK without opening a session, but 
	   we can't open a session unless we know whether a R/W session is OK, 
	   so we first try for a RW session and if that fails we go for a read-
	   only session */
	status = C_OpenSession( pkcs11Info->slotID, 
							CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL_PTR, 
							NULL_PTR, &hSession );
	if( status == CKR_TOKEN_WRITE_PROTECTED )
		{
		status = C_OpenSession( pkcs11Info->slotID, 
								CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, 
								&hSession );
		}
	if( status != CKR_OK )
		{
		cryptStatus = pkcs11MapError( status, CRYPT_ERROR_OPEN );
		if( cryptStatus == CRYPT_ERROR_OPEN && \
			!( tokenInfo.flags & CKF_USER_PIN_INITIALIZED ) )
			{
			/* We couldn't do much with the error code, it could be that the
			   token hasn't been initialised yet but unfortunately PKCS #11 
			   doesn't define an error code for this condition.  In addition
			   many tokens will allow a session to be opened and then fail 
			   with a "PIN not set" error at a later point (which allows for
			   more accurate error reporting), however a small number won't
			   allow a session to be opened and return some odd-looking error
			   because there's nothing useful available.  The best way to
			   report this in a meaningful manner to the caller is to check
			   whether the user PIN has been initialised, if it hasn't then 
			   it's likely that the token as a whole hasn't been initialised 
			   so we return a not initialised error */
			cryptStatus = CRYPT_ERROR_NOTINITED;
			}
		return( cryptStatus );
		}
	ENSURES( hSession != CK_OBJECT_NONE );
	pkcs11Info->hSession = hSession;
	deviceInfo->flags |= DEVICE_ACTIVE;

	/* Set up the capability information for this device.  Since there can 
	   be devices that have one set of capabilities but not the other (e.g.
	   a smart card that only performs RSA ops), we allow one of the two
	   sets of mechanism information setups to fail, but not both */
	mechanismInfoPtr = getMechanismInfoPKC( &mechanismInfoSize );
	cryptStatus = getCapabilities( deviceInfo, mechanismInfoPtr, 
								   mechanismInfoSize );
	mechanismInfoPtr = getMechanismInfoConv( &mechanismInfoSize );
	cryptStatus2 = getCapabilities( deviceInfo, mechanismInfoPtr, 
									mechanismInfoSize );
	if( cryptStatusError( cryptStatus ) && cryptStatusError( cryptStatus2 ) )
		{
		shutdownFunction( deviceInfo );
		return( ( cryptStatus == CRYPT_ERROR ) ? \
				CRYPT_ERROR_OPEN : ( int ) cryptStatus );
		}

	return( CRYPT_OK );
	}
Example #11
0
int
main (int argc, char *argv[])
{
  CK_RV err;
  bool token = false;
  CK_SLOT_ID_PTR slots;
  CK_ULONG slots_count;
  unsigned int i;

  (void) argv;

  if (argc > 1)
    token = true;

  init_cryptoki ();

  err = C_GetSlotList (token, NULL, &slots_count);
  fail_if_err (err);

  printf ("Number of slots%s: %lu\n", token ? " (with tokens)" : "",
	  slots_count);
  slots = malloc (sizeof (CK_SLOT_ID) * slots_count);
  if (!slots)
    fail_if_err (CKR_HOST_MEMORY);

  err = C_GetSlotList (token, slots, &slots_count);
  fail_if_err (err);

  //  while (1)
    {
  for (i = 0; i < slots_count; i++)
    {
      CK_SLOT_INFO info;

      err = C_GetSlotInfo (slots[i], &info);
      fail_if_err (err);

      printf ("%2i. Slot ID %lu\n", i, slots[i]);

      printf ("    %.64s\n", info.slotDescription);
      printf ("    Manufacturer ID: %.32s\n", info.manufacturerID);
      printf ("    Flags: %#lx", info.flags);
      if (info.flags)
	{
	  bool any = false;
	  CK_FLAGS xflags;

	  xflags = info.flags & ~(CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE
				  | CKF_HW_SLOT);
	  printf (" == ");
	  if (info.flags & CKF_TOKEN_PRESENT)
	    {
	      printf ("TOKEN_PRESENT");
	      any = true;
	    }
	  if (info.flags & CKF_REMOVABLE_DEVICE)
	    {
	      printf ("%sREMOVABLE_DEVICE", any ? " | " : "");
	      any = true;
	    }
	  if (info.flags & CKF_HW_SLOT)
	    {
	      printf ("%sHW_SLOT", any ? " | " : "");
	      any = true;
	    }
	  if (xflags)
	    printf ("%s%#lx", any ? " | " : "", xflags);
	}
      printf ("\n");

      printf ("    Hardware version: %i.%i\n", info.hardwareVersion.major,
	      info.hardwareVersion.minor);
      printf ("    Firmware version: %i.%i\n", info.firmwareVersion.major,
	      info.firmwareVersion.minor);
    }
#ifdef WIN32
  _sleep (2);
#else
  sleep (2);
#endif
    }

  return 0;
}
Example #12
0
File: fuzz.c Project: Fedict/eid-mw
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
	static bool initialized = false;
	CK_SLOT_ID slot;
	CK_ULONG count = 0, type;
	CK_SLOT_ID_PTR slotlist = NULL;
	CK_RV rv;
	CK_SESSION_HANDLE session;
	CK_ATTRIBUTE attrs[2];
	CK_OBJECT_HANDLE object;

	beid_set_fuzz_data(data, size, "3F00DF014031");
	check_rv(C_Initialize(NULL));
	do {
		slotlist = realloc(slotlist, sizeof(CK_SLOT_ID) * count);
	} while((rv = C_GetSlotList(CK_TRUE, slotlist, &count)) == CKR_BUFFER_TOO_SMALL);

	check_rv_late("C_GetSlotList");

	assert(count > 0);

	check_rv(C_OpenSession(slotlist[0], CKF_SERIAL_SESSION, NULL, NULL, &session));
	free(slotlist);
	slotlist = NULL;

	attrs[0].type = CKA_CLASS;
	attrs[0].pValue = &type;
	type = CKO_DATA;
	attrs[0].ulValueLen = sizeof(CK_ULONG);
	attrs[1].type = CKA_OBJECT_ID;
	attrs[1].pValue = "id";
	attrs[1].ulValueLen = strlen("id");

	check_rv(C_FindObjectsInit(session, attrs, 2));

	char *label_str = NULL;
	char *value_str = NULL;
	char *objid_str = NULL;

	do {
		char junk[1024];

		CK_ATTRIBUTE data[3] = {
			{CKA_LABEL, NULL_PTR, 0},
			{CKA_VALUE, NULL_PTR, 0},
			{CKA_OBJECT_ID, NULL_PTR, 0},
		};

		check_rv(C_FindObjects(session, &object, 1, &count));
		if(!count) continue;

		free(label_str);
		free(value_str);
		free(objid_str);

		check_rv(C_GetAttributeValue(session, object, data, 3));

		label_str = calloc(data[0].ulValueLen + 1, 1);
		data[0].pValue = label_str;

		value_str = calloc(data[1].ulValueLen + 1, 1);
		data[1].pValue = value_str;

		objid_str = calloc(data[2].ulValueLen + 1, 1);
		data[2].pValue = objid_str;

		check_rv(C_GetAttributeValue(session, object, data, 3));

		snprintf(junk, sizeof(junk), "%s%s%s", label_str, value_str, objid_str);
	} while(count);

	printf("label: %s, objid: %s, value: %s\n", label_str, objid_str, value_str);

	free(label_str);
	free(value_str);
	free(objid_str);

	check_rv(C_CloseSession(session));
	check_rv(C_Finalize(NULL));

	return 0;
}
CK_SLOT_ID Cryptoki_FindSlot(LPCSTR szProvider, CK_MECHANISM_TYPE_PTR mechs, INT32 mechCnt)
{
    CK_SLOT_ID slotList[10];
    CK_ULONG   slotCnt = ARRAYSIZE(slotList);
    UINT32 lenSP;
    CK_SLOT_ID slotID = CK_SLOT_ID_INVALID;
    UINT32      i;

    lenSP = szProvider == NULL ? 0 : hal_strlen_s(szProvider);
    
    if(CKR_OK == C_GetSlotList(TRUE, slotList, &slotCnt))
    {
        for(i=0; i<slotCnt; i++)
        {
            CK_TOKEN_INFO info;

            if(mechCnt == 0)
            {
                slotID = slotList[i];
                break;
            }
            else if(CKR_OK == C_GetTokenInfo(slotList[i], &info))
            {
                INT32 len2 = hal_strlen_s((const char*)info.label);
            
                if((lenSP == 0) || ((lenSP == len2) && (hal_strncmp_s(szProvider, (const char*)info.label, lenSP) == 0)))
                {
                    if(mechCnt > 0)
                    {
                        CK_MECHANISM_TYPE tokenMechs[100];
                        CK_ULONG cnt = 100;
                            
                        if(CKR_OK == C_GetMechanismList(slotList[i], tokenMechs, &cnt))
                        {
                            bool slotIsOK = false;
                            CK_ULONG t, s;

                            for(s = 0; (INT32)s < mechCnt; s++)
                            {
                                slotIsOK = false;

                                for(t = 0; t < cnt; t++)
                                {
                                    if(mechs[s] == tokenMechs[t])
                                    {
                                        slotIsOK = true;
                                        break;
                                    }
                                }

                                if(!slotIsOK) break;
                            }
                            
                            if(slotIsOK)
                            {
                                slotID = slotList[i];
                                break;
                            }
                        }
                    }
                    else 
                    {
                        slotID = slotList[i];
                        break;
                    }
                }
            }
        }
    }

    return slotID;
}
Example #14
0
int
main (int argc, char *argv[])
{
  CK_RV err;
  CK_SLOT_ID_PTR slots;
  CK_ULONG slots_count;
  unsigned int i;

  (void) argc;
  (void) argv;

  if (argc > 1 && !strcmp ("--printable", argv[1]))
    printable = true;
    
  init_cryptoki ();

  err = C_GetSlotList (true, NULL, &slots_count);
  fail_if_err (err);

  if (slots_count == 0)
    {
      printf ("Skipping test because no token is present.\n");
      return 77;
    }

  printf ("Number of slots with tokens: %lu\n", slots_count);
  slots = malloc (sizeof (CK_SLOT_ID) * slots_count);
  if (!slots)
    fail_if_err (CKR_HOST_MEMORY);

  err = C_GetSlotList (true, slots, &slots_count);
  fail_if_err (err);

  for (i = 0; i < slots_count; i++)
    {
      CK_SESSION_HANDLE session;
      CK_OBJECT_HANDLE object;
      CK_ULONG count;

      printf ("%2i. Slot ID %lu\n", i, slots[i]);
      err = C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL,
			   &session);
      fail_if_err (err);
     
      printf ("    Session ID: %lu\n", session);

      err = C_FindObjectsInit (session, NULL, 0);
      fail_if_err (err);

      do
	{
	  err = C_FindObjects (session, &object, 1, &count);
	  fail_if_err (err);

	  if (count)
	    {
	      printf ("    Object Handle: %lu\n", object);

	      err = dump_object (session, object);
	      fail_if_err (err);
	    }
	}
      while (count);

      err = C_FindObjectsFinal (session);
      fail_if_err (err);

      err = C_CloseSession (session);
      fail_if_err (err);
    }

  return 0;
}