summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-10-15 15:59:48 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-10-24 11:04:25 +0200
commitf68a86202bd1aaeb3988566def4374359b211875 (patch)
treeaeeaabaf6a12c9f35315e3a0f4f5f99afb5d3af7 /lib
parent1d5e93dbd69358fe7d66a3a6dd461d7fbb0738ee (diff)
downloadgnutls-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 'lib')
-rw-r--r--lib/pkcs11.c14
-rw-r--r--lib/pkcs11_int.h7
-rw-r--r--lib/pkcs11_write.c40
3 files changed, 47 insertions, 14 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 9909127903..1a335ea959 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -35,9 +35,7 @@
#include <pin.h>
#include <pkcs11_int.h>
-#include <p11-kit/p11-kit.h>
#include "pkcs11x.h"
-#include <p11-kit/pin.h>
#include <system-keys.h>
#include "x509/x509_int.h"
@@ -2781,10 +2779,10 @@ retrieve_pin_from_callback(const struct pin_info_st *pin_info,
return 0;
}
-static int
-retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
- struct ck_token_info *token_info, int attempts,
- ck_user_type_t user_type, struct p11_kit_pin **pin)
+int
+pkcs11_retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
+ struct ck_token_info *token_info, int attempts,
+ ck_user_type_t user_type, struct p11_kit_pin **pin)
{
const char *pinfile;
int ret = GNUTLS_E_PKCS11_PIN_ERROR;
@@ -2930,8 +2928,8 @@ pkcs11_login(struct pkcs11_session_info *sinfo,
}
ret =
- retrieve_pin(pin_info, info, &tinfo, attempt++,
- user_type, &pin);
+ pkcs11_retrieve_pin(pin_info, info, &tinfo, attempt++,
+ user_type, &pin);
if (ret < 0) {
gnutls_assert();
goto cleanup;
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index f52db0780c..76c09b460a 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -31,6 +31,8 @@
#define PKCS11_ID_SIZE 128
#define PKCS11_LABEL_SIZE 128
+#include <p11-kit/p11-kit.h>
+#include <p11-kit/pin.h>
#include <p11-kit/uri.h>
typedef unsigned char ck_bool_t;
@@ -269,6 +271,11 @@ static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
}
}
+int
+pkcs11_retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
+ struct ck_token_info *token_info, int attempts,
+ ck_user_type_t user_type, struct p11_kit_pin **pin);
+
ck_object_class_t pkcs11_type_to_class(gnutls_pkcs11_obj_type_t type);
ck_rv_t
diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c
index 35207d5543..cb5b65d508 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -1193,6 +1193,8 @@ gnutls_pkcs11_token_init(const char *token_url,
}
+#define L(x) ((x==NULL)?0:strlen(x))
+
/**
* gnutls_pkcs11_token_set_pin:
* @token_url: A PKCS #11 URL specifying a token
@@ -1200,9 +1202,11 @@ gnutls_pkcs11_token_init(const char *token_url,
* @newpin: new user's PIN
* @flags: one of #gnutls_pin_flag_t.
*
- * This function will modify or set a user's PIN for the given token.
- * If it is called to set a user pin for first time the oldpin must
- * be NULL.
+ * This function will modify or set a user or administrator's PIN for
+ * the given token. If it is called to set a PIN for first time
+ * the oldpin must be %NULL. When setting the admin's PIN with the
+ * %GNUTLS_PIN_SO flag, the @oldpin value must be provided (this requirement
+ * is relaxed after GnuTLS 3.6.5 since which the PIN will be requested if missing).
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
@@ -1240,7 +1244,8 @@ gnutls_pkcs11_token_set_pin(const char *token_url,
return ret;
}
- if (oldpin == NULL) {
+ if (oldpin == NULL && !(flags & GNUTLS_PIN_SO)) {
+ /* This changes only the user PIN */
rv = pkcs11_init_pin(sinfo.module, sinfo.pks,
(uint8_t *) newpin, strlen(newpin));
if (rv != CKR_OK) {
@@ -1251,9 +1256,32 @@ gnutls_pkcs11_token_set_pin(const char *token_url,
goto finish;
}
} else {
+ struct p11_kit_pin *pin;
+ unsigned oldpin_size;
+
+ oldpin_size = L(oldpin);
+
+ if (!(sinfo.tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
+ if (newpin == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (oldpin == NULL) {
+ struct pin_info_st pin_info;
+ memset(&pin_info, 0, sizeof(pin_info));
+
+ ret = pkcs11_retrieve_pin(&pin_info, info, &sinfo.tinfo, 0, CKU_SO, &pin);
+ if (ret < 0) {
+ gnutls_assert();
+ goto finish;
+ }
+ oldpin = (const char*)p11_kit_pin_get_value(pin, NULL);
+ oldpin_size = p11_kit_pin_get_length(pin);
+ }
+ }
+
rv = pkcs11_set_pin(sinfo.module, sinfo.pks,
- oldpin, strlen(oldpin),
- newpin, strlen(newpin));
+ oldpin, oldpin_size,
+ newpin, L(newpin));
if (rv != CKR_OK) {
gnutls_assert();
_gnutls_debug_log("p11: %s\n",