From 1a533ea0dcd02809ad503c2d354f7b7f1e2ca208 Mon Sep 17 00:00:00 2001 From: Mikhail Denisenko Date: Tue, 1 Dec 2015 16:24:38 -0500 Subject: [PATCH 1/2] Fixed bug #39 C_Login fails with CKR_PIN_INCORRECT when pin and pinLen are valid but pin is not null terminated --- ykcs11/token_vendors.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ykcs11/token_vendors.c b/ykcs11/token_vendors.c index b5bbfd8..debcf50 100644 --- a/ykcs11/token_vendors.c +++ b/ykcs11/token_vendors.c @@ -12,12 +12,23 @@ static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CH int tries = 0; // TODO: this is effectively disregarded, should we add a better value in ykpiv_verify? unsigned char key[24]; size_t key_len = sizeof(key); + unsigned char *term_pin; if (user == CKU_USER) { - if (ykpiv_verify(state, (char *)pin, &tries) != YKPIV_OK) { + // add null termination for the pin + term_pin = malloc(pin_len + 1); + if (term_pin == NULL) { + return CKR_HOST_MEMORY; + } + memcpy(term_pin, pin, pin_len); + term_pin[pin_len] = 0; + + if (ykpiv_verify(state, (char *)term_pin, &tries) != YKPIV_OK) { + free(term_pin); DBG("Failed to login"); return CKR_PIN_INCORRECT; } + free(term_pin); } else if (user == CKU_SO) { if(ykpiv_hex_decode((char *)pin, pin_len, key, &key_len) != YKPIV_OK) { From 36972ebc6fba9671f05de27f1e668596ba1db027 Mon Sep 17 00:00:00 2001 From: Mikhail Denisenko Date: Tue, 1 Dec 2015 16:45:09 -0500 Subject: [PATCH 2/2] Securely dispose of pin copy --- ykcs11/token_vendors.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ykcs11/token_vendors.c b/ykcs11/token_vendors.c index debcf50..9cb33b6 100644 --- a/ykcs11/token_vendors.c +++ b/ykcs11/token_vendors.c @@ -13,6 +13,7 @@ static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CH unsigned char key[24]; size_t key_len = sizeof(key); unsigned char *term_pin; + ykpiv_rc res; if (user == CKU_USER) { // add null termination for the pin @@ -23,12 +24,15 @@ static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CH memcpy(term_pin, pin, pin_len); term_pin[pin_len] = 0; - if (ykpiv_verify(state, (char *)term_pin, &tries) != YKPIV_OK) { - free(term_pin); + res = ykpiv_verify(state, (char *)term_pin, &tries); + + OPENSSL_cleanse(term_pin, pin_len); + free(term_pin); + + if (res != YKPIV_OK) { DBG("Failed to login"); return CKR_PIN_INCORRECT; } - free(term_pin); } else if (user == CKU_SO) { if(ykpiv_hex_decode((char *)pin, pin_len, key, &key_len) != YKPIV_OK) {