add attest action
This commit is contained in:
@@ -155,6 +155,7 @@ extern "C"
|
|||||||
#define YKPIV_INS_GET_VERSION 0xfd
|
#define YKPIV_INS_GET_VERSION 0xfd
|
||||||
#define YKPIV_INS_RESET 0xfb
|
#define YKPIV_INS_RESET 0xfb
|
||||||
#define YKPIV_INS_SET_PIN_RETRIES 0xfa
|
#define YKPIV_INS_SET_PIN_RETRIES 0xfa
|
||||||
|
#define YKPIV_INS_ATTEST 0xf9
|
||||||
|
|
||||||
#define YKPIV_PINPOLICY_TAG 0xaa
|
#define YKPIV_PINPOLICY_TAG 0xaa
|
||||||
#define YKPIV_PINPOLICY_NEVER 1
|
#define YKPIV_PINPOLICY_NEVER 1
|
||||||
|
|||||||
+1
-1
@@ -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",
|
"reset","pin-retries","import-key","import-certificate","set-chuid",
|
||||||
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
||||||
"selfsign-certificate","delete-certificate","read-certificate","status",
|
"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 "
|
text "
|
||||||
Multiple actions may be given at once and will be executed in order
|
Multiple actions may be given at once and will be executed in order
|
||||||
for example --action=verify-pin --action=request-certificate\n"
|
for example --action=verify-pin --action=request-certificate\n"
|
||||||
|
|||||||
@@ -1599,6 +1599,71 @@ static bool list_readers(ykpiv_state *state) {
|
|||||||
return true;
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct gengetopt_args_info args_info;
|
struct gengetopt_args_info args_info;
|
||||||
ykpiv_state *state;
|
ykpiv_state *state;
|
||||||
@@ -1630,6 +1695,7 @@ int main(int argc, char *argv[]) {
|
|||||||
case action_arg_readMINUS_certificate:
|
case action_arg_readMINUS_certificate:
|
||||||
case action_arg_testMINUS_signature:
|
case action_arg_testMINUS_signature:
|
||||||
case action_arg_testMINUS_decipher:
|
case action_arg_testMINUS_decipher:
|
||||||
|
case action_arg_attest:
|
||||||
if(args_info.slot_arg == slot__NULL) {
|
if(args_info.slot_arg == slot__NULL) {
|
||||||
fprintf(stderr, "The '%s' action needs a slot (-s) to operate on.\n",
|
fprintf(stderr, "The '%s' action needs a slot (-s) to operate on.\n",
|
||||||
cmdline_parser_action_values[action]);
|
cmdline_parser_action_values[action]);
|
||||||
@@ -1698,6 +1764,7 @@ int main(int argc, char *argv[]) {
|
|||||||
case action_arg_testMINUS_signature:
|
case action_arg_testMINUS_signature:
|
||||||
case action_arg_testMINUS_decipher:
|
case action_arg_testMINUS_decipher:
|
||||||
case action_arg_listMINUS_readers:
|
case action_arg_listMINUS_readers:
|
||||||
|
case action_arg_attest:
|
||||||
case action__NULL:
|
case action__NULL:
|
||||||
default:
|
default:
|
||||||
if(verbosity) {
|
if(verbosity) {
|
||||||
@@ -1897,6 +1964,12 @@ int main(int argc, char *argv[]) {
|
|||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case action__NULL:
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Wrong action. %d.\n", action);
|
fprintf(stderr, "Wrong action. %d.\n", action);
|
||||||
|
|||||||
Reference in New Issue
Block a user