Backported PKCS#11 loading improvements
This commit is contained in:
parent
b098d60c08
commit
8952f81162
|
@ -0,0 +1,289 @@
|
|||
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
|
||||
index ec5754e89..c8b2c71f2 100644
|
||||
--- a/lib/pkcs11.c
|
||||
+++ b/lib/pkcs11.c
|
||||
@@ -264,20 +264,20 @@ pkcs11_add_module(const char* name, struct ck_function_list *module, const char
|
||||
*/
|
||||
int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_function cb)
|
||||
{
|
||||
- int ret;
|
||||
+ int ret, sret = 0;
|
||||
|
||||
ret = gnutls_mutex_lock(&_gnutls_pkcs11_mutex);
|
||||
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)) {
|
||||
/* if we are initialized but a fork is detected */
|
||||
ret = _gnutls_pkcs11_reinit();
|
||||
if (ret == 0) {
|
||||
- ret = 1;
|
||||
+ sret = 1;
|
||||
if (cb) {
|
||||
int ret2 = cb(priv);
|
||||
if (ret2 < 0)
|
||||
@@ -287,25 +287,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 = sret;
|
||||
|
||||
- if (ret < 0)
|
||||
- return gnutls_assert_val(ret);
|
||||
+ cleanup:
|
||||
+ gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
|
||||
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3149,11 +3184,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));
|
||||
|
||||
@@ -3790,7 +3821,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));
|
||||
|
||||
@@ -3882,7 +3913,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));
|
||||
|
||||
@@ -3969,7 +4000,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));
|
||||
|
||||
@@ -4063,7 +4094,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 e27518e3f..168bb7807 100644
|
||||
--- a/lib/pkcs11_int.h
|
||||
+++ b/lib/pkcs11_int.h
|
||||
@@ -69,10 +69,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) \
|
||||
@@ -84,20 +88,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/pkcs11_privkey.c b/lib/pkcs11_privkey.c
|
||||
index 4a9d928a3..6e9027d0b 100644
|
||||
--- a/lib/pkcs11_privkey.c
|
||||
+++ b/lib/pkcs11_privkey.c
|
||||
@@ -36,7 +36,7 @@
|
||||
/* In case of a fork, it will invalidate the open session
|
||||
* in the privkey and start another */
|
||||
#define PKCS11_CHECK_INIT_PRIVKEY(k) \
|
||||
- ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, k, reopen_privkey_session); \
|
||||
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_ALL, k, reopen_privkey_session); \
|
||||
if (ret < 0) \
|
||||
return gnutls_assert_val(ret)
|
||||
|
||||
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
|
||||
index 1749d49b1..ec1a52ace 100644
|
||||
--- a/lib/x509/verify-high.c
|
||||
+++ b/lib/x509/verify-high.c
|
||||
@@ -368,7 +368,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);
|
||||
|
||||
@@ -964,7 +964,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;
|
||||
@@ -1036,7 +1036,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;
|
||||
@@ -1097,7 +1097,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);
|
|
@ -1,8 +1,9 @@
|
|||
# This spec file has been automatically updated
|
||||
Version: 3.5.18
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Patch1: gnutls-3.2.7-rpath.patch
|
||||
Patch2: gnutls-3.4.2-no-now-guile.patch
|
||||
Patch3: gnutls-3.5.18-pkcs11-loading.patch
|
||||
%bcond_without dane
|
||||
%bcond_without guile
|
||||
Summary: A TLS protocol implementation
|
||||
|
@ -138,6 +139,7 @@ gpgv2 --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
|
|||
%setup -q
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -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
|
||||
|
@ -268,6 +270,9 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Feb 16 2018 Nikos Mavrogiannopoulos <nmav@redhat.com> - 3.5.18-2
|
||||
- Backported PKCS#11 loading improvements.
|
||||
|
||||
* Fri Feb 16 2018 Nikos Mavrogiannopoulos <nmav@redhat.com> - 3.5.18-1
|
||||
- Update to upstream 3.5.18 release
|
||||
|
||||
|
|
Loading…
Reference in New Issue