pkcs15-tool: add compact output format
Closes https://github.com/OpenSC/OpenSC/pull/900
This commit is contained in:
parent
a16aaed41e
commit
a25a2484f1
|
@ -72,7 +72,7 @@
|
|||
<option>--dump</option>,
|
||||
<option>-D</option>
|
||||
</term>
|
||||
<listitem><para>Dump card objects.</para></listitem>
|
||||
<listitem><para>List all card objects.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -87,7 +87,7 @@
|
|||
<option>--list-certificates</option>,
|
||||
<option>-c</option>
|
||||
</term>
|
||||
<listitem><para>Lists all certificates stored on the token.</para></listitem>
|
||||
<listitem><para>List all certificates stored on the token.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -95,7 +95,7 @@
|
|||
<option>--list-data-objects</option>,
|
||||
<option>-C</option>
|
||||
</term>
|
||||
<listitem><para>Lists all data objects stored on the token.
|
||||
<listitem><para>List all data objects stored on the token.
|
||||
For some cards the PKCS#15 attributes of the private data objects are
|
||||
protected for reading and need the authentication with the User PIN.
|
||||
In such a case the <option>--verify-pin</option> option has to be used.
|
||||
|
@ -107,7 +107,7 @@
|
|||
<option>--list-keys</option>,
|
||||
<option>-k</option>
|
||||
</term>
|
||||
<listitem><para>Lists all private keys stored on the token. General
|
||||
<listitem><para>List all private keys stored on the token. General
|
||||
information about each private key is listed (eg. key name, id and
|
||||
algorithm). Actual private key values are not displayed.
|
||||
For some cards the PKCS#15 attributes of the private keys are protected for reading
|
||||
|
@ -119,7 +119,7 @@
|
|||
<term>
|
||||
<option>--list-pins</option>
|
||||
</term>
|
||||
<listitem><para>Lists all PINs stored on the token. General information
|
||||
<listitem><para>List all PINs stored on the token. General information
|
||||
about each PIN is listed (eg. PIN name). Actual PIN values are not shown.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -127,10 +127,18 @@
|
|||
<term>
|
||||
<option>--list-public-keys</option>
|
||||
</term>
|
||||
<listitem><para>Lists all public keys stored on the token, including
|
||||
<listitem><para>List all public keys stored on the token, including
|
||||
key name, id, algorithm and length information.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--short</option>
|
||||
<option>-s</option>
|
||||
</term>
|
||||
<listitem><para>Output lists in compact format.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--no-cache</option>
|
||||
|
|
|
@ -70,6 +70,7 @@ static char * opt_bind_to_aid = NULL;
|
|||
static const char * opt_newpin = NULL;
|
||||
static const char * opt_pin = NULL;
|
||||
static const char * opt_puk = NULL;
|
||||
static int compact = 0;
|
||||
static int verbose = 0;
|
||||
static int opt_no_prompt = 0;
|
||||
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
|
||||
|
@ -117,6 +118,7 @@ static const struct option options[] = {
|
|||
{ "list-data-objects", no_argument, NULL, 'C' },
|
||||
{ "list-pins", no_argument, NULL, OPT_LIST_PINS },
|
||||
{ "list-secret-keys", no_argument, NULL, OPT_LIST_SKEYS },
|
||||
{ "short", no_argument, NULL, 's' },
|
||||
{ "dump", no_argument, NULL, 'D' },
|
||||
{ "unblock-pin", no_argument, NULL, 'u' },
|
||||
{ "change-pin", no_argument, NULL, OPT_CHANGE_PIN },
|
||||
|
@ -149,18 +151,19 @@ static const char *option_help[] = {
|
|||
"Print OpenSC package version",
|
||||
"List card information",
|
||||
"List the on-card PKCS#15 applications",
|
||||
"Reads certificate with ID <arg>",
|
||||
"Lists certificates",
|
||||
"Read certificate with ID <arg>",
|
||||
"List certificates",
|
||||
"Reads data object with OID, applicationName or label <arg>",
|
||||
"Outputs raw 8 bit data to stdout. File output will not be affected by this, it always uses raw mode.",
|
||||
"Lists data objects",
|
||||
"Lists PIN codes",
|
||||
"Lists secret keys",
|
||||
"Dump card objects",
|
||||
"List data objects",
|
||||
"List PIN codes",
|
||||
"List secret keys",
|
||||
"Output lists in compact format",
|
||||
"List all card objects",
|
||||
"Unblock PIN code",
|
||||
"Change PIN or PUK code",
|
||||
"Lists private keys",
|
||||
"Lists public keys",
|
||||
"List private keys",
|
||||
"List public keys",
|
||||
"Reads public key with ID <arg>",
|
||||
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
|
||||
"Reads public key with ID <arg>, outputs ssh format",
|
||||
|
@ -206,6 +209,8 @@ struct _access_rule_text {
|
|||
{0, NULL},
|
||||
};
|
||||
|
||||
static const char *key_types[] = { "", "RSA", "DSA", "GOSTR3410", "EC", "", "", "" };
|
||||
|
||||
static void
|
||||
print_access_rules(const struct sc_pkcs15_accessrule *rules, int num)
|
||||
{
|
||||
|
@ -253,6 +258,14 @@ static void print_cert_info(const struct sc_pkcs15_object *obj)
|
|||
struct sc_pkcs15_cert *cert_parsed = NULL;
|
||||
int rv;
|
||||
|
||||
if (compact) {
|
||||
printf("\tPath:%s ID:%s", sc_print_path(&cert_info->path),
|
||||
sc_pkcs15_print_id(&cert_info->id));
|
||||
if (cert_info->authority)
|
||||
printf(" Authority");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("X.509 Certificate [%.*s]\n", (int) sizeof obj->label, obj->label);
|
||||
print_common_flags(obj);
|
||||
printf("\tAuthority : %s\n", cert_info->authority ? "yes" : "no");
|
||||
|
@ -270,7 +283,6 @@ static void print_cert_info(const struct sc_pkcs15_object *obj)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int list_certificates(void)
|
||||
{
|
||||
int r, i;
|
||||
|
@ -281,7 +293,9 @@ static int list_certificates(void)
|
|||
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
if (verbose)
|
||||
if (compact)
|
||||
printf("Card has %d Certificate(s).\n", r);
|
||||
else if (verbose)
|
||||
printf("Card has %d Certificate(s).\n\n", r);
|
||||
for (i = 0; i < r; i++) {
|
||||
print_cert_info(objs[i]);
|
||||
|
@ -494,12 +508,40 @@ static int list_data_objects(void)
|
|||
return 1;
|
||||
}
|
||||
count = r;
|
||||
if (verbose)
|
||||
if (compact)
|
||||
printf("Card has %d Data object(s).\n", count);
|
||||
else if (verbose)
|
||||
printf("Card has %d Data object(s).\n\n", count);
|
||||
for (i = 0; i < count; i++) {
|
||||
int idx;
|
||||
struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
|
||||
|
||||
if (compact) {
|
||||
printf("\tPath:%-12s", sc_print_path(&cinfo->path));
|
||||
if (sc_valid_oid(&cinfo->app_oid)) {
|
||||
printf(" %i", cinfo->app_oid.value[0]);
|
||||
for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && cinfo->app_oid.value[idx] != -1 ; idx++)
|
||||
printf(".%i", cinfo->app_oid.value[idx]);
|
||||
}
|
||||
if (objs[i]->auth_id.len == 0) {
|
||||
struct sc_pkcs15_data *data_object;
|
||||
r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
|
||||
if (r) {
|
||||
fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
|
||||
if (r == SC_ERROR_FILE_NOT_FOUND)
|
||||
continue; /* DEE emulation may say there is a file */
|
||||
return 1;
|
||||
}
|
||||
sc_pkcs15_free_data_object(data_object);
|
||||
printf(" Size:%6lu", cinfo->data.len);
|
||||
}else {
|
||||
printf(" AuthID:%3s", sc_pkcs15_print_id(&objs[i]->auth_id));
|
||||
}
|
||||
printf(" %-20s", cinfo->app_label);
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (objs[i]->label[0] != '\0')
|
||||
printf("Data object '%.*s'\n",(int) sizeof objs[i]->label, objs[i]->label);
|
||||
else
|
||||
|
@ -531,38 +573,63 @@ static int list_data_objects(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
||||
static void print_key_usages(int usage)
|
||||
{
|
||||
unsigned int i;
|
||||
struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
|
||||
const char *types[] = { "", "RSA", "DSA", "GOSTR3410", "EC", "", "", "" };
|
||||
size_t i;
|
||||
const char *usages[] = {
|
||||
"encrypt", "decrypt", "sign", "signRecover",
|
||||
"wrap", "unwrap", "verify", "verifyRecover",
|
||||
"derive", "nonRepudiation"
|
||||
"encrypt", "decrypt", "sign", "signRecover", "wrap", "unwrap",
|
||||
"verify", "verifyRecover", "derive", "nonRepudiation"
|
||||
};
|
||||
const size_t usage_count = NELEMENTS(usages);
|
||||
const char *access_flags[] = {
|
||||
"sensitive", "extract", "alwaysSensitive",
|
||||
"neverExtract", "local"
|
||||
for (i = 0; i < usage_count; i++)
|
||||
if (usage & (1 << i))
|
||||
printf(", %s", usages[i]);
|
||||
}
|
||||
|
||||
static void print_key_access_flags(int flags)
|
||||
{
|
||||
size_t i;
|
||||
const char *key_access_flags[] = {
|
||||
"sensitive", "extract", "alwaysSensitive","neverExtract", "local"
|
||||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
const size_t af_count = NELEMENTS(key_access_flags);
|
||||
for (i = 0; i < af_count; i++)
|
||||
if (flags & (1 << i))
|
||||
printf(", %s", key_access_flags[i]);
|
||||
}
|
||||
|
||||
static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
||||
{
|
||||
struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
|
||||
unsigned char guid[40];
|
||||
size_t guid_len;
|
||||
|
||||
printf("Private %s Key [%.*s]\n", types[7 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
if (compact) {
|
||||
printf("\t%-3s", key_types[7 & obj->type]);
|
||||
|
||||
if (prkey->modulus_length)
|
||||
printf("[%lu]", (unsigned long)prkey->modulus_length);
|
||||
else {
|
||||
if (prkey->field_length)
|
||||
printf("[%lu]", (unsigned long)prkey->field_length);
|
||||
}
|
||||
printf(" ID:%s", sc_pkcs15_print_id(&prkey->id));
|
||||
printf(" Ref:0x%02X", prkey->key_reference);
|
||||
if (obj->auth_id.len != 0)
|
||||
printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
|
||||
printf("\n\t %-16.*s [0x%X", 16, obj->label, prkey->usage);
|
||||
print_key_usages(prkey->usage);
|
||||
printf("]");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Private %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
print_common_flags(obj);
|
||||
printf("\tUsage : [0x%X]", prkey->usage);
|
||||
for (i = 0; i < usage_count; i++)
|
||||
if (prkey->usage & (1 << i)) {
|
||||
printf(", %s", usages[i]);
|
||||
}
|
||||
print_key_usages(prkey->usage);
|
||||
printf("\n");
|
||||
|
||||
printf("\tAccess Flags : [0x%X]", prkey->access_flags);
|
||||
for (i = 0; i < af_count; i++)
|
||||
if (prkey->access_flags & (1 << i))
|
||||
printf(", %s", access_flags[i]);
|
||||
print_key_access_flags(prkey->access_flags);
|
||||
printf("\n");
|
||||
|
||||
print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
|
||||
|
@ -604,7 +671,9 @@ static int list_private_keys(void)
|
|||
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
if (verbose)
|
||||
if (compact)
|
||||
printf("Card has %d Private key(s).\n", r);
|
||||
else if (verbose)
|
||||
printf("Card has %d Private key(s).\n\n", r);
|
||||
for (i = 0; i < r; i++) {
|
||||
print_prkey_info(objs[i]);
|
||||
|
@ -615,35 +684,34 @@ static int list_private_keys(void)
|
|||
|
||||
static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
||||
{
|
||||
unsigned int i;
|
||||
const struct sc_pkcs15_pubkey_info *pubkey = (const struct sc_pkcs15_pubkey_info *) obj->data;
|
||||
const char *types[] = { "", "RSA", "DSA", "GOSTR3410", "EC", "", "", "" };
|
||||
const char *usages[] = {
|
||||
"encrypt", "decrypt", "sign", "signRecover",
|
||||
"wrap", "unwrap", "verify", "verifyRecover",
|
||||
"derive", "nonRepudiation"
|
||||
};
|
||||
const unsigned int usage_count = NELEMENTS(usages);
|
||||
const char *access_flags[] = {
|
||||
"sensitive", "extract", "alwaysSensitive",
|
||||
"neverExtract", "local"
|
||||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
int have_path = (pubkey->path.len != 0) || (pubkey->path.aid.len != 0);
|
||||
|
||||
printf("Public %s Key [%.*s]\n", types[7 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
if (compact) {
|
||||
printf("\t%-3s", key_types[7 & obj->type]);
|
||||
|
||||
if (pubkey->modulus_length)
|
||||
printf("[%lu]", (unsigned long)pubkey->modulus_length);
|
||||
else
|
||||
printf("[FieldLength:%lu]", (unsigned long)pubkey->field_length);
|
||||
printf(" %s", sc_pkcs15_print_id(&pubkey->id));
|
||||
printf(" Ref:0x%02X", pubkey->key_reference);
|
||||
if (obj->auth_id.len != 0)
|
||||
printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
|
||||
printf(" %15.*s [0x%X", (int) sizeof obj->label, obj->label, pubkey->usage);
|
||||
print_key_usages(pubkey->usage);
|
||||
printf("]");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Public %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
print_common_flags(obj);
|
||||
printf("\tUsage : [0x%X]", pubkey->usage);
|
||||
for (i = 0; i < usage_count; i++)
|
||||
if (pubkey->usage & (1 << i)) {
|
||||
printf(", %s", usages[i]);
|
||||
}
|
||||
print_key_usages(pubkey->usage);
|
||||
printf("\n");
|
||||
|
||||
printf("\tAccess Flags : [0x%X]", pubkey->access_flags);
|
||||
for (i = 0; i < af_count; i++)
|
||||
if (pubkey->access_flags & (1 << i))
|
||||
printf(", %s", access_flags[i]);
|
||||
print_key_access_flags(pubkey->access_flags);
|
||||
printf("\n");
|
||||
|
||||
print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
|
||||
|
@ -683,7 +751,9 @@ static int list_public_keys(void)
|
|||
fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
if (verbose)
|
||||
if (compact)
|
||||
printf("Card has %d Public key(s).\n", r);
|
||||
else if (verbose)
|
||||
printf("Card has %d Public key(s).\n\n", r);
|
||||
for (i = 0; i < r; i++) {
|
||||
print_pubkey_info(objs[i]);
|
||||
|
@ -756,35 +826,19 @@ static int read_public_key(void)
|
|||
|
||||
static void print_skey_info(const struct sc_pkcs15_object *obj)
|
||||
{
|
||||
unsigned int i;
|
||||
struct sc_pkcs15_skey_info *skey = (struct sc_pkcs15_skey_info *) obj->data;
|
||||
const char *types[] = { "generic", "DES", "2DES", "3DES"};
|
||||
const char *usages[] = {
|
||||
"encrypt", "decrypt", "sign", "signRecover",
|
||||
"wrap", "unwrap", "verify", "verifyRecover",
|
||||
"derive"
|
||||
};
|
||||
const size_t usage_count = NELEMENTS(usages);
|
||||
const char *access_flags[] = {
|
||||
"sensitive", "extract", "alwaysSensitive",
|
||||
"neverExtract", "local"
|
||||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
unsigned char guid[40];
|
||||
size_t guid_len;
|
||||
|
||||
printf("Secret %s Key [%.*s]\n", types[3 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
print_common_flags(obj);
|
||||
printf("\tUsage : [0x%X]", skey->usage);
|
||||
for (i = 0; i < usage_count; i++)
|
||||
if (skey->usage & (1 << i))
|
||||
printf(", %s", usages[i]);
|
||||
print_key_usages(skey->usage);
|
||||
printf("\n");
|
||||
|
||||
printf("\tAccess Flags : [0x%X]", skey->access_flags);
|
||||
for (i = 0; i < af_count; i++)
|
||||
if (skey->access_flags & (1 << i))
|
||||
printf(", %s", access_flags[i]);
|
||||
print_key_access_flags(skey->access_flags);
|
||||
printf("\n");
|
||||
|
||||
print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
|
||||
|
@ -1320,10 +1374,32 @@ static void print_pin_info(const struct sc_pkcs15_object *obj)
|
|||
const size_t pf_count = NELEMENTS(pin_flags);
|
||||
size_t i;
|
||||
|
||||
if (obj->type == SC_PKCS15_TYPE_AUTH_PIN)
|
||||
printf("PIN [%.*s]\n", (int) sizeof obj->label, obj->label);
|
||||
else if (obj->type == SC_PKCS15_TYPE_AUTH_AUTHKEY)
|
||||
printf("AuthKey [%.*s]\n", (int) sizeof obj->label, obj->label);
|
||||
assert(obj->type == SC_PKCS15_TYPE_AUTH_PIN || obj->type == SC_PKCS15_TYPE_AUTH_AUTHKEY);
|
||||
|
||||
if (compact) {
|
||||
printf("\t%-3s ID:%s", obj->type == SC_PKCS15_TYPE_AUTH_PIN ? "PIN" : "Key",
|
||||
sc_pkcs15_print_id(&auth_info->auth_id));
|
||||
if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) {
|
||||
const struct sc_pkcs15_pin_attributes *pin_attrs = &(auth_info->attrs.pin);
|
||||
printf(" Ref:0x%02X", pin_attrs->reference);
|
||||
}
|
||||
else {
|
||||
const struct sc_pkcs15_authkey_attributes *attrs = &auth_info->attrs.authkey;
|
||||
printf(" Derived:%i", attrs->derived);
|
||||
printf(" SecretKeyID:%s", sc_pkcs15_print_id(&attrs->skey_id));
|
||||
}
|
||||
if (obj->auth_id.len)
|
||||
printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
|
||||
if (auth_info->path.len || auth_info->path.aid.len)
|
||||
printf(" Path:%s", sc_print_path(&auth_info->path));
|
||||
if (auth_info->tries_left >= 0)
|
||||
printf(" Tries:%d", auth_info->tries_left);
|
||||
printf(" %.*s", (int) sizeof obj->label, obj->label);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s [%.*s]\n", obj->type == SC_PKCS15_TYPE_AUTH_PIN ? "PIN" : "AuthKey",
|
||||
(int) sizeof obj->label, obj->label);
|
||||
|
||||
print_common_flags(obj);
|
||||
if (obj->auth_id.len)
|
||||
|
@ -1371,8 +1447,11 @@ static int list_pins(void)
|
|||
fprintf(stderr, "AUTH objects enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
if (verbose)
|
||||
if (compact)
|
||||
printf("Card has %d Authentication object(s).\n", r);
|
||||
else if (verbose)
|
||||
printf("Card has %d Authentication object(s).\n\n", r);
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
print_pin_info(objs[i]);
|
||||
printf("\n");
|
||||
|
@ -1406,7 +1485,8 @@ static int list_apps(FILE *fout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void list_info(void){
|
||||
static void list_info(void)
|
||||
{
|
||||
const char *flags[] = {
|
||||
"Read-only",
|
||||
"Login required",
|
||||
|
@ -1887,7 +1967,7 @@ int main(int argc, char * const argv[])
|
|||
c = OPT_PUK;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "r:cuko:va:LR:CwDTU", options, &long_optind);
|
||||
c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
if (c == '?')
|
||||
|
@ -1992,6 +2072,9 @@ int main(int argc, char * const argv[])
|
|||
case 'o':
|
||||
opt_outfile = optarg;
|
||||
break;
|
||||
case 's':
|
||||
compact++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue