diff --git a/p11-kit/add-profile.c b/p11-kit/add-profile.c index e3002c86..6920c3ae 100644 --- a/p11-kit/add-profile.c +++ b/p11-kit/add-profile.c @@ -43,7 +43,12 @@ #include "message.h" #include "tool.h" +#ifdef OS_UNIX +#include "tty.h" +#endif + #include +#include #include #include @@ -60,7 +65,8 @@ p11_kit_add_profile (int argc, static int add_profile (const char *token_str, - CK_PROFILE_ID profile) + CK_PROFILE_ID profile, + bool login) { int ret = 1; CK_RV rv; @@ -99,8 +105,12 @@ add_profile (const char *token_str, } behavior = P11_KIT_ITER_WANT_WRITABLE | P11_KIT_ITER_WITH_TOKENS | P11_KIT_ITER_WITHOUT_OBJECTS; - if (p11_kit_uri_get_pin_value (uri)) + if (login) { behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); @@ -171,12 +181,14 @@ p11_kit_add_profile (int argc, int opt, ret = 2; CK_ULONG profile = CKA_INVALID; p11_dict *profile_nicks = NULL; + bool login = false; enum { opt_verbose = 'v', opt_quiet = 'q', opt_help = 'h', opt_profile = 'p', + opt_login = CHAR_MAX + 1, }; struct option options[] = { @@ -184,12 +196,14 @@ p11_kit_add_profile (int argc, { "quiet", no_argument, NULL, opt_quiet }, { "help", no_argument, NULL, opt_help }, { "profile", required_argument, NULL, opt_profile }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; p11_tool_desc usages[] = { { 0, "usage: p11-kit add-profile --profile profile pkcs11:token" }, { opt_profile, "specify the profile to add" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -225,6 +239,9 @@ p11_kit_add_profile (int argc, goto cleanup; } break; + case opt_login: + login = true; + break; case '?': goto cleanup; default: @@ -246,9 +263,19 @@ p11_kit_add_profile (int argc, goto cleanup; } - ret = add_profile (*argv, profile); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = add_profile (*argv, profile, login); cleanup: +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif p11_dict_free (profile_nicks); return ret; diff --git a/p11-kit/delete-profile.c b/p11-kit/delete-profile.c index cade62ac..a2492ed5 100644 --- a/p11-kit/delete-profile.c +++ b/p11-kit/delete-profile.c @@ -43,7 +43,12 @@ #include "message.h" #include "tool.h" +#ifdef OS_UNIX +#include "tty.h" +#endif + #include +#include #include #include @@ -62,7 +67,8 @@ p11_kit_delete_profile (int argc, static int delete_profile (const char *token_str, - CK_PROFILE_ID profile) + CK_PROFILE_ID profile, + bool login) { int ret = 1; CK_RV rv; @@ -99,8 +105,12 @@ delete_profile (const char *token_str, } behavior = P11_KIT_ITER_WANT_WRITABLE | P11_KIT_ITER_WITH_TOKENS | P11_KIT_ITER_WITHOUT_OBJECTS; - if (p11_kit_uri_get_pin_value (uri)) + if (login) { behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); @@ -171,12 +181,14 @@ p11_kit_delete_profile (int argc, int opt, ret = 2; CK_ULONG profile = CKA_INVALID; p11_dict *profile_nicks = NULL; + bool login = false; enum { opt_verbose = 'v', opt_quiet = 'q', opt_help = 'h', opt_profile = 'p', + opt_login = CHAR_MAX + 1, }; struct option options[] = { @@ -184,12 +196,14 @@ p11_kit_delete_profile (int argc, { "quiet", no_argument, NULL, opt_quiet }, { "help", no_argument, NULL, opt_help }, { "profile", required_argument, NULL, opt_profile }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; p11_tool_desc usages[] = { { 0, "usage: p11-kit delete-profile --profile profile pkcs11:token" }, { opt_profile, "specify the profile to delete" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -225,6 +239,9 @@ p11_kit_delete_profile (int argc, goto cleanup; } break; + case opt_login: + login = true; + break; case '?': goto cleanup; default: @@ -246,9 +263,19 @@ p11_kit_delete_profile (int argc, goto cleanup; } - ret = delete_profile (*argv, profile); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = delete_profile (*argv, profile, login); cleanup: +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif p11_dict_free (profile_nicks); return ret; diff --git a/p11-kit/export-object.c b/p11-kit/export-object.c index e8852234..e29ff96d 100644 --- a/p11-kit/export-object.c +++ b/p11-kit/export-object.c @@ -46,6 +46,10 @@ #include "pem.h" #include "tool.h" +#ifdef OS_UNIX +#include "tty.h" +#endif + #ifdef WITH_ASN1 #include "asn1.h" #include "oid.h" @@ -424,13 +428,15 @@ export_certificate (P11KitIter *iter, } static int -export_object (const char *token_str) +export_object (const char *token_str, + bool login) { int ret = 1; CK_RV rv; CK_FUNCTION_LIST **modules = NULL; P11KitUri *uri = NULL; P11KitIter *iter = NULL; + P11KitIterBehavior behavior; CK_OBJECT_CLASS klass; CK_ATTRIBUTE attr = { CKA_CLASS, &klass, sizeof (klass) }; p11_buffer buf; @@ -455,7 +461,14 @@ export_object (const char *token_str) goto cleanup; } - iter = p11_kit_iter_new (uri, P11_KIT_ITER_WITH_LOGIN); + behavior = 0; + if (login) { + behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } + iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); goto cleanup; @@ -512,23 +525,27 @@ int p11_kit_export_object (int argc, char *argv[]) { - int opt; + int opt, ret; + bool login = false; enum { opt_verbose = 'v', opt_quiet = 'q', opt_help = 'h', + opt_login = CHAR_MAX + 1, }; struct option options[] = { { "verbose", no_argument, NULL, opt_verbose }, { "quiet", no_argument, NULL, opt_quiet }, { "help", no_argument, NULL, opt_help }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; p11_tool_desc usages[] = { { 0, "usage: p11-kit export-object pkcs11:token" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -543,6 +560,9 @@ p11_kit_export_object (int argc, case opt_help: p11_tool_usage (usages, options); return 0; + case opt_login: + login = true; + break; case '?': return 2; default: @@ -559,5 +579,18 @@ p11_kit_export_object (int argc, return 2; } - return export_object (*argv); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = export_object (*argv, login); + +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif + + return ret; } diff --git a/p11-kit/generate-keypair.c b/p11-kit/generate-keypair.c index 8dcaa341..7ad263b6 100644 --- a/p11-kit/generate-keypair.c +++ b/p11-kit/generate-keypair.c @@ -43,11 +43,16 @@ #include "message.h" #include "tool.h" +#ifdef OS_UNIX +#include "tty.h" +#endif + #ifdef P11_KIT_TESTABLE #include "mock.h" #endif #include +#include #include #include #include @@ -255,7 +260,8 @@ generate_keypair (const char *token_str, CK_MECHANISM mechanism, CK_ULONG bits, const uint8_t *ec_params, - size_t ec_params_len) + size_t ec_params_len, + bool login) { int ret = 1; CK_RV rv; @@ -292,8 +298,12 @@ generate_keypair (const char *token_str, } behavior = P11_KIT_ITER_WANT_WRITABLE | P11_KIT_ITER_WITH_TOKENS | P11_KIT_ITER_WITHOUT_OBJECTS; - if (p11_kit_uri_get_pin_value (uri)) + if (login) { behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); @@ -348,6 +358,7 @@ p11_kit_generate_keypair (int argc, const uint8_t *ec_params = NULL; size_t ec_params_len = 0; CK_MECHANISM mechanism = { CKA_INVALID, NULL_PTR, 0 }; + bool login = false; enum { opt_verbose = 'v', @@ -357,6 +368,7 @@ p11_kit_generate_keypair (int argc, opt_type = 't', opt_bits = 'b', opt_curve = 'c', + opt_login = CHAR_MAX + 1, }; struct option options[] = { @@ -367,6 +379,7 @@ p11_kit_generate_keypair (int argc, { "type", required_argument, NULL, opt_type }, { "bits", required_argument, NULL, opt_bits }, { "curve", required_argument, NULL, opt_curve }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; @@ -377,6 +390,7 @@ p11_kit_generate_keypair (int argc, { opt_type, "type of keys to generate" }, { opt_bits, "number of bits for key generation" }, { opt_curve, "name of the curve for key generation" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -410,6 +424,9 @@ p11_kit_generate_keypair (int argc, goto cleanup; } break; + case opt_login: + login = true; + break; case opt_verbose: p11_kit_be_loud (); break; @@ -439,9 +456,19 @@ p11_kit_generate_keypair (int argc, if (!check_args (mechanism.mechanism, bits, ec_params)) goto cleanup; - ret = generate_keypair (*argv, label, mechanism, bits, ec_params, ec_params_len); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = generate_keypair (*argv, label, mechanism, bits, ec_params, ec_params_len, login); cleanup: +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif free (label); return ret; diff --git a/p11-kit/list-objects.c b/p11-kit/list-objects.c index e31a6ff3..5625f6c8 100644 --- a/p11-kit/list-objects.c +++ b/p11-kit/list-objects.c @@ -45,9 +45,15 @@ #include "message.h" #include "print.h" #include "tool.h" + +#ifdef OS_UNIX +#include "tty.h" +#endif + #include "uri.h" #include +#include #include #include @@ -345,13 +351,15 @@ print_object (p11_list_printer *printer, } static int -list_objects (const char *token_str) +list_objects (const char *token_str, + bool login) { int ret = 1; size_t i; CK_FUNCTION_LIST **modules = NULL; P11KitUri *uri = NULL; P11KitIter *iter = NULL; + P11KitIterBehavior behavior; p11_list_printer printer; uri = p11_kit_uri_new (); @@ -371,7 +379,14 @@ list_objects (const char *token_str) goto cleanup; } - iter = p11_kit_iter_new (uri, P11_KIT_ITER_WITH_LOGIN); + behavior = 0; + if (login) { + behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } + iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); goto cleanup; @@ -397,23 +412,27 @@ int p11_kit_list_objects (int argc, char *argv[]) { - int opt; + int opt, ret; + bool login = false; enum { opt_verbose = 'v', opt_quiet = 'q', opt_help = 'h', + opt_login = CHAR_MAX + 1, }; struct option options[] = { { "verbose", no_argument, NULL, opt_verbose }, { "quiet", no_argument, NULL, opt_quiet }, { "help", no_argument, NULL, opt_help }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; p11_tool_desc usages[] = { { 0, "usage: p11-kit list-objects pkcs11:token" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -428,6 +447,9 @@ p11_kit_list_objects (int argc, case opt_help: p11_tool_usage (usages, options); return 0; + case opt_login: + login = true; + break; case '?': return 2; default: @@ -444,5 +466,18 @@ p11_kit_list_objects (int argc, return 2; } - return list_objects (*argv); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = list_objects (*argv, login); + +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif + + return ret; } diff --git a/p11-kit/list-profiles.c b/p11-kit/list-profiles.c index 90fb1eb3..7e81059e 100644 --- a/p11-kit/list-profiles.c +++ b/p11-kit/list-profiles.c @@ -42,7 +42,12 @@ #include "message.h" #include "tool.h" +#ifdef OS_UNIX +#include "tty.h" +#endif + #include +#include #include #include @@ -60,7 +65,8 @@ p11_kit_list_profiles (int argc, char *argv[]); static int -list_profiles (const char *token_str) +list_profiles (const char *token_str, + bool login) { int ret = 1; CK_RV rv; @@ -96,8 +102,12 @@ list_profiles (const char *token_str) } behavior = P11_KIT_ITER_WITH_TOKENS | P11_KIT_ITER_WITHOUT_OBJECTS; - if (p11_kit_uri_get_pin_value (uri)) + if (login) { behavior |= P11_KIT_ITER_WITH_LOGIN; +#ifdef OS_UNIX + p11_kit_uri_set_pin_source (uri, "tty"); +#endif + } iter = p11_kit_iter_new (uri, behavior); if (iter == NULL) { p11_message (_("failed to initialize iterator")); @@ -172,23 +182,27 @@ int p11_kit_list_profiles (int argc, char *argv[]) { - int opt; + int opt, ret; + bool login = false; enum { opt_verbose = 'v', opt_quiet = 'q', opt_help = 'h', + opt_login = CHAR_MAX + 1, }; struct option options[] = { { "verbose", no_argument, NULL, opt_verbose }, { "quiet", no_argument, NULL, opt_quiet }, { "help", no_argument, NULL, opt_help }, + { "login", no_argument, NULL, opt_login }, { 0 }, }; p11_tool_desc usages[] = { { 0, "usage: p11-kit list-profiles pkcs11:token" }, + { opt_login, "login to the token" }, { 0 }, }; @@ -203,6 +217,9 @@ p11_kit_list_profiles (int argc, case opt_help: p11_tool_usage (usages, options); return 0; + case opt_login: + login = true; + break; case '?': return 2; default: @@ -219,5 +236,18 @@ p11_kit_list_profiles (int argc, return 2; } - return list_profiles (*argv); +#ifdef OS_UNIX + /* Register a fallback PIN callback that reads from terminal. + * We don't care whether the registration succeeds as it is a fallback. + */ + (void)p11_kit_pin_register_callback ("tty", p11_pin_tty_callback, NULL, NULL); +#endif + + ret = list_profiles (*argv, login); + +#ifdef OS_UNIX + p11_kit_pin_unregister_callback ("tty", p11_pin_tty_callback, NULL); +#endif + + return ret; } diff --git a/p11-kit/test-generate-keypair.sh b/p11-kit/test-generate-keypair.sh index 25d806d7..fcc56067 100755 --- a/p11-kit/test-generate-keypair.sh +++ b/p11-kit/test-generate-keypair.sh @@ -47,19 +47,19 @@ teardown() { } test_generate_keypair_rsa() { - if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --label=rsa --type=rsa --bits=2048 "pkcs11:token=test-genkey?pin-value=12345"; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --login --label=rsa --type=rsa --bits=2048 "pkcs11:token=test-genkey?pin-value=12345"; then assert_fail "unable to run: p11-kit generate-keypair" fi } test_generate_keypair_ecdsa() { for curve in secp256r1 secp384r1 secp521r1; do - if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --label="ecdsa-$curve" --type=ecdsa --curve="$curve" "pkcs11:token=test-genkey?pin-value=12345"; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --login --label="ecdsa-$curve" --type=ecdsa --curve="$curve" "pkcs11:token=test-genkey?pin-value=12345"; then assert_fail "unable to run: p11-kit generate-keypair" fi done - if "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --label="ecdsa-unknown" --type=ecdsa --curve=unknown "pkcs11:token=test-genkey?pin-value=12345"; then + if "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --login --label="ecdsa-unknown" --type=ecdsa --curve=unknown "pkcs11:token=test-genkey?pin-value=12345"; then assert_fail "p11-kit generate-keypair succeeded for unknown ecdsa curve" fi } @@ -78,12 +78,12 @@ test_generate_keypair_eddsa() { curve="$curve ed448" fi for curve in $curves; do - if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --label="eddsa-$curve" --type=eddsa --curve="$curve" "pkcs11:token=test-genkey?pin-value=12345"; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --login --label="eddsa-$curve" --type=eddsa --curve="$curve" "pkcs11:token=test-genkey?pin-value=12345"; then assert_fail "unable to run: p11-kit generate-keypair" fi done - if "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --label="eddsa-unknown" --type=eddsa --curve=unknown "pkcs11:token=test-genkey?pin-value=12345"; then + if "$abs_top_builddir"/p11-kit/p11-kit-testable generate-keypair --login --label="eddsa-unknown" --type=eddsa --curve=unknown "pkcs11:token=test-genkey?pin-value=12345"; then assert_fail "p11-kit generate-keypair succeeded for unknown eddsa curve" fi } diff --git a/p11-kit/test-objects.sh b/p11-kit/test-objects.sh index b131e16a..f232c943 100755 --- a/p11-kit/test-objects.sh +++ b/p11-kit/test-objects.sh @@ -125,6 +125,60 @@ EOF fi } +test_list_private() { + cat > list.exp < list.out; then + assert_fail "unable to run: p11-kit list-objects" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong result" + fi +} + +test_list_private_without_login() { + cat > list.exp < list.out; then + assert_fail "unable to run: p11-kit list-objects" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong result" + fi +} + test_list_exact() { cat > list.exp <