From 32e66f4fc698f9b1d360b8c2bb19c456dfb2ba03 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Wed, 18 Nov 2015 13:42:11 +0100 Subject: [PATCH] add attest action --- lib/ykpiv.h | 1 + tool/cmdline.ggo | 2 +- tool/yubico-piv-tool.c | 73 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/lib/ykpiv.h b/lib/ykpiv.h index c0aa0ac..530c59c 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -155,6 +155,7 @@ extern "C" #define YKPIV_INS_GET_VERSION 0xfd #define YKPIV_INS_RESET 0xfb #define YKPIV_INS_SET_PIN_RETRIES 0xfa +#define YKPIV_INS_ATTEST 0xf9 #define YKPIV_PINPOLICY_TAG 0xaa #define YKPIV_PINPOLICY_NEVER 1 diff --git a/tool/cmdline.ggo b/tool/cmdline.ggo index 85ddfdb..498861d 100644 --- a/tool/cmdline.ggo +++ b/tool/cmdline.ggo @@ -32,7 +32,7 @@ option "action" a "Action to take" values="version","generate","set-mgm-key", "reset","pin-retries","import-key","import-certificate","set-chuid", "request-certificate","verify-pin","change-pin","change-puk","unblock-pin", "selfsign-certificate","delete-certificate","read-certificate","status", - "test-signature","test-decipher","list-readers" enum multiple + "test-signature","test-decipher","list-readers","attest" enum multiple text " Multiple actions may be given at once and will be executed in order for example --action=verify-pin --action=request-certificate\n" diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index 01a6690..02191c8 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -1599,6 +1599,71 @@ static bool list_readers(ykpiv_state *state) { return true; } +static bool attest(ykpiv_state *state, const char *slot, + enum enum_key_format key_format, const char *output_file_name) { + FILE *output_file; + unsigned char data[2048]; + unsigned long len = sizeof(data); + bool ret = false; + X509 *x509 = NULL; + unsigned char templ[] = {0, YKPIV_INS_ATTEST, 0, 0}; + int key; + int sw; + + sscanf(slot, "%2x", &key); + templ[2] = key; + + if(key_format != key_format_arg_PEM && key_format != key_format_arg_DER) { + fprintf(stderr, "Only PEM and DER format are supported for attest..\n"); + return false; + } + + output_file = open_file(output_file_name, OUTPUT); + if(!output_file) { + return false; + } + + if(ykpiv_transfer_data(state, templ, NULL, 0, data, &len, &sw) != YKPIV_OK) { + fprintf(stderr, "Failed to communicate.\n"); + goto attest_out; + } else if(sw != 0x9000) { + fprintf(stderr, "Failed to attest key.\n"); + goto attest_out; + } + + if(data[0] == 0x30) { + if(key_format == key_format_arg_PEM) { + const unsigned char *ptr = data; + int len2 = len; + x509 = X509_new(); + if(!x509) { + fprintf(stderr, "Failed allocating x509 structure.\n"); + goto attest_out; + } + x509 = d2i_X509(NULL, &ptr, len2); + if(!x509) { + fprintf(stderr, "Failed parsing x509 information.\n"); + goto attest_out; + } + PEM_write_X509(output_file, x509); + ret = true; + } else { + fwrite(data, len, 1, output_file); + } + ret = true; + } + +attest_out: + if(output_file != stdout) { + fclose(output_file); + } + if(x509) { + X509_free(x509); + } + + return ret; +} + int main(int argc, char *argv[]) { struct gengetopt_args_info args_info; ykpiv_state *state; @@ -1630,6 +1695,7 @@ int main(int argc, char *argv[]) { case action_arg_readMINUS_certificate: case action_arg_testMINUS_signature: case action_arg_testMINUS_decipher: + case action_arg_attest: if(args_info.slot_arg == slot__NULL) { fprintf(stderr, "The '%s' action needs a slot (-s) to operate on.\n", cmdline_parser_action_values[action]); @@ -1698,6 +1764,7 @@ int main(int argc, char *argv[]) { case action_arg_testMINUS_signature: case action_arg_testMINUS_decipher: case action_arg_listMINUS_readers: + case action_arg_attest: case action__NULL: default: if(verbosity) { @@ -1897,6 +1964,12 @@ int main(int argc, char *argv[]) { ret = EXIT_FAILURE; } break; + case action_arg_attest: + if(attest(state, args_info.slot_orig, args_info.key_format_arg, + args_info.output_arg) == false) { + ret = EXIT_FAILURE; + } + break; case action__NULL: default: fprintf(stderr, "Wrong action. %d.\n", action);