|
|
61e0f4 |
From 45d6529dbe1b69f3a838d01a83f0688e91696377 Mon Sep 17 00:00:00 2001
|
|
|
61e0f4 |
From: =?UTF-8?q?Micha=C5=82=20Trojnara?= <Michal.Trojnara@stunnel.org>
|
|
|
61e0f4 |
Date: Wed, 29 Aug 2018 21:35:48 +0200
|
|
|
61e0f4 |
Subject: [PATCH 07/23] Expose check_fork internal API
|
|
|
61e0f4 |
|
|
|
61e0f4 |
---
|
|
|
61e0f4 |
src/Makefile.am | 2 +-
|
|
|
61e0f4 |
src/atfork.c | 93 -------------------
|
|
|
61e0f4 |
src/libp11-int.h | 7 ++
|
|
|
61e0f4 |
src/p11_atfork.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
61e0f4 |
src/p11_front.c | 138 ----------------------------
|
|
|
61e0f4 |
5 files changed, 239 insertions(+), 232 deletions(-)
|
|
|
61e0f4 |
delete mode 100644 src/atfork.c
|
|
|
61e0f4 |
create mode 100644 src/p11_atfork.c
|
|
|
61e0f4 |
|
|
|
61e0f4 |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
61e0f4 |
index 3cdbce1..2ca250e 100644
|
|
|
61e0f4 |
--- a/src/Makefile.am
|
|
|
61e0f4 |
+++ b/src/Makefile.am
|
|
|
61e0f4 |
@@ -14,7 +14,7 @@ SHARED_EXT=@SHARED_EXT@
|
|
|
61e0f4 |
|
|
|
61e0f4 |
libp11_la_SOURCES = libpkcs11.c p11_attr.c p11_cert.c p11_err.c p11_ckr.c \
|
|
|
61e0f4 |
p11_key.c p11_load.c p11_misc.c p11_rsa.c p11_ec.c p11_pkey.c \
|
|
|
61e0f4 |
- p11_slot.c p11_front.c atfork.c libp11.exports
|
|
|
61e0f4 |
+ p11_slot.c p11_front.c p11_atfork.c libp11.exports
|
|
|
61e0f4 |
if WIN32
|
|
|
61e0f4 |
libp11_la_SOURCES += libp11.rc
|
|
|
61e0f4 |
else
|
|
|
61e0f4 |
diff --git a/src/atfork.c b/src/atfork.c
|
|
|
61e0f4 |
deleted file mode 100644
|
|
|
61e0f4 |
index 04691fb..0000000
|
|
|
61e0f4 |
--- a/src/atfork.c
|
|
|
61e0f4 |
+++ /dev/null
|
|
|
61e0f4 |
@@ -1,93 +0,0 @@
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
|
|
61e0f4 |
- * Copyright (C) 2014 Red Hat
|
|
|
61e0f4 |
- *
|
|
|
61e0f4 |
- * Author: Nikos Mavrogiannopoulos
|
|
|
61e0f4 |
- *
|
|
|
61e0f4 |
- * This is free software; you can redistribute it and/or
|
|
|
61e0f4 |
- * modify it under the terms of the GNU Lesser General Public License
|
|
|
61e0f4 |
- * as published by the Free Software Foundation; either version 2.1 of
|
|
|
61e0f4 |
- * the License, or (at your option) any later version.
|
|
|
61e0f4 |
- *
|
|
|
61e0f4 |
- * This library is distributed in the hope that it will be useful, but
|
|
|
61e0f4 |
- * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
61e0f4 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
61e0f4 |
- * Lesser General Public License for more details.
|
|
|
61e0f4 |
- *
|
|
|
61e0f4 |
- * You should have received a copy of the GNU Lesser General Public License
|
|
|
61e0f4 |
- * along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
|
61e0f4 |
- *
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-#include "libp11-int.h"
|
|
|
61e0f4 |
-#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
|
61e0f4 |
-#include <winsock2.h>
|
|
|
61e0f4 |
-#else
|
|
|
61e0f4 |
-#include <sys/socket.h>
|
|
|
61e0f4 |
-#endif
|
|
|
61e0f4 |
-#include <errno.h>
|
|
|
61e0f4 |
-#include <sys/stat.h>
|
|
|
61e0f4 |
-#include <sys/types.h>
|
|
|
61e0f4 |
-#include <unistd.h>
|
|
|
61e0f4 |
-#include <atfork.h>
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-#ifdef __sun
|
|
|
61e0f4 |
-# pragma fini(lib_deinit)
|
|
|
61e0f4 |
-# pragma init(lib_init)
|
|
|
61e0f4 |
-# define _CONSTRUCTOR
|
|
|
61e0f4 |
-# define _DESTRUCTOR
|
|
|
61e0f4 |
-#else
|
|
|
61e0f4 |
-# define _CONSTRUCTOR __attribute__((constructor))
|
|
|
61e0f4 |
-# define _DESTRUCTOR __attribute__((destructor))
|
|
|
61e0f4 |
-#endif
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-unsigned int P11_forkid = 0;
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-#ifndef _WIN32
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-# ifdef HAVE_ATFORK
|
|
|
61e0f4 |
-static void fork_handler(void)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- P11_forkid++;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-# endif
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-# if defined(HAVE___REGISTER_ATFORK)
|
|
|
61e0f4 |
-extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
|
|
|
61e0f4 |
-extern void *__dso_handle;
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-_CONSTRUCTOR
|
|
|
61e0f4 |
-int _P11_register_fork_handler(void)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-# else
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-unsigned int _P11_get_forkid(void)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- return getpid();
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-int _P11_detect_fork(unsigned int forkid)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- if (getpid() == forkid)
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
- return 1;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/* we have to detect fork manually */
|
|
|
61e0f4 |
-_CONSTRUCTOR
|
|
|
61e0f4 |
-int _P11_register_fork_handler(void)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- P11_forkid = getpid();
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-# endif
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-#endif /* !_WIN32 */
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/* vim: set noexpandtab: */
|
|
|
61e0f4 |
diff --git a/src/libp11-int.h b/src/libp11-int.h
|
|
|
61e0f4 |
index b62a13e..411f2b0 100644
|
|
|
61e0f4 |
--- a/src/libp11-int.h
|
|
|
61e0f4 |
+++ b/src/libp11-int.h
|
|
|
61e0f4 |
@@ -323,6 +323,13 @@ extern int pkcs11_store_certificate(PKCS11_TOKEN * token, X509 * x509,
|
|
|
61e0f4 |
extern int pkcs11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len);
|
|
|
61e0f4 |
extern int pkcs11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len);
|
|
|
61e0f4 |
|
|
|
61e0f4 |
+/* Reinitialize the module afer fork if needed */
|
|
|
61e0f4 |
+extern int check_fork(PKCS11_CTX *ctx);
|
|
|
61e0f4 |
+extern int check_slot_fork(PKCS11_SLOT *slot);
|
|
|
61e0f4 |
+extern int check_token_fork(PKCS11_TOKEN *token);
|
|
|
61e0f4 |
+extern int check_key_fork(PKCS11_KEY *key);
|
|
|
61e0f4 |
+extern int check_cert_fork(PKCS11_CERT *cert);
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
/* Internal implementation of deprecated features */
|
|
|
61e0f4 |
|
|
|
61e0f4 |
/* Generate and store a private key on the token */
|
|
|
61e0f4 |
diff --git a/src/p11_atfork.c b/src/p11_atfork.c
|
|
|
61e0f4 |
new file mode 100644
|
|
|
61e0f4 |
index 0000000..fce87c6
|
|
|
61e0f4 |
--- /dev/null
|
|
|
61e0f4 |
+++ b/src/p11_atfork.c
|
|
|
61e0f4 |
@@ -0,0 +1,231 @@
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
|
|
61e0f4 |
+ * Copyright (C) 2014 Red Hat
|
|
|
61e0f4 |
+ *
|
|
|
61e0f4 |
+ * Author: Nikos Mavrogiannopoulos
|
|
|
61e0f4 |
+ *
|
|
|
61e0f4 |
+ * This is free software; you can redistribute it and/or
|
|
|
61e0f4 |
+ * modify it under the terms of the GNU Lesser General Public License
|
|
|
61e0f4 |
+ * as published by the Free Software Foundation; either version 2.1 of
|
|
|
61e0f4 |
+ * the License, or (at your option) any later version.
|
|
|
61e0f4 |
+ *
|
|
|
61e0f4 |
+ * This library is distributed in the hope that it will be useful, but
|
|
|
61e0f4 |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
61e0f4 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
61e0f4 |
+ * Lesser General Public License for more details.
|
|
|
61e0f4 |
+ *
|
|
|
61e0f4 |
+ * You should have received a copy of the GNU Lesser General Public License
|
|
|
61e0f4 |
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
|
61e0f4 |
+ *
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+#include "libp11-int.h"
|
|
|
61e0f4 |
+#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
|
61e0f4 |
+#include <winsock2.h>
|
|
|
61e0f4 |
+#else
|
|
|
61e0f4 |
+#include <sys/socket.h>
|
|
|
61e0f4 |
+#endif
|
|
|
61e0f4 |
+#include <errno.h>
|
|
|
61e0f4 |
+#include <sys/stat.h>
|
|
|
61e0f4 |
+#include <sys/types.h>
|
|
|
61e0f4 |
+#include <unistd.h>
|
|
|
61e0f4 |
+#include <atfork.h>
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+#ifdef __sun
|
|
|
61e0f4 |
+# pragma fini(lib_deinit)
|
|
|
61e0f4 |
+# pragma init(lib_init)
|
|
|
61e0f4 |
+# define _CONSTRUCTOR
|
|
|
61e0f4 |
+# define _DESTRUCTOR
|
|
|
61e0f4 |
+#else
|
|
|
61e0f4 |
+# define _CONSTRUCTOR __attribute__((constructor))
|
|
|
61e0f4 |
+# define _DESTRUCTOR __attribute__((destructor))
|
|
|
61e0f4 |
+#endif
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+unsigned int P11_forkid = 0;
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+#ifndef _WIN32
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+# ifdef HAVE_ATFORK
|
|
|
61e0f4 |
+static void fork_handler(void)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ P11_forkid++;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+# endif
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+# if defined(HAVE___REGISTER_ATFORK)
|
|
|
61e0f4 |
+extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
|
|
|
61e0f4 |
+extern void *__dso_handle;
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+_CONSTRUCTOR
|
|
|
61e0f4 |
+int _P11_register_fork_handler(void)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+# else
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+unsigned int _P11_get_forkid(void)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ return getpid();
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+int _P11_detect_fork(unsigned int forkid)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ if (getpid() == forkid)
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+ return 1;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/* we have to detect fork manually */
|
|
|
61e0f4 |
+_CONSTRUCTOR
|
|
|
61e0f4 |
+int _P11_register_fork_handler(void)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ P11_forkid = getpid();
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+# endif
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+#endif /* !_WIN32 */
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
+ * It wipes out the internal state of the PKCS#11 library
|
|
|
61e0f4 |
+ * Any libp11 references to this state are no longer valid
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+static int check_fork_int(PKCS11_CTX *ctx)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (_P11_detect_fork(cpriv->forkid)) {
|
|
|
61e0f4 |
+ if (pkcs11_CTX_reload(ctx) < 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ cpriv->forkid = _P11_get_forkid();
|
|
|
61e0f4 |
+ }
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
+ * Also relogins and reopens the session if needed
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+static int check_slot_fork_int(PKCS11_SLOT *slot)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
|
61e0f4 |
+ PKCS11_CTX *ctx = SLOT2CTX(slot);
|
|
|
61e0f4 |
+ PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (check_fork_int(SLOT2CTX(slot)) < 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ if (spriv->forkid != cpriv->forkid) {
|
|
|
61e0f4 |
+ if (spriv->loggedIn) {
|
|
|
61e0f4 |
+ int saved = spriv->haveSession;
|
|
|
61e0f4 |
+ spriv->haveSession = 0;
|
|
|
61e0f4 |
+ spriv->loggedIn = 0;
|
|
|
61e0f4 |
+ if (pkcs11_relogin(slot) < 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ spriv->haveSession = saved;
|
|
|
61e0f4 |
+ }
|
|
|
61e0f4 |
+ if (spriv->haveSession) {
|
|
|
61e0f4 |
+ spriv->haveSession = 0;
|
|
|
61e0f4 |
+ if (pkcs11_reopen_session(slot) < 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ }
|
|
|
61e0f4 |
+ spriv->forkid = cpriv->forkid;
|
|
|
61e0f4 |
+ }
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
+ * Also reloads the key
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+static int check_key_fork_int(PKCS11_KEY *key)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_SLOT *slot = KEY2SLOT(key);
|
|
|
61e0f4 |
+ PKCS11_KEY_private *kpriv = PRIVKEY(key);
|
|
|
61e0f4 |
+ PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (check_slot_fork_int(slot) < 0)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ if (spriv->forkid != kpriv->forkid) {
|
|
|
61e0f4 |
+ pkcs11_reload_key(key);
|
|
|
61e0f4 |
+ kpriv->forkid = spriv->forkid;
|
|
|
61e0f4 |
+ }
|
|
|
61e0f4 |
+ return 0;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Locking interface to check_fork_int()
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+int check_fork(PKCS11_CTX *ctx)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
+ int rv;
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (ctx == NULL)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
+ CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
+ rv = check_fork_int(ctx);
|
|
|
61e0f4 |
+ CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
+ return rv;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Locking interface to check_slot_fork_int()
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+int check_slot_fork(PKCS11_SLOT *slot)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
+ int rv;
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (slot == NULL)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ cpriv = PRIVCTX(SLOT2CTX(slot));
|
|
|
61e0f4 |
+ CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
+ rv = check_slot_fork_int(slot);
|
|
|
61e0f4 |
+ CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
+ return rv;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Reinitialize token (just its slot)
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+int check_token_fork(PKCS11_TOKEN *token)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ if (token == NULL)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ return check_slot_fork(TOKEN2SLOT(token));
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Locking interface to check_key_fork_int()
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+int check_key_fork(PKCS11_KEY *key)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
+ int rv;
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+ if (key == NULL)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ cpriv = PRIVCTX(KEY2CTX(key));
|
|
|
61e0f4 |
+ CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
+ rv = check_key_fork_int(key);
|
|
|
61e0f4 |
+ CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
+ return rv;
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/*
|
|
|
61e0f4 |
+ * Reinitialize cert (just its token)
|
|
|
61e0f4 |
+ */
|
|
|
61e0f4 |
+int check_cert_fork(PKCS11_CERT *cert)
|
|
|
61e0f4 |
+{
|
|
|
61e0f4 |
+ if (cert == NULL)
|
|
|
61e0f4 |
+ return -1;
|
|
|
61e0f4 |
+ return check_token_fork(CERT2TOKEN(cert));
|
|
|
61e0f4 |
+}
|
|
|
61e0f4 |
+
|
|
|
61e0f4 |
+/* vim: set noexpandtab: */
|
|
|
61e0f4 |
diff --git a/src/p11_front.c b/src/p11_front.c
|
|
|
61e0f4 |
index 167a778..efdd4c0 100644
|
|
|
61e0f4 |
--- a/src/p11_front.c
|
|
|
61e0f4 |
+++ b/src/p11_front.c
|
|
|
61e0f4 |
@@ -25,144 +25,6 @@
|
|
|
61e0f4 |
* PKCS11_get_ec_key_method
|
|
|
61e0f4 |
*/
|
|
|
61e0f4 |
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
- * It wipes out the internal state of the PKCS#11 library
|
|
|
61e0f4 |
- * Any libp11 references to this state are no longer valid
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_fork_int(PKCS11_CTX *ctx)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (_P11_detect_fork(cpriv->forkid)) {
|
|
|
61e0f4 |
- if (pkcs11_CTX_reload(ctx) < 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- cpriv->forkid = _P11_get_forkid();
|
|
|
61e0f4 |
- }
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
- * Also relogins and reopens the session if needed
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_slot_fork_int(PKCS11_SLOT *slot)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
|
61e0f4 |
- PKCS11_CTX *ctx = SLOT2CTX(slot);
|
|
|
61e0f4 |
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (check_fork_int(SLOT2CTX(slot)) < 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- if (spriv->forkid != cpriv->forkid) {
|
|
|
61e0f4 |
- if (spriv->loggedIn) {
|
|
|
61e0f4 |
- int saved = spriv->haveSession;
|
|
|
61e0f4 |
- spriv->haveSession = 0;
|
|
|
61e0f4 |
- spriv->loggedIn = 0;
|
|
|
61e0f4 |
- if (pkcs11_relogin(slot) < 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- spriv->haveSession = saved;
|
|
|
61e0f4 |
- }
|
|
|
61e0f4 |
- if (spriv->haveSession) {
|
|
|
61e0f4 |
- spriv->haveSession = 0;
|
|
|
61e0f4 |
- if (pkcs11_reopen_session(slot) < 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- }
|
|
|
61e0f4 |
- spriv->forkid = cpriv->forkid;
|
|
|
61e0f4 |
- }
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * PKCS#11 reinitialization after fork
|
|
|
61e0f4 |
- * Also reloads the key
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_key_fork_int(PKCS11_KEY *key)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_SLOT *slot = KEY2SLOT(key);
|
|
|
61e0f4 |
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
|
|
|
61e0f4 |
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (check_slot_fork_int(slot) < 0)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- if (spriv->forkid != kpriv->forkid) {
|
|
|
61e0f4 |
- pkcs11_reload_key(key);
|
|
|
61e0f4 |
- kpriv->forkid = spriv->forkid;
|
|
|
61e0f4 |
- }
|
|
|
61e0f4 |
- return 0;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Locking interface to check_fork_int()
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_fork(PKCS11_CTX *ctx)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
- int rv;
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (ctx == NULL)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- cpriv = PRIVCTX(ctx);
|
|
|
61e0f4 |
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
- rv = check_fork_int(ctx);
|
|
|
61e0f4 |
- CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
- return rv;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Locking interface to check_slot_fork_int()
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_slot_fork(PKCS11_SLOT *slot)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
- int rv;
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (slot == NULL)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- cpriv = PRIVCTX(SLOT2CTX(slot));
|
|
|
61e0f4 |
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
- rv = check_slot_fork_int(slot);
|
|
|
61e0f4 |
- CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
- return rv;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Reinitialize token (just its slot)
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_token_fork(PKCS11_TOKEN *token)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- if (token == NULL)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- return check_slot_fork(TOKEN2SLOT(token));
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Locking interface to check_key_fork_int()
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_key_fork(PKCS11_KEY *key)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- PKCS11_CTX_private *cpriv;
|
|
|
61e0f4 |
- int rv;
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
- if (key == NULL)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- cpriv = PRIVCTX(KEY2CTX(key));
|
|
|
61e0f4 |
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
|
61e0f4 |
- rv = check_key_fork_int(key);
|
|
|
61e0f4 |
- CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
|
61e0f4 |
- return rv;
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
-/*
|
|
|
61e0f4 |
- * Reinitialize cert (just its token)
|
|
|
61e0f4 |
- */
|
|
|
61e0f4 |
-static int check_cert_fork(PKCS11_CERT *cert)
|
|
|
61e0f4 |
-{
|
|
|
61e0f4 |
- if (cert == NULL)
|
|
|
61e0f4 |
- return -1;
|
|
|
61e0f4 |
- return check_token_fork(CERT2TOKEN(cert));
|
|
|
61e0f4 |
-}
|
|
|
61e0f4 |
-
|
|
|
61e0f4 |
/* External interface to the libp11 features */
|
|
|
61e0f4 |
|
|
|
61e0f4 |
PKCS11_CTX *PKCS11_CTX_new(void)
|
|
|
61e0f4 |
--
|
|
|
61e0f4 |
2.17.1
|
|
|
61e0f4 |
|