G'day,
I'm using libmusclepkcs11.so to create data objects on a Cyberflex
e-gate 32K card. I can create and lookup multiple data objects in a
session, but once the session is closed, I can only lookup one of the
data objects created. Each data object is created as a token object, and
I'm searching for data objects by looking for all objects where
CKA_CLASS has the value CKO_DATA.
Is this a PKCS#11 issue, a card issue, a libmusclepkcs11 issue, a Muscle
applet issue, or a programming issue? I'd like to store and view
mutliple data objects on a card, but it seems that I can only view one
data object afterwards.
Attached is the application I use to create and view data objects on the
card. Also attached is some sample output, where I create three data
objects in one session (and a lookup returns three data object handles).
When I next run the application, only one data object is returned via
the same lookup.
Any tips on how to view multiple data objects appreciated.
I'm using libmusclecard-1.2.9-beta7, and the Muscle applet as loaded
using CardManagerClient 1.0.1
-- Geoff
/*
* Program to add, delete, and view a data object via PKCS#11
*/
#include <stdio.h>
#include <assert.h>
#include <dlfcn.h>
#include <string.h>
#include <stdlib.h>
/* unix defns for pkcs11.h */
#define CK_PTR *
#define CK_DEFINE_FUNCTION(returnType, name) \
returnType name
#define CK_DECLARE_FUNCTION(returnType, name) \
returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) \
returnType (* name)
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#include <pkcs11.h>
typedef struct Session {
CK_FUNCTION_LIST_PTR functions;
CK_SESSION_HANDLE handle;
} Session;
static Session *open_session (const char *module, int slot, char *pin);
static void close_session (const Session *session);
static void create_data_objects (const Session *session, int objects);
static void delete_data_objects (const Session *session);
static void view_data_objects (const Session *session);
static const char * get_attr_type_str (const CK_ATTRIBUTE_TYPE type);
static const char * get_attr_value_str (const CK_ATTRIBUTE *attr);
static const char *get_rv_string(const CK_RV rv);
static void dump_attributes (const Session *session, CK_OBJECT_HANDLE hObject);
static void printUsage (const char *progname) {
printf ("Usage: %s {option}\n", progname);
printf ("Options:\n");
printf (" --module <path> Path to PKCS#11 module\n");
printf (" --slot <num> Slot number to use [DEFAULT=0]\n");
printf (" --pin <pin> PIN for user login\n");
printf (" --create {x|y|z} Create data object x, y, or z\n");
printf (" --delete Delete data object(s)\n");
printf (" --view View data objects\n");
printf (" --help Show this help\n");
}
/* Actions that may be performed */
typedef enum {
ACTION_NONE, /* No action defined */
ACTION_CREATE, /* Create data objects */
ACTION_DELETE, /* Delete all data objects */
ACTION_VIEW, /* View all data objects */
} Action;
#define OBJECT_X 0x0001
#define OBJECT_Y 0x0002
#define OBJECT_Z 0x0004
int main (int argc, char **argv) {
const char *module = NULL;
int slot = 0;
char *pin = NULL;
int i;
Action action = ACTION_NONE;
int objects = 0;
Session *session;
/* Process args. */
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (strcmp (arg, "--module") == 0) {
module = argv[++i];
}
else if (strcmp (arg, "--slot") == 0) {
slot = atoi (argv[++i]);
}
else if (strcmp (arg, "--pin") == 0) {
pin = argv[++i];
}
else if (strcmp (arg, "--create") == 0) {
action = ACTION_CREATE;
while (i < (argc-1) && strcmp (argv[i+1], "--") != 0) {
const char *s = argv[++i];
if (strcmp (s, "x") == 0) {
objects |= OBJECT_X;
}
else if (strcmp (s, "y") == 0) {
objects |= OBJECT_Y;
}
else if (strcmp (s, "z") == 0) {
objects |= OBJECT_Z;
}
else {
printf ("*** Unknown object: %s ***\n", s);
printUsage (argv[0]);
exit (1);
}
}
}
else if (strcmp (arg, "--delete") == 0) {
action = ACTION_DELETE;
}
else if (strcmp (arg, "--view") == 0) {
action = ACTION_VIEW;
}
else if (strcmp (arg, "--help") == 0) {
printUsage (argv[0]);
exit (0);
}
else {
printf ("*** Unknown option: '%s' ***\n", arg);
printUsage (argv[0]);
exit (-1);
}
}
/* Make sure a module was specified. */
if (module == NULL) {
printf ("*** Must specify a module ***\n");
printUsage (argv[0]);
exit (-1);
}
/* Make sure an action was specified */
if (action == ACTION_NONE) {
printf ("*** Must specify an action (--create, --delete, or --view) ***\n");
printUsage (argv[0]);
exit (-1);
}
session = open_session (module, slot, pin);
if (session == NULL) {
exit (-1);
}
/* Perform the appropriate action */
switch (action) {
case ACTION_CREATE:
create_data_objects (session, objects);
break;
case ACTION_DELETE:
delete_data_objects (session);
break;
case ACTION_VIEW:
view_data_objects (session);
break;
default:
assert (0); /* should not get here */
}
close_session (session);
return 0;
}
/**
* Create data object with given attributes
*/
static CK_OBJECT_HANDLE create_data_object (const Session *session,
CK_BBOOL attr_private,
CK_CHAR *attr_application,
CK_CHAR *attr_label,
CK_CHAR *attr_value)
{
CK_RV rv;
CK_BBOOL true = TRUE;
CK_OBJECT_HANDLE hObject;
CK_OBJECT_CLASS objectClass = CKO_DATA;
CK_ATTRIBUTE template[] = {
{ CKA_CLASS, &objectClass, sizeof (CK_OBJECT_CLASS) },
{ CKA_TOKEN, &true, sizeof (CK_BBOOL) },
{ CKA_PRIVATE, &attr_private, sizeof (CK_BBOOL) },
{ CKA_MODIFIABLE, &true, sizeof (CK_BBOOL) },
{ CKA_APPLICATION, attr_application, strlen (attr_application) },
{ CKA_LABEL, attr_label, strlen (attr_label) },
{ CKA_VALUE, attr_value, strlen (attr_value) },
{ CKA_OBJECT_ID, NULL, 0 },
};
CK_ULONG templateSize = sizeof (template) / sizeof (template[0]);
CK_ULONG i;
/* Pre-condition checks. */
assert (session != NULL);
printf ("## Creating object with template:\n");
for (i = 0; i < templateSize; i++) {
CK_ATTRIBUTE *attr = &template[i];
printf ("%s: length = %u, value = %s\n",
get_attr_type_str (attr->type),
(unsigned int) attr->ulValueLen,
get_attr_value_str (attr));
}
printf ("## Creating object ... ");
rv = (*session->functions->C_CreateObject) (session->handle, template,
templateSize, &hObject);
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
return CK_INVALID_HANDLE;
}
printf ("ok: handle = %04lX\n", hObject);
return hObject;
}
/**
* Create data objects
*/
static void create_data_objects (const Session *session, int objects)
{
printf ("========== Creating data objects ==========\n");
/* private="TRUE", application="test", label="x", value="foo" */
if (objects & OBJECT_X) {
printf ("=== Creating object X ===\n");
create_data_object (session, TRUE, "test", "x", "foo");
}
/* private="FALSE", application="test", label="y", value="bar" */
if (objects & OBJECT_Y) {
printf ("=== Creating object Y ===\n");
create_data_object (session, FALSE, "test", "y", "bar");
}
/* private="false", application="test", label="z", value="baz" */
if (objects & OBJECT_Z) {
printf ("=== Creating object Z ===\n");
create_data_object (session, FALSE, "test", "z", "baz");
}
printf ("===========================================\n");
/* Now view all data objects */
view_data_objects (session);
}
typedef struct {
CK_OBJECT_HANDLE *hObjects;
CK_ULONG ulCount;
} ObjectHandles;
#define MAX_OBJECTS 128
/**
* Get handles of all data objects.
*/
static ObjectHandles *get_data_object_handles (const Session *session)
{
CK_RV rv;
ObjectHandles *handles;
CK_OBJECT_CLASS objClass = CKO_DATA;
/* Template matches all objects with CKA_CLASS == CKO_DATA */
CK_ATTRIBUTE template[] = {
{ CKA_CLASS, &objClass, sizeof (objClass) },
};
CK_ULONG ulTemplateCount = sizeof (template) / sizeof (template[0]);
/* Pre-condition checks. */
assert (session != NULL);
/* Allocate object handles structure */
handles = (ObjectHandles *) malloc (sizeof (ObjectHandles));
assert (handles != NULL);
/* Allocate array of object handles */
handles->ulCount = MAX_OBJECTS;
handles->hObjects = (CK_OBJECT_HANDLE *)
malloc (sizeof (CK_OBJECT_HANDLE) * MAX_OBJECTS);
assert (handles->hObjects != NULL);
/* Initiate the object search */
printf ("## Searching for data objects ... ");
rv = (*session->functions->C_FindObjectsInit)(session->handle, template,
ulTemplateCount);
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
printf ("failed: %s\n", get_rv_string (rv));
return NULL;
}
/* Perform the search */
rv = (*session->functions->C_FindObjects) (session->handle,
handles->hObjects,
handles->ulCount,
&handles->ulCount);
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
return NULL;
}
printf ("ok\n");
printf ("## Found %lu data object(s)\n", handles->ulCount);
/* Remember to call C_FindObjectsFinal to terminate the search */
printf ("## Finalizing search ... ");
rv = (*session->functions->C_FindObjectsFinal)(session->handle);
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
return NULL;
}
printf ("ok\n");
return handles;
}
/**
* Delete all data objects
*/
static void delete_data_objects (const Session *session)
{
ObjectHandles *handles;
CK_ULONG i;
/* Pre-condition checks. */
assert (session != NULL);
printf ("========== Deleting data objects ==========\n");
/* Get handles to all data objects */
handles = get_data_object_handles (session);
assert (handles != NULL);
/* For each handle, delete the corresponding object */
for (i = 0; i < handles->ulCount; i++) {
CK_OBJECT_HANDLE hObject = handles->hObjects[i];
assert (hObject != CK_INVALID_HANDLE);
printf ("## Object %04lX shall be deleted, attributes are:\n", hObject);
dump_attributes (session, hObject);
printf ("## Deleting object %04lX\n", hObject);
(*session->functions->C_DestroyObject) (session->handle, hObject);
}
handles = get_data_object_handles (session);
assert (handles != NULL);
/* Emit a warning if data objects can still be found */
if (handles->ulCount > 0) {
printf ("WARNING: there are still %lu data object(s) present\n",
handles->ulCount);
}
printf ("==========================================\n");
}
/**
* View all data objects.
*/
static void view_data_objects (const Session *session)
{
ObjectHandles *handles;
CK_ULONG i;
/* Pre-condition checks. */
assert (session != NULL);
printf ("========== Viewing data objects ==========\n");
/* Get handles to all data objects */
handles = get_data_object_handles (session);
assert (handles != NULL);
/* View attributes of corresponding object */
for (i = 0; i < handles->ulCount; i++) {
CK_OBJECT_HANDLE hObject = handles->hObjects[i];
assert (hObject != CK_INVALID_HANDLE);
printf ("## Viewing attributes of object %04lX\n", hObject);
dump_attributes (session, hObject);
}
printf ("==========================================\n");
}
/* =================== Attribute display functions ====================== */
typedef const char * (*AttributeToStringFn) (const CK_ATTRIBUTE *attr);
/* Information about an attribute */
typedef struct {
CK_ATTRIBUTE_TYPE type;
const char *name;
const AttributeToStringFn converter;
} AttributeInfo;
/**
* Get string representation of an attribute containing a CK_OBJECT_CLASS
* value.
*/
static const char * ObjectClassToString (const CK_ATTRIBUTE *attr) {
CK_OBJECT_CLASS *value;
char buf[128];
/* Pre-condition checks */
assert (attr != NULL);
assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
assert (attr->pValue != NULL);
value = (CK_OBJECT_CLASS *) attr->pValue;
switch (*value) {
case CKO_DATA: return "CKO_DATA";
case CKO_CERTIFICATE: return "CKO_CERTIFICATE";
case CKO_PUBLIC_KEY: return "CKO_PUBLIC_KEY";
case CKO_PRIVATE_KEY: return "CKO_PRIVATE_KEY";
case CKO_SECRET_KEY: return "CKO_SECRET_KEY";
case CKO_HW_FEATURE: return "CKO_HW_FEATURE";
case CKO_DOMAIN_PARAMETERS: return "CKO_DOMAIN_PARAMETERS";
/* Undefined: case CKO_MECHANISM: return "CKO_MECHANISM"; */
}
/* Check for vendor-defined value */
if (*value >= CKO_VENDOR_DEFINED) {
return "CKO_VENDOR_DEFINED";
}
/* Unknown object class */
sprintf (buf, "<Unknown:%04lX>", *value);
return strdup (buf);
}
/**
* Get a string representation of an attribute containing a CK_BBOOL
* value.
*/
static const char * BBoolToString (const CK_ATTRIBUTE *attr) {
const CK_BBOOL *value;
/* Pre-condition checks */
assert (attr != NULL);
assert (attr->ulValueLen == sizeof (CK_BBOOL));
assert (attr->pValue != NULL);
value = (CK_BBOOL *) attr->pValue;
return (*value) ? "TRUE" : "FALSE";
}
/**
* Get the string representation of an attribute containing an RFC2279
* string value.
*/
static const char * RFC2279StringToString (const CK_ATTRIBUTE *attr) {
char *buf;
/* Pre-condition checks */
assert (attr != NULL);
assert (attr->pValue != NULL);
assert (attr->ulValueLen != -1);
/* Allocate buffer to hold string, and terminating zero */
buf = (char *) malloc (attr->ulValueLen + 1);
assert (buf != NULL);
/* Copy rfc2279 string, and add terminating zero */
strncpy (buf, attr->pValue, attr->ulValueLen);
buf[attr->ulValueLen] = (char) 0;
return buf;
}
/**
* Get the string representation of an attribute containing a
* byte array.
*/
static const char * ByteArrayToString (const CK_ATTRIBUTE *attr) {
CK_BYTE *value;
char *buf;
CK_ULONG i;
/* Pre-condition checks */
assert (attr != NULL);
assert (attr->pValue != NULL);
assert (attr->ulValueLen != -1);
value = (CK_BYTE *) attr->pValue;
/* Allocate buffer to hold hex representation */
buf = (char *) malloc (attr->ulValueLen * 3);
assert (buf != NULL);
/* Copy byte array to hex buffer */
for (i = 0; i < attr->ulValueLen; i++) {
char t[3];
if (i > 0) {
buf[(i*3)-1] = ':';
}
sprintf (t, "%02X", value[i]);
buf[(i*3)] = t[0];
buf[(i*3)+1] = t[1];
}
buf[attr->ulValueLen*3] = 0;
return buf;
}
/** Attribute information table */
static const AttributeInfo ATTRIBUTE_INFOS[] = {
{ CKA_CLASS, "CKA_CLASS", ObjectClassToString },
{ CKA_TOKEN, "CKA_TOKEN", BBoolToString },
{ CKA_PRIVATE, "CKA_PRIVATE", BBoolToString },
{ CKA_MODIFIABLE, "CKA_MODIFIABLE", BBoolToString },
{ CKA_LABEL, "CKA_LABEL", RFC2279StringToString },
{ CKA_APPLICATION, "CKA_APPLICATION", RFC2279StringToString },
{ CKA_OBJECT_ID, "CKA_OBJECT_ID", ByteArrayToString },
{ CKA_VALUE, "CKA_VALUE", ByteArrayToString },
};
#define NUM_ATTRIBUTE_INFOS \
(sizeof (ATTRIBUTE_INFOS) / sizeof (ATTRIBUTE_INFOS[0]))
/**
* Get a string representing the attribute type.
*/
static const char * get_attr_type_str (const CK_ATTRIBUTE_TYPE type) {
char buf[128];
size_t i;
for (i = 0; i < NUM_ATTRIBUTE_INFOS; i++) {
if (ATTRIBUTE_INFOS[i].type == type) {
return ATTRIBUTE_INFOS[i].name;
}
}
sprintf (buf, "Unknown: %lu", type);
return strdup (buf);
}
/**
* Get a string representing the attribute value.
*/
static const char * get_attr_value_str (const CK_ATTRIBUTE *attr) {
char buf[128];
size_t i;
/* Check for empty value */
if (attr->pValue == NULL || attr->ulValueLen == -1) {
return "<empty>";
}
/* Check for known attribute type, and call converter fn */
for (i = 0; i < NUM_ATTRIBUTE_INFOS; i++) {
if (ATTRIBUTE_INFOS[i].type == attr->type) {
return ATTRIBUTE_INFOS[i].converter (attr);
}
}
/* Unknown attribute type */
sprintf (buf, "<Unknown: %lu>", attr->type);
return strdup (buf);
}
/**
* Dump all data attributes for the object with the given handle.
*/
static void dump_attributes (const Session *session, CK_OBJECT_HANDLE hObject)
{
CK_RV rv;
CK_ATTRIBUTE template[] = {
{ CKA_CLASS, NULL_PTR, 0 },
{ CKA_TOKEN, NULL_PTR, 0 },
{ CKA_PRIVATE, NULL_PTR, 0 },
{ CKA_MODIFIABLE, NULL_PTR, 0 },
{ CKA_LABEL, NULL_PTR, 0 },
{ CKA_APPLICATION, NULL_PTR, 0 },
{ CKA_OBJECT_ID, NULL_PTR, 0 },
{ CKA_VALUE, NULL_PTR, 0 }
};
CK_ULONG templateSize = sizeof (template) / sizeof (template[0]);
CK_ULONG i;
/* Pre-condition checks. */
assert (session != NULL);
assert (hObject != CK_INVALID_HANDLE);
/* Get the length of the attributes */
printf ("## Getting attribute values ... ");
rv = (*session->functions->C_GetAttributeValue) (session->handle, hObject,
template, templateSize);
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
printf ("failed: %s\n", get_rv_string (rv));
return;
}
/* Allocate memory for the attribute values. */
for (i = 0; i < templateSize; i++) {
CK_ATTRIBUTE *attr = &template[i];
/* Check that the attribute's length can be determined. */
if (attr->ulValueLen != -1) {
/* Allocate space for the attribute value. */
attr->pValue = (CK_BYTE_PTR) malloc (attr->ulValueLen);
assert (attr->pValue != NULL);
}
}
/* Get the value of the attributes */
rv = (*session->functions->C_GetAttributeValue) (session->handle, hObject,
template, templateSize);
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
printf ("failed: %s\n", get_rv_string (rv));
return;
}
printf ("ok\n");
for (i = 0; i < templateSize; i++) {
CK_ATTRIBUTE *attr = &template[i];
printf ("%s: length = %lu, value = %s\n",
get_attr_type_str (attr->type),
attr->ulValueLen,
get_attr_value_str (attr));
}
}
/* ===================== Session management ============================= */
/**
* Open a new session.
*/
static Session *open_session (const char *module, int slot, char *pin) {
Session *session;
void *hModule;
CK_C_GetFunctionList pC_GetFunctionList;
CK_RV rv;
/* Pre-condition checks */
assert (module != NULL);
session = (Session *) calloc (1, sizeof (Session));
assert (session != NULL);
/* Load the PKCS #11 module. */
printf ("## Loading module: %s ...", module);
fflush (stdout);
hModule = dlopen (module, RTLD_LAZY);
printf ((hModule == NULL) ? "failed\n" : "ok\n");
assert (hModule!=NULL);
/* Get function pointer to C_GetFunctionList. */
pC_GetFunctionList =
(CK_C_GetFunctionList) dlsym (hModule, "C_GetFunctionList");
assert (pC_GetFunctionList!=NULL);
/* Get function pointers to all PKCS #11 functions. */
rv = (*pC_GetFunctionList) (&session->functions);
assert (rv == CKR_OK);
/* Initalize Cryptoki. */
rv = (*session->functions->C_Initialize) (NULL);
assert (rv==CKR_OK);
/* Open a read/write session on the given slot */
printf ("## Opening session for slot = %02d ... ", slot);
rv = (*session->functions->C_OpenSession)(slot,
CKF_SERIAL_SESSION|CKF_RW_SESSION,
0, 0, &session->handle);
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
return NULL;
}
printf ("ok\n");
if (pin != NULL) {
printf ("## Performing login with PIN '%s' .... ", pin);
rv = (*session->functions->C_Login)(session->handle, CKU_USER,
pin, strlen(pin));
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
return NULL;
}
printf ("ok\n");
}
return session;
}
/**
* Close the session.
*/
static void close_session (const Session *session) {
CK_RV rv;
/* Pre-condition checks */
assert (session != NULL);
printf ("## Finalizing ... ");
rv = (*session->functions->C_Finalize)(0);
if (rv != CKR_OK) {
printf ("failed: %s\n", get_rv_string (rv));
}
else {
printf ("ok\n");
}
}
static const char *get_rv_string(const CK_RV rv) {
static char buf[128];
switch (rv) {
case CKR_ARGUMENTS_BAD: return "bad arguments";
case CKR_CANCEL: return "cancel";
case CKR_CRYPTOKI_NOT_INITIALIZED: return "cryptoki not initialized";
case CKR_DATA_LEN_RANGE: return "data len range";
case CKR_DEVICE_ERROR: return "device error";
case CKR_DEVICE_MEMORY: return "device memory";
case CKR_DEVICE_REMOVED: return "device removed";
case CKR_FUNCTION_CANCELED: return "function canceled";
case CKR_FUNCTION_FAILED: return "function failed";
case CKR_FUNCTION_NOT_SUPPORTED: return "function not supported";
case CKR_GENERAL_ERROR: return "general error";
case CKR_HOST_MEMORY: return "host memory";
case CKR_OK: return "ok";
case CKR_OPERATION_ACTIVE: return "operation active";
case CKR_OPERATION_NOT_INITIALIZED: return "operation not initialized";
case CKR_PIN_INCORRECT: return "pin incorrect";
case CKR_PIN_LOCKED: return "pin locked";
case CKR_RANDOM_SEED_NOT_SUPPORTED: return "random seed not supported";
case CKR_RANDOM_NO_RNG: return "no rng";
case CKR_SESSION_CLOSED: return "session closed";
case CKR_SESSION_COUNT: return "session count";
case CKR_SESSION_HANDLE_INVALID: return "session handle invalid";
case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "session parallel not supported";
case CKR_SESSION_READ_ONLY: return "session read only";
case CKR_SESSION_EXISTS: return "session exists";
case CKR_SESSION_READ_ONLY_EXISTS: return "session read-only exists";
case CKR_SESSION_READ_WRITE_SO_EXISTS: return "session read write SO exists";
case CKR_SIGNATURE_INVALID: return "signature invalid";
case CKR_SIGNATURE_LEN_RANGE: return "signature len range";
case CKR_SLOT_ID_INVALID: return "slot id invalid";
case CKR_TEMPLATE_INCOMPLETE: return "template incomplete";
case CKR_TEMPLATE_INCONSISTENT: return "template inconsistent";
case CKR_TOKEN_NOT_PRESENT: return "token not present";
case CKR_TOKEN_NOT_RECOGNIZED: return "token not recognized";
case CKR_USER_ALREADY_LOGGED_IN: return "user already logged in";
case CKR_USER_NOT_LOGGED_IN: return "user not logged in";
case CKR_USER_PIN_NOT_INITIALIZED: return "user pin not initialized";
case CKR_USER_TOO_MANY_TYPES: return "user too many types";
case CKR_USER_TYPE_INVALID: return "user type invalid";
}
sprintf (buf, "Unknown error: %lu", rv);
return strdup (buf);
}
-- Create three data objects on the card --
$ ./p11-add-data-object --module /usr/local/lib/libmusclepkcs11.so --slot 1
--pin 00000000 --create x y z
## Loading module: /usr/local/lib/libmusclepkcs11.so ...ok
## Opening session for slot = 01 ... ok
## Performing login with PIN '00000000' .... ok
========== Creating data objects ==========
=== Creating object X ===
## Creating object with template:
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = TRUE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_APPLICATION: length = 4, value = test
CKA_LABEL: length = 1, value = x
CKA_VALUE: length = 3, value = 66:6F:6F
CKA_OBJECT_ID: length = 0, value = <empty>
## Creating object ... ok: handle = 804E508
=== Creating object Y ===
## Creating object with template:
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = FALSE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_APPLICATION: length = 4, value = test
CKA_LABEL: length = 1, value = y
CKA_VALUE: length = 3, value = 62:61:72
CKA_OBJECT_ID: length = 0, value = <empty>
## Creating object ... ok: handle = 804F020
=== Creating object Z ===
## Creating object with template:
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = FALSE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_APPLICATION: length = 4, value = test
CKA_LABEL: length = 1, value = z
CKA_VALUE: length = 3, value = 62:61:7A
CKA_OBJECT_ID: length = 0, value = <empty>
## Creating object ... ok: handle = 804F208
===========================================
========== Viewing data objects ==========
## Searching for data objects ... ok
## Found 3 data object(s)
## Finalizing search ... ok
## Viewing attributes of object 804F208
## Getting attribute values ... ok
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = FALSE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_LABEL: length = 1, value = z
CKA_APPLICATION: length = 4, value = test
CKA_OBJECT_ID: length = 0, value =
CKA_VALUE: length = 3, value = 62:61:7Ah
## Viewing attributes of object 804F020
## Getting attribute values ... ok
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = FALSE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_LABEL: length = 1, value = y
CKA_APPLICATION: length = 4, value = test
CKA_OBJECT_ID: length = 0, value =
CKA_VALUE: length = 3, value = 62:61:72
## Viewing attributes of object 804E508
## Getting attribute values ... ok
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = TRUE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_LABEL: length = 1, value = x
CKA_APPLICATION: length = 4, value = test
CKA_OBJECT_ID: length = 0, value =
CKA_VALUE: length = 3, value = 66:6F:6F
==========================================
## Finalizing ... ok
-- View all data objects on the card ---
$ ./p11-add-data-object --module /usr/local/lib/libmusclepkcs11.so --slot 1
--pin 00000000 --view
## Loading module: /usr/local/lib/libmusclepkcs11.so ...ok
## Opening session for slot = 01 ... ok
## Performing login with PIN '00000000' .... ok
========== Viewing data objects ==========
## Searching for data objects ... ok
## Found 1 data object(s)
## Finalizing search ... ok
## Viewing attributes of object 804E508
## Getting attribute values ... ok
CKA_CLASS: length = 4, value = CKO_DATA
CKA_TOKEN: length = 1, value = TRUE
CKA_PRIVATE: length = 1, value = FALSE
CKA_MODIFIABLE: length = 1, value = TRUE
CKA_LABEL: length = 1, value = z
CKA_APPLICATION: length = 4, value = test
CKA_OBJECT_ID: length = 0, value =
CKA_VALUE: length = 3, value = 62:61:7A
==========================================
## Finalizing ... ok
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle