Solaris 开发者安全性指南

消息摘要示例

    此示例使用 PKCS #11 函数通过输入文件创建摘要。该示例执行以下步骤:

  1. 指定摘要机制。

    此示例中使用的是 CKM_MD5 摘要机制。

  2. 查找适用于指定摘要算法的插槽。

    此示例使用 Sun 的便利函数 SUNW_C_GetMechSession()SUNW_C_GetMechSession() 用于打开 cryptoki 库,该库用于存放 Solaris 加密框架中所使用的全部 PKCS #11 函数。SUNW_C_GetMechSession() 随后使用所需的机制来查找插槽。然后,将会启动会话。这个便利函数可有效地替换 C_Initialize() 调用、C_OpenSession() 调用以及查找支持指定机制的插槽所需的任何代码。

  3. 获取 cryptoki 信息。

    本部分实际上不是创建消息摘要所必需的,之所以将其包括在内是为了说明 C_GetInfo() 函数的用法。此示例中将获取制造商 ID。其他信息选项用于检索版本和库数据。

  4. 针对插槽执行摘要操作。

    此任务中的消息摘要可通过以下三个步骤创建:

    1. 打开输入文件。

    2. 通过调用 C_DigestInit() 来初始化摘要操作。

    3. 使用 C_DigestUpdate() 逐段处理数据。

    4. 使用 C_DigestFinal() 获取完整的摘要,从而结束摘要操作过程。

  5. 结束会话。

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

以下示例中显示了消息摘要示例的源代码。


注 –

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



示例 9–1 使用 PKCS #11 函数创建消息摘要

#include <stdio.h>

#include <fcntl.h>

#include <errno.h>

#include <sys/types.h>

#include <security/cryptoki.h>

#include <security/pkcs11.h>



#define BUFFERSIZ    8192

#define MAXDIGEST    64



/* Calculate the digest of a user supplied file. */

void

main(int argc, char **argv)

{

	CK_BYTE digest[MAXDIGEST];

	CK_INFO info;

	CK_MECHANISM mechanism;

	CK_SESSION_HANDLE hSession;

	CK_SESSION_INFO Info;

	CK_ULONG ulDatalen = BUFFERSIZ;

	CK_ULONG ulDigestLen = MAXDIGEST;

	CK_RV rv;

	CK_SLOT_ID SlotID;



	int i, bytes_read = 0;

	char inbuf[BUFFERSIZ];

	FILE *fs;

	int error = 0;



	/* Specify the CKM_MD5 digest mechanism as the target */

	mechanism.mechanism = CKM_MD5;

	mechanism.pParameter = NULL_PTR;

	mechanism.ulParameterLen = 0;



	/* Use SUNW convenience function to initialize the cryptoki

	 * library, and open a session with a slot that supports

	 * the mechanism we plan on using. */

	rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession);

	if (rv != CKR_OK) {

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

		exit(1);

	}



	/* Get cryptoki information, the manufacturer ID */

	rv = C_GetInfo(&info);

	if (rv != CKR_OK) {

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

	}

	fprintf(stdout, "Manufacturer ID = %s\n", info.manufacturerID);



	/* Open the input file */

	if ((fs = fopen(argv[1], "r")) == NULL) {

		perror("fopen");

		fprintf(stderr, "\n\tusage: %s filename>\n", argv[0]);

		error = 1;

		goto exit_session;

	}



	/* Initialize the digest session */

	if ((rv = C_DigestInit(hSession, &mechanism)) != CKR_OK) {

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

		error = 1;

		goto exit_digest;

	}



	/* Read in the data and create digest of this portion */

	while (!feof(fs) && (ulDatalen = fread(inbuf, 1, BUFFERSIZ, fs)) > 0) {

		if ((rv = C_DigestUpdate(hSession, (CK_BYTE_PTR)inbuf,

				    ulDatalen)) != CKR_OK) {

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

			error = 1;

			goto exit_digest;

		}

		bytes_read += ulDatalen;

	}

	fprintf(stdout, "%d bytes read and digested!!!\n\n", bytes_read);



	/* Get complete digest */

	ulDigestLen = sizeof (digest);

	if ((rv = C_DigestFinal(hSession, (CK_BYTE_PTR)digest,

			    &ulDigestLen)) != CKR_OK) {

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

		error = 1;

		goto exit_digest;

	}



	/* Print the results */

	fprintf(stdout, "The value of the digest is: ");

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

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

	}

	fprintf(stdout, "\nDone!!!\n");



exit_digest:

	fclose(fs);



exit_session:

	(void) C_CloseSession(hSession);



exit_program:

	(void) C_Finalize(NULL_PTR);



	exit(error);



}