test-certificate.c

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

#include "../../config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#include <conio.h>
#else
#include <unistd.h>
#endif
#if !(defined(ENABLE_PKCS11H_CERTIFICATE) && (defined(ENABLE_PKCS11H_ENGINE_OPENSSL) || defined (ENABLE_PKCS11H_ENGINE_GNUTLS) || defined(ENABLE_PKCS11H_ENGINE_WIN32)))
int main () {
printf ("!win32, certificate, enum and crypto engine interfaces should be enabled for this test");
exit (0);
return 0;
}
#else
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
#include <unistd.h>
static
void
fatal0 (const char * const m) {
fprintf (stderr, "%sn", m);
exit (1);
}
static
void
fatal (const char * const m, CK_RV rv) {
fprintf (stderr, "%s - %lu - %s\n", m, rv, pkcs11h_getMessage (rv));
exit (1);
}
static
void
mypause (const char * const m) {
char temp[10];
fprintf (stdout, "%s", m);
fflush (stdout);
if (fgets (temp, sizeof (temp), stdin) == NULL) {
fatal0("fgets failed");
}
}
static
void
_pkcs11h_hooks_log (
IN void * const global_data,
IN unsigned flags,
IN const char * const format,
IN va_list args
) {
vfprintf (stdout, format, args);
fprintf (stdout, "\n");
fflush (stdout);
}
static
PKCS11H_BOOL
_pkcs11h_hooks_token_prompt (
IN void * const global_data,
IN void * const user_data,
IN const pkcs11h_token_id_t token,
IN const unsigned retry
) {
char buf[1024];
PKCS11H_BOOL fValidInput = FALSE;
PKCS11H_BOOL fRet = FALSE;
while (!fValidInput) {
fprintf (stderr, "Please insert token '%s' 'ok' or 'cancel': ", token->display);
if (fgets (buf, sizeof (buf), stdin) == NULL) {
fatal0("fgets failed");
}
buf[sizeof (buf)-1] = '\0';
fflush (stdin);
if (buf[strlen (buf)-1] == '\n') {
buf[strlen (buf)-1] = '\0';
}
if (buf[strlen (buf)-1] == '\r') {
buf[strlen (buf)-1] = '\0';
}
if (!strcmp (buf, "ok")) {
fValidInput = TRUE;
fRet = TRUE;
}
else if (!strcmp (buf, "cancel")) {
fValidInput = TRUE;
}
}
return fRet;
}
static
PKCS11H_BOOL
_pkcs11h_hooks_pin_prompt (
IN void * const global_data,
IN void * const user_data,
IN const pkcs11h_token_id_t token,
IN const unsigned retry,
OUT char * const pin,
IN const size_t pin_max
) {
char prompt[1024];
char *p = NULL;
snprintf (prompt, sizeof (prompt), "Please enter '%s' PIN or 'cancel': ", token->display);
#if defined(_WIN32)
{
size_t i = 0;
char c;
while (i < pin_max && (c = getch ()) != '\r') {
pin[i++] = c;
}
}
fprintf (stderr, "\n");
#else
p = getpass (prompt);
#endif
strncpy (pin, p, pin_max);
pin[pin_max-1] = '\0';
return strcmp (pin, "cancel") != 0;
}
void
sign_test (const pkcs11h_certificate_t cert) {
static unsigned const char sha1_data[] = {
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, /* 1.3.14.3.2.26 */
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* dummy data */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14
};
CK_RV rv;
unsigned char *blob;
size_t blob_size;
if (
(rv = pkcs11h_certificate_signAny (
cert,
CKM_RSA_PKCS,
sha1_data,
sizeof (sha1_data),
NULL,
&blob_size
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_sign(1) failed", rv);
}
blob = (unsigned char *)malloc (blob_size);
if (
(rv = pkcs11h_certificate_signAny (
cert,
CKM_RSA_PKCS,
sha1_data,
sizeof (sha1_data),
blob,
&blob_size
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_sign(1) failed", rv);
}
free (blob);
}
int main () {
pkcs11h_certificate_id_list_t issuers, certs, temp;
pkcs11h_certificate_t cert;
CK_RV rv;
printf ("Initializing pkcs11-helper\n");
if ((rv = pkcs11h_initialize ()) != CKR_OK) {
fatal ("pkcs11h_initialize failed", rv);
}
printf ("Registering pkcs11-helper hooks\n");
if ((rv = pkcs11h_setLogHook (_pkcs11h_hooks_log, NULL)) != CKR_OK) {
fatal ("pkcs11h_setLogHook failed", rv);
}
pkcs11h_setLogLevel (TEST_LOG_LEVEL);
if ((rv = pkcs11h_setTokenPromptHook (_pkcs11h_hooks_token_prompt, NULL)) != CKR_OK) {
fatal ("pkcs11h_setTokenPromptHook failed", rv);
}
if ((rv = pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt, NULL)) != CKR_OK) {
fatal ("pkcs11h_setPINPromptHook failed", rv);
}
printf ("Adding provider '%s'\n", TEST_PROVIDER);
if (
(rv = pkcs11h_addProvider (
TEST_PROVIDER,
TEST_PROVIDER,
FALSE,
PKCS11H_PRIVATEMODE_MASK_AUTO,
PKCS11H_SLOTEVENT_METHOD_AUTO,
0,
FALSE
)) != CKR_OK
) {
fatal ("pkcs11h_addProvider failed", rv);
}
mypause ("Please remove all tokens, press <Enter>: ");
printf ("Enumerating token certificate (list should be empty, no prompt)\n");
if (
(rv = pkcs11h_certificate_enumCertificateIds (
PKCS11H_ENUM_METHOD_CACHE,
NULL,
PKCS11H_PROMPT_MASK_ALLOW_ALL,
&issuers,
&certs
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
}
if (issuers != NULL || certs != NULL) {
fatal ("No certificates should be found", rv);
}
mypause ("Please insert token, press <Enter>: ");
printf ("Getting certificate cache, should be available certificates\n");
if (
(rv = pkcs11h_certificate_enumCertificateIds (
PKCS11H_ENUM_METHOD_CACHE,
NULL,
PKCS11H_PROMPT_MASK_ALLOW_ALL,
&issuers,
&certs
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
}
for (temp = issuers;temp != NULL;temp = temp->next) {
printf ("Issuer: %s\n", temp->certificate_id->displayName);
}
for (temp = certs;temp != NULL;temp = temp->next) {
printf ("Certificate: %s\n", temp->certificate_id->displayName);
}
if (certs == NULL) {
fatal ("No certificates found", rv);
}
pkcs11h_certificate_freeCertificateIdList (issuers);
pkcs11h_certificate_freeCertificateIdList (certs);
mypause ("Please remove token, press <Enter>: ");
printf ("Getting certificate cache, should be similar to last\n");
if (
(rv = pkcs11h_certificate_enumCertificateIds (
PKCS11H_ENUM_METHOD_CACHE,
NULL,
PKCS11H_PROMPT_MASK_ALLOW_ALL,
&issuers,
&certs
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
}
for (temp = issuers;temp != NULL;temp = temp->next) {
printf ("Issuer: %s\n", temp->certificate_id->displayName);
}
for (temp = certs;temp != NULL;temp = temp->next) {
printf ("Certificate: %s\n", temp->certificate_id->displayName);
}
if (certs == NULL) {
fatal ("No certificates found", rv);
}
printf ("Creating certificate context\n");
if (
(rv = pkcs11h_certificate_create (
certs->certificate_id,
NULL,
PKCS11H_PROMPT_MASK_ALLOW_ALL,
PKCS11H_PIN_CACHE_INFINITE,
&cert
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_create failed", rv);
}
printf ("Perforing signature #1 (you should be prompt for token and PIN)\n");
sign_test (cert);
printf ("Perforing signature #2 (you should NOT be prompt for anything)\n");
sign_test (cert);
mypause ("Please remove and insert token, press <Enter>: ");
printf ("Perforing signature #3 (you should be prompt only for PIN)\n");
sign_test (cert);
printf ("Perforing signature #4 (you should NOT be prompt for anything)\n");
if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
fatal ("pkcs11h_certificate_free failed", rv);
}
if (
(rv = pkcs11h_certificate_create (
certs->certificate_id,
NULL,
PKCS11H_PROMPT_MASK_ALLOW_ALL,
PKCS11H_PIN_CACHE_INFINITE,
&cert
)) != CKR_OK
) {
fatal ("pkcs11h_certificate_create failed", rv);
}
sign_test (cert);
printf ("Terminating pkcs11-helper\n");
if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
fatal ("pkcs11h_certificate_free failed", rv);
}
pkcs11h_certificate_freeCertificateIdList (issuers);
pkcs11h_certificate_freeCertificateIdList (certs);
if ((rv = pkcs11h_terminate ()) != CKR_OK) {
fatal ("pkcs11h_terminate failed", rv);
}
exit (0);
return 0;
}
#endif
PKCS11H_ENUM_METHOD_CACHE
#define PKCS11H_ENUM_METHOD_CACHE
Definition pkcs11h-core.h:198
PKCS11H_PRIVATEMODE_MASK_AUTO
#define PKCS11H_PRIVATEMODE_MASK_AUTO
Definition pkcs11h-core.h:146
PKCS11H_PROMPT_MASK_ALLOW_ALL
#define PKCS11H_PROMPT_MASK_ALLOW_ALL
Definition pkcs11h-core.h:184
pkcs11h_certificate_enumCertificateIds
CK_RV pkcs11h_certificate_enumCertificateIds(IN const unsigned method, IN void *const user_data, IN const unsigned mask_prompt, OUT pkcs11h_certificate_id_list_t *const p_cert_id_issuers_list, OUT pkcs11h_certificate_id_list_t *const p_cert_id_end_list)
Enumerate available certificates.
pkcs11h_certificate_signAny
CK_RV pkcs11h_certificate_signAny(IN const pkcs11h_certificate_t certificate, IN const CK_MECHANISM_TYPE mech_type, IN const unsigned char *const source, IN const size_t source_size, OUT unsigned char *const target, IN OUT size_t *const p_target_size)
Sign data with method determined by key attributes.
pkcs11h_certificate_freeCertificateIdList
CK_RV pkcs11h_certificate_freeCertificateIdList(IN const pkcs11h_certificate_id_list_t cert_id_list)
Free certificate_id list.
pkcs11h_certificate_t
struct pkcs11h_certificate_s * pkcs11h_certificate_t
Certificate object.
Definition pkcs11h-certificate.h:92
pkcs11h_certificate_create
CK_RV pkcs11h_certificate_create(IN const pkcs11h_certificate_id_t certificate_id, IN void *const user_data, IN const unsigned mask_prompt, IN const int pin_cache_period, OUT pkcs11h_certificate_t *const p_certificate)
Create a certificate object out of certificate_id.
pkcs11h_certificate_freeCertificate
CK_RV pkcs11h_certificate_freeCertificate(IN pkcs11h_certificate_t certificate)
Free certificate object.
pkcs11h_setTokenPromptHook
CK_RV pkcs11h_setTokenPromptHook(IN const pkcs11h_hook_token_prompt_t hook, IN void *const global_data)
Set a token prompt callback.
pkcs11h_getMessage
const char * pkcs11h_getMessage(IN const CK_RV rv)
Get message by return value.
pkcs11h_terminate
CK_RV pkcs11h_terminate(void)
Terminate helper interface.
pkcs11h_setLogLevel
void pkcs11h_setLogLevel(IN const unsigned flags)
Set current log level of the helper.
pkcs11h_setPINPromptHook
CK_RV pkcs11h_setPINPromptHook(IN const pkcs11h_hook_pin_prompt_t hook, IN void *const global_data)
Set a pin prompt callback.
pkcs11h_initialize
CK_RV pkcs11h_initialize(void)
Initialize helper interface.
PKCS11H_PIN_CACHE_INFINITE
#define PKCS11H_PIN_CACHE_INFINITE
Definition pkcs11h-core.h:138
pkcs11h_setLogHook
CK_RV pkcs11h_setLogHook(IN const pkcs11h_hook_log_t hook, IN void *const global_data)
Set a log callback.
pkcs11h_addProvider
CK_RV pkcs11h_addProvider(IN const char *const reference, IN const char *const provider_location, IN const PKCS11H_BOOL allow_protected_auth, IN const unsigned mask_private_mode, IN const unsigned slot_event_method, IN const unsigned slot_poll_interval, IN const PKCS11H_BOOL cert_is_private)
Register, configure and initialize a PKCS#11 provider.
pkcs11h-certificate.h
pkcs11-helper certificate functions.
pkcs11h_certificate_id_list_s
Certificate id list.
Definition pkcs11h-certificate.h:124
pkcs11h_certificate_id_list_s::next
pkcs11h_certificate_id_list_t next
Definition pkcs11h-certificate.h:126
pkcs11h_certificate_id_list_s::certificate_id
pkcs11h_certificate_id_t certificate_id
Definition pkcs11h-certificate.h:128
pkcs11h_certificate_id_s::displayName
char displayName[1024]
Definition pkcs11h-certificate.h:109
pkcs11h_token_id_s
Token identifier.
Definition pkcs11h-core.h:493

pkcs11-helper, Copyright (C) Alon Bar-Lev <alon.barlev@gmail.com> |