Oracle® Solaris 11 セキュリティー開発者ガイド

印刷ビューの終了

更新: 2014 年 7 月
 
 

メッセージダイジェストの例

    この例では、PKCS #11 関数を使って入力ファイルからダイジェストを作成します。この例では、次の手順を実行します。

  1. ダイジェストのメカニズムを指定します。

    この例では、CKM_MD5 ダイジェストメカニズムが使用されます。

  2. 指定されたダイジェストアルゴリズムをサポートするスロットを検索します。

    この例では、Oracle Solaris の簡易関数 SUNW_C_GetMechSession() を使用しています。SUNW_C_GetMechSession() は、cryptoki ライブラリをオープンします。このライブラリには、Oracle 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() を使ってライブラリをクローズします。

メッセージダイジェストのソースコード例を、次に示します。

使用例 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);

}