From 645f42a890264fd73862480dd0749960900032fa Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 9 Sep 2015 19:12:50 +0900 Subject: [PATCH] allow cancelling execution of commands which take long time --- ChangeLog | 5 +++++ chopstx | 2 +- src/main.c | 2 +- src/openpgp-do.c | 4 ++++ src/openpgp.c | 30 ++++++++++++++++++++++++++++-- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc08598..788c300 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2015-09-09 Niibe Yutaka + * src/openpgp.c (process_command_apdu): Protect command execution + against cancelling the execution thread. + (cmd_pso, cmd_internal_authenticate): Allow cancellation. + * src/openpgp-do.c (gpg_do_keygen): Allow cancellation. + * src/main.c (main): Handle LED_USB_RESET. * src/usb-icc.c (ccid_usb_reset): New. diff --git a/chopstx b/chopstx index baef99b..acd4460 160000 --- a/chopstx +++ b/chopstx @@ -1 +1 @@ -Subproject commit baef99bf11db42df18e2155e14fe774260747c91 +Subproject commit acd4460a6ee0f7caa1d7871acd51cdcf6bb4264c diff --git a/src/main.c b/src/main.c index e598f41..b9d553a 100644 --- a/src/main.c +++ b/src/main.c @@ -392,7 +392,7 @@ main (int argc, char *argv[]) display_fatal_code (); break; case LED_USB_RESET: - ccid_reset (); + ccid_usb_reset (); chopstx_join (ccid_thd, NULL); /* Invoke the CCID thread again. */ ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid, diff --git a/src/openpgp-do.c b/src/openpgp-do.c index e18f42d..78cb180 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "config.h" @@ -2059,7 +2060,10 @@ gpg_do_keygen (uint8_t kk_byte) if (attr == ALGO_RSA2K || attr == ALGO_RSA4K) { + int cs = chopstx_setcancelstate (0); /* Allow cancellation. */ + /* XXX: We need to free up the allocated memory on cancellation. */ p_q_modulus = rsa_genkey (prvkey_len); + chopstx_setcancelstate (cs); if (p_q_modulus == NULL) { GPG_MEMORY_FAILURE (); diff --git a/src/openpgp.c b/src/openpgp.c index 5964de7..c1e9693 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -817,6 +817,7 @@ cmd_pso (void) int attr; int pubkey_len; unsigned int result_len = 0; + int cs; DEBUG_INFO (" - PSO: "); DEBUG_WORD ((uint32_t)&r); @@ -853,9 +854,11 @@ cmd_pso (void) DEBUG_BINARY (kd[GPG_KEY_FOR_SIGNING].data, pubkey_len); + cs = chopstx_setcancelstate (0); result_len = pubkey_len; r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len, &kd[GPG_KEY_FOR_SIGNING], pubkey_len); + chopstx_setcancelstate (cs); } else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1) { @@ -867,6 +870,7 @@ cmd_pso (void) return; } + cs = chopstx_setcancelstate (0); result_len = ECDSA_SIGNATURE_LENGTH; if (attr == ALGO_NISTP256R1) r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU, @@ -874,6 +878,7 @@ cmd_pso (void) else /* ALGO_SECP256K1 */ r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU, kd[GPG_KEY_FOR_SIGNING].data); + chopstx_setcancelstate (cs); } else if (attr == ALGO_ED25519) { @@ -886,11 +891,13 @@ cmd_pso (void) return; } + cs = chopstx_setcancelstate (0); result_len = EDDSA_SIGNATURE_LENGTH; r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output, kd[GPG_KEY_FOR_SIGNING].data, kd[GPG_KEY_FOR_SIGNING].data+32, kd[GPG_KEY_FOR_SIGNING].pubkey); + chopstx_setcancelstate (cs); memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH); } else @@ -932,8 +939,10 @@ cmd_pso (void) GPG_CONDITION_NOT_SATISFIED (); return; } + cs = chopstx_setcancelstate (0); r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len, &kd[GPG_KEY_FOR_DECRYPTION], &result_len); + chopstx_setcancelstate (cs); } else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1) { @@ -947,6 +956,7 @@ cmd_pso (void) return; } + cs = chopstx_setcancelstate (0); result_len = 65; if (attr == ALGO_NISTP256R1) r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data + header, res_APDU, @@ -954,6 +964,7 @@ cmd_pso (void) else r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data + header, res_APDU, kd[GPG_KEY_FOR_DECRYPTION].data); + chopstx_setcancelstate (cs); } else if (attr == ALGO_CURVE25519) { @@ -965,9 +976,11 @@ cmd_pso (void) return; } + cs = chopstx_setcancelstate (0); result_len = 32; r = ecdh_decrypt_curve25519 (apdu.cmd_apdu_data + header, res_APDU, kd[GPG_KEY_FOR_DECRYPTION].data); + chopstx_setcancelstate (cs); } else { @@ -1003,6 +1016,7 @@ cmd_internal_authenticate (void) int len = apdu.cmd_apdu_data_len; int r = -1; unsigned int result_len = 0; + int cs; DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n"); @@ -1033,9 +1047,11 @@ cmd_internal_authenticate (void) return; } + cs = chopstx_setcancelstate (0); result_len = pubkey_len; r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len, &kd[GPG_KEY_FOR_AUTHENTICATION], pubkey_len); + chopstx_setcancelstate (cs); } else if (attr == ALGO_NISTP256R1) { @@ -1046,9 +1062,11 @@ cmd_internal_authenticate (void) return; } + cs = chopstx_setcancelstate (0); result_len = ECDSA_SIGNATURE_LENGTH; r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU, kd[GPG_KEY_FOR_AUTHENTICATION].data); + chopstx_setcancelstate (cs); } else if (attr == ALGO_SECP256K1) { @@ -1059,9 +1077,11 @@ cmd_internal_authenticate (void) return; } + cs = chopstx_setcancelstate (0); result_len = ECDSA_SIGNATURE_LENGTH; r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU, kd[GPG_KEY_FOR_AUTHENTICATION].data); + chopstx_setcancelstate (cs); } else if (attr == ALGO_ED25519) { @@ -1074,11 +1094,13 @@ cmd_internal_authenticate (void) return; } + cs = chopstx_setcancelstate (0); result_len = EDDSA_SIGNATURE_LENGTH; r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output, kd[GPG_KEY_FOR_AUTHENTICATION].data, kd[GPG_KEY_FOR_AUTHENTICATION].data+32, kd[GPG_KEY_FOR_AUTHENTICATION].pubkey); + chopstx_setcancelstate (cs); memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH); } @@ -1322,7 +1344,11 @@ process_command_apdu (void) break; if (i < NUM_CMDS) - cmds[i].cmd_handler (); + { + chopstx_setcancelstate (1); + cmds[i].cmd_handler (); + chopstx_setcancelstate (0); + } else { DEBUG_INFO (" - ??"); @@ -1355,10 +1381,10 @@ card_thread (chopstx_t thd, struct eventflag *ccid_comm) while (1) { - eventmask_t m = eventflag_wait (openpgp_comm); #if defined(PINPAD_SUPPORT) int len, pw_len, newpw_len; #endif + eventmask_t m = eventflag_wait (openpgp_comm); DEBUG_INFO ("GPG!: ");