From fd91542eb82c61feeb3b9483afa6ab303b6ef1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Beauz=C3=A9e-Luyssen?= Date: Thu, 13 Dec 2018 17:31:29 +0100 Subject: win32: Use CertOpenStore instead of CertOpenSystemStore CertOpenSystemStore is not available when building for windows store. Both functions are available since windows XP, so there is no compatibility change. CertOpenSystemStore documentation states "Only current user certificates are accessible using this method, not the local machine store." hence we pass CERT_SYSTEM_STORE_CURRENT_USER. We also use the wide chars variants, in the event the ansi ones are silently rejected by windows store applications (which is not documented, but which I strongly suspect) This is equivalent to Wine's implementation of CertOpenSystemStore: https://github.com/wine-mirror/wine/blob/master/dlls/crypt32/store.c#L904 --- lib/system/certs.c | 4 ++-- lib/system/keys-win.c | 8 ++++---- tests/windows/crypt32.c | 9 +++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/system/certs.c b/lib/system/certs.c index 53eb561d00..f9090f1e74 100644 --- a/lib/system/certs.c +++ b/lib/system/certs.c @@ -161,9 +161,9 @@ int add_system_trust(gnutls_x509_trust_list_t list, unsigned int tl_flags, gnutls_datum_t data; if (i == 0) - store = CertOpenSystemStore(0, "ROOT"); + store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER , L"ROOT"); else - store = CertOpenSystemStore(0, "CA"); + store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"CA"); if (store == NULL) return GNUTLS_E_FILE_ERROR; diff --git a/lib/system/keys-win.c b/lib/system/keys-win.c index eac511b975..abd3608474 100644 --- a/lib/system/keys-win.c +++ b/lib/system/keys-win.c @@ -647,7 +647,7 @@ int _gnutls_privkey_import_system_url(gnutls_privkey_t pkey, const char *url) blob.cbData = id_size; blob.pbData = id; - store = CertOpenSystemStore(0, "MY"); + store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (store == NULL) { gnutls_assert(); ret = GNUTLS_E_FILE_ERROR; @@ -884,7 +884,7 @@ int _gnutls_x509_crt_import_system_url(gnutls_x509_crt_t crt, const char *url) blob.cbData = id_size; blob.pbData = id; - store = CertOpenSystemStore(0, "MY"); + store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (store == NULL) { gnutls_assert(); ret = GNUTLS_E_FILE_ERROR; @@ -1132,7 +1132,7 @@ gnutls_system_key_iter_get_info(gnutls_system_key_iter_t * iter, if (*iter == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - (*iter)->store = CertOpenSystemStore(0, "MY"); + (*iter)->store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if ((*iter)->store == NULL) { gnutls_free(*iter); *iter = NULL; @@ -1205,7 +1205,7 @@ int gnutls_system_key_delete(const char *cert_url, const char *key_url) blob.cbData = id_size; blob.pbData = id; - store = CertOpenSystemStore(0, "MY"); + store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (store != NULL) { do { cert = CertFindCertificateInStore(store, diff --git a/tests/windows/crypt32.c b/tests/windows/crypt32.c index 11325f7beb..6987f1faf9 100644 --- a/tests/windows/crypt32.c +++ b/tests/windows/crypt32.c @@ -56,6 +56,15 @@ HCERTSTORE WINAPI CertOpenSystemStore( return VALID_PTR; } +__declspec(dllexport) +HCERTSTORE WINAPI CertOpenStore( + LPCSTR lpszStoreProvider, DWORD dwEncodingType, + HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, + const void *pvPara) +{ + return VALID_PTR; +} + __declspec(dllexport) BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { -- cgit v1.2.1 From ac34af7160c866b7e2354d2d197e63af48e479d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Beauz=C3=A9e-Luyssen?= Date: Mon, 17 Dec 2018 11:37:12 +0100 Subject: win32: Check that CertOpenStore is behaving as CertOpenSystemStore The test isn't located in tests/windows since we need the actual libcrypt32 implementations. --- tests/Makefile.am | 4 +++ tests/win-certopenstore.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/win-certopenstore.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 7bc98df743..043aefc01d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -486,6 +486,10 @@ else TESTS_ENVIRONMENT += WINDOWS=1 +win32_certopenstore_SOURCES = win-certopenstore.c +win32_certopenstore_LDADD = $(LDADD) -lcrypt32 +ctests += win32-certopenstore + endif cpptests = diff --git a/tests/win-certopenstore.c b/tests/win-certopenstore.c new file mode 100644 index 0000000000..162defa4e3 --- /dev/null +++ b/tests/win-certopenstore.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Hugo Beauzée-Luyssen + * + * Author: Hugo Beauzée-Luyssen + * + * This file is part of GnuTLS. + * + * GnuTLS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * This test verifies the assumptions about CertOpenStore and + * CertOpenSystemStore to be equivalent when passed some specific flags + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef _WIN32 +#error "This test shouldn't have been included" +#endif + +#include +#include +#include + +void doit(void) +{ + HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER , L"ROOT"); + assert(hStore != NULL); + HCERTSTORE hSystemStore = CertOpenSystemStore(0, "ROOT"); + assert(hSystemStore != NULL); + + PCCERT_CONTEXT prevCtx = NULL; + PCCERT_CONTEXT ctx = NULL; + PCCERT_CONTEXT sysPrevCtx = NULL; + PCCERT_CONTEXT sysCtx = NULL; + + while (1) + { + ctx = CertEnumCertificatesInStore(hStore, prevCtx); + sysCtx = CertEnumCertificatesInStore(hSystemStore, sysPrevCtx); + if (ctx == NULL || sysCtx == NULL) + break; + if (CertCompareIntegerBlob(&ctx->pCertInfo->SerialNumber, + &sysCtx->pCertInfo->SerialNumber) != TRUE) + assert(0); + + prevCtx = ctx; + sysPrevCtx = sysCtx; + } + assert(ctx == NULL && sysCtx == NULL); + + CertCloseStore(hStore, 0); + CertCloseStore(hSystemStore, 0); +} + -- cgit v1.2.1