diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-10-15 15:59:48 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-10-24 11:04:25 +0200 |
commit | f68a86202bd1aaeb3988566def4374359b211875 (patch) | |
tree | aeeaabaf6a12c9f35315e3a0f4f5f99afb5d3af7 /src | |
parent | 1d5e93dbd69358fe7d66a3a6dd461d7fbb0738ee (diff) | |
download | gnutls-f68a86202bd1aaeb3988566def4374359b211875.tar.gz |
p11tool: fix initialization of security officer's PINtmp-initialize-so-pin-fix
Previously we would call gnutls_pkcs11_token_set_pin() without an
old PIN provided, which will result to the use of C_InitPIN() on the
underlying module. The C_InitPIN() in contrast with C_SetPIN() will
only work for the user and not for the administrator. As such, we
always provide the oldpin for when we change the admin's PIN.
Resolves #561
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/common.c | 76 | ||||
-rw-r--r-- | src/common.h | 5 | ||||
-rw-r--r-- | src/p11tool-args.def | 5 | ||||
-rw-r--r-- | src/pkcs11.c | 57 |
4 files changed, 95 insertions, 48 deletions
diff --git a/src/common.c b/src/common.c index d94253311c..852200bde1 100644 --- a/src/common.c +++ b/src/common.c @@ -984,6 +984,54 @@ int check_command(gnutls_session_t session, const char *str, unsigned no_cli_cer return 0; } +/* error is indicated by returning an empty string */ +void getpass_copy(char *pass, size_t max_pass_size, const char *prompt) +{ + char *tmp; + size_t len; + + tmp = getpass(prompt); + if (tmp == NULL) { + pass[0] = 0; + return; + } + + len = strlen(tmp); + if (len >= max_pass_size) { + gnutls_memset(tmp, 0, len); + pass[0] = 0; + return; + } + + strcpy(pass, tmp); + gnutls_memset(tmp, 0, len); + + return; +} + +/* error is indicated by returning an empty string */ +void getenv_copy(char *str, size_t max_str_size, const char *envvar) +{ + char *tmp; + size_t len; + + tmp = getenv(envvar); + if (tmp == NULL) { + str[0] = 0; + return; + } + + len = strlen(tmp); + if (len >= max_str_size) { + str[0] = 0; + return; + } + + strcpy(str, tmp); + + return; +} + #define MIN(x,y) ((x)<(y))?(x):(y) #define MAX_CACHE_TRIES 5 int @@ -991,26 +1039,26 @@ pin_callback(void *user, int attempt, const char *token_url, const char *token_label, unsigned int flags, char *pin, size_t pin_max) { - const char *password = NULL; + char password[MAX_PIN_LEN] = ""; common_info_st *info = user; const char *desc; int cache = MAX_CACHE_TRIES; unsigned len; /* allow caching of PIN */ static char *cached_url = NULL; - static char cached_pin[32] = ""; + static char cached_pin[MAX_PIN_LEN] = ""; const char *env; if (flags & GNUTLS_PIN_SO) { env = "GNUTLS_SO_PIN"; desc = "security officer"; - if (info) - password = info->so_pin; + if (info && info->so_pin) + snprintf(password, sizeof(password), "%s", info->so_pin); } else { env = "GNUTLS_PIN"; desc = "user"; - if (info) - password = info->pin; + if (info && info->pin) + snprintf(password, sizeof(password), "%s", info->pin); } if (flags & GNUTLS_PIN_FINAL_TRY) { @@ -1046,19 +1094,19 @@ pin_callback(void *user, int attempt, const char *token_url, } } - if (password == NULL) { - password = getenv(env); - if (password == NULL) /* compatibility */ - password = getenv("GNUTLS_PIN"); + if (password[0] == 0) { + getenv_copy(password, sizeof(password), env); + if (password[0] == 0) /* compatibility */ + getenv_copy(password, sizeof(password), "GNUTLS_PIN"); } - if (password == NULL && (info == NULL || info->batch == 0 || info->ask_pass != 0)) { + if (password[0] == 0 && (info == NULL || info->batch == 0 || info->ask_pass != 0)) { if (token_label && token_label[0] != 0) { fprintf(stderr, "Token '%s' with URL '%s' ", token_label, token_url); fprintf(stderr, "requires %s PIN\n", desc); - password = getpass("Enter PIN: "); + getpass_copy(password, sizeof(password), "Enter PIN: "); } else { - password = getpass("Enter password: "); + getpass_copy(password, sizeof(password), "Enter password: "); } } else { @@ -1072,7 +1120,7 @@ pin_callback(void *user, int attempt, const char *token_url, } } - if (password == NULL || password[0] == 0 || password[0] == '\n') { + if (password[0] == 0 || password[0] == '\n') { fprintf(stderr, "No PIN given.\n"); if (info != NULL && info->batch != 0) { fprintf(stderr, "note: when operating in batch mode, set the GNUTLS_PIN or GNUTLS_SO_PIN environment variables\n"); diff --git a/src/common.h b/src/common.h index 61227a5af0..a4a49d0fe9 100644 --- a/src/common.h +++ b/src/common.h @@ -25,6 +25,7 @@ #include <config.h> #include <gnutls/gnutls.h> +#include <gnutls/pkcs11.h> #include <certtool-common.h> #include <c-ctype.h> #include <string.h> @@ -71,6 +72,10 @@ const char *raw_to_hex(const unsigned char *raw, size_t raw_size); const char *raw_to_base64(const unsigned char *raw, size_t raw_size); int check_command(gnutls_session_t session, const char *str, unsigned no_cli_cert); +#define MAX_PIN_LEN GNUTLS_PKCS11_MAX_PIN_LEN +void getenv_copy(char *str, size_t max_str_size, const char *envvar); +void getpass_copy(char *pass, size_t max_pass_size, const char *prompt); + int pin_callback(void *user, int attempt, const char *token_url, const char *token_label, unsigned int flags, char *pin, diff --git a/src/p11tool-args.def b/src/p11tool-args.def index 3f320ce416..8477a4ddac 100644 --- a/src/p11tool-args.def +++ b/src/p11tool-args.def @@ -57,8 +57,9 @@ flag = { flag = { name = initialize-so-pin; - descrip = "Initializes/Resets a PKCS #11 token security officer PIN"; - doc = ""; + descrip = "Initializes/Resets a PKCS #11 token security officer PIN."; + doc = "This initializes the security officer's PIN. When used non-interactively use the GNUTLS_NEW_SO_PIN +environment variables to initialize SO's PIN."; }; flag = { diff --git a/src/pkcs11.c b/src/pkcs11.c index 0dc2c563fe..66ef6b0fe0 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -21,8 +21,6 @@ */ #include <config.h> -#include <getpass.h> - #include <gnutls/gnutls.h> #include <gnutls/pkcs11.h> #include <gnutls/abstract.h> @@ -1411,8 +1409,7 @@ pkcs11_init(FILE * outfile, const char *url, const char *label, common_info_st * info) { int ret; - const char *pin; - char so_pin[32]; + char so_pin[MAX_PIN_LEN]; pkcs11_common(info); @@ -1426,21 +1423,19 @@ pkcs11_init(FILE * outfile, const char *url, const char *label, app_exit(1); } - if (info->so_pin != NULL) - pin = info->so_pin; - else { - pin = getenv("GNUTLS_SO_PIN"); - if (pin == NULL && info->batch == 0) - pin = getpass("Enter Security Officer's PIN: "); - if (pin == NULL) + if (info->so_pin != NULL) { + snprintf(so_pin, sizeof(so_pin), "%s", info->so_pin); + } else { + getenv_copy(so_pin, sizeof(so_pin), "GNUTLS_SO_PIN"); + if (so_pin[0] == 0 && info->batch == 0) + getpass_copy(so_pin, sizeof(so_pin), "Enter Security Officer's PIN: "); + if (so_pin[0] == 0) app_exit(1); } - if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n') + if (so_pin[0] == '\n' || so_pin[0] == 0) app_exit(1); - strcpy(so_pin, pin); - fprintf(stderr, "Initializing token... "); ret = gnutls_pkcs11_token_init(url, so_pin, label); if (ret < 0) { @@ -1459,7 +1454,7 @@ void pkcs11_set_token_pin(FILE * outfile, const char *url, common_info_st * info, unsigned so) { int ret; - const char *pin; + char newpin[MAX_PIN_LEN] = ""; pkcs11_common(info); @@ -1468,34 +1463,32 @@ pkcs11_set_token_pin(FILE * outfile, const char *url, common_info_st * info, uns app_exit(1); } - fprintf(stderr, "Setting token's user PIN...\n"); + if (so) + fprintf(stderr, "Setting admin's PIN...\n"); + else + fprintf(stderr, "Setting user's PIN...\n"); if (so) { - if (info->so_pin != NULL) { - pin = info->so_pin; - } else { - pin = getenv("GNUTLS_SO_PIN"); - if (pin == NULL && info->batch == 0) - pin = getpass("Enter Administrators's new PIN: "); - if (pin == NULL) - app_exit(1); + getenv_copy(newpin, sizeof(newpin), "GNUTLS_NEW_SO_PIN"); + if (newpin[0] == 0 && info->batch == 0) { + getpass_copy(newpin, sizeof(newpin), "Enter Administrators's new PIN: "); } } else { if (info->pin != NULL) { - pin = info->pin; + snprintf(newpin, sizeof(newpin), "%s", info->pin); } else { - pin = getenv("GNUTLS_PIN"); - if (pin == NULL && info->batch == 0) - pin = getpass("Enter User's new PIN: "); - if (pin == NULL) - app_exit(1); + getenv_copy(newpin, sizeof(newpin), "GNUTLS_PIN"); + if (newpin[0] == 0 && info->batch == 0) + getpass_copy(newpin, sizeof(newpin), "Enter User's new PIN: "); } } - if (pin == NULL || pin[0] == '\n') + if (newpin[0] == 0 || newpin[0] == '\n') { + fprintf(stderr, "No PIN was given to change\n"); app_exit(1); + } - ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, (so!=0)?GNUTLS_PIN_SO:GNUTLS_PIN_USER); + ret = gnutls_pkcs11_token_set_pin(url, NULL, newpin, (so!=0)?GNUTLS_PIN_SO:GNUTLS_PIN_USER); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); |