sync crypt32 with wine 1.1.33

svn path=/trunk/; revision=44184
This commit is contained in:
Christoph von Wittich 2009-11-15 22:58:08 +00:00
parent 5db2650780
commit 86d5f9981c
22 changed files with 2824 additions and 630 deletions

View file

@ -60,6 +60,8 @@ static const char b64[] =
typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString);
typedef BOOL (*BinaryToStringWFunc)(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString);
static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
@ -97,7 +99,8 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
needed = bytes + pad_bytes + 1;
needed += (needed / 64 + 1) * strlen(sep);
if (sep)
needed += (needed / 64 + 1) * strlen(sep);
if (needed > *out_len)
{
@ -114,7 +117,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
i = 0;
while (div > 0)
{
if (i && i % 64 == 0)
if (sep && i && i % 64 == 0)
{
strcpy(ptr, sep);
ptr += strlen(sep);
@ -160,7 +163,8 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
*ptr++ = '=';
break;
}
strcpy(ptr, sep);
if (sep)
strcpy(ptr, sep);
return ERROR_SUCCESS;
}
@ -170,14 +174,16 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{
static const char crlf[] = "\r\n", lf[] = "\n";
BOOL ret = TRUE;
LPCSTR header = NULL, trailer = NULL, sep = NULL;
LPCSTR header = NULL, trailer = NULL, sep;
DWORD charsNeeded;
if (dwFlags & CRYPT_STRING_NOCR)
sep = lf;
else if (dwFlags & CRYPT_STRING_NOCRLF)
sep = NULL;
else
sep = crlf;
switch (dwFlags & 0x7fffffff)
switch (dwFlags & 0x0fffffff)
{
case CRYPT_STRING_BASE64:
/* no header or footer */
@ -198,7 +204,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
charsNeeded = 0;
encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
charsNeeded += strlen(sep);
if (sep)
charsNeeded += strlen(sep);
if (header)
charsNeeded += strlen(header) + strlen(sep);
if (trailer)
@ -212,8 +219,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{
strcpy(ptr, header);
ptr += strlen(ptr);
strcpy(ptr, sep);
ptr += strlen(sep);
if (sep)
{
strcpy(ptr, sep);
ptr += strlen(sep);
}
}
encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
ptr += size - 1;
@ -221,8 +231,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{
strcpy(ptr, trailer);
ptr += strlen(ptr);
strcpy(ptr, sep);
ptr += strlen(sep);
if (sep)
{
strcpy(ptr, sep);
ptr += strlen(sep);
}
}
*pcchString = charsNeeded - 1;
}
@ -256,7 +269,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
return FALSE;
}
switch (dwFlags & 0x7fffffff)
switch (dwFlags & 0x0fffffff)
{
case CRYPT_STRING_BINARY:
encoder = EncodeBinaryToBinaryA;
@ -271,7 +284,210 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff);
/* fall through */
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
}
static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
WCHAR* out_buf, DWORD *out_len)
{
int div, i;
const BYTE *d = in_buf;
int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
DWORD needed;
LPWSTR ptr;
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
needed = bytes + pad_bytes + 1;
if (sep)
needed += (needed / 64 + 1) * strlenW(sep);
if (needed > *out_len)
{
*out_len = needed;
return ERROR_INSUFFICIENT_BUFFER;
}
else
*out_len = needed;
/* Three bytes of input give 4 chars of output */
div = in_len / 3;
ptr = out_buf;
i = 0;
while (div > 0)
{
if (sep && i && i % 64 == 0)
{
strcpyW(ptr, sep);
ptr += strlenW(sep);
}
/* first char is the first 6 bits of the first byte*/
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
/* second char is the last 2 bits of the first byte and the first 4
* bits of the second byte */
*ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
/* third char is the last 4 bits of the second byte and the first 2
* bits of the third byte */
*ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
/* fourth char is the remaining 6 bits of the third byte */
*ptr++ = b64[ d[2] & 0x3f];
i += 4;
d += 3;
div--;
}
switch(pad_bytes)
{
case 1:
/* first char is the first 6 bits of the first byte*/
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
/* second char is the last 2 bits of the first byte and the first 4
* bits of the second byte */
*ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
/* third char is the last 4 bits of the second byte padded with
* two zeroes */
*ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
/* fourth char is a = to indicate one byte of padding */
*ptr++ = '=';
break;
case 2:
/* first char is the first 6 bits of the first byte*/
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
/* second char is the last 2 bits of the first byte padded with
* four zeroes*/
*ptr++ = b64[ ((d[0] << 4) & 0x30)];
/* third char is = to indicate padding */
*ptr++ = '=';
/* fourth char is = to indicate padding */
*ptr++ = '=';
break;
}
if (sep)
strcpyW(ptr, sep);
return ERROR_SUCCESS;
}
static BOOL BinaryToBase64W(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
{
static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 };
BOOL ret = TRUE;
LPCWSTR header = NULL, trailer = NULL, sep;
DWORD charsNeeded;
if (dwFlags & CRYPT_STRING_NOCR)
sep = lf;
else if (dwFlags & CRYPT_STRING_NOCRLF)
sep = NULL;
else
sep = crlf;
switch (dwFlags & 0x0fffffff)
{
case CRYPT_STRING_BASE64:
/* no header or footer */
break;
case CRYPT_STRING_BASE64HEADER:
header = CERT_HEADER_W;
trailer = CERT_TRAILER_W;
break;
case CRYPT_STRING_BASE64REQUESTHEADER:
header = CERT_REQUEST_HEADER_W;
trailer = CERT_REQUEST_TRAILER_W;
break;
case CRYPT_STRING_BASE64X509CRLHEADER:
header = X509_HEADER_W;
trailer = X509_TRAILER_W;
break;
}
charsNeeded = 0;
encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded);
if (sep)
charsNeeded += strlenW(sep);
if (header)
charsNeeded += strlenW(header) + strlenW(sep);
if (trailer)
charsNeeded += strlenW(trailer) + strlenW(sep);
if (charsNeeded <= *pcchString)
{
LPWSTR ptr = pszString;
DWORD size = charsNeeded;
if (header)
{
strcpyW(ptr, header);
ptr += strlenW(ptr);
if (sep)
{
strcpyW(ptr, sep);
ptr += strlenW(sep);
}
}
encodeBase64W(pbBinary, cbBinary, sep, ptr, &size);
ptr += size - 1;
if (trailer)
{
strcpyW(ptr, trailer);
ptr += strlenW(ptr);
if (sep)
{
strcpyW(ptr, sep);
ptr += strlenW(sep);
}
}
*pcchString = charsNeeded - 1;
}
else if (pszString)
{
*pcchString = charsNeeded;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
ret = FALSE;
}
else
*pcchString = charsNeeded;
return ret;
}
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
{
BinaryToStringWFunc encoder = NULL;
TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
pcchString);
if (!pbBinary)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!pcchString)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (dwFlags & 0x0fffffff)
{
case CRYPT_STRING_BASE64:
case CRYPT_STRING_BASE64HEADER:
case CRYPT_STRING_BASE64REQUESTHEADER:
case CRYPT_STRING_BASE64X509CRLHEADER:
encoder = BinaryToBase64W;
break;
case CRYPT_STRING_BINARY:
case CRYPT_STRING_HEX:
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff);
/* fall through */
default:
SetLastError(ERROR_INVALID_PARAMETER);

View file

@ -71,6 +71,53 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
return ret;
}
BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName,
const BYTE *pbCertEncoded, DWORD cbCertEncoded)
{
HCERTSTORE store;
BOOL ret = FALSE;
TRACE("(%s, %p, %d)\n", debugstr_a(pszCertStoreName), pbCertEncoded,
cbCertEncoded);
store = CertOpenSystemStoreA(0, pszCertStoreName);
if (store)
{
ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL);
CertCloseStore(store, 0);
}
return ret;
}
BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName,
const BYTE *pbCertEncoded, DWORD cbCertEncoded)
{
HCERTSTORE store;
BOOL ret = FALSE;
TRACE("(%s, %p, %d)\n", debugstr_w(pszCertStoreName), pbCertEncoded,
cbCertEncoded);
store = CertOpenSystemStoreW(0, pszCertStoreName);
if (store)
{
ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL);
CertCloseStore(store, 0);
}
return ret;
}
BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
PCCERT_CONTEXT *ppCertContext)
{
FIXME("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition,
ppCertContext);
return FALSE;
}
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
const BYTE *pbCertEncoded, DWORD cbCertEncoded)
{
@ -133,12 +180,14 @@ static void CertDataContext_Free(void *context)
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
{
BOOL ret = TRUE;
TRACE("(%p)\n", pCertContext);
if (pCertContext)
Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
ret = Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
CertDataContext_Free);
return TRUE;
return ret;
}
DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
@ -1120,12 +1169,6 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara);
static BOOL compare_cert_any(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
return TRUE;
}
static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
@ -1202,7 +1245,7 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
/* Matching serial number and subject match.. */
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
&pCertInfo->Issuer, &pCertContext->pCertInfo->Subject);
&pCertContext->pCertInfo->Subject, &pCertInfo->Issuer);
if (ret)
ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber,
&pCertInfo->SerialNumber);
@ -1213,7 +1256,7 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
&pCertInfo->SerialNumber);
if (ret)
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
&pCertInfo->Issuer, &pCertContext->pCertInfo->Issuer);
&pCertContext->pCertInfo->Issuer, &pCertInfo->Issuer);
}
TRACE("returning %d\n", ret);
return ret;
@ -1267,11 +1310,70 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType,
return ret;
}
static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
BOOL ret = FALSE;
PCCERT_CONTEXT subject = pvPara;
PCCERT_CONTEXT toCompare = pvPara;
return CertCompareCertificate(pCertContext->dwCertEncodingType,
pCertContext->pCertInfo, toCompare->pCertInfo);
}
static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
const CRYPT_HASH_BLOB *hash = pvPara;
DWORD size = 0;
BOOL ret;
ret = CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
if (ret && size == hash->cbData)
{
LPBYTE buf = CryptMemAlloc(size);
if (buf)
{
CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, buf, &size);
ret = !memcmp(buf, hash->pbData, size);
CryptMemFree(buf);
}
}
else
ret = FALSE;
return ret;
}
static inline PCCERT_CONTEXT cert_compare_certs_in_store(HCERTSTORE store,
PCCERT_CONTEXT prev, CertCompareFunc compare, DWORD dwType, DWORD dwFlags,
const void *pvPara)
{
BOOL matches = FALSE;
PCCERT_CONTEXT ret;
ret = prev;
do {
ret = CertEnumCertificatesInStore(store, ret);
if (ret)
matches = compare(ret, dwType, dwFlags, pvPara);
} while (ret != NULL && !matches);
return ret;
}
typedef PCCERT_CONTEXT (*CertFindFunc)(HCERTSTORE store, DWORD dwType,
DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev);
static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType,
DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
{
return CertEnumCertificatesInStore(store, prev);
}
static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType,
DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
{
BOOL ret;
PCCERT_CONTEXT found = NULL, subject = pvPara;
PCERT_EXTENSION ext;
DWORD size;
@ -1295,18 +1397,17 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
sizeof(CERT_NAME_BLOB));
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
&info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
}
else if (info->KeyId.cbData)
{
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
}
else
ret = FALSE;
if (ret)
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_cert_id, dwType, dwFlags, &id);
LocalFree(info);
}
}
@ -1343,8 +1444,6 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
&info->AuthorityCertSerialNumber,
sizeof(CRYPT_INTEGER_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
}
else
{
@ -1356,53 +1455,83 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
{
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
}
else
ret = FALSE;
if (ret)
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_cert_id, dwType, dwFlags, &id);
LocalFree(info);
}
}
else
ret = compare_cert_by_name(pCertContext,
CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags,
&subject->pCertInfo->Issuer);
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT,
dwFlags, &subject->pCertInfo->Issuer);
return found;
}
static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext,
DWORD dwType, DWORD dwFlags, const void *pvPara)
{
PCERT_NAME_BLOB name;
DWORD len;
BOOL ret = FALSE;
if (dwType & CERT_INFO_SUBJECT_FLAG)
name = &pCertContext->pCertInfo->Subject;
else
name = &pCertContext->pCertInfo->Issuer;
len = CertNameToStrW(pCertContext->dwCertEncodingType, name,
CERT_SIMPLE_NAME_STR, NULL, 0);
if (len)
{
LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR));
if (str)
{
LPWSTR ptr;
CertNameToStrW(pCertContext->dwCertEncodingType, name,
CERT_SIMPLE_NAME_STR, str, len);
for (ptr = str; *ptr; ptr++)
*ptr = tolowerW(*ptr);
if (strstrW(str, pvPara))
ret = TRUE;
CryptMemFree(str);
}
}
return ret;
}
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
static PCCERT_CONTEXT find_cert_by_name_str(HCERTSTORE store, DWORD dwType,
DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
{
PCCERT_CONTEXT toCompare = pvPara;
return CertCompareCertificate(pCertContext->dwCertEncodingType,
pCertContext->pCertInfo, toCompare->pCertInfo);
}
PCCERT_CONTEXT found = NULL;
static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
const CRYPT_HASH_BLOB *hash = pvPara;
DWORD size = 0;
BOOL ret;
TRACE("%s\n", debugstr_w(pvPara));
ret = CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
if (ret && size == hash->cbData)
if (pvPara)
{
LPBYTE buf = CryptMemAlloc(size);
DWORD len = strlenW(pvPara);
LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR));
if (buf)
if (str)
{
CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, buf, &size);
ret = !memcmp(buf, hash->pbData, size);
CryptMemFree(buf);
LPCWSTR src;
LPWSTR dst;
for (src = pvPara, dst = str; *src; src++, dst++)
*dst = tolowerW(*src);
*dst = 0;
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_name_str, dwType, dwFlags, str);
CryptMemFree(str);
}
}
else
ret = FALSE;
return ret;
found = find_cert_any(store, dwType, dwFlags, NULL, prev);
return found;
}
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
@ -1410,7 +1539,8 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT pPrevCertContext)
{
PCCERT_CONTEXT ret;
CertCompareFunc compare;
CertFindFunc find = NULL;
CertCompareFunc compare = NULL;
TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType,
dwFlags, dwType, pvPara, pPrevCertContext);
@ -1418,7 +1548,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
switch (dwType >> CERT_COMPARE_SHIFT)
{
case CERT_COMPARE_ANY:
compare = compare_cert_any;
find = find_cert_any;
break;
case CERT_COMPARE_MD5_HASH:
compare = compare_cert_by_md5_hash;
@ -1432,6 +1562,9 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
case CERT_COMPARE_PUBLIC_KEY:
compare = compare_cert_by_public_key;
break;
case CERT_COMPARE_NAME_STR_W:
find = find_cert_by_name_str;
break;
case CERT_COMPARE_SUBJECT_CERT:
compare = compare_cert_by_subject_cert;
break;
@ -1439,7 +1572,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
compare = compare_cert_by_cert_id;
break;
case CERT_COMPARE_ISSUER_OF:
compare = compare_cert_by_issuer;
find = find_cert_by_issuer;
break;
case CERT_COMPARE_EXISTING:
compare = compare_existing_cert;
@ -1449,27 +1582,17 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
break;
default:
FIXME("find type %08x unimplemented\n", dwType);
compare = NULL;
}
if (compare)
{
BOOL matches = FALSE;
ret = pPrevCertContext;
do {
ret = CertEnumCertificatesInStore(hCertStore, ret);
if (ret)
matches = compare(ret, dwType, dwFlags, pvPara);
} while (ret != NULL && !matches);
if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
}
if (find)
ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext);
else if (compare)
ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
compare, dwType, dwFlags, pvPara);
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
TRACE("returning %p\n", ret);
return ret;
}
@ -1781,13 +1904,19 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_MD5;
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
if (ret)
{
BYTE *buf;
DWORD size = 0;
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO,
pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType,
X509_PUBLIC_KEY_INFO, pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL,
(LPBYTE)&buf, &size);
if (ret)
{
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
@ -2117,6 +2246,43 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
return ret;
}
BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType,
PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage)
{
PCERT_EXTENSION ext;
BOOL ret = FALSE;
TRACE("(%08x, %p, %p, %d)\n", dwCertEncodingType, pCertInfo, pbKeyUsage,
cbKeyUsage);
ext = CertFindExtension(szOID_KEY_USAGE, pCertInfo->cExtension,
pCertInfo->rgExtension);
if (ext)
{
CRYPT_BIT_BLOB usage;
DWORD size = sizeof(usage);
ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BITS,
ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL,
&usage, &size);
if (ret)
{
if (cbKeyUsage < usage.cbData)
ret = FALSE;
else
{
memcpy(pbKeyUsage, usage.pbData, usage.cbData);
if (cbKeyUsage > usage.cbData)
memset(pbKeyUsage + usage.cbData, 0,
cbKeyUsage - usage.cbData);
}
}
}
else
SetLastError(0);
return ret;
}
BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags,
PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage)
{
@ -2727,7 +2893,10 @@ static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNu
assert(pSubjectIssuerBlob);
assert(pubKey);
info->dwVersion = CERT_V3;
if (pExtensions && pExtensions->cExtension)
info->dwVersion = CERT_V3;
else
info->dwVersion = CERT_V1;
info->SerialNumber.cbData = pSerialNumber->cbData;
info->SerialNumber.pbData = pSerialNumber->pbData;
if (pSignatureAlgorithm)

File diff suppressed because it is too large Load diff

View file

@ -255,11 +255,19 @@ static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
void *pCertContext)
{
BOOL ret;
PCCERT_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCertContext);
ret = CertDeleteCertificateFromStore(
Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
/* Deleting the linked context results in its ref count getting
* decreased, but the caller of this (CertDeleteCertificateFromStore) also
* decreases pCertContext's ref count, by calling
* CertFreeCertificateContext. Increase ref count of linked context to
* compensate.
*/
linked = Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT));
CertDuplicateCertificateContext(linked);
ret = CertDeleteCertificateFromStore(linked);
return ret;
}
@ -333,11 +341,18 @@ static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
void *pCrlContext)
{
BOOL ret;
PCCRL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCrlContext);
ret = CertDeleteCRLFromStore(
Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
/* Deleting the linked context results in its ref count getting
* decreased, but the caller of this (CertDeleteCRLFromStore) also
* decreases pCrlContext's ref count, by calling CertFreeCRLContext.
* Increase ref count of linked context to compensate.
*/
linked = Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT));
CertDuplicateCRLContext(linked);
ret = CertDeleteCRLFromStore(linked);
return ret;
}
@ -411,11 +426,57 @@ static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
void *pCtlContext)
{
BOOL ret;
PCCTL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCtlContext);
ret = CertDeleteCTLFromStore(
Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT)));
/* Deleting the linked context results in its ref count getting
* decreased, but the caller of this (CertDeleteCTLFromStore) also
* decreases pCtlContext's ref count, by calling CertFreeCTLContext.
* Increase ref count of linked context to compensate.
*/
linked = Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT));
CertDuplicateCTLContext(linked);
ret = CertDeleteCTLFromStore(linked);
return ret;
}
static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
BOOL ret;
PWINE_COLLECTIONSTORE store = hCertStore;
PWINE_STORE_LIST_ENTRY entry;
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
if (!store)
return TRUE;
if (store->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (store->hdr.type != StoreTypeCollection)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
ret = TRUE;
EnterCriticalSection(&store->cs);
LIST_FOR_EACH_ENTRY(entry, &store->stores, WINE_STORE_LIST_ENTRY, entry)
{
if (entry->store->control)
{
ret = entry->store->control(entry->store, dwFlags, dwCtrlType,
pvCtrlPara);
if (!ret)
break;
}
}
LeaveCriticalSection(&store->cs);
return ret;
}
@ -446,6 +507,7 @@ PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
store->hdr.ctls.addContext = CRYPT_CollectionAddCTL;
store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL;
store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL;
store->hdr.control = CRYPT_CollectionControl;
InitializeCriticalSection(&store->cs);
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
list_init(&store->stores);

View file

@ -24,7 +24,7 @@
#include "wine/list.h"
#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
WINE_DEFAULT_DEBUG_CHANNEL(context);
typedef enum _ContextType {
ContextTypeData,
@ -94,7 +94,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned
linkContext->type = ContextTypeLink;
linkContext->linked = linkedBase;
if (addRef)
InterlockedIncrement(&linkedBase->ref);
Context_AddRef(linked, contextSize);
TRACE("%p's ref count is %d\n", context, linkContext->ref);
}
TRACE("returning %p\n", context);
@ -106,6 +106,37 @@ void Context_AddRef(void *context, size_t contextSize)
PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
InterlockedIncrement(&baseContext->ref);
TRACE("%p's ref count is %d\n", context, baseContext->ref);
if (baseContext->type == ContextTypeLink)
{
void *linkedContext = Context_GetLinkedContext(context, contextSize);
PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
contextSize);
/* Add-ref the linked contexts too */
while (linkedContext && linkedBase->type == ContextTypeLink)
{
InterlockedIncrement(&linkedBase->ref);
TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
linkedContext = Context_GetLinkedContext(linkedContext,
contextSize);
if (linkedContext)
linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
contextSize);
else
linkedBase = NULL;
}
if (linkedContext)
{
/* It's not a link context, so it wasn't add-ref'ed in the while
* loop, so add-ref it here.
*/
linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
contextSize);
InterlockedIncrement(&linkedBase->ref);
TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
}
}
}
void *Context_GetExtra(const void *context, size_t contextSize)
@ -135,35 +166,39 @@ PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t context
((PDATA_CONTEXT)ptr)->properties : NULL;
}
void Context_Release(void *context, size_t contextSize,
BOOL Context_Release(void *context, size_t contextSize,
ContextFreeFunc dataContextFree)
{
PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
BOOL ret = TRUE;
if (base->ref <= 0)
{
ERR("%p's ref count is %d\n", context, base->ref);
return FALSE;
}
if (base->type == ContextTypeLink)
{
/* The linked context is of the same type as this, so release
* it as well, using the same offset and data free function.
*/
ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT(
((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
dataContextFree);
}
if (InterlockedDecrement(&base->ref) == 0)
{
TRACE("freeing %p\n", context);
switch (base->type)
if (base->type == ContextTypeData)
{
case ContextTypeData:
ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
dataContextFree(context);
break;
case ContextTypeLink:
/* The linked context is of the same type as this, so release
* it as well, using the same offset and data free function.
*/
Context_Release(CONTEXT_FROM_BASE_CONTEXT(
((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
dataContextFree);
break;
default:
assert(0);
}
CryptMemFree(context);
}
else
TRACE("%p's ref count is %d\n", context, base->ref);
return ret;
}
void Context_CopyProperties(const void *to, const void *from,
@ -278,14 +313,21 @@ void *ContextList_Enum(struct ContextList *list, void *pPrev)
return ret;
}
void ContextList_Delete(struct ContextList *list, void *context)
BOOL ContextList_Remove(struct ContextList *list, void *context)
{
struct list *entry = ContextList_ContextToEntry(list, context);
BOOL inList = FALSE;
EnterCriticalSection(&list->cs);
list_remove(entry);
if (!list_empty(entry))
{
list_remove(entry);
inList = TRUE;
}
LeaveCriticalSection(&list->cs);
list->contextInterface->free(context);
if (inList)
list_init(entry);
return inList;
}
static void ContextList_Empty(struct ContextList *list)

View file

@ -228,7 +228,8 @@ PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore,
PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
{
TRACE("(%p)\n", pCrlContext);
Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
if (pCrlContext)
Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
return pCrlContext;
}
@ -242,12 +243,14 @@ static void CrlDataContext_Free(void *context)
BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
{
BOOL ret = TRUE;
TRACE("(%p)\n", pCrlContext);
if (pCrlContext)
Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
CrlDataContext_Free);
return TRUE;
return ret;
}
DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,

View file

@ -1,11 +1,12 @@
@ stdcall CertAddCRLContextToStore(long ptr long ptr)
@ stdcall CertAddCTLContextToStore(long ptr long ptr)
@ stdcall CertAddCertificateContextToStore(long ptr long ptr)
@ stdcall CertAddEncodedCRLToStore(long long ptr long long ptr)
@ stdcall CertAddEncodedCTLToStore(long long ptr long long ptr)
@ stdcall CertAddEncodedCertificateToStore(long long ptr long long ptr)
@ stub CertAddEncodedCertificateToSystemStoreA
@ stub CertAddEncodedCertificateToSystemStoreW
@ stdcall CertAddCRLContextToStore(ptr ptr long ptr)
@ stdcall CertAddCTLContextToStore(ptr ptr long ptr)
@ stdcall CertAddCertificateContextToStore(ptr ptr long ptr)
@ stdcall CertAddCertificateLinkToStore(ptr ptr long ptr)
@ stdcall CertAddEncodedCRLToStore(ptr long ptr long long ptr)
@ stdcall CertAddEncodedCTLToStore(ptr long ptr long long ptr)
@ stdcall CertAddEncodedCertificateToStore(ptr long ptr long long ptr)
@ stdcall CertAddEncodedCertificateToSystemStoreA(str ptr long)
@ stdcall CertAddEncodedCertificateToSystemStoreW(wstr ptr long)
@ stdcall CertAddEnhancedKeyUsageIdentifier(ptr str)
@ stdcall CertAddSerializedElementToStore(ptr ptr long long long long ptr ptr)
@ stdcall CertAddStoreToCollection(ptr ptr long long)
@ -15,7 +16,7 @@
@ stdcall CertCompareCertificateName(long ptr ptr)
@ stdcall CertCompareIntegerBlob(ptr ptr)
@ stdcall CertComparePublicKeyInfo(long ptr ptr)
@ stdcall CertControlStore(long long long ptr)
@ stdcall CertControlStore(ptr long long ptr)
@ stdcall CertCreateCRLContext(long ptr long)
@ stdcall CertCreateCTLContext(long ptr long)
@ stdcall CertCreateCertificateChainEngine(ptr ptr)
@ -35,13 +36,13 @@
@ stdcall CertEnumCTLContextProperties(ptr long)
@ stdcall CertEnumCTLsInStore(ptr ptr)
@ stdcall CertEnumCertificateContextProperties(ptr long)
@ stdcall CertEnumCertificatesInStore(long ptr)
@ stdcall CertEnumCertificatesInStore(ptr ptr)
@ stdcall CertEnumPhysicalStore(ptr long ptr ptr)
@ stdcall CertEnumSystemStore(long ptr ptr ptr)
@ stdcall CertFindAttribute(str long ptr)
@ stdcall CertFindCRLInStore(long long long long ptr ptr)
@ stdcall CertFindCTLInStore(long long long long ptr ptr)
@ stdcall CertFindCertificateInStore(long long long long ptr ptr)
@ stdcall CertFindCRLInStore(ptr long long long ptr ptr)
@ stdcall CertFindCTLInStore(ptr long long long ptr ptr)
@ stdcall CertFindCertificateInStore(ptr long long long ptr ptr)
@ stdcall CertFindCertificateInCRL(ptr ptr long ptr ptr)
@ stdcall CertFindExtension(str long ptr)
@ stdcall CertFindRDNAttr(str ptr)
@ -57,12 +58,12 @@
@ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr)
@ stdcall CertGetCertificateContextProperty(ptr long ptr ptr)
@ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr)
@ stub CertGetIntendedKeyUsage
@ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr)
@ stdcall CertGetIntendedKeyUsage(long ptr ptr long)
@ stdcall CertGetIssuerCertificateFromStore(ptr ptr ptr ptr)
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
@ stdcall CertGetPublicKeyLength(long ptr)
@ stdcall CertGetStoreProperty(long long ptr ptr)
@ stdcall CertGetStoreProperty(ptr long ptr ptr)
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
@ stub CertIsRDNAttrsInCertificateName
@ -76,8 +77,8 @@
@ stdcall CertRDNValueToStrA(long ptr ptr long)
@ stdcall CertRDNValueToStrW(long ptr ptr long)
@ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str)
@ stdcall CertRemoveStoreFromCollection(long long)
@ stdcall CertSaveStore(long long long long ptr long)
@ stdcall CertRemoveStoreFromCollection(ptr ptr)
@ stdcall CertSaveStore(ptr long long long ptr long)
@ stdcall CertSerializeCRLStoreElement(ptr long ptr ptr)
@ stdcall CertSerializeCTLStoreElement(ptr long ptr ptr)
@ stdcall CertSerializeCertificateStoreElement(ptr long ptr ptr)
@ -98,7 +99,7 @@
@ stdcall CertVerifyValidityNesting(ptr ptr)
@ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW
@ stdcall CryptBinaryToStringA(ptr long long ptr ptr)
@ stub CryptBinaryToStringW # (ptr long long ptr ptr)
@ stdcall CryptBinaryToStringW(ptr long long ptr ptr)
@ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr)
@ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr)
@ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW

View file

@ -41,7 +41,7 @@ STRINGTABLE DISCARDABLE
IDS_ENHANCED_KEY_USAGE "Erweiterte Schlüsselbenutzung"
IDS_AUTHORITY_INFO_ACCESS "Autoritätsinformationszugriff"
IDS_CERT_EXTENSIONS "Zertifikatserweiterung"
IDS_NEXT_UPDATE_LOCATION "Next Update Location"
IDS_NEXT_UPDATE_LOCATION "nächster Aktualisierungsort"
IDS_YES_OR_NO_TRUST "Vertrauen oder nicht vertrauen"
IDS_EMAIL_ADDRESS "E-Mail-Adresse"
IDS_UNSTRUCTURED_NAME "Unstrukturierter Name"

View file

@ -113,6 +113,10 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData);
BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
/* The following aren't defined in wincrypt.h, as they're "reserved" */
#define CERT_CERT_PROP_ID 32
#define CERT_CRL_PROP_ID 33
@ -278,6 +282,12 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
*/
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store);
/* Reads contexts serialized in the blob into the memory store. Returns FALSE
* if the file is not of the expected format.
*/
BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob,
HCERTSTORE store);
/* Fixes up the pointers in info, where info is assumed to be a
* CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any
* provider parameters, in a contiguous buffer, but where info's pointers are
@ -291,7 +301,7 @@ void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info);
*/
DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent,
PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz);
const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz);
/**
* Context functions
@ -336,8 +346,9 @@ typedef void (*ContextFreeFunc)(void *context);
/* Decrements context's ref count. If context is a link context, releases its
* linked context as well.
* If a data context has its ref count reach 0, calls dataContextFree on it.
* Returns FALSE if the reference count is <= 0 when called.
*/
void Context_Release(void *context, size_t contextSize,
BOOL Context_Release(void *context, size_t contextSize,
ContextFreeFunc dataContextFree);
/**
@ -377,7 +388,11 @@ void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace);
void *ContextList_Enum(struct ContextList *list, void *pPrev);
void ContextList_Delete(struct ContextList *list, void *context);
/* Removes a context from the list. Returns TRUE if the context was removed,
* or FALSE if not. (The context may have been duplicated, so subsequent
* removes have no effect.)
*/
BOOL ContextList_Remove(struct ContextList *list, void *context);
void ContextList_Free(struct ContextList *list);

View file

@ -309,10 +309,7 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
if (!pCtlContext)
ret = TRUE;
else if (!pCtlContext->hCertStore)
{
ret = TRUE;
CertFreeCTLContext(pCtlContext);
}
ret = CertFreeCTLContext(pCtlContext);
else
{
PWINECRYPT_CERTSTORE hcs = pCtlContext->hCertStore;
@ -321,7 +318,8 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
ret = FALSE;
else
ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext);
CertFreeCTLContext(pCtlContext);
if (ret)
ret = CertFreeCTLContext(pCtlContext);
}
return ret;
}
@ -455,7 +453,8 @@ end:
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
{
TRACE("(%p)\n", pCtlContext);
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
if (pCtlContext)
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
return pCtlContext;
}
@ -471,12 +470,14 @@ static void CTLDataContext_Free(void *context)
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
{
BOOL ret = TRUE;
TRACE("(%p)\n", pCTLContext);
if (pCTLContext)
Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
ret = Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
CTLDataContext_Free);
return TRUE;
return ret;
}
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,

File diff suppressed because it is too large Load diff

View file

@ -415,7 +415,7 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
{
const CERT_PUBLIC_KEY_INFO *info = pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->Algorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
{ &info->PublicKey, CRYPT_AsnEncodeBits, 0 },
};
@ -464,6 +464,25 @@ static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
return ret;
}
BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
const CERT_PUBLIC_KEY_INFO *info = pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->PublicKey, CRYPT_AsnEncodeBits, 0 },
};
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
/* Like in Windows, this blithely ignores the validity of the passed-in
* CERT_INFO, and just encodes it as-is. The resulting encoded data may not
* decode properly, see CRYPT_AsnDecodeCertInfo.
@ -484,40 +503,40 @@ static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType,
{ &info->Issuer, CRYPT_CopyEncodedBlob, 0 },
{ &info->NotBefore, CRYPT_AsnEncodeValidity, 0 },
{ &info->Subject, CRYPT_CopyEncodedBlob, 0 },
{ &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfo, 0 },
{ &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfoNoNull, 0 },
{ 0 }
};
struct AsnConstructedItem constructed[3] = { { 0 } };
DWORD cItem = 7, cConstructed = 0;
struct AsnConstructedItem constructed = { 0 };
struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
DWORD cItem = 7, cSwapped = 0;
if (info->IssuerUniqueId.cbData)
{
constructed[cConstructed].tag = 1;
constructed[cConstructed].pvStructInfo = &info->IssuerUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
swapped[cSwapped].tag = ASN_CONTEXT | 1;
swapped[cSwapped].pvStructInfo = &info->IssuerUniqueId;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
if (info->SubjectUniqueId.cbData)
{
constructed[cConstructed].tag = 2;
constructed[cConstructed].pvStructInfo = &info->SubjectUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
swapped[cSwapped].tag = ASN_CONTEXT | 2;
swapped[cSwapped].pvStructInfo = &info->SubjectUniqueId;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
if (info->cExtension)
{
constructed[cConstructed].tag = 3;
constructed[cConstructed].pvStructInfo = &info->cExtension;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed[cConstructed];
constructed.tag = 3;
constructed.pvStructInfo = &info->cExtension;
constructed.encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++;
}
@ -2800,13 +2819,10 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
DWORD cPolicyQualifier = *(DWORD *)pvStructInfo;
const CERT_POLICY_QUALIFIER_INFO *rgPolicyQualifier =
*(const CERT_POLICY_QUALIFIER_INFO **)
((LPBYTE)pvStructInfo + sizeof(DWORD));
const CERT_POLICY_INFO *info = pvStructInfo;
BOOL ret;
if (!cPolicyQualifier)
if (!info->cPolicyQualifier)
{
*pcbEncoded = 0;
ret = TRUE;
@ -2820,10 +2836,11 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
DWORD bytesNeeded = 0, lenBytes, size, i;
ret = TRUE;
for (i = 0; ret && i < cPolicyQualifier; i++)
for (i = 0; ret && i < info->cPolicyQualifier; i++)
{
items[0].pvStructInfo = rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = &rgPolicyQualifier[i].Qualifier;
items[0].pvStructInfo =
info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = &info->rgPolicyQualifier[i].Qualifier;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size);
@ -2847,12 +2864,12 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < cPolicyQualifier; i++)
for (i = 0; ret && i < info->cPolicyQualifier; i++)
{
items[0].pvStructInfo =
rgPolicyQualifier[i].pszPolicyQualifierId;
info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo =
&rgPolicyQualifier[i].Qualifier;
&info->rgPolicyQualifier[i].Qualifier;
size = bytesNeeded;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]),
@ -2877,7 +2894,7 @@ static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType,
{
struct AsnEncodeSequenceItem items[2] = {
{ info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 },
{ &info->cPolicyQualifier, CRYPT_AsnEncodeCertPolicyQualifiers, 0 },
{ info, CRYPT_AsnEncodeCertPolicyQualifiers, 0 },
};
BOOL ret;
@ -2952,6 +2969,132 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType,
return ret;
}
static BOOL CRYPT_AsnEncodeCertPolicyMapping(DWORD dwCertEncodingType,
const CERT_POLICY_MAPPING *mapping, DWORD dwFlags, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
struct AsnEncodeSequenceItem items[] = {
{ mapping->pszIssuerDomainPolicy, CRYPT_AsnEncodeOid, 0 },
{ mapping->pszSubjectDomainPolicy, CRYPT_AsnEncodeOid, 0 },
};
if (!mapping->pszIssuerDomainPolicy || !mapping->pszSubjectDomainPolicy)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeCertPolicyMappings(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo;
DWORD bytesNeeded = 0, lenBytes, size, i;
ret = TRUE;
for (i = 0; ret && i < info->cPolicyMapping; i++)
{
ret = CRYPT_AsnEncodeCertPolicyMapping(dwCertEncodingType,
&info->rgPolicyMapping[i], dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG,
NULL, &size);
if (ret)
bytesNeeded += size;
}
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (ret)
{
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < info->cPolicyMapping; i++)
{
size = bytesNeeded;
ret = CRYPT_AsnEncodeCertPolicyMapping(
dwCertEncodingType, &info->rgPolicyMapping[i],
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pbEncoded, &size);
if (ret)
{
pbEncoded += size;
bytesNeeded -= size;
}
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCertPolicyConstraints(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CERT_POLICY_CONSTRAINTS_INFO *info = pvStructInfo;
struct AsnEncodeSequenceItem items[2];
struct AsnEncodeTagSwappedItem swapped[2];
DWORD cItem = 0, cSwapped = 0;
if (info->fRequireExplicitPolicy)
{
swapped[cSwapped].tag = ASN_CONTEXT | 0;
swapped[cSwapped].pvStructInfo =
&info->dwRequireExplicitPolicySkipCerts;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInt;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
if (info->fInhibitPolicyMapping)
{
swapped[cSwapped].tag = ASN_CONTEXT | 1;
swapped[cSwapped].pvStructInfo =
&info->dwInhibitPolicyMappingSkipCerts;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInt;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, NULL, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@ -4314,6 +4457,12 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(X509_NAME_CONSTRAINTS):
encodeFunc = CRYPT_AsnEncodeNameConstraints;
break;
case LOWORD(X509_POLICY_MAPPINGS):
encodeFunc = CRYPT_AsnEncodeCertPolicyMappings;
break;
case LOWORD(X509_POLICY_CONSTRAINTS):
encodeFunc = CRYPT_AsnEncodeCertPolicyConstraints;
break;
case LOWORD(PKCS7_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodePKCSSignerInfo;
break;
@ -4330,6 +4479,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeUtcTime;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
encodeFunc = CRYPT_AsnEncodeCertPolicyMappings;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId2;
else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
@ -4356,6 +4507,10 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeCRLDistPoints;
else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
encodeFunc = CRYPT_AsnEncodeCertPolicies;
else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
encodeFunc = CRYPT_AsnEncodeCertPolicyMappings;
else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
encodeFunc = CRYPT_AsnEncodeCertPolicyConstraints;
else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage;
else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
@ -4567,6 +4722,7 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDL
}
else
{
*pcbInfo = sizeNeeded;
pInfo->Algorithm.pszObjId = (char *)pInfo +
sizeof(CERT_PUBLIC_KEY_INFO);
lstrcpyA(pInfo->Algorithm.pszObjId,

View file

@ -43,7 +43,6 @@ static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
if (store->dirty)
CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
CertCloseStore(store->memStore, dwFlags);
CloseHandle(store->file);
CryptMemFree(store);
}

View file

@ -64,8 +64,9 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void)
{
HCRYPTPROV prov;
CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
if (!CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
return hDefProv;
InterlockedCompareExchangePointer((PVOID *)&hDefProv, (PVOID)prov,
NULL);
if (hDefProv != prov)

View file

@ -719,27 +719,22 @@ static BOOL CRYPT_ConstructBlob(CRYPT_DATA_BLOB *out, const CRYPT_DATA_BLOB *in)
return ret;
}
typedef struct _BlobArray
{
DWORD cBlobs;
PCRYPT_DATA_BLOB blobs;
} BlobArray;
static BOOL CRYPT_ConstructBlobArray(BlobArray *out, const BlobArray *in)
static BOOL CRYPT_ConstructBlobArray(DWORD *outCBlobs,
PCRYPT_DATA_BLOB *outPBlobs, DWORD cBlobs, const PCRYPT_DATA_BLOB pBlobs)
{
BOOL ret = TRUE;
out->cBlobs = in->cBlobs;
if (out->cBlobs)
*outCBlobs = cBlobs;
if (cBlobs)
{
out->blobs = CryptMemAlloc(out->cBlobs * sizeof(CRYPT_DATA_BLOB));
if (out->blobs)
*outPBlobs = CryptMemAlloc(cBlobs * sizeof(CRYPT_DATA_BLOB));
if (*outPBlobs)
{
DWORD i;
memset(out->blobs, 0, out->cBlobs * sizeof(CRYPT_DATA_BLOB));
for (i = 0; ret && i < out->cBlobs; i++)
ret = CRYPT_ConstructBlob(&out->blobs[i], &in->blobs[i]);
memset(*outPBlobs, 0, cBlobs * sizeof(CRYPT_DATA_BLOB));
for (i = 0; ret && i < cBlobs; i++)
ret = CRYPT_ConstructBlob(&(*outPBlobs)[i], &pBlobs[i]);
}
else
ret = FALSE;
@ -747,13 +742,13 @@ static BOOL CRYPT_ConstructBlobArray(BlobArray *out, const BlobArray *in)
return ret;
}
static void CRYPT_FreeBlobArray(BlobArray *array)
static void CRYPT_FreeBlobArray(DWORD cBlobs, PCRYPT_DATA_BLOB blobs)
{
DWORD i;
for (i = 0; i < array->cBlobs; i++)
CryptMemFree(array->blobs[i].pbData);
CryptMemFree(array->blobs);
for (i = 0; i < cBlobs; i++)
CryptMemFree(blobs[i].pbData);
CryptMemFree(blobs);
}
static BOOL CRYPT_ConstructAttribute(CRYPT_ATTRIBUTE *out,
@ -765,8 +760,8 @@ static BOOL CRYPT_ConstructAttribute(CRYPT_ATTRIBUTE *out,
if (out->pszObjId)
{
strcpy(out->pszObjId, in->pszObjId);
ret = CRYPT_ConstructBlobArray((BlobArray *)&out->cValue,
(const BlobArray *)&in->cValue);
ret = CRYPT_ConstructBlobArray(&out->cValue, &out->rgValue,
in->cValue, in->rgValue);
}
else
ret = FALSE;
@ -1179,8 +1174,10 @@ static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
CryptMemFree(msg->innerOID);
CryptMemFree(msg->data.pbData);
CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCertEncoded);
CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCrlEncoded);
CRYPT_FreeBlobArray(msg->msg_data.info->cCertEncoded,
msg->msg_data.info->rgCertEncoded);
CRYPT_FreeBlobArray(msg->msg_data.info->cCrlEncoded,
msg->msg_data.info->rgCrlEncoded);
for (i = 0; i < msg->msg_data.info->cSignerInfo; i++)
CSignerInfo_Free(&msg->msg_data.info->rgSignerInfo[i]);
CSignedMsgData_CloseHandles(&msg->msg_data);
@ -1435,13 +1432,13 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags,
}
}
if (ret)
ret = CRYPT_ConstructBlobArray(
(BlobArray *)&msg->msg_data.info->cCertEncoded,
(const BlobArray *)&info->cCertEncoded);
ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCertEncoded,
&msg->msg_data.info->rgCertEncoded, info->cCertEncoded,
info->rgCertEncoded);
if (ret)
ret = CRYPT_ConstructBlobArray(
(BlobArray *)&msg->msg_data.info->cCrlEncoded,
(const BlobArray *)&info->cCrlEncoded);
ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCrlEncoded,
&msg->msg_data.info->rgCrlEncoded, info->cCrlEncoded,
info->rgCrlEncoded);
if (!ret)
{
CSignedEncodeMsg_Close(msg);

View file

@ -283,20 +283,13 @@ end:
return ret;
}
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
static BOOL CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName,
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
LPCWSTR fileName = pvObject;
HANDLE file;
BOOL ret = FALSE;
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
{
FIXME("unimplemented for non-file type %d\n", dwObjectType);
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
return FALSE;
}
TRACE("%s\n", debugstr_w(fileName));
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
@ -322,6 +315,50 @@ static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
return ret;
}
static BOOL CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob,
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
BOOL ret;
TRACE("(%d, %p)\n", blob->cbData, blob->pbData);
ret = CRYPT_ReadSerializedStoreFromBlob(blob, store);
if (ret)
{
if (pdwMsgAndCertEncodingType)
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
if (pdwContentType)
*pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
if (phCertStore)
*phCertStore = CertDuplicateStore(store);
}
CertCloseStore(store, 0);
TRACE("returning %d\n", ret);
return ret;
}
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
switch (dwObjectType)
{
case CERT_QUERY_OBJECT_FILE:
return CRYPT_QuerySerializedStoreFromFile(pvObject,
pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
case CERT_QUERY_OBJECT_BLOB:
return CRYPT_QuerySerializedStoreFromBlob(pvObject,
pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
default:
FIXME("unimplemented for type %d\n", dwObjectType);
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
return FALSE;
}
}
static BOOL CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB *blob,
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
{
@ -562,11 +599,13 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
{
if (pdwFormatType)
*pdwFormatType = formatType;
if (phMsg)
*phMsg = msg;
if (phCertStore)
*phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0,
0, msg);
if (phMsg)
*phMsg = msg;
else
CryptMsgClose(msg);
}
if (blob == &fileBlob)
CryptMemFree(blob->pbData);

View file

@ -873,9 +873,18 @@ static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
{
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
/* Copy remainder of string "left" */
memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
(len - (spotToRemove - multi)) * sizeof(WCHAR));
if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len)
{
/* Removing last string in list, terminate multi string directly */
*spotToRemove = 0;
*(spotToRemove + 1) = 0;
}
else
{
/* Copy remainder of string "left" */
memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
(len - (spotToRemove - multi)) * sizeof(WCHAR));
}
ret = TRUE;
}
else

View file

@ -261,9 +261,23 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
"chain creation failed");
else
{
/* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */
if (chain->TrustStatus.dwErrorStatus &
~CERT_TRUST_IS_UNTRUSTED_ROOT)
DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT |
CERT_TRUST_IS_NOT_VALID_FOR_USAGE |
CERT_TRUST_INVALID_BASIC_CONSTRAINTS |
CERT_TRUST_IS_NOT_TIME_VALID;
/* The certificate chain verification only allows certain
* invalid CA certs if they're installed locally: CA
* certs missing the key usage extension, and CA certs
* missing the basic constraints extension. Of course
* there's a chicken and egg problem: we have to accept
* them here in order for them to be accepted later.
* Expired, locally installed certs are also allowed here,
* because we don't know (yet) what date will be checked
* for an item signed by one of these certs.
* Thus, accept certs with any of the allowed errors.
*/
if (chain->TrustStatus.dwErrorStatus & ~allowedErrors)
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
trust_status_to_str(chain->TrustStatus.dwErrorStatus &
~CERT_TRUST_IS_UNTRUSTED_ROOT));
@ -705,6 +719,7 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store)
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, store);
}
CertCloseStore(from, 0);
}
static HCERTSTORE create_root_store(void)

View file

@ -425,14 +425,18 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
typedef BOOL (*read_serialized_func)(void *handle, void *buffer,
DWORD bytesToRead, DWORD *bytesRead);
static BOOL CRYPT_ReadSerializedStore(void *handle,
read_serialized_func read_func, HCERTSTORE store)
{
BYTE fileHeaderBuf[sizeof(fileHeader)];
DWORD read;
BOOL ret;
/* Failure reading is non-critical, we'll leave the store empty */
ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL);
ret = read_func(handle, fileHeaderBuf, sizeof(fileHeaderBuf), &read);
if (ret)
{
if (!read)
@ -448,7 +452,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
DWORD bufSize = 0;
do {
ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL);
ret = read_func(handle, &propHdr, sizeof(propHdr), &read);
if (ret && read == sizeof(propHdr))
{
if (contextInterface && context &&
@ -470,7 +474,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
}
if (buf)
{
ret = ReadFile(file, buf, propHdr.cb, &read, NULL);
ret = read_func(handle, buf, propHdr.cb, &read);
if (ret && read == propHdr.cb)
{
if (propHdr.propID == CERT_CERT_PROP_ID)
@ -495,8 +499,18 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
CERT_STORE_ADD_NEW, &context);
}
else
ret = CRYPT_ReadContextProp(contextInterface,
context, &propHdr, buf, read);
{
if (!contextInterface)
{
WARN("prop id %d before a context id\n",
propHdr.propID);
ret = FALSE;
}
else
ret = CRYPT_ReadContextProp(
contextInterface, context, &propHdr, buf,
read);
}
}
}
else
@ -519,6 +533,48 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
return ret;
}
static BOOL read_file_wrapper(void *handle, void *buffer, DWORD bytesToRead,
DWORD *bytesRead)
{
return ReadFile(handle, buffer, bytesToRead, bytesRead, NULL);
}
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
{
return CRYPT_ReadSerializedStore(file, read_file_wrapper, store);
}
struct BlobReader
{
const CRYPT_DATA_BLOB *blob;
DWORD current;
};
static BOOL read_blob_wrapper(void *handle, void *buffer, DWORD bytesToRead,
DWORD *bytesRead)
{
struct BlobReader *reader = handle;
BOOL ret;
if (reader->current < reader->blob->cbData)
{
*bytesRead = min(bytesToRead, reader->blob->cbData - reader->current);
memcpy(buffer, reader->blob->pbData + reader->current, *bytesRead);
ret = TRUE;
}
else
ret = FALSE;
return ret;
}
BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob,
HCERTSTORE store)
{
struct BlobReader reader = { blob, 0 };
return CRYPT_ReadSerializedStore(&reader, read_blob_wrapper, store);
}
static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{

View file

@ -184,9 +184,13 @@ static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->certs, pCertContext);
return TRUE;
if (ContextList_Remove(ms->certs, pCertContext))
ret = CertFreeCertificateContext(pCertContext);
else
ret = TRUE;
return ret;
}
static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
@ -225,9 +229,13 @@ static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->crls, pCrlContext);
return TRUE;
if (ContextList_Remove(ms->crls, pCrlContext))
ret = CertFreeCRLContext(pCrlContext);
else
ret = TRUE;
return ret;
}
static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
@ -266,9 +274,20 @@ static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->ctls, pCtlContext);
return TRUE;
if (ContextList_Remove(ms->ctls, pCtlContext))
ret = CertFreeCTLContext(pCtlContext);
else
ret = TRUE;
return ret;
}
static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
@ -314,7 +333,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
store->hdr.ctls.addContext = CRYPT_MemAddCtl;
store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
store->hdr.control = NULL;
store->hdr.control = CRYPT_MemControl;
store->certs = ContextList_Create(pCertInterface,
sizeof(CERT_CONTEXT));
store->crls = ContextList_Create(pCRLInterface,
@ -966,10 +985,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
if (!pCertContext)
ret = TRUE;
else if (!pCertContext->hCertStore)
{
ret = TRUE;
CertFreeCertificateContext(pCertContext);
}
ret = CertFreeCertificateContext(pCertContext);
else
{
PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
@ -979,7 +995,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
else
ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
if (ret)
CertFreeCertificateContext(pCertContext);
ret = CertFreeCertificateContext(pCertContext);
}
return ret;
}
@ -1105,10 +1121,7 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
if (!pCrlContext)
ret = TRUE;
else if (!pCrlContext->hCertStore)
{
ret = TRUE;
CertFreeCRLContext(pCrlContext);
}
ret = CertFreeCRLContext(pCrlContext);
else
{
PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
@ -1117,7 +1130,8 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
ret = FALSE;
else
ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
CertFreeCRLContext(pCrlContext);
if (ret)
ret = CertFreeCRLContext(pCrlContext);
}
return ret;
}
@ -1161,6 +1175,8 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
return FALSE;
if (hcs->ref <= 0)
ERR("%p's ref count is %d\n", hcs, hcs->ref);
if (InterlockedDecrement(&hcs->ref) == 0)
{
TRACE("%p's ref count is 0, freeing\n", hcs);

View file

@ -16,6 +16,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
@ -1017,11 +1020,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
{
if (!pszNameString)
ret = strlenW(entry->pwszRfc822Name) + 1;
ret = strlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString)
{
ret = min(strlenW(entry->pwszRfc822Name), cchNameString - 1);
memcpy(pszNameString, entry->pwszRfc822Name,
ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
@ -1045,7 +1048,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
ret = CertNameToStrW(pCertContext->dwCertEncodingType,
&entry->DirectoryName, *(DWORD *)pvTypePara, pszNameString,
&entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString,
cchNameString);
if (info)
LocalFree(info);
@ -1062,7 +1065,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0,
&entry->DirectoryName, 0, pszNameString, cchNameString);
&entry->u.DirectoryName, 0, pszNameString, cchNameString);
if (altInfo)
LocalFree(altInfo);
}
@ -1102,12 +1105,12 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
{
if (!pszNameString)
ret = strlenW(entry->pwszRfc822Name) + 1;
ret = strlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString)
{
ret = min(strlenW(entry->pwszRfc822Name),
ret = min(strlenW(entry->u.pwszRfc822Name),
cchNameString - 1);
memcpy(pszNameString, entry->pwszRfc822Name,
memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
@ -1139,11 +1142,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
{
if (!pszNameString)
ret = strlenW(entry->pwszDNSName) + 1;
ret = strlenW(entry->u.pwszDNSName) + 1;
else if (cchNameString)
{
ret = min(strlenW(entry->pwszDNSName), cchNameString - 1);
memcpy(pszNameString, entry->pwszDNSName, ret * sizeof(WCHAR));
ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}
@ -1163,11 +1166,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry)
{
if (!pszNameString)
ret = strlenW(entry->pwszURL) + 1;
ret = strlenW(entry->u.pwszURL) + 1;
else if (cchNameString)
{
ret = min(strlenW(entry->pwszURL), cchNameString - 1);
memcpy(pszNameString, entry->pwszURL, ret * sizeof(WCHAR));
ret = min(strlenW(entry->u.pwszURL), cchNameString - 1);
memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR));
pszNameString[ret++] = 0;
}
}

View file

@ -2750,6 +2750,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CRYPT_STRING_BASE64X509CRLHEADER 0x00000009
#define CRYPT_STRING_HEXADDR 0x0000000a
#define CRYPT_STRING_HEXASCIIADDR 0x0000000b
#define CRYPT_STRING_NOCRLF 0x40000000
#define CRYPT_STRING_NOCR 0x80000000
/* OIDs */
@ -2946,6 +2947,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_POLICY_CONSTRAINTS "2.5.29.36"
#define szOID_ENHANCED_KEY_USAGE "2.5.29.37"
#define szOID_FRESHEST_CRL "2.5.29.46"
#define szOID_INHIBIT_ANY_POLICY "2.5.29.54"
#define szOID_DOMAIN_COMPONENT "0.9.2342.19200300.100.1.25"
#define szOID_PKCS_12_FRIENDLY_NAME_ATTR "1.2.840.113549.1.9.20"
#define szOID_PKCS_12_LOCAL_KEY_ID "1.2.840.113549.1.9.21"
@ -4053,6 +4055,13 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded,
DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext);
BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName,
const BYTE *pbCertEncoded, DWORD cbCertEncoded);
BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName,
const BYTE *pbCertEncoded, DWORD cbCertEncoded);
#define CertAddEncodedCertificateToSystemStore \
WINELIB_NAME_AW(CertAddEncodedCertificateToSystemStore)
BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded,
DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext);
@ -4139,6 +4148,9 @@ BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext,
BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement);
BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType,
PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage);
BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags,
PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage);
BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext,