2006-12-19 21:33:40 +00:00
|
|
|
/* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
2002-03-07 13:03:00 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* PKCS#15 PIN code test
|
|
|
|
*/
|
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2002-03-07 13:03:00 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2003-10-31 12:29:12 +00:00
|
|
|
#include <assert.h>
|
2010-03-04 08:14:36 +00:00
|
|
|
|
|
|
|
#include "libopensc/opensc.h"
|
|
|
|
#include "libopensc/pkcs15.h"
|
2002-03-22 00:13:25 +00:00
|
|
|
#include "sc-test.h"
|
2002-03-07 13:03:00 +00:00
|
|
|
|
2007-06-21 12:58:57 +00:00
|
|
|
void sc_test_print_card(const sc_pkcs15_card_t *mycard)
|
2003-10-31 12:29:12 +00:00
|
|
|
{
|
|
|
|
const char *flags[] = {
|
|
|
|
"Read-only",
|
|
|
|
"Login required",
|
|
|
|
"PRN generation",
|
|
|
|
"EID compliant"
|
|
|
|
};
|
|
|
|
int i, count = 0;
|
|
|
|
|
2007-06-21 12:58:57 +00:00
|
|
|
assert(mycard != NULL);
|
2010-10-05 15:44:58 +00:00
|
|
|
printf("PKCS#15 Card [%s]:\n", mycard->tokeninfo->label);
|
|
|
|
printf("\tVersion : %d\n", mycard->tokeninfo->version);
|
|
|
|
printf("\tSerial number : %s\n", mycard->tokeninfo->serial_number);
|
|
|
|
printf("\tManufacturer ID: %s\n", mycard->tokeninfo->manufacturer_id);
|
|
|
|
if (mycard->tokeninfo->preferred_language)
|
|
|
|
printf("\tLanguage : %s\n", mycard->tokeninfo->preferred_language);
|
2003-10-31 12:29:12 +00:00
|
|
|
printf("\tFlags : ");
|
|
|
|
for (i = 0; i < 4; i++) {
|
2010-10-05 15:44:58 +00:00
|
|
|
if ((mycard->tokeninfo->flags >> i) & 1) {
|
2003-10-31 12:29:12 +00:00
|
|
|
if (count)
|
|
|
|
printf(", ");
|
|
|
|
printf("%s", flags[i]);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2002-03-22 00:13:25 +00:00
|
|
|
static void print_pin(const struct sc_pkcs15_object *obj)
|
2002-03-07 13:03:00 +00:00
|
|
|
{
|
2002-03-22 00:13:25 +00:00
|
|
|
const char *pin_flags[] =
|
|
|
|
{
|
2002-03-07 13:03:00 +00:00
|
|
|
"case-sensitive", "local", "change-disabled",
|
|
|
|
"unblock-disabled", "initialized", "needs-padding",
|
|
|
|
"unblockingPin", "soPin", "disable_allowed",
|
|
|
|
"integrity-protected", "confidentiality-protected",
|
|
|
|
"exchangeRefData"
|
|
|
|
};
|
|
|
|
struct sc_pkcs15_pin_info *pin;
|
2002-03-22 00:13:25 +00:00
|
|
|
const int pf_count = sizeof(pin_flags) / sizeof(pin_flags[0]);
|
2002-03-07 13:03:00 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
pin = (struct sc_pkcs15_pin_info *) obj->data;
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&pin->auth_id));
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\tFlags : [0x%02X]", pin->flags);
|
|
|
|
for (i = 0; i < pf_count; i++)
|
|
|
|
if (pin->flags & (1 << i)) {
|
|
|
|
printf(", %s", pin_flags[i]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
2006-05-01 10:02:50 +00:00
|
|
|
printf("\tLength : min_len:%lu, max_len:%lu, stored_len:%lu\n",
|
|
|
|
(unsigned long) pin->min_length,
|
|
|
|
(unsigned long) pin->max_length,
|
|
|
|
(unsigned long) pin->stored_length);
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\tPad char : 0x%02X\n", pin->pad_char);
|
|
|
|
printf("\tReference : %d\n", pin->reference);
|
2003-04-11 10:32:50 +00:00
|
|
|
printf("\tEncoding : ");
|
|
|
|
switch (pin->type) {
|
|
|
|
case SC_PKCS15_PIN_TYPE_BCD:
|
|
|
|
printf("BCD\n"); break;
|
|
|
|
case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC:
|
|
|
|
printf("ASCII-numeric\n"); break;
|
|
|
|
case SC_PKCS15_PIN_TYPE_UTF8:
|
|
|
|
printf("UTF8\n"); break;
|
|
|
|
case SC_PKCS15_PIN_TYPE_HALFNIBBLE_BCD:
|
|
|
|
printf("half-nibble BCD\n"); break;
|
|
|
|
case SC_PKCS15_PIN_TYPE_ISO9564_1:
|
|
|
|
printf("ISO 9564-1\n"); break;
|
|
|
|
default:
|
|
|
|
printf("[encoding %d]\n", pin->type);
|
|
|
|
}
|
2005-11-28 23:07:33 +00:00
|
|
|
if (pin->path.len)
|
|
|
|
printf("\tPath : %s\n", sc_print_path(&pin->path));
|
2003-10-31 12:29:12 +00:00
|
|
|
if (pin->tries_left >= 0)
|
|
|
|
printf("\tTries left : %d\n", pin->tries_left);
|
2002-03-07 13:03:00 +00:00
|
|
|
}
|
|
|
|
|
2002-04-17 20:46:56 +00:00
|
|
|
static void print_prkey(const struct sc_pkcs15_object *obj)
|
2002-03-07 13:03:00 +00:00
|
|
|
{
|
|
|
|
int i;
|
2008-05-05 13:00:01 +00:00
|
|
|
size_t j;
|
2002-03-22 00:13:25 +00:00
|
|
|
const char *usages[] =
|
|
|
|
{
|
2002-03-07 13:03:00 +00:00
|
|
|
"encrypt", "decrypt", "sign", "signRecover",
|
|
|
|
"wrap", "unwrap", "verify", "verifyRecover",
|
|
|
|
"derive", "nonRepudiation"
|
|
|
|
};
|
2002-03-22 00:13:25 +00:00
|
|
|
const int usage_count = sizeof(usages) / sizeof(usages[0]);
|
|
|
|
const char *access_flags[] =
|
|
|
|
{
|
2002-03-07 13:03:00 +00:00
|
|
|
"sensitive", "extract", "alwaysSensitive",
|
|
|
|
"neverExtract", "local"
|
|
|
|
};
|
2002-03-22 00:13:25 +00:00
|
|
|
const int af_count = sizeof(access_flags) / sizeof(access_flags[0]);
|
2002-03-07 13:03:00 +00:00
|
|
|
struct sc_pkcs15_prkey_info *prkey;
|
|
|
|
|
|
|
|
prkey = (struct sc_pkcs15_prkey_info *) obj->data;
|
|
|
|
|
|
|
|
printf("\tUsage : [0x%X]", prkey->usage);
|
2002-03-22 00:13:25 +00:00
|
|
|
for (i = 0; i < usage_count; i++)
|
|
|
|
if (prkey->usage & (1 << i)) {
|
|
|
|
printf(", %s", usages[i]);
|
|
|
|
}
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\n");
|
|
|
|
printf("\tAccess Flags: [0x%X]", prkey->access_flags);
|
2002-03-22 00:13:25 +00:00
|
|
|
for (i = 0; i < af_count; i++)
|
|
|
|
if (prkey->access_flags & (1 << i)) {
|
|
|
|
printf(", %s", access_flags[i]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
2002-04-18 09:13:18 +00:00
|
|
|
if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)
|
2006-05-01 10:02:50 +00:00
|
|
|
printf("\tModLength : %lu\n",
|
|
|
|
(unsigned long) prkey->modulus_length);
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\tKey ref : %d\n", prkey->key_reference);
|
|
|
|
printf("\tNative : %s\n", prkey->native ? "yes" : "no");
|
2003-10-31 16:02:54 +00:00
|
|
|
if (prkey->path.len) {
|
|
|
|
printf("\tPath : ");
|
2008-05-05 13:00:01 +00:00
|
|
|
for (j = 0; j < prkey->path.len; j++)
|
|
|
|
printf("%02X", prkey->path.value[j]);
|
2003-10-31 16:02:54 +00:00
|
|
|
if (prkey->path.type == SC_PATH_TYPE_PATH_PROT)
|
|
|
|
printf(" (protected)");
|
|
|
|
printf("\n");
|
|
|
|
}
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tID : %s\n", sc_pkcs15_print_id(&prkey->id));
|
2002-03-07 13:03:00 +00:00
|
|
|
}
|
|
|
|
|
2002-04-17 20:46:56 +00:00
|
|
|
static void print_pubkey(const struct sc_pkcs15_object *obj)
|
2002-03-07 13:03:00 +00:00
|
|
|
{
|
|
|
|
int i;
|
2008-05-05 13:00:01 +00:00
|
|
|
size_t j;
|
2002-03-22 00:13:25 +00:00
|
|
|
const char *usages[] =
|
|
|
|
{
|
2002-03-07 13:03:00 +00:00
|
|
|
"encrypt", "decrypt", "sign", "signRecover",
|
|
|
|
"wrap", "unwrap", "verify", "verifyRecover",
|
|
|
|
"derive", "nonRepudiation"
|
|
|
|
};
|
2002-03-22 00:13:25 +00:00
|
|
|
const int usage_count = sizeof(usages) / sizeof(usages[0]);
|
|
|
|
const char *access_flags[] =
|
|
|
|
{
|
2002-03-07 13:03:00 +00:00
|
|
|
"sensitive", "extract", "alwaysSensitive",
|
|
|
|
"neverExtract", "local"
|
|
|
|
};
|
2002-03-22 00:13:25 +00:00
|
|
|
const int af_count = sizeof(access_flags) / sizeof(access_flags[0]);
|
2002-03-07 13:03:00 +00:00
|
|
|
struct sc_pkcs15_pubkey_info *pubkey;
|
|
|
|
|
|
|
|
pubkey = (struct sc_pkcs15_pubkey_info *) obj->data;
|
|
|
|
|
|
|
|
printf("\tUsage : [0x%X]", pubkey->usage);
|
2002-03-22 00:13:25 +00:00
|
|
|
for (i = 0; i < usage_count; i++)
|
|
|
|
if (pubkey->usage & (1 << i)) {
|
|
|
|
printf(", %s", usages[i]);
|
|
|
|
}
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\n");
|
|
|
|
printf("\tAccess Flags: [0x%X]", pubkey->access_flags);
|
2002-03-22 00:13:25 +00:00
|
|
|
for (i = 0; i < af_count; i++)
|
|
|
|
if (pubkey->access_flags & (1 << i)) {
|
|
|
|
printf(", %s", access_flags[i]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
2002-04-18 09:13:18 +00:00
|
|
|
if (obj->type == SC_PKCS15_TYPE_PUBKEY_RSA)
|
2006-05-01 10:02:50 +00:00
|
|
|
printf("\tModLength : %lu\n",
|
|
|
|
(unsigned long) pubkey->modulus_length);
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\tKey ref : %d\n", pubkey->key_reference);
|
|
|
|
printf("\tNative : %s\n", pubkey->native ? "yes" : "no");
|
|
|
|
printf("\tPath : ");
|
2008-05-05 13:00:01 +00:00
|
|
|
for (j = 0; j < pubkey->path.len; j++)
|
|
|
|
printf("%02X", pubkey->path.value[j]);
|
2002-03-07 13:03:00 +00:00
|
|
|
printf("\n");
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tID : %s\n", sc_pkcs15_print_id(&pubkey->id));
|
2002-03-07 13:03:00 +00:00
|
|
|
}
|
|
|
|
|
2002-03-22 00:13:25 +00:00
|
|
|
static void print_cert_x509(const struct sc_pkcs15_object *obj)
|
2002-03-07 13:03:00 +00:00
|
|
|
{
|
|
|
|
struct sc_pkcs15_cert_info *cert;
|
|
|
|
|
|
|
|
cert = (struct sc_pkcs15_cert_info *) obj->data;
|
2002-04-02 11:41:00 +00:00
|
|
|
printf("\tAuthority : %s\n", cert->authority ? "yes" : "no");
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tPath : %s\n",
|
|
|
|
cert->path.len? sc_print_path(&cert->path) : "<direct encoding>");
|
|
|
|
printf("\tID : %s\n", sc_pkcs15_print_id(&cert->id));
|
2002-03-07 13:03:00 +00:00
|
|
|
|
|
|
|
/* XXX original p15dump code would read the certificate
|
|
|
|
* and dump the label */
|
|
|
|
}
|
|
|
|
|
2002-12-18 10:17:01 +00:00
|
|
|
static void print_data_object_summary(const struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_pkcs15_data_info *data_object;
|
2005-07-29 14:38:57 +00:00
|
|
|
unsigned i;
|
2002-12-18 10:17:01 +00:00
|
|
|
|
|
|
|
data_object = (struct sc_pkcs15_data_info *) obj->data;
|
|
|
|
printf("\tPath : ");
|
|
|
|
for (i = 0; i < data_object->path.len; i++)
|
|
|
|
printf("%02X", data_object->path.value[i]);
|
|
|
|
printf("\n");
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tID : %s\n", sc_pkcs15_print_id(&data_object->id));
|
2002-12-18 10:17:01 +00:00
|
|
|
|
|
|
|
/* XXX original p15dump code would read the data object
|
|
|
|
* and dump the label */
|
|
|
|
}
|
|
|
|
|
2002-03-22 00:13:25 +00:00
|
|
|
void sc_test_print_object(const struct sc_pkcs15_object *obj)
|
2002-03-07 13:03:00 +00:00
|
|
|
{
|
2002-03-22 00:13:25 +00:00
|
|
|
const char *kind;
|
|
|
|
void (*printer) (const struct sc_pkcs15_object *);
|
2002-03-07 13:03:00 +00:00
|
|
|
|
|
|
|
switch (obj->type) {
|
|
|
|
case SC_PKCS15_TYPE_AUTH_PIN:
|
|
|
|
printer = print_pin;
|
|
|
|
kind = "PIN";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
2002-04-17 20:46:56 +00:00
|
|
|
printer = print_prkey;
|
2002-03-07 13:03:00 +00:00
|
|
|
kind = "Private RSA key";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
2002-04-17 20:46:56 +00:00
|
|
|
printer = print_pubkey;
|
2002-03-07 13:03:00 +00:00
|
|
|
kind = "Public RSA key";
|
|
|
|
break;
|
2002-04-17 20:46:56 +00:00
|
|
|
case SC_PKCS15_TYPE_PRKEY_DSA:
|
|
|
|
printer = print_prkey;
|
|
|
|
kind = "Private DSA key";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_DSA:
|
|
|
|
printer = print_pubkey;
|
|
|
|
kind = "Public DSA key";
|
|
|
|
break;
|
2002-03-07 13:03:00 +00:00
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
printer = print_cert_x509;
|
|
|
|
kind = "X.509 Certificate";
|
|
|
|
break;
|
2002-12-18 10:17:01 +00:00
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
|
|
|
printer = print_data_object_summary;
|
|
|
|
kind = "Data Object";
|
|
|
|
break;
|
2002-03-07 13:03:00 +00:00
|
|
|
default:
|
|
|
|
printer = NULL;
|
|
|
|
kind = "Something";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%s", kind);
|
|
|
|
if (obj->label[0])
|
|
|
|
printf(" [%s]\n", obj->label);
|
|
|
|
else
|
|
|
|
printf(" (no label)\n");
|
2003-11-19 20:33:12 +00:00
|
|
|
printf("\tCom. Flags : ");
|
|
|
|
switch (obj->flags) {
|
|
|
|
case 0x01: printf("private\n"); break;
|
|
|
|
case 0x02: printf("modifiable\n"); break;
|
|
|
|
case 0x03: printf("private, modifiable\n"); break;
|
|
|
|
default: printf("0x%X\n", obj->flags);
|
2002-03-07 13:03:00 +00:00
|
|
|
}
|
2003-11-19 20:33:12 +00:00
|
|
|
if (obj->auth_id.len)
|
|
|
|
printf("\tCom. Auth ID: %s\n", sc_pkcs15_print_id(&obj->auth_id));
|
2003-08-11 13:55:16 +00:00
|
|
|
if (obj->user_consent)
|
|
|
|
printf("\tUser consent: %u\n", obj->user_consent);
|
|
|
|
|
2002-03-07 13:03:00 +00:00
|
|
|
if (printer)
|
|
|
|
printer(obj);
|
|
|
|
}
|