test-certificate.c

The following example shows some basic usage of the certificate interface.

00001 #include "../../config.h"
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #if defined(_WIN32)
00006 #include <conio.h>
00007 #else
00008 #include <unistd.h>
00009 #endif
00010 
00011 #if !(defined(ENABLE_PKCS11H_CERTIFICATE) && (defined(ENABLE_PKCS11H_ENGINE_OPENSSL) || defined (ENABLE_PKCS11H_ENGINE_GNUTLS) || defined(ENABLE_PKCS11H_ENGINE_WIN32)))
00012 int main () {
00013         printf ("!win32, certificate, enum and crypto engine interfaces should be enabled for this test");
00014         exit (0);
00015         return 0;
00016 }
00017 #else
00018 
00019 #include <pkcs11-helper-1.0/pkcs11h-certificate.h>
00020 #include <unistd.h>
00021 
00022 static
00023 void
00024 fatal (const char * const m, CK_RV rv) {
00025         fprintf (stderr, "%s - %lu - %s\n", m, rv, pkcs11h_getMessage (rv));
00026         exit (1);
00027 }
00028 
00029 static
00030 void
00031 mypause (const char * const m) {
00032         char temp[10];
00033 
00034         fprintf (stdout, "%s", m);
00035         fflush (stdout);
00036         fgets (temp, sizeof (temp), stdin);
00037 }
00038 
00039 static
00040 void
00041 _pkcs11h_hooks_log (
00042         IN void * const global_data,
00043         IN unsigned flags,
00044         IN const char * const format,
00045         IN va_list args
00046 ) {
00047         vfprintf (stdout, format, args);
00048         fprintf (stdout, "\n");
00049         fflush (stdout);
00050 }
00051 
00052 static
00053 PKCS11H_BOOL
00054 _pkcs11h_hooks_token_prompt (
00055         IN void * const global_data,
00056         IN void * const user_data,
00057         IN const pkcs11h_token_id_t token,
00058         IN const unsigned retry
00059 ) {
00060         char buf[1024];
00061         PKCS11H_BOOL fValidInput = FALSE;
00062         PKCS11H_BOOL fRet = FALSE;
00063 
00064         while (!fValidInput) {
00065                 fprintf (stderr, "Please insert token '%s' 'ok' or 'cancel': ", token->display);
00066                 fgets (buf, sizeof (buf), stdin);
00067                 buf[sizeof (buf)-1] = '\0';
00068                 fflush (stdin);
00069 
00070                 if (buf[strlen (buf)-1] == '\n') {
00071                         buf[strlen (buf)-1] = '\0';
00072                 }
00073                 if (buf[strlen (buf)-1] == '\r') {
00074                         buf[strlen (buf)-1] = '\0';
00075                 }
00076 
00077                 if (!strcmp (buf, "ok")) {
00078                         fValidInput = TRUE;
00079                         fRet = TRUE;
00080                 }
00081                 else if (!strcmp (buf, "cancel")) {
00082                         fValidInput = TRUE;
00083                 }
00084         }
00085 
00086         return fRet; 
00087 }
00088 
00089 static
00090 PKCS11H_BOOL
00091 _pkcs11h_hooks_pin_prompt (
00092         IN void * const global_data,
00093         IN void * const user_data,
00094         IN const pkcs11h_token_id_t token,
00095         IN const unsigned retry,
00096         OUT char * const pin,
00097         IN const size_t pin_max
00098 ) {
00099         char prompt[1024];
00100         char *p = NULL;
00101 
00102         snprintf (prompt, sizeof (prompt), "Please enter '%s' PIN or 'cancel': ", token->display);
00103 
00104 #if defined(_WIN32)
00105         {
00106                 size_t i = 0;
00107                 char c;
00108                 while (i < pin_max && (c = getch ()) != '\r') {
00109                         pin[i++] = c;
00110                 }
00111         }
00112 
00113         fprintf (stderr, "\n");
00114 #else
00115         p = getpass (prompt);
00116 #endif
00117 
00118         strncpy (pin, p, pin_max);
00119         pin[pin_max-1] = '\0';
00120 
00121         return strcmp (pin, "cancel") != 0;
00122 }
00123 
00124 void
00125 sign_test (const pkcs11h_certificate_t cert) {
00126 
00127         static unsigned const char sha1_data[] = {
00128                 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, /* 1.3.14.3.2.26 */
00129                 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
00130                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* dummy data */
00131                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
00132                 0x10, 0x11, 0x12, 0x13, 0x14
00133         };
00134 
00135         CK_RV rv;
00136                                          
00137         unsigned char *blob;
00138         size_t blob_size;
00139 
00140         if (
00141                 (rv = pkcs11h_certificate_signAny (
00142                         cert,
00143                         CKM_RSA_PKCS,
00144                         sha1_data,
00145                         sizeof (sha1_data),
00146                         NULL,
00147                         &blob_size
00148                 )) != CKR_OK
00149         ) {
00150                 fatal ("pkcs11h_certificate_sign(1) failed", rv);
00151         }
00152 
00153         blob = (unsigned char *)malloc (blob_size);
00154 
00155         if (
00156                 (rv = pkcs11h_certificate_signAny (
00157                         cert,
00158                         CKM_RSA_PKCS,
00159                         sha1_data,
00160                         sizeof (sha1_data),
00161                         blob,
00162                         &blob_size
00163                 )) != CKR_OK
00164         ) {
00165                 fatal ("pkcs11h_certificate_sign(1) failed", rv);
00166         }
00167 
00168         free (blob);
00169 }
00170 
00171 int main () {
00172         pkcs11h_certificate_id_list_t issuers, certs, temp;
00173         pkcs11h_certificate_t cert;
00174         CK_RV rv;
00175 
00176         printf ("Initializing pkcs11-helper\n");
00177 
00178         if ((rv = pkcs11h_initialize ()) != CKR_OK) {
00179                 fatal ("pkcs11h_initialize failed", rv);
00180         }
00181 
00182         printf ("Registering pkcs11-helper hooks\n");
00183 
00184         if ((rv = pkcs11h_setLogHook (_pkcs11h_hooks_log, NULL)) != CKR_OK) {
00185                 fatal ("pkcs11h_setLogHook failed", rv);
00186         }
00187 
00188         pkcs11h_setLogLevel (TEST_LOG_LEVEL);
00189 
00190         if ((rv = pkcs11h_setTokenPromptHook (_pkcs11h_hooks_token_prompt, NULL)) != CKR_OK) {
00191                 fatal ("pkcs11h_setTokenPromptHook failed", rv);
00192         }
00193 
00194         if ((rv = pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt, NULL)) != CKR_OK) {
00195                 fatal ("pkcs11h_setPINPromptHook failed", rv);
00196         }
00197 
00198         printf ("Adding provider '%s'\n", TEST_PROVIDER);
00199 
00200         if (
00201                 (rv = pkcs11h_addProvider (
00202                         TEST_PROVIDER,
00203                         TEST_PROVIDER,
00204                         FALSE,
00205                         PKCS11H_PRIVATEMODE_MASK_AUTO,
00206                         PKCS11H_SLOTEVENT_METHOD_AUTO,
00207                         0,
00208                         FALSE
00209                 )) != CKR_OK
00210         ) {
00211                 fatal ("pkcs11h_addProvider failed", rv);
00212         }
00213 
00214         mypause ("Please remove all tokens, press <Enter>: ");
00215 
00216         printf ("Enumerating token certificate (list should be empty, no prompt)\n");
00217 
00218         if (
00219                 (rv = pkcs11h_certificate_enumCertificateIds (
00220                         PKCS11H_ENUM_METHOD_CACHE,
00221                         NULL,
00222                         PKCS11H_PROMPT_MASK_ALLOW_ALL,
00223                         &issuers,
00224                         &certs
00225                 )) != CKR_OK
00226         ) {
00227                 fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
00228         }
00229 
00230         if (issuers != NULL || certs != NULL) {
00231                 fatal ("No certificates should be found", rv);
00232         }
00233 
00234         mypause ("Please insert token, press <Enter>: ");
00235 
00236         printf ("Getting certificate cache, should be available certificates\n");
00237 
00238         if (
00239                 (rv = pkcs11h_certificate_enumCertificateIds (
00240                         PKCS11H_ENUM_METHOD_CACHE,
00241                         NULL,
00242                         PKCS11H_PROMPT_MASK_ALLOW_ALL,
00243                         &issuers,
00244                         &certs
00245                 )) != CKR_OK
00246         ) {
00247                 fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
00248         }
00249 
00250         for (temp = issuers;temp != NULL;temp = temp->next) {
00251                 printf ("Issuer: %s\n", temp->certificate_id->displayName);
00252         }
00253         for (temp = certs;temp != NULL;temp = temp->next) {
00254                 printf ("Certificate: %s\n", temp->certificate_id->displayName);
00255         }
00256 
00257         if (certs == NULL) {
00258                 fatal ("No certificates found", rv);
00259         }
00260 
00261         pkcs11h_certificate_freeCertificateIdList (issuers);
00262         pkcs11h_certificate_freeCertificateIdList (certs);
00263 
00264         mypause ("Please remove token, press <Enter>: ");
00265 
00266         printf ("Getting certificate cache, should be similar to last\n");
00267 
00268         if (
00269                 (rv = pkcs11h_certificate_enumCertificateIds (
00270                         PKCS11H_ENUM_METHOD_CACHE,
00271                         NULL,
00272                         PKCS11H_PROMPT_MASK_ALLOW_ALL,
00273                         &issuers,
00274                         &certs
00275                 )) != CKR_OK
00276         ) {
00277                 fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
00278         }
00279 
00280         for (temp = issuers;temp != NULL;temp = temp->next) {
00281                 printf ("Issuer: %s\n", temp->certificate_id->displayName);
00282         }
00283         for (temp = certs;temp != NULL;temp = temp->next) {
00284                 printf ("Certificate: %s\n", temp->certificate_id->displayName);
00285         }
00286 
00287         if (certs == NULL) {
00288                 fatal ("No certificates found", rv);
00289         }
00290 
00291         printf ("Creating certificate context\n");
00292 
00293         if (
00294                 (rv = pkcs11h_certificate_create (
00295                         certs->certificate_id,
00296                         NULL,
00297                         PKCS11H_PROMPT_MASK_ALLOW_ALL,
00298                         PKCS11H_PIN_CACHE_INFINITE,
00299                         &cert
00300                 )) != CKR_OK
00301         ) {
00302                 fatal ("pkcs11h_certificate_create failed", rv);
00303         }
00304 
00305         printf ("Perforing signature #1 (you should be prompt for token and PIN)\n");
00306 
00307         sign_test (cert);
00308 
00309         printf ("Perforing signature #2 (you should NOT be prompt for anything)\n");
00310 
00311         sign_test (cert);
00312 
00313         mypause ("Please remove and insert token, press <Enter>: ");
00314 
00315         printf ("Perforing signature #3 (you should be prompt only for PIN)\n");
00316 
00317         sign_test (cert);
00318 
00319         printf ("Perforing signature #4 (you should NOT be prompt for anything)\n");
00320 
00321         if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
00322                 fatal ("pkcs11h_certificate_free failed", rv);
00323         }
00324 
00325         if (
00326                 (rv = pkcs11h_certificate_create (
00327                         certs->certificate_id,
00328                         NULL,
00329                         PKCS11H_PROMPT_MASK_ALLOW_ALL,
00330                         PKCS11H_PIN_CACHE_INFINITE,
00331                         &cert
00332                 )) != CKR_OK
00333         ) {
00334                 fatal ("pkcs11h_certificate_create failed", rv);
00335         }
00336 
00337         sign_test (cert);
00338 
00339         printf ("Terminating pkcs11-helper\n");
00340 
00341         if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
00342                 fatal ("pkcs11h_certificate_free failed", rv);
00343         }
00344 
00345         pkcs11h_certificate_freeCertificateIdList (issuers);
00346         pkcs11h_certificate_freeCertificateIdList (certs);
00347 
00348         if ((rv = pkcs11h_terminate ()) != CKR_OK) {
00349                 fatal ("pkcs11h_terminate failed", rv);
00350         }
00351 
00352         exit (0);
00353         return 0;
00354 }
00355 
00356 #endif

pkcs11-helper, Copyright (C) Alon Bar-Lev <alon.barlev@gmail.com>OpenSC-Project.org Logo