Module: wine Branch: master Commit: ab9a53f68551072119d40f15041d796cfa864708 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ab9a53f68551072119d40f1504...
Author: Juan Lang juan.lang@gmail.com Date: Fri Oct 24 14:37:02 2008 -0700
cryptui: Choose appropriate destination store for a cert.
---
dlls/cryptui/main.c | 74 ++++++++++++++++++++++++++++++++++++++++-- dlls/cryptui/tests/cryptui.c | 9 ++--- 2 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index ba1e33d..3b116f0 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -139,10 +139,79 @@ static PCCERT_CONTEXT make_cert_from_file(LPCWSTR fileName) return cert; }
+/* Decodes a cert's basic constraints extension (either szOID_BASIC_CONSTRAINTS + * or szOID_BASIC_CONSTRAINTS2, whichever is present) to determine if it + * should be a CA. If neither extension is present, returns + * defaultIfNotSpecified. + */ +static BOOL is_ca_cert(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified) +{ + BOOL isCA = defaultIfNotSpecified; + PCERT_EXTENSION ext = CertFindExtension(szOID_BASIC_CONSTRAINTS, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + + if (ext) + { + CERT_BASIC_CONSTRAINTS_INFO *info; + DWORD size = 0; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS, + ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, + NULL, (LPBYTE)&info, &size)) + { + if (info->SubjectType.cbData == 1) + isCA = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG; + LocalFree(info); + } + } + else + { + ext = CertFindExtension(szOID_BASIC_CONSTRAINTS2, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + if (ext) + { + CERT_BASIC_CONSTRAINTS2_INFO info; + DWORD size = sizeof(CERT_BASIC_CONSTRAINTS2_INFO); + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, + szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData, + 0, NULL, &info, &size)) + isCA = info.fCA; + } + } + return isCA; +} + +static inline BOOL is_cert_self_signed(PCCERT_CONTEXT cert) +{ + return CertCompareCertificateName(cert->dwCertEncodingType, + &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer); +} + +static HCERTSTORE choose_store_for_cert(PCCERT_CONTEXT cert) +{ + static const WCHAR Root[] = {'R','o','o','t',0}; + static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s', + 'B','o','o','k',0 }; + static const WCHAR CA[] = { 'C','A',0 }; + LPCWSTR storeName; + + if (is_ca_cert(cert, TRUE)) + { + if (is_cert_self_signed(cert)) + storeName = Root; + else + storeName = CA; + } + else + storeName = AddressBook; + return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, storeName); +} + BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore) { - static const WCHAR Root[] = {'R','o','o','t',0}; BOOL ret; HCERTSTORE store; const CERT_CONTEXT *cert; @@ -187,8 +256,7 @@ BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardT if (hDestCertStore) store = hDestCertStore; else { - FIXME("certificate store should be determined dynamically, picking Root store\n"); - if (!(store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, Root))) + if (!(store = choose_store_for_cert(cert))) { WARN("unable to open certificate store\n"); CertFreeCertificateContext(cert); diff --git a/dlls/cryptui/tests/cryptui.c b/dlls/cryptui/tests/cryptui.c index b70011a..2ffc83e 100644 --- a/dlls/cryptui/tests/cryptui.c +++ b/dlls/cryptui/tests/cryptui.c @@ -396,7 +396,6 @@ static void test_crypt_ui_wiz_import(void) info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, iTunesCert3, sizeof(iTunesCert3)); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); - todo_wine ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); if (ret) { @@ -408,7 +407,7 @@ static void test_crypt_ui_wiz_import(void) if (addressBook) { find_and_delete_cert_in_store(addressBook, "AddressBook", - info.u.pCertContext, "iTunesCert3", TRUE); + info.u.pCertContext, "iTunesCert3", FALSE); CertCloseStore(addressBook, 0); } } @@ -446,7 +445,6 @@ static void test_crypt_ui_wiz_import(void) info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, iTunesCert1, sizeof(iTunesCert1)); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); - todo_wine ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); if (ret) { @@ -458,7 +456,7 @@ static void test_crypt_ui_wiz_import(void) if (addressBook) { find_and_delete_cert_in_store(addressBook, "AddressBook", - info.u.pCertContext, "iTunesCert1", TRUE); + info.u.pCertContext, "iTunesCert1", FALSE); CertCloseStore(addressBook, 0); } } @@ -467,7 +465,6 @@ static void test_crypt_ui_wiz_import(void) info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, iTunesCert2, sizeof(iTunesCert2)); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); - todo_wine ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); if (ret) { @@ -478,7 +475,7 @@ static void test_crypt_ui_wiz_import(void) if (ca) { find_and_delete_cert_in_store(ca, "CA", - info.u.pCertContext, "iTunesCert2", TRUE); + info.u.pCertContext, "iTunesCert2", FALSE); CertCloseStore(ca, 0); } }