この例では、PKCS #11 関数を使って入力ファイルからダイジェストを作成します。この例では、次の手順を実行します。
ダイジェストのメカニズムを指定します。
この例では、CKM_MD5 ダイジェストメカニズムが使用されます。
指定されたダイジェストアルゴリズムをサポートするスロットを検索します。
この例では、Oracle Solaris の簡易関数 SUNW_C_GetMechSession() を使用しています。SUNW_C_GetMechSession() は、cryptoki ライブラリをオープンします。このライブラリには、Oracle Solaris 暗号化フレームワークで使用されるすべての PKCS #11 関数が含まれています。続いて SUNW_C_GetMechSession() は、目的のメカニズムを備えたスロットを検索します。そして、セッションが開始されます。この簡易関数は事実上、C_Initialize() 呼び出し、C_OpenSession() 呼び出し、および指定されたメカニズムをサポートするスロットの検索に必要なすべてのコードと同等の機能を備えています。
cryptoki の情報を取得します。
この部分は実際には、メッセージダイジェストの作成に直接関係しませんが、C_GetInfo() 関数の使用法を示す意味でここに含めてあります。この例では開発元の ID を取得しています。その他の情報のオプションとして、バージョンとライブラリデータも取得できます。
スロットを使ってダイジェスト処理を実行します。
このタスクにおけるメッセージダイジェストの作成手順は次のとおりです。
入力ファイルをオープンします。
C_DigestInit() を呼び出してダイジェスト処理を初期化します。
C_DigestUpdate() を使ってデータを一度に一部分ずつ処理します。
ダイジェスト処理を終了するために、C_DigestFinal() を使って完全なダイジェストを取得します。
セッションを終了します。
このプログラムは、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); }