Solaris 开发者安全性指南

随机字节生成示例

示例 9–4 说明了如何使用可以生成随机字节的机制来查找插槽。此示例执行以下步骤:

  1. 初始化 cryptoki 库。

  2. 调用 GetRandSlot(),以便使用可以生成随机字节的机制来查找插槽。

      插槽查找任务执行以下步骤:

    1. 调用 C_GetSlotList() 函数以获取可用插槽的列表。

      与 PKCS #11 约定中所建议的一样,C_GetSlotList() 需要调用两次。第一次调用 C_GetSlotList() 用于获取进行内存分配的插槽数量,第二次调用 C_GetSlotList() 用于检索插槽。

    2. 查找可以生成随机字节的插槽。

      对于每个插槽,该函数都可以使用 GetTokenInfo() 来获取令牌信息,并在设置了 CKF_RNG 标志的情况下检查匹配项。如果找到设置了 CKF_RNG 标志的插槽,则 GetRandSlot() 函数将返回。

  3. 使用 C_OpenSession() 来打开会话。

  4. 使用 C_GenerateRandom() 来生成随机字节。

  5. 结束会话。

    程序使用 C_CloseSession() 关闭会话,使用 C_Finalize() 关闭库。

随机数生成样例的源代码如以下示例所示。


注 –

此示例的源代码也可以通过 Sun 下载中心获取。请访问 http://www.sun.com/download/products.xml?id=41912db5



示例 9–4 使用 PKCS #11 函数生成随机数

#include <stdio.h>

#include <fcntl.h>

#include <errno.h>

#include <sys/types.h>

#include <security/cryptoki.h>

#include <security/pkcs11.h>



#define RANDSIZE 64



boolean_t GetRandSlot(CK_SLOT_ID_PTR pslot);



/* Example generates random bytes. */

void

main(int argc, char **argv)

{

	CK_RV   rv;

	CK_MECHANISM mech;

	CK_SESSION_HANDLE hSession;

	CK_SESSION_INFO sessInfo;

	CK_SLOT_ID slotID;

	CK_BYTE randBytes[RANDSIZE];



	boolean_t found_slot = B_FALSE;

	int error;

	int i;



	/* Initialize the CRYPTOKI library */

	rv = C_Initialize(NULL_PTR);



	if (rv != CKR_OK) {

		fprintf(stderr, "C_Initialize: Error = 0x%.8X\n", rv);

		exit(1);

	}



	found_slot = GetRandSlot(&slotID);



	if (!found_slot) {

		goto exit_program;

	}



	/* Open a session on the slot found */

	rv = C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR,

	    &hSession);



	if (rv != CKR_OK) {

		fprintf(stderr, "C_OpenSession: rv = 0x%.8x\n", rv);

		error = 1;

		goto exit_program;

	}



	/* Generate random bytes */

	rv = C_GenerateRandom(hSession, randBytes, RANDSIZE);



	if (rv != CKR_OK) {

		fprintf(stderr, "C_GenerateRandom: rv = 0x%.8x\n", rv);

		error = 1;

		goto exit_session;

	}



	fprintf(stdout, "Random value: ");

	for (i = 0; i < RANDSIZE; i++) {

		fprintf(stdout, "%.2x", randBytes[i]);

	}



exit_session:

	(void) C_CloseSession(hSession);



exit_program:

	(void) C_Finalize(NULL_PTR);

	exit(error);



}



boolean_t

GetRandSlot(CK_SLOT_ID_PTR pslot)

{

	CK_SLOT_ID_PTR pSlotList;

	CK_SLOT_ID SlotID;

	CK_TOKEN_INFO tokenInfo;

	CK_ULONG ulSlotCount;

	CK_MECHANISM_TYPE_PTR pMechTypeList = NULL_PTR;

	CK_ULONG ulMechTypecount;

	boolean_t result = B_FALSE;

	int i = 0;



	CK_RV rv;



	/* Get slot list for memory allocation */

	rv = C_GetSlotList(0, NULL_PTR, &ulSlotCount);



	if ((rv == CKR_OK) && (ulSlotCount > 0)) {

		fprintf(stdout, "slotCount = %d\n", (int)ulSlotCount);

		pSlotList = malloc(ulSlotCount * sizeof (CK_SLOT_ID));



		if (pSlotList == NULL) {

			fprintf(stderr,

			    "System error: unable to allocate memory\n");

			return (result);

		}



		/* Get the slot list for processing */

		rv = C_GetSlotList(0, pSlotList, &ulSlotCount);

		if (rv != CKR_OK) {

			fprintf(stderr, "GetSlotList failed: unable to get "

			    "slot list.\n");

			free(pSlotList);

			return (result);

		}

	} else {

		fprintf(stderr, "GetSlotList failed: unable to get slot"

		    " count.\n");

		return (result);

	}



	/* Find a slot capable of doing random number generation */

	for (i = 0; i < ulSlotCount; i++) {

		SlotID = pSlotList[i];



		rv = C_GetTokenInfo(SlotID, &tokenInfo);



		if (rv != CKR_OK) {

			/* Check the next slot */

			continue;

		}



		if (tokenInfo.flags & CKF_RNG) {

			/* Found a random number generator */

			*pslot = SlotID;

			fprintf(stdout, "Slot # %d supports random number "

			    "generation!\n", SlotID);

			result = B_TRUE;

			break;

		}

	}



	if (pSlotList)

		free(pSlotList);



	return (result);



}