From f0189e8378fb44403eb2e412e4346962298f441e Mon Sep 17 00:00:00 2001 From: Viktor Tarasov Date: Thu, 30 Apr 2015 13:50:28 +0200 Subject: [PATCH] pkcs11-tool: option to 'decrypt some data' --- doc/tools/pkcs11-tool.1.xml | 7 ++++ src/tools/pkcs11-tool.c | 79 ++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 23d5512e..3efcccc2 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -236,6 +236,13 @@ Sign some data. + + + , + + Decrypt some data. + + id diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f549c754..aac68263 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -117,7 +117,8 @@ enum { OPT_NEW_PIN, OPT_LOGIN_TYPE, OPT_TEST_EC, - OPT_DERIVE + OPT_DERIVE, + OPT_DECRYPT }; static const struct option options[] = { @@ -129,6 +130,7 @@ static const struct option options[] = { { "list-objects", 0, NULL, 'O' }, { "sign", 0, NULL, 's' }, + { "decrypt", 0, NULL, OPT_DECRYPT }, { "hash", 0, NULL, 'h' }, { "derive", 0, NULL, OPT_DERIVE }, { "mechanism", 1, NULL, 'm' }, @@ -187,6 +189,7 @@ static const char *option_help[] = { "Show objects on token", "Sign some data", + "Decrypt some data", "Hash some data", "Derive a secret key using another key and some data", "Specify mechanism (use -M for a list of supported mechanisms)", @@ -334,8 +337,8 @@ static void show_object(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj); -static void sign_data(CK_SLOT_ID, - CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +static void sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +static void decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE); static void derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static int gen_keypair(CK_SESSION_HANDLE, @@ -388,6 +391,7 @@ int main(int argc, char * argv[]) int do_list_mechs = 0; int do_list_objects = 0; int do_sign = 0; + int do_decrypt = 0; int do_hash = 0; int do_derive = 0; int do_gen_keypair = 0; @@ -546,6 +550,11 @@ int main(int argc, char * argv[]) do_sign = 1; action_count++; break; + case OPT_DECRYPT: + need_session |= NEED_SESSION_RW; + do_decrypt = 1; + action_count++; + break; case 'f': opt_sig_format = optarg; break; @@ -754,7 +763,7 @@ int main(int argc, char * argv[]) if (do_list_mechs) list_mechs(opt_slot); - if (do_sign) { + if (do_sign || do_decrypt) { CK_TOKEN_INFO info; get_token_info(opt_slot, &info); @@ -811,7 +820,7 @@ int main(int argc, char * argv[]) goto end; } - if (do_sign || do_derive) { + if (do_sign || do_derive || do_decrypt) { if (!find_object(session, CKO_PRIVATE_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) @@ -828,6 +837,9 @@ int main(int argc, char * argv[]) if (do_sign) sign_data(opt_slot, session, object); + if (do_decrypt) + decrypt_data(opt_slot, session, object); + if (do_hash) hash_data(opt_slot, session); @@ -1453,6 +1465,63 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, close(fd); } + +static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + unsigned char in_buffer[1024], out_buffer[1024]; + CK_MECHANISM mech; + CK_RV rv; + CK_ULONG in_len, out_len; + int fd, r; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_DECRYPT|CKF_HW, NULL, 0, &opt_mechanism)) + util_fatal("Decrypt mechanism not supported\n"); + + printf("Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); + memset(&mech, 0, sizeof(mech)); + mech.mechanism = opt_mechanism; + + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + r = read(fd, in_buffer, sizeof(in_buffer)); + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); + in_len = r; + + rv = p11->C_DecryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_DecryptInit", rv); + + out_len = sizeof(out_buffer); + rv = p11->C_Decrypt(session, in_buffer, in_len, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_Decrypt", rv); + + if (fd != 0) + close(fd); + + if (opt_output == NULL) { + fd = 1; + } + else { + fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR); + if (fd < 0) + util_fatal("failed to open %s: %m", opt_output); + } + + r = write(fd, out_buffer, out_len); + if (r < 0) + util_fatal("Failed to write to %s: %m", opt_output); + if (fd != 1) + close(fd); +} + + static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session) { unsigned char buffer[64];