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,
00129 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
00130 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
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