Prepare to provide OPENSSL_cleanup.
authorjsing <jsing@openbsd.org>
Sat, 3 Sep 2022 17:47:47 +0000 (17:47 +0000)
committerjsing <jsing@openbsd.org>
Sat, 3 Sep 2022 17:47:47 +0000 (17:47 +0000)
OPENSSL_cleanup() cleans up and deallocates memory in use by the library.
There are a couple of use cases for this, primarily related to memory
leak testing. This will not be called automatically in LibreSSL, which
means that OpenSSL's OPENSSL_NO_INIT_ATEXIT is implied. If code wants to
clean up then they need to explicitly call this themselves.

ok tb@

lib/libcrypto/crypto.h
lib/libcrypto/crypto_init.c
lib/libcrypto/x509/x509_issuer_cache.h

index 8237253..2d93441 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto.h,v 1.55 2022/07/12 14:42:48 kn Exp $ */
+/* $OpenBSD: crypto.h,v 1.56 2022/09/03 17:47:47 jsing Exp $ */
 /* ====================================================================
  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
@@ -562,6 +562,9 @@ void ERR_load_CRYPTO_strings(void);
 #define OPENSSL_INIT_ENGINE_ALL_BUILTIN                _OPENSSL_INIT_FLAG_NOOP
 
 int OPENSSL_init_crypto(uint64_t opts, const void *settings);
+#if defined(LIBRESSL_NEXT_API) || defined(LIBRESSL_INTERNAL)
+void OPENSSL_cleanup(void);
+#endif
 
 #ifdef  __cplusplus
 }
index 67e7920..69ba629 100644 (file)
 #include <pthread.h>
 #include <stdio.h>
 
-#include <openssl/objects.h>
 #include <openssl/conf.h>
-#include <openssl/evp.h>
+#include <openssl/engine.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
 
 #include "cryptlib.h"
+#include "x509_issuer_cache.h"
 
 int OpenSSL_config(const char *);
 int OpenSSL_no_config(void);
 
+static pthread_once_t crypto_init_once = PTHREAD_ONCE_INIT;
 static pthread_t crypto_init_thread;
+static int crypto_init_cleaned_up;
 
 static void
 OPENSSL_init_crypto_internal(void)
@@ -45,12 +49,15 @@ OPENSSL_init_crypto_internal(void)
 int
 OPENSSL_init_crypto(uint64_t opts, const void *settings)
 {
-       static pthread_once_t once = PTHREAD_ONCE_INIT;
+       if (crypto_init_cleaned_up) {
+               CRYPTOerror(ERR_R_INIT_FAIL);
+               return 0;
+       }
 
        if (pthread_equal(pthread_self(), crypto_init_thread))
                return 1; /* don't recurse */
 
-       if (pthread_once(&once, OPENSSL_init_crypto_internal) != 0)
+       if (pthread_once(&crypto_init_once, OPENSSL_init_crypto_internal) != 0)
                return 0;
 
        if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) &&
@@ -63,3 +70,16 @@ OPENSSL_init_crypto(uint64_t opts, const void *settings)
 
        return 1;
 }
+
+void
+OPENSSL_cleanup(void)
+{
+       /* This currently calls init... */
+       ERR_free_strings();
+
+       ENGINE_cleanup();
+       EVP_cleanup();
+       x509_issuer_cache_free();
+
+       crypto_init_cleaned_up = 1;
+}
index 6dedde7..3afe65b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509_issuer_cache.h,v 1.1 2020/09/11 14:30:51 beck Exp $ */
+/* $OpenBSD: x509_issuer_cache.h,v 1.2 2022/09/03 17:47:47 jsing Exp $ */
 /*
  * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
  *
@@ -41,6 +41,7 @@ int x509_issuer_cache_set_max(size_t max);
 int x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md);
 void x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md,
     int valid);
+void x509_issuer_cache_free();
 
 __END_HIDDEN_DECLS