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, typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString); 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, static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString) 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); TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
needed = bytes + pad_bytes + 1; needed = bytes + pad_bytes + 1;
needed += (needed / 64 + 1) * strlen(sep); if (sep)
needed += (needed / 64 + 1) * strlen(sep);
if (needed > *out_len) if (needed > *out_len)
{ {
@ -114,7 +117,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
i = 0; i = 0;
while (div > 0) while (div > 0)
{ {
if (i && i % 64 == 0) if (sep && i && i % 64 == 0)
{ {
strcpy(ptr, sep); strcpy(ptr, sep);
ptr += strlen(sep); ptr += strlen(sep);
@ -160,7 +163,8 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
*ptr++ = '='; *ptr++ = '=';
break; break;
} }
strcpy(ptr, sep); if (sep)
strcpy(ptr, sep);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -170,14 +174,16 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{ {
static const char crlf[] = "\r\n", lf[] = "\n"; static const char crlf[] = "\r\n", lf[] = "\n";
BOOL ret = TRUE; BOOL ret = TRUE;
LPCSTR header = NULL, trailer = NULL, sep = NULL; LPCSTR header = NULL, trailer = NULL, sep;
DWORD charsNeeded; DWORD charsNeeded;
if (dwFlags & CRYPT_STRING_NOCR) if (dwFlags & CRYPT_STRING_NOCR)
sep = lf; sep = lf;
else if (dwFlags & CRYPT_STRING_NOCRLF)
sep = NULL;
else else
sep = crlf; sep = crlf;
switch (dwFlags & 0x7fffffff) switch (dwFlags & 0x0fffffff)
{ {
case CRYPT_STRING_BASE64: case CRYPT_STRING_BASE64:
/* no header or footer */ /* no header or footer */
@ -198,7 +204,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
charsNeeded = 0; charsNeeded = 0;
encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded); encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
charsNeeded += strlen(sep); if (sep)
charsNeeded += strlen(sep);
if (header) if (header)
charsNeeded += strlen(header) + strlen(sep); charsNeeded += strlen(header) + strlen(sep);
if (trailer) if (trailer)
@ -212,8 +219,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{ {
strcpy(ptr, header); strcpy(ptr, header);
ptr += strlen(ptr); ptr += strlen(ptr);
strcpy(ptr, sep); if (sep)
ptr += strlen(sep); {
strcpy(ptr, sep);
ptr += strlen(sep);
}
} }
encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
ptr += size - 1; ptr += size - 1;
@ -221,8 +231,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
{ {
strcpy(ptr, trailer); strcpy(ptr, trailer);
ptr += strlen(ptr); ptr += strlen(ptr);
strcpy(ptr, sep); if (sep)
ptr += strlen(sep); {
strcpy(ptr, sep);
ptr += strlen(sep);
}
} }
*pcchString = charsNeeded - 1; *pcchString = charsNeeded - 1;
} }
@ -256,7 +269,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
return FALSE; return FALSE;
} }
switch (dwFlags & 0x7fffffff) switch (dwFlags & 0x0fffffff)
{ {
case CRYPT_STRING_BINARY: case CRYPT_STRING_BINARY:
encoder = EncodeBinaryToBinaryA; encoder = EncodeBinaryToBinaryA;
@ -271,7 +284,210 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR: 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 */ /* fall through */
default: default:
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);

View file

@ -71,6 +71,53 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
return ret; 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, PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
const BYTE *pbCertEncoded, DWORD cbCertEncoded) const BYTE *pbCertEncoded, DWORD cbCertEncoded)
{ {
@ -133,12 +180,14 @@ static void CertDataContext_Free(void *context)
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext) BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
{ {
BOOL ret = TRUE;
TRACE("(%p)\n", pCertContext); TRACE("(%p)\n", pCertContext);
if (pCertContext) if (pCertContext)
Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT), ret = Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
CertDataContext_Free); CertDataContext_Free);
return TRUE; return ret;
} }
DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
@ -1120,12 +1169,6 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType, typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara); 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, static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara) 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.. */ /* Matching serial number and subject match.. */
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
&pCertInfo->Issuer, &pCertContext->pCertInfo->Subject); &pCertContext->pCertInfo->Subject, &pCertInfo->Issuer);
if (ret) if (ret)
ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber, ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber,
&pCertInfo->SerialNumber); &pCertInfo->SerialNumber);
@ -1213,7 +1256,7 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
&pCertInfo->SerialNumber); &pCertInfo->SerialNumber);
if (ret) if (ret)
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
&pCertInfo->Issuer, &pCertContext->pCertInfo->Issuer); &pCertContext->pCertInfo->Issuer, &pCertInfo->Issuer);
} }
TRACE("returning %d\n", ret); TRACE("returning %d\n", ret);
return ret; return ret;
@ -1267,11 +1310,70 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType,
return ret; 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) DWORD dwFlags, const void *pvPara)
{ {
BOOL ret = FALSE; PCCERT_CONTEXT toCompare = pvPara;
PCCERT_CONTEXT subject = 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; PCERT_EXTENSION ext;
DWORD size; DWORD size;
@ -1295,18 +1397,17 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
sizeof(CERT_NAME_BLOB)); sizeof(CERT_NAME_BLOB));
memcpy(&id.u.IssuerSerialNumber.SerialNumber, memcpy(&id.u.IssuerSerialNumber.SerialNumber,
&info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
} }
else if (info->KeyId.cbData) else if (info->KeyId.cbData)
{ {
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
} }
else else
ret = FALSE; ret = FALSE;
if (ret)
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_cert_id, dwType, dwFlags, &id);
LocalFree(info); LocalFree(info);
} }
} }
@ -1343,8 +1444,6 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
memcpy(&id.u.IssuerSerialNumber.SerialNumber, memcpy(&id.u.IssuerSerialNumber.SerialNumber,
&info->AuthorityCertSerialNumber, &info->AuthorityCertSerialNumber,
sizeof(CRYPT_INTEGER_BLOB)); sizeof(CRYPT_INTEGER_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
} }
else else
{ {
@ -1356,53 +1455,83 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
{ {
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
&id);
} }
else else
ret = FALSE; ret = FALSE;
if (ret)
found = cert_compare_certs_in_store(store, prev,
compare_cert_by_cert_id, dwType, dwFlags, &id);
LocalFree(info); LocalFree(info);
} }
} }
else else
ret = compare_cert_by_name(pCertContext, found = cert_compare_certs_in_store(store, prev,
CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags, compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT,
&subject->pCertInfo->Issuer); 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; return ret;
} }
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, static PCCERT_CONTEXT find_cert_by_name_str(HCERTSTORE store, DWORD dwType,
DWORD dwFlags, const void *pvPara) DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev)
{ {
PCCERT_CONTEXT toCompare = pvPara; PCCERT_CONTEXT found = NULL;
return CertCompareCertificate(pCertContext->dwCertEncodingType,
pCertContext->pCertInfo, toCompare->pCertInfo);
}
static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, TRACE("%s\n", debugstr_w(pvPara));
DWORD dwFlags, const void *pvPara)
{
const CRYPT_HASH_BLOB *hash = pvPara;
DWORD size = 0;
BOOL ret;
ret = CertGetCertificateContextProperty(pCertContext, if (pvPara)
CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
if (ret && size == hash->cbData)
{ {
LPBYTE buf = CryptMemAlloc(size); DWORD len = strlenW(pvPara);
LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR));
if (buf) if (str)
{ {
CertGetCertificateContextProperty(pCertContext, LPCWSTR src;
CERT_SIGNATURE_HASH_PROP_ID, buf, &size); LPWSTR dst;
ret = !memcmp(buf, hash->pbData, size);
CryptMemFree(buf); 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 else
ret = FALSE; found = find_cert_any(store, dwType, dwFlags, NULL, prev);
return ret; return found;
} }
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
@ -1410,7 +1539,8 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT pPrevCertContext) PCCERT_CONTEXT pPrevCertContext)
{ {
PCCERT_CONTEXT ret; PCCERT_CONTEXT ret;
CertCompareFunc compare; CertFindFunc find = NULL;
CertCompareFunc compare = NULL;
TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType, TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType,
dwFlags, dwType, pvPara, pPrevCertContext); dwFlags, dwType, pvPara, pPrevCertContext);
@ -1418,7 +1548,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
switch (dwType >> CERT_COMPARE_SHIFT) switch (dwType >> CERT_COMPARE_SHIFT)
{ {
case CERT_COMPARE_ANY: case CERT_COMPARE_ANY:
compare = compare_cert_any; find = find_cert_any;
break; break;
case CERT_COMPARE_MD5_HASH: case CERT_COMPARE_MD5_HASH:
compare = compare_cert_by_md5_hash; compare = compare_cert_by_md5_hash;
@ -1432,6 +1562,9 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
case CERT_COMPARE_PUBLIC_KEY: case CERT_COMPARE_PUBLIC_KEY:
compare = compare_cert_by_public_key; compare = compare_cert_by_public_key;
break; break;
case CERT_COMPARE_NAME_STR_W:
find = find_cert_by_name_str;
break;
case CERT_COMPARE_SUBJECT_CERT: case CERT_COMPARE_SUBJECT_CERT:
compare = compare_cert_by_subject_cert; compare = compare_cert_by_subject_cert;
break; break;
@ -1439,7 +1572,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
compare = compare_cert_by_cert_id; compare = compare_cert_by_cert_id;
break; break;
case CERT_COMPARE_ISSUER_OF: case CERT_COMPARE_ISSUER_OF:
compare = compare_cert_by_issuer; find = find_cert_by_issuer;
break; break;
case CERT_COMPARE_EXISTING: case CERT_COMPARE_EXISTING:
compare = compare_existing_cert; compare = compare_existing_cert;
@ -1449,27 +1582,17 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
break; break;
default: default:
FIXME("find type %08x unimplemented\n", dwType); FIXME("find type %08x unimplemented\n", dwType);
compare = NULL;
} }
if (compare) if (find)
{ ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext);
BOOL matches = FALSE; else if (compare)
ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
ret = pPrevCertContext; compare, dwType, dwFlags, pvPara);
do {
ret = CertEnumCertificatesInStore(hCertStore, ret);
if (ret)
matches = compare(ret, dwType, dwFlags, pvPara);
} while (ret != NULL && !matches);
if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
}
else else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL; ret = NULL;
} if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
TRACE("returning %p\n", ret); TRACE("returning %p\n", ret);
return ret; return ret;
} }
@ -1781,13 +1904,19 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
hCryptProv = CRYPT_GetDefaultProvider(); hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid) if (!Algid)
Algid = CALG_MD5; Algid = CALG_MD5;
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
if (ret) if (ret)
{ {
BYTE *buf; BYTE *buf;
DWORD size = 0; DWORD size = 0;
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO, ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType,
pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); X509_PUBLIC_KEY_INFO, pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL,
(LPBYTE)&buf, &size);
if (ret) if (ret)
{ {
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
@ -2117,6 +2246,43 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
return ret; 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, BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags,
PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage) 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(pSubjectIssuerBlob);
assert(pubKey); 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.cbData = pSerialNumber->cbData;
info->SerialNumber.pbData = pSerialNumber->pbData; info->SerialNumber.pbData = pSerialNumber->pbData;
if (pSignatureAlgorithm) 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) void *pCertContext)
{ {
BOOL ret; BOOL ret;
PCCERT_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCertContext); TRACE("(%p, %p)\n", store, pCertContext);
ret = CertDeleteCertificateFromStore( /* Deleting the linked context results in its ref count getting
Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT))); * 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; return ret;
} }
@ -333,11 +341,18 @@ static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
void *pCrlContext) void *pCrlContext)
{ {
BOOL ret; BOOL ret;
PCCRL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCrlContext); TRACE("(%p, %p)\n", store, pCrlContext);
ret = CertDeleteCRLFromStore( /* Deleting the linked context results in its ref count getting
Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT))); * 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; return ret;
} }
@ -411,11 +426,57 @@ static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
void *pCtlContext) void *pCtlContext)
{ {
BOOL ret; BOOL ret;
PCCTL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCtlContext); TRACE("(%p, %p)\n", store, pCtlContext);
ret = CertDeleteCTLFromStore( /* Deleting the linked context results in its ref count getting
Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT))); * 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; return ret;
} }
@ -446,6 +507,7 @@ PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
store->hdr.ctls.addContext = CRYPT_CollectionAddCTL; store->hdr.ctls.addContext = CRYPT_CollectionAddCTL;
store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL; store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL;
store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL; store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL;
store->hdr.control = CRYPT_CollectionControl;
InitializeCriticalSection(&store->cs); InitializeCriticalSection(&store->cs);
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs"); store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
list_init(&store->stores); list_init(&store->stores);

View file

@ -24,7 +24,7 @@
#include "wine/list.h" #include "wine/list.h"
#include "crypt32_private.h" #include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt); WINE_DEFAULT_DEBUG_CHANNEL(context);
typedef enum _ContextType { typedef enum _ContextType {
ContextTypeData, ContextTypeData,
@ -94,7 +94,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned
linkContext->type = ContextTypeLink; linkContext->type = ContextTypeLink;
linkContext->linked = linkedBase; linkContext->linked = linkedBase;
if (addRef) if (addRef)
InterlockedIncrement(&linkedBase->ref); Context_AddRef(linked, contextSize);
TRACE("%p's ref count is %d\n", context, linkContext->ref); TRACE("%p's ref count is %d\n", context, linkContext->ref);
} }
TRACE("returning %p\n", context); 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); PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
InterlockedIncrement(&baseContext->ref); 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) 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; ((PDATA_CONTEXT)ptr)->properties : NULL;
} }
void Context_Release(void *context, size_t contextSize, BOOL Context_Release(void *context, size_t contextSize,
ContextFreeFunc dataContextFree) ContextFreeFunc dataContextFree)
{ {
PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize); 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) if (InterlockedDecrement(&base->ref) == 0)
{ {
TRACE("freeing %p\n", context); TRACE("freeing %p\n", context);
switch (base->type) if (base->type == ContextTypeData)
{ {
case ContextTypeData:
ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties); ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
dataContextFree(context); 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); CryptMemFree(context);
} }
else else
TRACE("%p's ref count is %d\n", context, base->ref); TRACE("%p's ref count is %d\n", context, base->ref);
return ret;
} }
void Context_CopyProperties(const void *to, const void *from, void Context_CopyProperties(const void *to, const void *from,
@ -278,14 +313,21 @@ void *ContextList_Enum(struct ContextList *list, void *pPrev)
return ret; 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); struct list *entry = ContextList_ContextToEntry(list, context);
BOOL inList = FALSE;
EnterCriticalSection(&list->cs); EnterCriticalSection(&list->cs);
list_remove(entry); if (!list_empty(entry))
{
list_remove(entry);
inList = TRUE;
}
LeaveCriticalSection(&list->cs); LeaveCriticalSection(&list->cs);
list->contextInterface->free(context); if (inList)
list_init(entry);
return inList;
} }
static void ContextList_Empty(struct ContextList *list) 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) PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
{ {
TRACE("(%p)\n", pCrlContext); TRACE("(%p)\n", pCrlContext);
Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT)); if (pCrlContext)
Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
return pCrlContext; return pCrlContext;
} }
@ -242,12 +243,14 @@ static void CrlDataContext_Free(void *context)
BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext) BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
{ {
BOOL ret = TRUE;
TRACE("(%p)\n", pCrlContext); TRACE("(%p)\n", pCrlContext);
if (pCrlContext) if (pCrlContext)
Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT), ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
CrlDataContext_Free); CrlDataContext_Free);
return TRUE; return ret;
} }
DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,

View file

@ -1,11 +1,12 @@
@ stdcall CertAddCRLContextToStore(long ptr long ptr) @ stdcall CertAddCRLContextToStore(ptr ptr long ptr)
@ stdcall CertAddCTLContextToStore(long ptr long ptr) @ stdcall CertAddCTLContextToStore(ptr ptr long ptr)
@ stdcall CertAddCertificateContextToStore(long ptr long ptr) @ stdcall CertAddCertificateContextToStore(ptr ptr long ptr)
@ stdcall CertAddEncodedCRLToStore(long long ptr long long ptr) @ stdcall CertAddCertificateLinkToStore(ptr ptr long ptr)
@ stdcall CertAddEncodedCTLToStore(long long ptr long long ptr) @ stdcall CertAddEncodedCRLToStore(ptr long ptr long long ptr)
@ stdcall CertAddEncodedCertificateToStore(long long ptr long long ptr) @ stdcall CertAddEncodedCTLToStore(ptr long ptr long long ptr)
@ stub CertAddEncodedCertificateToSystemStoreA @ stdcall CertAddEncodedCertificateToStore(ptr long ptr long long ptr)
@ stub CertAddEncodedCertificateToSystemStoreW @ stdcall CertAddEncodedCertificateToSystemStoreA(str ptr long)
@ stdcall CertAddEncodedCertificateToSystemStoreW(wstr ptr long)
@ stdcall CertAddEnhancedKeyUsageIdentifier(ptr str) @ stdcall CertAddEnhancedKeyUsageIdentifier(ptr str)
@ stdcall CertAddSerializedElementToStore(ptr ptr long long long long ptr ptr) @ stdcall CertAddSerializedElementToStore(ptr ptr long long long long ptr ptr)
@ stdcall CertAddStoreToCollection(ptr ptr long long) @ stdcall CertAddStoreToCollection(ptr ptr long long)
@ -15,7 +16,7 @@
@ stdcall CertCompareCertificateName(long ptr ptr) @ stdcall CertCompareCertificateName(long ptr ptr)
@ stdcall CertCompareIntegerBlob(ptr ptr) @ stdcall CertCompareIntegerBlob(ptr ptr)
@ stdcall CertComparePublicKeyInfo(long 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 CertCreateCRLContext(long ptr long)
@ stdcall CertCreateCTLContext(long ptr long) @ stdcall CertCreateCTLContext(long ptr long)
@ stdcall CertCreateCertificateChainEngine(ptr ptr) @ stdcall CertCreateCertificateChainEngine(ptr ptr)
@ -35,13 +36,13 @@
@ stdcall CertEnumCTLContextProperties(ptr long) @ stdcall CertEnumCTLContextProperties(ptr long)
@ stdcall CertEnumCTLsInStore(ptr ptr) @ stdcall CertEnumCTLsInStore(ptr ptr)
@ stdcall CertEnumCertificateContextProperties(ptr long) @ stdcall CertEnumCertificateContextProperties(ptr long)
@ stdcall CertEnumCertificatesInStore(long ptr) @ stdcall CertEnumCertificatesInStore(ptr ptr)
@ stdcall CertEnumPhysicalStore(ptr long ptr ptr) @ stdcall CertEnumPhysicalStore(ptr long ptr ptr)
@ stdcall CertEnumSystemStore(long ptr ptr ptr) @ stdcall CertEnumSystemStore(long ptr ptr ptr)
@ stdcall CertFindAttribute(str long ptr) @ stdcall CertFindAttribute(str long ptr)
@ stdcall CertFindCRLInStore(long long long long ptr ptr) @ stdcall CertFindCRLInStore(ptr long long long ptr ptr)
@ stdcall CertFindCTLInStore(long long long long ptr ptr) @ stdcall CertFindCTLInStore(ptr long long long ptr ptr)
@ stdcall CertFindCertificateInStore(long long long long ptr ptr) @ stdcall CertFindCertificateInStore(ptr long long long ptr ptr)
@ stdcall CertFindCertificateInCRL(ptr ptr long ptr ptr) @ stdcall CertFindCertificateInCRL(ptr ptr long ptr ptr)
@ stdcall CertFindExtension(str long ptr) @ stdcall CertFindExtension(str long ptr)
@ stdcall CertFindRDNAttr(str ptr) @ stdcall CertFindRDNAttr(str ptr)
@ -57,12 +58,12 @@
@ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr) @ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr)
@ stdcall CertGetCertificateContextProperty(ptr long ptr ptr) @ stdcall CertGetCertificateContextProperty(ptr long ptr ptr)
@ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr) @ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr)
@ stub CertGetIntendedKeyUsage @ stdcall CertGetIntendedKeyUsage(long ptr ptr long)
@ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr) @ stdcall CertGetIssuerCertificateFromStore(ptr ptr ptr ptr)
@ stdcall CertGetNameStringA(ptr long long ptr ptr long) @ stdcall CertGetNameStringA(ptr long long ptr ptr long)
@ stdcall CertGetNameStringW(ptr long long ptr ptr long) @ stdcall CertGetNameStringW(ptr long long ptr ptr long)
@ stdcall CertGetPublicKeyLength(long ptr) @ stdcall CertGetPublicKeyLength(long ptr)
@ stdcall CertGetStoreProperty(long long ptr ptr) @ stdcall CertGetStoreProperty(ptr long ptr ptr)
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr) @ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr) @ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
@ stub CertIsRDNAttrsInCertificateName @ stub CertIsRDNAttrsInCertificateName
@ -76,8 +77,8 @@
@ stdcall CertRDNValueToStrA(long ptr ptr long) @ stdcall CertRDNValueToStrA(long ptr ptr long)
@ stdcall CertRDNValueToStrW(long ptr ptr long) @ stdcall CertRDNValueToStrW(long ptr ptr long)
@ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str) @ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str)
@ stdcall CertRemoveStoreFromCollection(long long) @ stdcall CertRemoveStoreFromCollection(ptr ptr)
@ stdcall CertSaveStore(long long long long ptr long) @ stdcall CertSaveStore(ptr long long long ptr long)
@ stdcall CertSerializeCRLStoreElement(ptr long ptr ptr) @ stdcall CertSerializeCRLStoreElement(ptr long ptr ptr)
@ stdcall CertSerializeCTLStoreElement(ptr long ptr ptr) @ stdcall CertSerializeCTLStoreElement(ptr long ptr ptr)
@ stdcall CertSerializeCertificateStoreElement(ptr long ptr ptr) @ stdcall CertSerializeCertificateStoreElement(ptr long ptr ptr)
@ -98,7 +99,7 @@
@ stdcall CertVerifyValidityNesting(ptr ptr) @ stdcall CertVerifyValidityNesting(ptr ptr)
@ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW @ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW
@ stdcall CryptBinaryToStringA(ptr long long ptr ptr) @ 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 CryptStringToBinaryA(str long long ptr ptr ptr ptr)
@ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr) @ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr)
@ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW @ 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_ENHANCED_KEY_USAGE "Erweiterte Schlüsselbenutzung"
IDS_AUTHORITY_INFO_ACCESS "Autoritätsinformationszugriff" IDS_AUTHORITY_INFO_ACCESS "Autoritätsinformationszugriff"
IDS_CERT_EXTENSIONS "Zertifikatserweiterung" 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_YES_OR_NO_TRUST "Vertrauen oder nicht vertrauen"
IDS_EMAIL_ADDRESS "E-Mail-Adresse" IDS_EMAIL_ADDRESS "E-Mail-Adresse"
IDS_UNSTRUCTURED_NAME "Unstrukturierter Name" 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, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData); 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" */ /* The following aren't defined in wincrypt.h, as they're "reserved" */
#define CERT_CERT_PROP_ID 32 #define CERT_CERT_PROP_ID 32
#define CERT_CRL_PROP_ID 33 #define CERT_CRL_PROP_ID 33
@ -278,6 +282,12 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
*/ */
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store); 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 /* 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 * 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 * 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, 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 * Context functions
@ -336,8 +346,9 @@ typedef void (*ContextFreeFunc)(void *context);
/* Decrements context's ref count. If context is a link context, releases its /* Decrements context's ref count. If context is a link context, releases its
* linked context as well. * linked context as well.
* If a data context has its ref count reach 0, calls dataContextFree on it. * 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); 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_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); void ContextList_Free(struct ContextList *list);

View file

@ -309,10 +309,7 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
if (!pCtlContext) if (!pCtlContext)
ret = TRUE; ret = TRUE;
else if (!pCtlContext->hCertStore) else if (!pCtlContext->hCertStore)
{ ret = CertFreeCTLContext(pCtlContext);
ret = TRUE;
CertFreeCTLContext(pCtlContext);
}
else else
{ {
PWINECRYPT_CERTSTORE hcs = pCtlContext->hCertStore; PWINECRYPT_CERTSTORE hcs = pCtlContext->hCertStore;
@ -321,7 +318,8 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
ret = FALSE; ret = FALSE;
else else
ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext); ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext);
CertFreeCTLContext(pCtlContext); if (ret)
ret = CertFreeCTLContext(pCtlContext);
} }
return ret; return ret;
} }
@ -455,7 +453,8 @@ end:
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext) PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
{ {
TRACE("(%p)\n", pCtlContext); TRACE("(%p)\n", pCtlContext);
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT)); if (pCtlContext)
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
return pCtlContext; return pCtlContext;
} }
@ -471,12 +470,14 @@ static void CTLDataContext_Free(void *context)
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext) BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
{ {
BOOL ret = TRUE;
TRACE("(%p)\n", pCTLContext); TRACE("(%p)\n", pCTLContext);
if (pCTLContext) if (pCTLContext)
Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT), ret = Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
CTLDataContext_Free); CTLDataContext_Free);
return TRUE; return ret;
} }
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, 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; const CERT_PUBLIC_KEY_INFO *info = pvStructInfo;
struct AsnEncodeSequenceItem items[] = { struct AsnEncodeSequenceItem items[] = {
{ &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 }, { &info->Algorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
{ &info->PublicKey, CRYPT_AsnEncodeBits, 0 }, { &info->PublicKey, CRYPT_AsnEncodeBits, 0 },
}; };
@ -464,6 +464,25 @@ static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
return ret; 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 /* 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 * CERT_INFO, and just encodes it as-is. The resulting encoded data may not
* decode properly, see CRYPT_AsnDecodeCertInfo. * decode properly, see CRYPT_AsnDecodeCertInfo.
@ -484,40 +503,40 @@ static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType,
{ &info->Issuer, CRYPT_CopyEncodedBlob, 0 }, { &info->Issuer, CRYPT_CopyEncodedBlob, 0 },
{ &info->NotBefore, CRYPT_AsnEncodeValidity, 0 }, { &info->NotBefore, CRYPT_AsnEncodeValidity, 0 },
{ &info->Subject, CRYPT_CopyEncodedBlob, 0 }, { &info->Subject, CRYPT_CopyEncodedBlob, 0 },
{ &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfo, 0 }, { &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfoNoNull, 0 },
{ 0 } { 0 }
}; };
struct AsnConstructedItem constructed[3] = { { 0 } }; struct AsnConstructedItem constructed = { 0 };
DWORD cItem = 7, cConstructed = 0; struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
DWORD cItem = 7, cSwapped = 0;
if (info->IssuerUniqueId.cbData) if (info->IssuerUniqueId.cbData)
{ {
constructed[cConstructed].tag = 1; swapped[cSwapped].tag = ASN_CONTEXT | 1;
constructed[cConstructed].pvStructInfo = &info->IssuerUniqueId; swapped[cSwapped].pvStructInfo = &info->IssuerUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits; swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed]; items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cConstructed++; cSwapped++;
cItem++; cItem++;
} }
if (info->SubjectUniqueId.cbData) if (info->SubjectUniqueId.cbData)
{ {
constructed[cConstructed].tag = 2; swapped[cSwapped].tag = ASN_CONTEXT | 2;
constructed[cConstructed].pvStructInfo = &info->SubjectUniqueId; swapped[cSwapped].pvStructInfo = &info->SubjectUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits; swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed]; items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cConstructed++; cSwapped++;
cItem++; cItem++;
} }
if (info->cExtension) if (info->cExtension)
{ {
constructed[cConstructed].tag = 3; constructed.tag = 3;
constructed[cConstructed].pvStructInfo = &info->cExtension; constructed.pvStructInfo = &info->cExtension;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions; constructed.encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed[cConstructed]; items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++; cItem++;
} }
@ -2800,13 +2819,10 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{ {
DWORD cPolicyQualifier = *(DWORD *)pvStructInfo; const CERT_POLICY_INFO *info = pvStructInfo;
const CERT_POLICY_QUALIFIER_INFO *rgPolicyQualifier =
*(const CERT_POLICY_QUALIFIER_INFO **)
((LPBYTE)pvStructInfo + sizeof(DWORD));
BOOL ret; BOOL ret;
if (!cPolicyQualifier) if (!info->cPolicyQualifier)
{ {
*pcbEncoded = 0; *pcbEncoded = 0;
ret = TRUE; ret = TRUE;
@ -2820,10 +2836,11 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
DWORD bytesNeeded = 0, lenBytes, size, i; DWORD bytesNeeded = 0, lenBytes, size, i;
ret = TRUE; ret = TRUE;
for (i = 0; ret && i < cPolicyQualifier; i++) for (i = 0; ret && i < info->cPolicyQualifier; i++)
{ {
items[0].pvStructInfo = rgPolicyQualifier[i].pszPolicyQualifierId; items[0].pvStructInfo =
items[1].pvStructInfo = &rgPolicyQualifier[i].Qualifier; info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = &info->rgPolicyQualifier[i].Qualifier;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), sizeof(items) / sizeof(items[0]),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size); 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, CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes); &lenBytes);
pbEncoded += lenBytes; pbEncoded += lenBytes;
for (i = 0; ret && i < cPolicyQualifier; i++) for (i = 0; ret && i < info->cPolicyQualifier; i++)
{ {
items[0].pvStructInfo = items[0].pvStructInfo =
rgPolicyQualifier[i].pszPolicyQualifierId; info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = items[1].pvStructInfo =
&rgPolicyQualifier[i].Qualifier; &info->rgPolicyQualifier[i].Qualifier;
size = bytesNeeded; size = bytesNeeded;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), sizeof(items) / sizeof(items[0]),
@ -2877,7 +2894,7 @@ static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType,
{ {
struct AsnEncodeSequenceItem items[2] = { struct AsnEncodeSequenceItem items[2] = {
{ info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 }, { info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 },
{ &info->cPolicyQualifier, CRYPT_AsnEncodeCertPolicyQualifiers, 0 }, { info, CRYPT_AsnEncodeCertPolicyQualifiers, 0 },
}; };
BOOL ret; BOOL ret;
@ -2952,6 +2969,132 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType,
return ret; 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, static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@ -4314,6 +4457,12 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(X509_NAME_CONSTRAINTS): case LOWORD(X509_NAME_CONSTRAINTS):
encodeFunc = CRYPT_AsnEncodeNameConstraints; encodeFunc = CRYPT_AsnEncodeNameConstraints;
break; break;
case LOWORD(X509_POLICY_MAPPINGS):
encodeFunc = CRYPT_AsnEncodeCertPolicyMappings;
break;
case LOWORD(X509_POLICY_CONSTRAINTS):
encodeFunc = CRYPT_AsnEncodeCertPolicyConstraints;
break;
case LOWORD(PKCS7_SIGNER_INFO): case LOWORD(PKCS7_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodePKCSSignerInfo; encodeFunc = CRYPT_AsnEncodePKCSSignerInfo;
break; break;
@ -4330,6 +4479,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeUtcTime; encodeFunc = CRYPT_AsnEncodeUtcTime;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId; encodeFunc = CRYPT_AsnEncodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
encodeFunc = CRYPT_AsnEncodeCertPolicyMappings;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2)) else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId2; encodeFunc = CRYPT_AsnEncodeAuthorityKeyId2;
else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
@ -4356,6 +4507,10 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeCRLDistPoints; encodeFunc = CRYPT_AsnEncodeCRLDistPoints;
else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
encodeFunc = CRYPT_AsnEncodeCertPolicies; 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)) else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage; encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage;
else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
@ -4567,6 +4722,7 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDL
} }
else else
{ {
*pcbInfo = sizeNeeded;
pInfo->Algorithm.pszObjId = (char *)pInfo + pInfo->Algorithm.pszObjId = (char *)pInfo +
sizeof(CERT_PUBLIC_KEY_INFO); sizeof(CERT_PUBLIC_KEY_INFO);
lstrcpyA(pInfo->Algorithm.pszObjId, lstrcpyA(pInfo->Algorithm.pszObjId,

View file

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

View file

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

View file

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

View file

@ -283,20 +283,13 @@ end:
return ret; return ret;
} }
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, static BOOL CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName,
const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{ {
LPCWSTR fileName = pvObject;
HANDLE file; HANDLE file;
BOOL ret = FALSE; 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)); TRACE("%s\n", debugstr_w(fileName));
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL); OPEN_EXISTING, 0, NULL);
@ -322,6 +315,50 @@ static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
return ret; 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, static BOOL CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB *blob,
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg) DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
{ {
@ -562,11 +599,13 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
{ {
if (pdwFormatType) if (pdwFormatType)
*pdwFormatType = formatType; *pdwFormatType = formatType;
if (phMsg)
*phMsg = msg;
if (phCertStore) if (phCertStore)
*phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0, *phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0,
0, msg); 0, msg);
if (phMsg)
*phMsg = msg;
else
CryptMsgClose(msg);
} }
if (blob == &fileBlob) if (blob == &fileBlob)
CryptMemFree(blob->pbData); CryptMemFree(blob->pbData);

View file

@ -873,9 +873,18 @@ static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
{ {
DWORD len = CRYPT_GetMultiStringCharacterLen(multi); DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
/* Copy remainder of string "left" */ if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len)
memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1, {
(len - (spotToRemove - multi)) * sizeof(WCHAR)); /* 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; ret = TRUE;
} }
else else

View file

@ -261,9 +261,23 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
"chain creation failed"); "chain creation failed");
else else
{ {
/* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */ DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT |
if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE |
~CERT_TRUST_IS_UNTRUSTED_ROOT) 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), TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
trust_status_to_str(chain->TrustStatus.dwErrorStatus & trust_status_to_str(chain->TrustStatus.dwErrorStatus &
~CERT_TRUST_IS_UNTRUSTED_ROOT)); ~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); ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, store); check_and_store_certs(from, store);
} }
CertCloseStore(from, 0);
} }
static HCERTSTORE create_root_store(void) 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' }; 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)]; BYTE fileHeaderBuf[sizeof(fileHeader)];
DWORD read; DWORD read;
BOOL ret; BOOL ret;
/* Failure reading is non-critical, we'll leave the store empty */ /* 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 (ret)
{ {
if (!read) if (!read)
@ -448,7 +452,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
DWORD bufSize = 0; DWORD bufSize = 0;
do { do {
ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL); ret = read_func(handle, &propHdr, sizeof(propHdr), &read);
if (ret && read == sizeof(propHdr)) if (ret && read == sizeof(propHdr))
{ {
if (contextInterface && context && if (contextInterface && context &&
@ -470,7 +474,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
} }
if (buf) if (buf)
{ {
ret = ReadFile(file, buf, propHdr.cb, &read, NULL); ret = read_func(handle, buf, propHdr.cb, &read);
if (ret && read == propHdr.cb) if (ret && read == propHdr.cb)
{ {
if (propHdr.propID == CERT_CERT_PROP_ID) if (propHdr.propID == CERT_CERT_PROP_ID)
@ -495,8 +499,18 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
CERT_STORE_ADD_NEW, &context); CERT_STORE_ADD_NEW, &context);
} }
else 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 else
@ -519,6 +533,48 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
return ret; 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, static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement) 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) static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
{ {
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->certs, pCertContext); if (ContextList_Remove(ms->certs, pCertContext))
return TRUE; ret = CertFreeCertificateContext(pCertContext);
else
ret = TRUE;
return ret;
} }
static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl, 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) static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
{ {
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->crls, pCrlContext); if (ContextList_Remove(ms->crls, pCrlContext))
return TRUE; ret = CertFreeCRLContext(pCrlContext);
else
ret = TRUE;
return ret;
} }
static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl, 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) static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
{ {
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
BOOL ret;
ContextList_Delete(ms->ctls, pCtlContext); if (ContextList_Remove(ms->ctls, pCtlContext))
return TRUE; 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) 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.addContext = CRYPT_MemAddCtl;
store->hdr.ctls.enumContext = CRYPT_MemEnumCtl; store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl; store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
store->hdr.control = NULL; store->hdr.control = CRYPT_MemControl;
store->certs = ContextList_Create(pCertInterface, store->certs = ContextList_Create(pCertInterface,
sizeof(CERT_CONTEXT)); sizeof(CERT_CONTEXT));
store->crls = ContextList_Create(pCRLInterface, store->crls = ContextList_Create(pCRLInterface,
@ -966,10 +985,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
if (!pCertContext) if (!pCertContext)
ret = TRUE; ret = TRUE;
else if (!pCertContext->hCertStore) else if (!pCertContext->hCertStore)
{ ret = CertFreeCertificateContext(pCertContext);
ret = TRUE;
CertFreeCertificateContext(pCertContext);
}
else else
{ {
PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore; PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
@ -979,7 +995,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
else else
ret = hcs->certs.deleteContext(hcs, (void *)pCertContext); ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
if (ret) if (ret)
CertFreeCertificateContext(pCertContext); ret = CertFreeCertificateContext(pCertContext);
} }
return ret; return ret;
} }
@ -1105,10 +1121,7 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
if (!pCrlContext) if (!pCrlContext)
ret = TRUE; ret = TRUE;
else if (!pCrlContext->hCertStore) else if (!pCrlContext->hCertStore)
{ ret = CertFreeCRLContext(pCrlContext);
ret = TRUE;
CertFreeCRLContext(pCrlContext);
}
else else
{ {
PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore; PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
@ -1117,7 +1130,8 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
ret = FALSE; ret = FALSE;
else else
ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext); ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
CertFreeCRLContext(pCrlContext); if (ret)
ret = CertFreeCRLContext(pCrlContext);
} }
return ret; return ret;
} }
@ -1161,6 +1175,8 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC ) if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
return FALSE; return FALSE;
if (hcs->ref <= 0)
ERR("%p's ref count is %d\n", hcs, hcs->ref);
if (InterlockedDecrement(&hcs->ref) == 0) if (InterlockedDecrement(&hcs->ref) == 0)
{ {
TRACE("%p's ref count is 0, freeing\n", hcs); 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 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdarg.h> #include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winnls.h" #include "winnls.h"
@ -1017,11 +1020,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
{ {
if (!pszNameString) if (!pszNameString)
ret = strlenW(entry->pwszRfc822Name) + 1; ret = strlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString) else if (cchNameString)
{ {
ret = min(strlenW(entry->pwszRfc822Name), cchNameString - 1); ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1);
memcpy(pszNameString, entry->pwszRfc822Name, memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR)); ret * sizeof(WCHAR));
pszNameString[ret++] = 0; pszNameString[ret++] = 0;
} }
@ -1045,7 +1048,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
ret = CertNameToStrW(pCertContext->dwCertEncodingType, ret = CertNameToStrW(pCertContext->dwCertEncodingType,
&entry->DirectoryName, *(DWORD *)pvTypePara, pszNameString, &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString,
cchNameString); cchNameString);
if (info) if (info)
LocalFree(info); LocalFree(info);
@ -1062,7 +1065,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0,
&entry->DirectoryName, 0, pszNameString, cchNameString); &entry->u.DirectoryName, 0, pszNameString, cchNameString);
if (altInfo) if (altInfo)
LocalFree(altInfo); LocalFree(altInfo);
} }
@ -1102,12 +1105,12 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
{ {
if (!pszNameString) if (!pszNameString)
ret = strlenW(entry->pwszRfc822Name) + 1; ret = strlenW(entry->u.pwszRfc822Name) + 1;
else if (cchNameString) else if (cchNameString)
{ {
ret = min(strlenW(entry->pwszRfc822Name), ret = min(strlenW(entry->u.pwszRfc822Name),
cchNameString - 1); cchNameString - 1);
memcpy(pszNameString, entry->pwszRfc822Name, memcpy(pszNameString, entry->u.pwszRfc822Name,
ret * sizeof(WCHAR)); ret * sizeof(WCHAR));
pszNameString[ret++] = 0; pszNameString[ret++] = 0;
} }
@ -1139,11 +1142,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
{ {
if (!pszNameString) if (!pszNameString)
ret = strlenW(entry->pwszDNSName) + 1; ret = strlenW(entry->u.pwszDNSName) + 1;
else if (cchNameString) else if (cchNameString)
{ {
ret = min(strlenW(entry->pwszDNSName), cchNameString - 1); ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1);
memcpy(pszNameString, entry->pwszDNSName, ret * sizeof(WCHAR)); memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR));
pszNameString[ret++] = 0; pszNameString[ret++] = 0;
} }
} }
@ -1163,11 +1166,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
if (entry) if (entry)
{ {
if (!pszNameString) if (!pszNameString)
ret = strlenW(entry->pwszURL) + 1; ret = strlenW(entry->u.pwszURL) + 1;
else if (cchNameString) else if (cchNameString)
{ {
ret = min(strlenW(entry->pwszURL), cchNameString - 1); ret = min(strlenW(entry->u.pwszURL), cchNameString - 1);
memcpy(pszNameString, entry->pwszURL, ret * sizeof(WCHAR)); memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR));
pszNameString[ret++] = 0; pszNameString[ret++] = 0;
} }
} }

View file

@ -2750,6 +2750,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CRYPT_STRING_BASE64X509CRLHEADER 0x00000009 #define CRYPT_STRING_BASE64X509CRLHEADER 0x00000009
#define CRYPT_STRING_HEXADDR 0x0000000a #define CRYPT_STRING_HEXADDR 0x0000000a
#define CRYPT_STRING_HEXASCIIADDR 0x0000000b #define CRYPT_STRING_HEXASCIIADDR 0x0000000b
#define CRYPT_STRING_NOCRLF 0x40000000
#define CRYPT_STRING_NOCR 0x80000000 #define CRYPT_STRING_NOCR 0x80000000
/* OIDs */ /* OIDs */
@ -2946,6 +2947,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_POLICY_CONSTRAINTS "2.5.29.36" #define szOID_POLICY_CONSTRAINTS "2.5.29.36"
#define szOID_ENHANCED_KEY_USAGE "2.5.29.37" #define szOID_ENHANCED_KEY_USAGE "2.5.29.37"
#define szOID_FRESHEST_CRL "2.5.29.46" #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_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_FRIENDLY_NAME_ATTR "1.2.840.113549.1.9.20"
#define szOID_PKCS_12_LOCAL_KEY_ID "1.2.840.113549.1.9.21" #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 dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded,
DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext); 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, BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded,
DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext); DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext);
@ -4139,6 +4148,9 @@ BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext,
BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); 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, BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags,
PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage); PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage);
BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext,