2 * Copyright 2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSUNION
29 #include "cryptuiapi.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(cryptui
);
34 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
36 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
40 case DLL_WINE_PREATTACH
:
41 return FALSE
; /* prefer native version */
42 case DLL_PROCESS_ATTACH
:
43 DisableThreadLibraryCalls(hinstDLL
);
45 case DLL_PROCESS_DETACH
:
53 /***********************************************************************
54 * CryptUIDlgCertMgr (CRYPTUI.@)
56 BOOL WINAPI
CryptUIDlgCertMgr(PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr
)
58 FIXME("(%p): stub\n", pCryptUICertMgr
);
62 BOOL WINAPI
CryptUIDlgViewCertificateA(
63 PCCRYPTUI_VIEWCERTIFICATE_STRUCTA pCertViewInfo
, BOOL
*pfPropertiesChanged
)
65 CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo
;
69 TRACE("(%p, %p)\n", pCertViewInfo
, pfPropertiesChanged
);
71 memcpy(&viewInfo
, pCertViewInfo
, sizeof(viewInfo
));
72 if (pCertViewInfo
->szTitle
)
74 int len
= MultiByteToWideChar(CP_ACP
, 0, pCertViewInfo
->szTitle
, -1,
77 title
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
80 MultiByteToWideChar(CP_ACP
, 0, pCertViewInfo
->szTitle
, -1, title
,
82 viewInfo
.szTitle
= title
;
90 ret
= CryptUIDlgViewCertificateW(&viewInfo
, pfPropertiesChanged
);
91 HeapFree(GetProcessHeap(), 0, title
);
96 BOOL WINAPI
CryptUIDlgViewCertificateW(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo
,
97 BOOL
*pfPropertiesChanged
)
99 FIXME("(%p, %p): stub\n", pCertViewInfo
, pfPropertiesChanged
);
100 if (pfPropertiesChanged
) *pfPropertiesChanged
= FALSE
;
104 static PCCERT_CONTEXT
make_cert_from_file(LPCWSTR fileName
)
107 DWORD size
, encoding
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
111 file
= CreateFileW(fileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
112 OPEN_EXISTING
, 0, NULL
);
113 if (file
== INVALID_HANDLE_VALUE
)
115 WARN("can't open certificate file %s\n", debugstr_w(fileName
));
118 if ((size
= GetFileSize(file
, NULL
)))
120 if ((buffer
= HeapAlloc(GetProcessHeap(), 0, size
)))
123 if (!ReadFile(file
, buffer
, size
, &read
, NULL
) || read
!= size
)
125 WARN("can't read certificate file %s\n", debugstr_w(fileName
));
126 HeapFree(GetProcessHeap(), 0, buffer
);
134 WARN("empty file %s\n", debugstr_w(fileName
));
139 cert
= CertCreateCertificateContext(encoding
, buffer
, size
);
140 HeapFree(GetProcessHeap(), 0, buffer
);
144 /* Decodes a cert's basic constraints extension (either szOID_BASIC_CONSTRAINTS
145 * or szOID_BASIC_CONSTRAINTS2, whichever is present) to determine if it
146 * should be a CA. If neither extension is present, returns
147 * defaultIfNotSpecified.
149 static BOOL
is_ca_cert(PCCERT_CONTEXT cert
, BOOL defaultIfNotSpecified
)
151 BOOL isCA
= defaultIfNotSpecified
;
152 PCERT_EXTENSION ext
= CertFindExtension(szOID_BASIC_CONSTRAINTS
,
153 cert
->pCertInfo
->cExtension
, cert
->pCertInfo
->rgExtension
);
157 CERT_BASIC_CONSTRAINTS_INFO
*info
;
160 if (CryptDecodeObjectEx(X509_ASN_ENCODING
, szOID_BASIC_CONSTRAINTS
,
161 ext
->Value
.pbData
, ext
->Value
.cbData
, CRYPT_DECODE_ALLOC_FLAG
,
162 NULL
, (LPBYTE
)&info
, &size
))
164 if (info
->SubjectType
.cbData
== 1)
165 isCA
= info
->SubjectType
.pbData
[0] & CERT_CA_SUBJECT_FLAG
;
171 ext
= CertFindExtension(szOID_BASIC_CONSTRAINTS2
,
172 cert
->pCertInfo
->cExtension
, cert
->pCertInfo
->rgExtension
);
175 CERT_BASIC_CONSTRAINTS2_INFO info
;
176 DWORD size
= sizeof(CERT_BASIC_CONSTRAINTS2_INFO
);
178 if (CryptDecodeObjectEx(X509_ASN_ENCODING
,
179 szOID_BASIC_CONSTRAINTS2
, ext
->Value
.pbData
, ext
->Value
.cbData
,
180 0, NULL
, &info
, &size
))
187 static HCERTSTORE
choose_store_for_cert(PCCERT_CONTEXT cert
)
189 static const WCHAR AddressBook
[] = { 'A','d','d','r','e','s','s',
191 static const WCHAR CA
[] = { 'C','A',0 };
194 if (is_ca_cert(cert
, TRUE
))
197 storeName
= AddressBook
;
198 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, 0,
199 CERT_SYSTEM_STORE_CURRENT_USER
, storeName
);
202 BOOL WINAPI
CryptUIWizImport(DWORD dwFlags
, HWND hwndParent
, LPCWSTR pwszWizardTitle
,
203 PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc
, HCERTSTORE hDestCertStore
)
207 const CERT_CONTEXT
*cert
;
208 BOOL freeCert
= FALSE
;
210 TRACE("(0x%08x, %p, %s, %p, %p)\n", dwFlags
, hwndParent
, debugstr_w(pwszWizardTitle
),
211 pImportSrc
, hDestCertStore
);
213 if (!(dwFlags
& CRYPTUI_WIZ_NO_UI
)) FIXME("UI not implemented\n");
216 pImportSrc
->dwSize
!= sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO
))
218 SetLastError(E_INVALIDARG
);
222 switch (pImportSrc
->dwSubjectChoice
)
224 case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE
:
225 if (!(cert
= make_cert_from_file(pImportSrc
->u
.pwszFileName
)))
227 WARN("unable to create certificate context\n");
233 case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT
:
234 cert
= pImportSrc
->u
.pCertContext
;
237 SetLastError(E_INVALIDARG
);
242 FIXME("source type not implemented: %u\n", pImportSrc
->dwSubjectChoice
);
243 SetLastError(E_INVALIDARG
);
246 if (hDestCertStore
) store
= hDestCertStore
;
249 if (!(store
= choose_store_for_cert(cert
)))
251 WARN("unable to open certificate store\n");
252 CertFreeCertificateContext(cert
);
256 ret
= CertAddCertificateContextToStore(store
, cert
, CERT_STORE_ADD_REPLACE_EXISTING
, NULL
);
258 if (!hDestCertStore
) CertCloseStore(store
, 0);
260 CertFreeCertificateContext(cert
);