fix regression in loading of modules

This commit is contained in:
Nikos Mavrogiannopoulos 2017-11-30 13:51:07 +01:00
parent 4d2f92f055
commit f8a7e84de2
2 changed files with 265 additions and 1 deletions

View File

@ -0,0 +1,261 @@
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index e6e37c60c..1a1c76d8c 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -273,7 +273,7 @@ int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_
if (ret != 0)
return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
- if (providers_initialized >= req_level) {
+ if (providers_initialized > PROV_UNINITIALIZED) {
ret = 0;
if (_gnutls_detect_fork(pkcs11_forkid)) {
@@ -290,25 +290,60 @@ int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_
}
}
- gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
- return ret;
- } else if (providers_initialized < req_level &&
- (req_level == PROV_INIT_TRUSTED)) {
- _gnutls_debug_log("Initializing needed PKCS #11 modules\n");
- ret = auto_load(1);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ }
- providers_initialized = PROV_INIT_TRUSTED;
- } else {
- _gnutls_debug_log("Initializing all PKCS #11 modules\n");
- ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
+ /* Possible Transitions: PROV_UNINITIALIZED -> PROV_INIT_MANUAL -> PROV_INIT_MANUAL_TRUSTED
+ * PROV_UNINITIALIZED -> PROV_INIT_TRUSTED -> PROV_INIT_ALL
+ *
+ * request for PROV_INIT_TRUSTED may result to PROV_INIT_MANUAL_TRUSTED
+ * request for PROV_INIT_ALL may result to PROV_INIT_MANUAL or PROV_INIT_MANUAL_TRUSTED
+ */
+ switch(req_level) {
+ case PROV_UNINITIALIZED:
+ case PROV_INIT_MANUAL:
+ break;
+ case PROV_INIT_TRUSTED:
+ case PROV_INIT_MANUAL_TRUSTED:
+ if (providers_initialized < PROV_INIT_MANUAL_TRUSTED) {
+ _gnutls_debug_log("Initializing needed PKCS #11 modules\n");
+ ret = auto_load(1);
+ if (ret < 0) {
+ gnutls_assert();
+ }
+
+ if (providers_initialized == PROV_INIT_MANUAL)
+ providers_initialized = PROV_INIT_MANUAL_TRUSTED;
+ else
+ providers_initialized = PROV_INIT_TRUSTED;
+
+ goto cleanup;
+ }
+ break;
+ case PROV_INIT_ALL:
+ if (providers_initialized == PROV_INIT_TRUSTED ||
+ providers_initialized == PROV_UNINITIALIZED) {
+ _gnutls_debug_log("Initializing all PKCS #11 modules\n");
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
+ if (ret < 0) {
+ gnutls_assert();
+ }
+
+ providers_initialized = PROV_INIT_ALL;
+ goto cleanup;
+ }
+ break;
}
- gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
+ ret = 0;
- if (ret < 0)
- return gnutls_assert_val(ret);
+ cleanup:
+ gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
- return 0;
+ return ret;
}
@@ -3220,11 +3255,7 @@ gnutls_pkcs11_obj_list_import_url4(gnutls_pkcs11_obj_t ** p_list,
int ret;
struct find_obj_data_st priv;
- if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED) {
- PKCS11_CHECK_INIT_TRUSTED;
- } else {
- PKCS11_CHECK_INIT;
- }
+ PKCS11_CHECK_INIT_FLAGS(flags);
memset(&priv, 0, sizeof(priv));
@@ -3965,7 +3996,7 @@ int gnutls_pkcs11_get_raw_issuer(const char *url, gnutls_x509_crt_t cert,
size_t id_size;
struct p11_kit_uri *info = NULL;
- PKCS11_CHECK_INIT;
+ PKCS11_CHECK_INIT_FLAGS(flags);
memset(&priv, 0, sizeof(priv));
@@ -4057,7 +4088,7 @@ int gnutls_pkcs11_get_raw_issuer_by_dn (const char *url, const gnutls_datum_t *d
struct find_cert_st priv;
struct p11_kit_uri *info = NULL;
- PKCS11_CHECK_INIT;
+ PKCS11_CHECK_INIT_FLAGS(flags);
memset(&priv, 0, sizeof(priv));
@@ -4144,7 +4175,7 @@ int gnutls_pkcs11_get_raw_issuer_by_subject_key_id (const char *url,
struct find_cert_st priv;
struct p11_kit_uri *info = NULL;
- PKCS11_CHECK_INIT;
+ PKCS11_CHECK_INIT_FLAGS(flags);
memset(&priv, 0, sizeof(priv));
@@ -4238,7 +4269,7 @@ unsigned gnutls_pkcs11_crt_is_known(const char *url, gnutls_x509_crt_t cert,
size_t serial_size;
struct p11_kit_uri *info = NULL;
- PKCS11_CHECK_INIT_RET(0);
+ PKCS11_CHECK_INIT_FLAGS_RET(flags, 0);
memset(&priv, 0, sizeof(priv));
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index de9afbdee..3ba9c5501 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -86,10 +86,14 @@ typedef int (*pkcs11_reinit_function)(void *priv);
typedef enum init_level_t {
PROV_UNINITIALIZED = 0,
PROV_INIT_MANUAL,
+ PROV_INIT_MANUAL_TRUSTED,
PROV_INIT_TRUSTED,
PROV_INIT_ALL
} init_level_t;
+/* See _gnutls_pkcs11_check_init() for possible Transitions.
+ */
+
int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_function cb);
#define FIX_KEY_USAGE(pk, usage) \
@@ -101,20 +105,26 @@ int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_
}
#define PKCS11_CHECK_INIT \
- ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, NULL, NULL); \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_ALL, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(ret)
-#define PKCS11_CHECK_INIT_TRUSTED \
- ret = _gnutls_pkcs11_check_init(PROV_INIT_TRUSTED, NULL, NULL); \
+#define PKCS11_CHECK_INIT_RET(x) \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_ALL, NULL, NULL); \
+ if (ret < 0) \
+ return gnutls_assert_val(x)
+
+#define PKCS11_CHECK_INIT_FLAGS(f) \
+ ret = _gnutls_pkcs11_check_init((f & GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE)?PROV_INIT_TRUSTED:PROV_INIT_ALL, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(ret)
-#define PKCS11_CHECK_INIT_RET(x) \
- ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, NULL, NULL); \
+#define PKCS11_CHECK_INIT_FLAGS_RET(f, x) \
+ ret = _gnutls_pkcs11_check_init((f & GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE)?PROV_INIT_TRUSTED:PROV_INIT_ALL, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(x)
+
/* thus function is called for every token in the traverse_tokens
* function. Once everything is traversed it is called with NULL tinfo.
* It should return 0 if found what it was looking for.
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 69fc0f2e6..7b375d61f 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -367,7 +367,7 @@ advance_iter(gnutls_x509_trust_list_t list,
if (list->pkcs11_token != NULL) {
if (iter->pkcs11_list == NULL) {
ret = gnutls_pkcs11_obj_list_import_url2(&iter->pkcs11_list, &iter->pkcs11_size,
- list->pkcs11_token, (GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED), 0);
+ list->pkcs11_token, (GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED), 0);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -972,7 +972,7 @@ int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
gnutls_datum_t der = {NULL, 0};
/* use the token for verification */
ret = gnutls_pkcs11_get_raw_issuer(list->pkcs11_token, cert, &der,
- GNUTLS_X509_FMT_DER, 0);
+ GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
if (ret < 0) {
gnutls_assert();
return ret;
@@ -1044,7 +1044,7 @@ int gnutls_x509_trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list,
gnutls_datum_t der = {NULL, 0};
/* use the token for verification */
ret = gnutls_pkcs11_get_raw_issuer_by_dn(list->pkcs11_token, dn, &der,
- GNUTLS_X509_FMT_DER, 0);
+ GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
if (ret < 0) {
gnutls_assert();
return ret;
@@ -1105,7 +1105,7 @@ int gnutls_x509_trust_list_get_issuer_by_subject_key_id(gnutls_x509_trust_list_t
gnutls_datum_t der = {NULL, 0};
/* use the token for verification */
ret = gnutls_pkcs11_get_raw_issuer_by_subject_key_id(list->pkcs11_token, dn, spki, &der,
- GNUTLS_X509_FMT_DER, 0);
+ GNUTLS_X509_FMT_DER, GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
if (ret < 0) {
gnutls_assert();
return ret;
diff --git a/lib/x509/verify-high2.c b/lib/x509/verify-high2.c
index fb9f9ce10..8c75b2641 100644
--- a/lib/x509/verify-high2.c
+++ b/lib/x509/verify-high2.c
@@ -188,6 +188,10 @@ int add_trust_list_pkcs11_object_url(gnutls_x509_trust_list_t list, const char *
gnutls_pkcs11_obj_t *pcrt_list = NULL;
unsigned int pcrt_list_size = 0, i;
int ret;
+
+ /* here we don't use the flag GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE,
+ * as we want to explicitly load from any module available in the system.
+ */
ret =
gnutls_pkcs11_obj_list_import_url2(&pcrt_list, &pcrt_list_size,
url,
@@ -323,7 +327,7 @@ gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list,
*/
if (is_pkcs11_url_object(ca_file) != 0) {
return add_trust_list_pkcs11_object_url(list, ca_file, tl_flags);
- } else { /* token */
+ } else { /* trusted token */
if (list->pkcs11_token != NULL)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
list->pkcs11_token = gnutls_strdup(ca_file);
@@ -331,7 +335,7 @@ gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list,
/* enumerate the certificates */
ret = gnutls_pkcs11_obj_list_import_url(NULL, &pcrt_list_size,
ca_file,
- (GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED),
+ (GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED),
0);
if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
return gnutls_assert_val(ret);

View File

@ -1,9 +1,10 @@
# This spec file has been automatically updated
Version: 3.6.1
Release: 2%{?dist}
Release: 3%{?dist}
Patch1: gnutls-3.2.7-rpath.patch
Patch2: gnutls-3.4.2-no-now-guile.patch
Patch3: gnutls-3.6.1-pkcs11-loading.patch
Patch4: gnutls-3.6.1-pkcs11-loading2.patch
%bcond_without dane
%bcond_without guile
Summary: A TLS protocol implementation
@ -139,6 +140,8 @@ gpgv2 --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
sed -i -e 's|sys_lib_dlsearch_path_spec="/lib /usr/lib|sys_lib_dlsearch_path_spec="/lib /usr/lib %{_libdir}|g' configure
rm -f lib/minitasn1/*.c lib/minitasn1/*.h