From: Nikos Mavrogiannopoulos Date: Thu, 3 Jul 2014 13:03:24 +0000 (+0200) Subject: On fork invalidate the PKCS #11 privkey cached session X-Git-Tag: gnutls_3_3_6~62 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0fcb17580b3999d689a0a9fed633ebe5c71014bf;p=thirdparty%2Fgnutls.git On fork invalidate the PKCS #11 privkey cached session --- diff --git a/lib/pkcs11.c b/lib/pkcs11.c index c4b84cde92..3b55d3eac5 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -243,6 +243,11 @@ pkcs11_add_module(const char* name, struct ck_function_list *module, const char return 0; } +/* Returns: + * - negative error code on error, + * - 0 on success + * - 1 on success (and a fork was detected) + */ int _gnutls_pkcs11_check_init(void) { int ret; @@ -262,6 +267,8 @@ int _gnutls_pkcs11_check_init(void) if (init_pid != getpid()) { /* if we are initialized but a fork is detected */ ret = gnutls_pkcs11_reinit(); + if (ret == 0) + ret = 1; } #endif diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index fcdae3551a..7f2c19da2f 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -30,6 +30,15 @@ #include #include +/* In case of a fork, it will invalidate the open session + * in privkey */ +#define PKCS11_CHECK_INIT_PRIVKEY(k) \ + ret = _gnutls_pkcs11_check_init(); \ + if (ret < 0) \ + return gnutls_assert_val(ret); \ + if (ret == 1) \ + memset(&k->sinfo, 0, sizeof(k->sinfo)) + struct gnutls_pkcs11_privkey_st { gnutls_pk_algorithm_t pk_algorithm; unsigned int flags; @@ -218,7 +227,7 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, struct pkcs11_session_info *sinfo; ck_object_handle_t obj; - PKCS11_CHECK_INIT; + PKCS11_CHECK_INIT_PRIVKEY(key); if (key->sinfo.init != 0) { sinfo = &key->sinfo; @@ -325,7 +334,7 @@ int gnutls_pkcs11_privkey_status(gnutls_pkcs11_privkey_t key) ck_object_handle_t obj; struct ck_session_info session_info; - PKCS11_CHECK_INIT; + PKCS11_CHECK_INIT_PRIVKEY(key); if (key->sinfo.init != 0) { sinfo = &key->sinfo; @@ -467,7 +476,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, struct pkcs11_session_info _sinfo; struct pkcs11_session_info *sinfo; - PKCS11_CHECK_INIT; + PKCS11_CHECK_INIT_PRIVKEY(key); if (key->sinfo.init != 0) { sinfo = &key->sinfo; @@ -520,7 +529,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, ret = 0; cleanup: - if (key->sinfo.init == 0) + if (sinfo != &key->sinfo) pkcs11_close_session(sinfo); return ret; @@ -811,6 +820,7 @@ gnutls_pkcs11_privkey_generate2(const char *url, gnutls_pk_algorithm_t pk, gnutls_pkcs11_obj_deinit(obj); if (pkey != NULL) gnutls_pubkey_deinit(pkey); + if (sinfo.pks != 0) pkcs11_close_session(&sinfo);