]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
On fork invalidate the PKCS #11 privkey cached session
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 3 Jul 2014 13:03:24 +0000 (15:03 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 3 Jul 2014 13:03:24 +0000 (15:03 +0200)
lib/pkcs11.c
lib/pkcs11_privkey.c

index c4b84cde92c801b0161264b66ecb99afb2f4b8f7..3b55d3eac5d34e974388172518040239ef240d7f 100644 (file)
@@ -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
 
index fcdae3551afc42b9cfcef1833bdd4c4b9f1c34f6..7f2c19da2f06304ee210a0f0b2dc4167736cc476 100644 (file)
 #include <fips.h>
 #include <p11-kit/uri.h>
 
+/* 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);