100 lines
2.6 KiB
Diff
100 lines
2.6 KiB
Diff
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
|
|
index 9b7047a..8cd9fd3 100644
|
|
--- a/lib/gnutls_global.c
|
|
+++ b/lib/gnutls_global.c
|
|
@@ -53,8 +53,8 @@ extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
|
|
void *_gnutls_file_mutex;
|
|
void *_gnutls_pkcs11_mutex;
|
|
|
|
-ASN1_TYPE _gnutls_pkix1_asn;
|
|
-ASN1_TYPE _gnutls_gnutls_asn;
|
|
+ASN1_TYPE _gnutls_pkix1_asn = ASN1_TYPE_EMPTY;
|
|
+ASN1_TYPE _gnutls_gnutls_asn = ASN1_TYPE_EMPTY;
|
|
|
|
gnutls_log_func _gnutls_log_func = NULL;
|
|
gnutls_audit_log_func _gnutls_audit_log_func = NULL;
|
|
@@ -166,6 +166,9 @@ gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
|
|
GNUTLS_STATIC_MUTEX(global_init_mutex);
|
|
static int _gnutls_init = 0;
|
|
|
|
+/* cache the return code */
|
|
+static int _gnutls_init_ret = 0;
|
|
+
|
|
/**
|
|
* gnutls_global_init:
|
|
*
|
|
@@ -186,6 +189,9 @@ static int _gnutls_init = 0;
|
|
* do not support library constructors and static linking. This
|
|
* function also became thread safe.
|
|
*
|
|
+ * A subsequent call of this function if the initial has failed will
|
|
+ * return the same error code.
|
|
+ *
|
|
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
* otherwise a negative error code is returned.
|
|
**/
|
|
@@ -199,7 +205,7 @@ int gnutls_global_init(void)
|
|
|
|
_gnutls_init++;
|
|
if (_gnutls_init > 1) {
|
|
- ret = 0;
|
|
+ ret = _gnutls_init_ret;
|
|
goto out;
|
|
}
|
|
|
|
@@ -235,14 +241,17 @@ int gnutls_global_init(void)
|
|
goto out;
|
|
}
|
|
|
|
+ _gnutls_pkix1_asn = ASN1_TYPE_EMPTY;
|
|
res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
|
|
if (res != ASN1_SUCCESS) {
|
|
+ gnutls_assert();
|
|
ret = _gnutls_asn2err(res);
|
|
goto out;
|
|
}
|
|
|
|
res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
|
|
if (res != ASN1_SUCCESS) {
|
|
+ gnutls_assert();
|
|
ret = _gnutls_asn2err(res);
|
|
goto out;
|
|
}
|
|
@@ -306,6 +315,7 @@ int gnutls_global_init(void)
|
|
ret = 0;
|
|
|
|
out:
|
|
+ _gnutls_init_ret = ret;
|
|
GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
|
|
return ret;
|
|
}
|
|
@@ -316,11 +326,19 @@ static void _gnutls_global_deinit(unsigned destructor)
|
|
|
|
if (_gnutls_init == 1) {
|
|
_gnutls_init = 0;
|
|
+ if (_gnutls_init_ret < 0) {
|
|
+ /* only deinitialize if gnutls_global_init() has
|
|
+ * succeeded */
|
|
+ gnutls_assert();
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
gnutls_crypto_deinit();
|
|
_gnutls_rnd_deinit();
|
|
_gnutls_ext_deinit();
|
|
asn1_delete_structure(&_gnutls_gnutls_asn);
|
|
asn1_delete_structure(&_gnutls_pkix1_asn);
|
|
+
|
|
_gnutls_crypto_deregister();
|
|
gnutls_system_global_deinit();
|
|
_gnutls_cryptodev_deinit();
|
|
@@ -341,6 +359,8 @@ static void _gnutls_global_deinit(unsigned destructor)
|
|
if (_gnutls_init > 0)
|
|
_gnutls_init--;
|
|
}
|
|
+
|
|
+ fail:
|
|
GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
|
|
}
|
|
|