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

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