Next: , Previous: , Up: Smart cards and HSMs   [Contents][Index]


5.3.4 Reading objects

All PKCS #11 objects are referenced by GnuTLS functions by URLs as described in [PKCS11URI]. This allows for a consistent naming of objects across systems and applications in the same system. For example a public key on a smart card may be referenced as:

pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
manufacturer=EnterSafe;object=test1;type=public;\
id=32f153f3e37990b08624141077ca5dec2d15faed

while the smart card itself can be referenced as:

pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe

Objects stored in a PKCS #11 token can typically be extracted if they are not marked as sensitive. Usually only private keys are marked as sensitive and cannot be extracted, while certificates and other data can be retrieved. The functions that can be used to enumerate and access objects are shown below.

int gnutls_pkcs11_obj_list_import_url4 (gnutls_pkcs11_obj_t ** p_list, unsigned int * n_list, const char * url, unsigned int flags)
int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj, const char * url, unsigned int flags)
int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t obj, gnutls_pkcs11_url_type_t detailed, char ** url)
Function: int gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t obj, gnutls_pkcs11_obj_info_t itype, void * output, size_t * output_size)

obj: should contain a gnutls_pkcs11_obj_t type

itype: Denotes the type of information requested

output: where output will be stored

output_size: contains the maximum size of the output buffer and will be overwritten with the actual size.

This function will return information about the PKCS11 certificate such as the label, id as well as token information where the key is stored.

When output is text, a null terminated string is written to output and its string length is written to output_size (without null terminator). If the buffer is too small, output_size will contain the expected buffer size (with null terminator for text) and return GNUTLS_E_SHORT_MEMORY_BUFFER .

In versions previously to 3.6.0 this function included the null terminator to output_size . After 3.6.0 the output size doesn’t include the terminator character.

Returns: GNUTLS_E_SUCCESS (0) on success or a negative error code on error.

Since: 2.12.0

int gnutls_x509_crt_import_pkcs11 (gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pkcs11_crt)
int gnutls_x509_crt_import_url (gnutls_x509_crt_t crt, const char * url, unsigned int flags)
int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs, unsigned int cert_max, gnutls_pkcs11_obj_t *const objs, unsigned int flags)

Properties of the physical token can also be accessed and altered with GnuTLS. For example data in a token can be erased (initialized), PIN can be altered, etc.

int gnutls_pkcs11_token_init (const char * token_url, const char * so_pin, const char * label)
int gnutls_pkcs11_token_get_url (unsigned int seq, gnutls_pkcs11_url_type_t detailed, char ** url)
int gnutls_pkcs11_token_get_info (const char * url, gnutls_pkcs11_token_info_t ttype, void * output, size_t * output_size)
int gnutls_pkcs11_token_get_flags (const char * url, unsigned int * flags)
int gnutls_pkcs11_token_set_pin (const char * token_url, const char * oldpin, const char * newpin, unsigned int flags)

The following examples demonstrate the usage of the API. The first example will list all available PKCS #11 tokens in a system and the latter will list all certificates in a token that have a corresponding private key.

int i;
char* url;

gnutls_global_init();

for (i=0;;i++) 
  {
    ret = gnutls_pkcs11_token_get_url(i, &url);
    if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
      break;

    if (ret < 0)
      exit(1);
		
    fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
    gnutls_free(url);
  }
gnutls_global_deinit();
/* This example code is placed in the public domain. */

#include <config.h>
#include <gnutls/gnutls.h>
#include <gnutls/pkcs11.h>
#include <stdio.h>
#include <stdlib.h>

#define URL "pkcs11:URL"

int main(int argc, char **argv)
{
	gnutls_pkcs11_obj_t *obj_list;
	gnutls_x509_crt_t xcrt;
	unsigned int obj_list_size = 0;
	gnutls_datum_t cinfo;
	int ret;
	unsigned int i;

	ret = gnutls_pkcs11_obj_list_import_url4(
		&obj_list, &obj_list_size, URL,
		GNUTLS_PKCS11_OBJ_FLAG_CRT |
			GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY);
	if (ret < 0)
		return -1;

	/* now all certificates are in obj_list */
	for (i = 0; i < obj_list_size; i++) {
		gnutls_x509_crt_init(&xcrt);

		gnutls_x509_crt_import_pkcs11(xcrt, obj_list[i]);

		gnutls_x509_crt_print(xcrt, GNUTLS_CRT_PRINT_FULL, &cinfo);

		fprintf(stdout, "cert[%d]:\n %s\n\n", i, cinfo.data);

		gnutls_free(cinfo.data);
		gnutls_x509_crt_deinit(xcrt);
	}

	for (i = 0; i < obj_list_size; i++)
		gnutls_pkcs11_obj_deinit(obj_list[i]);
	gnutls_free(obj_list);

	return 0;
}

Next: , Previous: , Up: Smart cards and HSMs   [Contents][Index]