Blame SOURCES/openssl-pkcs11-0.4.8-expose-check-fork.patch

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