Commit ab9a53f6 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

cryptui: Choose appropriate destination store for a cert.

parent 4b66952b
...@@ -139,10 +139,79 @@ static PCCERT_CONTEXT make_cert_from_file(LPCWSTR fileName) ...@@ -139,10 +139,79 @@ static PCCERT_CONTEXT make_cert_from_file(LPCWSTR fileName)
return cert; 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, BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle,
PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore) PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore)
{ {
static const WCHAR Root[] = {'R','o','o','t',0};
BOOL ret; BOOL ret;
HCERTSTORE store; HCERTSTORE store;
const CERT_CONTEXT *cert; const CERT_CONTEXT *cert;
...@@ -187,8 +256,7 @@ BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardT ...@@ -187,8 +256,7 @@ BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardT
if (hDestCertStore) store = hDestCertStore; if (hDestCertStore) store = hDestCertStore;
else else
{ {
FIXME("certificate store should be determined dynamically, picking Root store\n"); if (!(store = choose_store_for_cert(cert)))
if (!(store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, Root)))
{ {
WARN("unable to open certificate store\n"); WARN("unable to open certificate store\n");
CertFreeCertificateContext(cert); CertFreeCertificateContext(cert);
......
...@@ -396,7 +396,6 @@ static void test_crypt_ui_wiz_import(void) ...@@ -396,7 +396,6 @@ static void test_crypt_ui_wiz_import(void)
info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
iTunesCert3, sizeof(iTunesCert3)); iTunesCert3, sizeof(iTunesCert3));
ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
todo_wine
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret) if (ret)
{ {
...@@ -408,7 +407,7 @@ static void test_crypt_ui_wiz_import(void) ...@@ -408,7 +407,7 @@ static void test_crypt_ui_wiz_import(void)
if (addressBook) if (addressBook)
{ {
find_and_delete_cert_in_store(addressBook, "AddressBook", find_and_delete_cert_in_store(addressBook, "AddressBook",
info.u.pCertContext, "iTunesCert3", TRUE); info.u.pCertContext, "iTunesCert3", FALSE);
CertCloseStore(addressBook, 0); CertCloseStore(addressBook, 0);
} }
} }
...@@ -446,7 +445,6 @@ static void test_crypt_ui_wiz_import(void) ...@@ -446,7 +445,6 @@ static void test_crypt_ui_wiz_import(void)
info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
iTunesCert1, sizeof(iTunesCert1)); iTunesCert1, sizeof(iTunesCert1));
ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
todo_wine
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret) if (ret)
{ {
...@@ -458,7 +456,7 @@ static void test_crypt_ui_wiz_import(void) ...@@ -458,7 +456,7 @@ static void test_crypt_ui_wiz_import(void)
if (addressBook) if (addressBook)
{ {
find_and_delete_cert_in_store(addressBook, "AddressBook", find_and_delete_cert_in_store(addressBook, "AddressBook",
info.u.pCertContext, "iTunesCert1", TRUE); info.u.pCertContext, "iTunesCert1", FALSE);
CertCloseStore(addressBook, 0); CertCloseStore(addressBook, 0);
} }
} }
...@@ -467,7 +465,6 @@ static void test_crypt_ui_wiz_import(void) ...@@ -467,7 +465,6 @@ static void test_crypt_ui_wiz_import(void)
info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
iTunesCert2, sizeof(iTunesCert2)); iTunesCert2, sizeof(iTunesCert2));
ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL); ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
todo_wine
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError()); ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret) if (ret)
{ {
...@@ -478,7 +475,7 @@ static void test_crypt_ui_wiz_import(void) ...@@ -478,7 +475,7 @@ static void test_crypt_ui_wiz_import(void)
if (ca) if (ca)
{ {
find_and_delete_cert_in_store(ca, "CA", find_and_delete_cert_in_store(ca, "CA",
info.u.pCertContext, "iTunesCert2", TRUE); info.u.pCertContext, "iTunesCert2", FALSE);
CertCloseStore(ca, 0); CertCloseStore(ca, 0);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment