Autosyncing with Wine HEAD

svn path=/trunk/; revision=26519
This commit is contained in:
The Wine Synchronizer 2007-04-26 13:37:57 +00:00
parent 68e79fb538
commit c6e78e42c8
22 changed files with 3172 additions and 863 deletions

View file

@ -222,7 +222,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
{
BinaryToStringAFunc encoder = NULL;
TRACE("(%p, %ld, %08lx, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
pcchString);
if (!pbBinary)
@ -251,7 +251,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff);
FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
/* fall through */
default:
SetLastError(ERROR_INVALID_PARAMETER);
@ -523,7 +523,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
StringToBinaryAFunc decoder;
LONG ret;
TRACE("(%s, %ld, %08lx, %p, %p, %p, %p)\n", debugstr_a(pszString),
TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_a(pszString),
cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
if (!pszString)
@ -564,7 +564,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff);
FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
/* fall through */
default:
SetLastError(ERROR_INVALID_PARAMETER);

View file

@ -19,6 +19,8 @@
#include <assert.h>
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
@ -54,7 +56,7 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
pbCertEncoded, cbCertEncoded);
BOOL ret;
TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType,
TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType,
pbCertEncoded, cbCertEncoded, dwAddDisposition, ppCertContext);
if (cert)
@ -76,7 +78,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
PCERT_INFO certInfo = NULL;
DWORD size = 0;
TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCertEncoded,
TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCertEncoded,
cbCertEncoded);
ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_TO_BE_SIGNED,
@ -141,7 +143,7 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
(void *)pCertContext, sizeof(CERT_CONTEXT));
DWORD ret;
TRACE("(%p, %ld)\n", pCertContext, dwPropId);
TRACE("(%p, %d)\n", pCertContext, dwPropId);
if (properties)
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
@ -174,7 +176,7 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
BOOL ret;
CRYPT_DATA_BLOB blob;
TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData);
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
if (properties)
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
@ -272,7 +274,7 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
{
BOOL ret;
TRACE("(%p, %ld, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData);
TRACE("(%p, %d, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData);
switch (dwPropId)
{
@ -362,17 +364,27 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
* - rgProvParam[0]...
*/
static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to,
PCRYPT_KEY_PROV_INFO from)
const CRYPT_KEY_PROV_INFO *from)
{
DWORD i;
LPBYTE nextData = (LPBYTE)to + sizeof(CRYPT_KEY_PROV_INFO);
to->pwszContainerName = (LPWSTR)nextData;
lstrcpyW(to->pwszContainerName, from->pwszContainerName);
nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
to->pwszProvName = (LPWSTR)nextData;
lstrcpyW(to->pwszProvName, from->pwszProvName);
nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
if (from->pwszContainerName)
{
to->pwszContainerName = (LPWSTR)nextData;
lstrcpyW(to->pwszContainerName, from->pwszContainerName);
nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
}
else
to->pwszContainerName = NULL;
if (from->pwszProvName)
{
to->pwszProvName = (LPWSTR)nextData;
lstrcpyW(to->pwszProvName, from->pwszProvName);
nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
}
else
to->pwszProvName = NULL;
to->dwProvType = from->dwProvType;
to->dwFlags = from->dwFlags;
to->cProvParam = from->cProvParam;
@ -391,14 +403,20 @@ static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to,
}
static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties,
PCRYPT_KEY_PROV_INFO info)
const CRYPT_KEY_PROV_INFO *info)
{
BOOL ret;
LPBYTE buf = NULL;
DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i, containerSize, provNameSize;
containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
if (info->pwszContainerName)
containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
else
containerSize = 0;
if (info->pwszProvName)
provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
else
provNameSize = 0;
size += containerSize + provNameSize;
for (i = 0; i < info->cProvParam; i++)
size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
@ -422,7 +440,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
Context_GetProperties(context, sizeof(CERT_CONTEXT));
BOOL ret;
TRACE("(%p, %ld, %08lx, %p)\n", context, dwPropId, dwFlags, pvData);
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
if (!properties)
ret = FALSE;
@ -450,7 +468,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
{
if (pvData)
{
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
ret = ContextPropertyList_SetProperty(properties, dwPropId,
blob->pbData, blob->cbData);
@ -465,7 +483,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
case CERT_DATE_STAMP_PROP_ID:
if (pvData)
ret = ContextPropertyList_SetProperty(properties, dwPropId,
(LPBYTE)pvData, sizeof(FILETIME));
(const BYTE *)pvData, sizeof(FILETIME));
else
{
ContextPropertyList_RemoveProperty(properties, dwPropId);
@ -476,7 +494,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
{
if (pvData)
{
PCERT_KEY_CONTEXT keyContext = (PCERT_KEY_CONTEXT)pvData;
const CERT_KEY_CONTEXT *keyContext = (const CERT_KEY_CONTEXT *)pvData;
ret = ContextPropertyList_SetProperty(properties, dwPropId,
(const BYTE *)keyContext, keyContext->cbSize);
@ -491,7 +509,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
case CERT_KEY_PROV_INFO_PROP_ID:
if (pvData)
ret = CertContext_SetKeyProvInfoProperty(properties,
(PCRYPT_KEY_PROV_INFO)pvData);
(const CRYPT_KEY_PROV_INFO *)pvData);
else
{
ContextPropertyList_RemoveProperty(properties, dwPropId);
@ -510,7 +528,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
if (!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
CryptReleaseContext(keyContext.hCryptProv, 0);
if (pvData)
keyContext.hCryptProv = *(HCRYPTPROV *)pvData;
keyContext.hCryptProv = *(const HCRYPTPROV *)pvData;
else
keyContext.hCryptProv = 0;
ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
@ -519,7 +537,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
break;
}
default:
FIXME("%ld: stub\n", dwPropId);
FIXME("%d: stub\n", dwPropId);
ret = FALSE;
}
}
@ -532,7 +550,7 @@ BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
{
BOOL ret;
TRACE("(%p, %ld, %08lx, %p)\n", pCertContext, dwPropId, dwFlags, pvData);
TRACE("(%p, %d, %08x, %p)\n", pCertContext, dwPropId, dwFlags, pvData);
/* Handle special cases for "read-only"/invalid prop IDs. Windows just
* crashes on most of these, I'll be safer.
@ -613,7 +631,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
CERT_KEY_CONTEXT keyContext;
DWORD size;
TRACE("(%p, %08lx, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved,
TRACE("(%p, %08x, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved,
phCryptProv, pdwKeySpec, pfCallerFreeProv);
if (dwFlags & CRYPT_ACQUIRE_USE_PROV_INFO_FLAG)
@ -682,7 +700,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType,
PCERT_INFO pCertId1, PCERT_INFO pCertId2)
{
TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2);
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2);
return CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer,
&pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber,
@ -694,7 +712,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType,
{
BOOL ret;
TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2);
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2);
if (pCertName1->cbData == pCertName2->cbData)
{
@ -713,7 +731,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType,
* insignificant if it's a leading 0 for positive numbers or a leading 0xff
* for negative numbers. pInt is assumed to be little-endian.
*/
static DWORD CRYPT_significantBytes(PCRYPT_INTEGER_BLOB pInt)
static DWORD CRYPT_significantBytes(const CRYPT_INTEGER_BLOB *pInt)
{
DWORD ret = pInt->cbData;
@ -756,7 +774,7 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
{
BOOL ret;
TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
@ -772,6 +790,45 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
return ret;
}
DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
PCERT_PUBLIC_KEY_INFO pPublicKey)
{
DWORD len = 0;
TRACE("(%08x, %p)\n", dwCertEncodingType, pPublicKey);
if (dwCertEncodingType != X509_ASN_ENCODING)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
}
if (pPublicKey->Algorithm.pszObjId &&
!strcmp(pPublicKey->Algorithm.pszObjId, szOID_RSA_DH))
{
FIXME("unimplemented for DH public keys\n");
SetLastError(CRYPT_E_ASN1_BADTAG);
}
else
{
DWORD size;
PBYTE buf;
BOOL ret = CryptDecodeObjectEx(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
&size);
if (ret)
{
RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)((LPBYTE)buf +
sizeof(BLOBHEADER));
len = rsaPubKey->bitlen;
LocalFree(buf);
}
}
return len;
}
typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara);
@ -861,7 +918,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT ret;
CertCompareFunc compare;
TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType,
TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType,
dwFlags, dwType, pvPara, pPrevCertContext);
switch (dwType >> CERT_COMPARE_SHIFT)
@ -885,7 +942,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
compare = compare_cert_by_issuer;
break;
default:
FIXME("find type %08lx unimplemented\n", dwType);
FIXME("find type %08x unimplemented\n", dwType);
compare = NULL;
}
@ -913,7 +970,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, PCERT_INFO pCertId)
{
TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId);
TRACE("(%p, %08x, %p)\n", hCertStore, dwCertEncodingType, pCertId);
if (!pCertId)
{
@ -972,7 +1029,7 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
{
PCCERT_CONTEXT ret;
TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext,
TRACE("(%p, %p, %p, %08x)\n", hCertStore, pSubjectContext,
pPrevIssuerContext, *pdwFlags);
if (!pSubjectContext)
@ -1003,7 +1060,7 @@ PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr,
PCRYPT_ATTRIBUTE ret = NULL;
DWORD i;
TRACE("%s %ld %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
TRACE("%s %d %p\n", debugstr_a(pszObjId), cAttr, rgAttr);
if (!cAttr)
return NULL;
@ -1025,7 +1082,7 @@ PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions,
PCERT_EXTENSION ret = NULL;
DWORD i;
TRACE("%s %ld %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
TRACE("%s %d %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions);
if (!cExtensions)
return NULL;
@ -1086,6 +1143,15 @@ LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify,
return ret;
}
BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo,
PCERT_INFO pIssuerInfo)
{
TRACE("(%p, %p)\n", pSubjectInfo, pIssuerInfo);
return CertVerifyTimeValidity(&pSubjectInfo->NotBefore, pIssuerInfo) == 0
&& CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0;
}
BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
DWORD *pcbComputedHash)
@ -1093,7 +1159,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
BOOL ret = TRUE;
HCRYPTHASH hHash = 0;
TRACE("(%ld, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags,
TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags,
pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
@ -1115,39 +1181,160 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
return ret;
}
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid,
DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
BOOL ret = TRUE;
HCRYPTHASH hHash = 0;
TRACE("(%08lx, %d, %08x, %d, %p, %p, %p)\n", hCryptProv, Algid, dwFlags,
dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_MD5;
if (ret)
{
BYTE *buf;
DWORD size = 0;
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO,
pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
if (ret)
{
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, buf, size, 0);
if (ret)
ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
pcbComputedHash, 0);
CryptDestroyHash(hHash);
}
LocalFree(buf);
}
}
return ret;
}
BOOL WINAPI CryptSignCertificate(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
{
BOOL ret;
ALG_ID algID;
PCCRYPT_OID_INFO info;
HCRYPTHASH hHash;
TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %p, %p, %p)\n", hCryptProv,
TRACE("(%08lx, %d, %d, %p, %d, %p, %p, %p, %p)\n", hCryptProv,
dwKeySpec, dwCertEncodingType, pbEncodedToBeSigned, cbEncodedToBeSigned,
pSignatureAlgorithm, pvHashAuxInfo, pbSignature, pcbSignature);
algID = CertOIDToAlgId(pSignatureAlgorithm->pszObjId);
if (!algID)
info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pSignatureAlgorithm->pszObjId, 0);
if (!info)
{
SetLastError(NTE_BAD_ALGID);
return FALSE;
}
if (!hCryptProv)
if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, pbEncodedToBeSigned,
cbEncodedToBeSigned, 0);
if (ret)
ret = CryptGetHashParam(hHash, HP_HASHVAL, pbSignature,
pcbSignature, 0);
CryptDestroyHash(hHash);
}
}
else
{
if (!hCryptProv)
{
SetLastError(ERROR_INVALID_PARAMETER);
ret = FALSE;
}
else
{
ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, pbEncodedToBeSigned,
cbEncodedToBeSigned, 0);
if (ret)
ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature,
pcbSignature);
CryptDestroyHash(hHash);
}
}
}
return ret;
}
ret = CryptCreateHash(hCryptProv, algID, 0, 0, &hHash);
BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV hCryptProv,
DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType,
const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
const void *pvHashAuxInfo, PBYTE pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
DWORD encodedSize, hashSize;
TRACE("(%08lx, %d, %d, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec,
dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo,
pSignatureAlgorithm, pvHashAuxInfo, pbEncoded, pcbEncoded);
ret = CryptEncodeObject(dwCertEncodingType, lpszStructType, pvStructInfo,
NULL, &encodedSize);
if (ret)
{
ret = CryptHashData(hHash, pbEncodedToBeSigned, cbEncodedToBeSigned, 0);
if (ret)
ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature,
pcbSignature);
CryptDestroyHash(hHash);
PBYTE encoded = CryptMemAlloc(encodedSize);
if (encoded)
{
ret = CryptEncodeObject(dwCertEncodingType, lpszStructType,
pvStructInfo, encoded, &encodedSize);
if (ret)
{
ret = CryptSignCertificate(hCryptProv, dwKeySpec,
dwCertEncodingType, encoded, encodedSize, pSignatureAlgorithm,
pvHashAuxInfo, NULL, &hashSize);
if (ret)
{
PBYTE hash = CryptMemAlloc(hashSize);
if (hash)
{
ret = CryptSignCertificate(hCryptProv, dwKeySpec,
dwCertEncodingType, encoded, encodedSize,
pSignatureAlgorithm, pvHashAuxInfo, hash, &hashSize);
if (ret)
{
CERT_SIGNED_CONTENT_INFO info = { { 0 } };
info.ToBeSigned.cbData = encodedSize;
info.ToBeSigned.pbData = encoded;
memcpy(&info.SignatureAlgorithm,
pSignatureAlgorithm,
sizeof(info.SignatureAlgorithm));
info.Signature.cbData = hashSize;
info.Signature.pbData = hash;
info.Signature.cUnusedBits = 0;
ret = CryptEncodeObject(dwCertEncodingType,
X509_CERT, &info, pbEncoded, pcbEncoded);
}
CryptMemFree(hash);
}
}
}
CryptMemFree(encoded);
}
}
return ret;
}
@ -1163,25 +1350,56 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV hCryptProv,
static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV hCryptProv,
DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
PCERT_SIGNED_CONTENT_INFO signedCert)
const CERT_SIGNED_CONTENT_INFO *signedCert)
{
BOOL ret;
ALG_ID algID = CertOIDToAlgId(pubKeyInfo->Algorithm.pszObjId);
HCRYPTKEY key;
PCCRYPT_OID_INFO info;
ALG_ID pubKeyID, hashID;
info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pubKeyInfo->Algorithm.pszObjId, 0);
if (!info || (info->dwGroupId != CRYPT_PUBKEY_ALG_OID_GROUP_ID &&
info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID))
{
SetLastError(NTE_BAD_ALGID);
return FALSE;
}
if (info->dwGroupId == CRYPT_PUBKEY_ALG_OID_GROUP_ID)
{
switch (info->u.Algid)
{
case CALG_RSA_KEYX:
pubKeyID = CALG_RSA_SIGN;
hashID = CALG_SHA1;
break;
case CALG_RSA_SIGN:
pubKeyID = CALG_RSA_SIGN;
hashID = CALG_SHA1;
break;
default:
FIXME("unimplemented for %s\n", pubKeyInfo->Algorithm.pszObjId);
return FALSE;
}
}
else
{
hashID = info->u.Algid;
if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
else
pubKeyID = hashID;
}
/* Load the default provider if necessary */
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
pubKeyInfo, algID, 0, NULL, &key);
pubKeyInfo, pubKeyID, 0, NULL, &key);
if (ret)
{
HCRYPTHASH hash;
/* Some key algorithms aren't hash algorithms, so map them */
if (algID == CALG_RSA_SIGN || algID == CALG_RSA_KEYX)
algID = CALG_SHA1;
ret = CryptCreateHash(hCryptProv, algID, 0, 0, &hash);
ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash);
if (ret)
{
ret = CryptHashData(hash, signedCert->ToBeSigned.pbData,
@ -1203,7 +1421,7 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv,
BOOL ret = TRUE;
CRYPT_DATA_BLOB subjectBlob;
TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %08lx, %p)\n", hCryptProv,
TRACE("(%08lx, %d, %d, %p, %d, %p, %08x, %p)\n", hCryptProv,
dwCertEncodingType, dwSubjectType, pvSubject, dwIssuerType, pvIssuer,
dwFlags, pvReserved);
@ -1302,7 +1520,7 @@ BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags,
return FALSE;
}
TRACE("(%p, %08lx, %p, %ld)\n", pCertContext, dwFlags, pUsage, *pcbUsage);
TRACE("(%p, %08x, %p, %d)\n", pCertContext, dwFlags, pUsage, *pcbUsage);
if (!(dwFlags & CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG))
{
@ -1556,7 +1774,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
BOOL allUsagesValid = TRUE;
CERT_ENHKEY_USAGE validUsages = { 0, NULL };
TRACE("(%ld, %p, %p, %p, %ld)\n", cCerts, *rghCerts, cNumOIDSs,
TRACE("(%d, %p, %p, %p, %d)\n", cCerts, *rghCerts, cNumOIDSs,
rghOIDs, *pcbOIDs);
for (i = 0; ret && i < cCerts; i++)
@ -1693,7 +1911,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
* pInfo is NULL, from the attributes of hProv.
*/
static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
PCRYPT_KEY_PROV_INFO pInfo, HCRYPTPROV hProv)
const CRYPT_KEY_PROV_INFO *pInfo, HCRYPTPROV hProv)
{
CRYPT_KEY_PROV_INFO info = { 0 };
BOOL ret;
@ -1777,7 +1995,7 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
/* Creates a signed certificate context from the unsigned, encoded certificate
* in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
*/
static PCCERT_CONTEXT CRYPT_CreateSignedCert(PCRYPT_DER_BLOB blob,
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob,
HCRYPTPROV hProv, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
{
PCCERT_CONTEXT context = NULL;
@ -1832,11 +2050,11 @@ static PCCERT_CONTEXT CRYPT_CreateSignedCert(PCRYPT_DER_BLOB blob,
* pubKey: The public key of the certificate. Must not be NULL.
* pExtensions: Extensions to be included with the certificate. Optional.
*/
static void CRYPT_MakeCertInfo(PCERT_INFO info, PCRYPT_DATA_BLOB pSerialNumber,
PCERT_NAME_BLOB pSubjectIssuerBlob,
PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime,
PSYSTEMTIME pEndTime, PCERT_PUBLIC_KEY_INFO pubKey,
PCERT_EXTENSIONS pExtensions)
static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNumber,
const CERT_NAME_BLOB *pSubjectIssuerBlob,
const CRYPT_ALGORITHM_IDENTIFIER *pSignatureAlgorithm, const SYSTEMTIME *pStartTime,
const SYSTEMTIME *pEndTime, const CERT_PUBLIC_KEY_INFO *pubKey,
const CERT_EXTENSIONS *pExtensions)
{
static CHAR oid[] = szOID_RSA_SHA1RSA;
@ -1952,7 +2170,7 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
PCERT_PUBLIC_KEY_INFO pubKey = NULL;
DWORD pubKeySize = 0;
TRACE("(0x%08lx, %p, %08lx, %p, %p, %p, %p, %p)\n", hProv,
TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
pExtensions, pExtensions);

View file

@ -0,0 +1,172 @@
/*
* Copyright 2006 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
/* This represents a subset of a certificate chain engine: it doesn't include
* the "hOther" store described by MSDN, because I'm not sure how that's used.
* It also doesn't include the "hTrust" store, because I don't yet implement
* CTLs or complex certificate chains.
*/
typedef struct _CertificateChainEngine
{
LONG ref;
HCERTSTORE hRoot;
HCERTSTORE hWorld;
DWORD dwFlags;
DWORD dwUrlRetrievalTimeout;
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
} CertificateChainEngine, *PCertificateChainEngine;
static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection,
DWORD cStores, HCERTSTORE *stores)
{
DWORD i;
for (i = 0; i < cStores; i++)
CertAddStoreToCollection(collection, stores[i], 0, 0);
}
static inline void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores)
{
DWORD i;
for (i = 0; i < cStores; i++)
CertCloseStore(stores[i], 0);
}
static const WCHAR rootW[] = { 'R','o','o','t',0 };
static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store)
{
BOOL ret = TRUE;
if (store)
{
HCERTSTORE rootStore = CertOpenSystemStoreW(0, rootW);
PCCERT_CONTEXT cert = NULL, check;
BYTE hash[20];
DWORD size;
do {
cert = CertEnumCertificatesInStore(store, cert);
if (cert)
{
size = sizeof(hash);
ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID,
hash, &size);
if (ret)
{
CRYPT_HASH_BLOB blob = { sizeof(hash), hash };
check = CertFindCertificateInStore(rootStore,
cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
NULL);
if (!check)
ret = FALSE;
else
CertFreeCertificateContext(check);
}
}
} while (ret && cert);
if (cert)
CertFreeCertificateContext(cert);
CertCloseStore(rootStore, 0);
}
return ret;
}
BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig,
HCERTCHAINENGINE *phChainEngine)
{
static const WCHAR caW[] = { 'C','A',0 };
static const WCHAR myW[] = { 'M','y',0 };
static const WCHAR trustW[] = { 'T','r','u','s','t',0 };
BOOL ret;
TRACE("(%p, %p)\n", pConfig, phChainEngine);
if (pConfig->cbSize != sizeof(*pConfig))
{
SetLastError(E_INVALIDARG);
return FALSE;
}
*phChainEngine = NULL;
ret = CRYPT_CheckRestrictedRoot(pConfig->hRestrictedRoot);
if (ret)
{
PCertificateChainEngine engine =
CryptMemAlloc(sizeof(CertificateChainEngine));
if (engine)
{
HCERTSTORE worldStores[4];
engine->ref = 1;
if (pConfig->hRestrictedRoot)
engine->hRoot = CertDuplicateStore(pConfig->hRestrictedRoot);
else
engine->hRoot = CertOpenSystemStoreW(0, rootW);
engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
worldStores[0] = CertDuplicateStore(engine->hRoot);
worldStores[1] = CertOpenSystemStoreW(0, caW);
worldStores[2] = CertOpenSystemStoreW(0, myW);
worldStores[3] = CertOpenSystemStoreW(0, trustW);
CRYPT_AddStoresToCollection(engine->hWorld,
sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
CRYPT_AddStoresToCollection(engine->hWorld,
pConfig->cAdditionalStore, pConfig->rghAdditionalStore);
CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]),
worldStores);
engine->dwFlags = pConfig->dwFlags;
engine->dwUrlRetrievalTimeout = pConfig->dwUrlRetrievalTimeout;
engine->MaximumCachedCertificates =
pConfig->MaximumCachedCertificates;
engine->CycleDetectionModulus = pConfig->CycleDetectionModulus;
*phChainEngine = (HCERTCHAINENGINE)engine;
ret = TRUE;
}
else
ret = FALSE;
}
return ret;
}
void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
{
PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine;
TRACE("(%p)\n", hChainEngine);
if (engine && InterlockedDecrement(&engine->ref) == 0)
{
CertCloseStore(engine->hWorld, 0);
CertCloseStore(engine->hRoot, 0);
CryptMemFree(engine);
}
}

View file

@ -94,7 +94,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned
linkContext->linked = linkedBase;
if (addRef)
InterlockedIncrement(&linkedBase->ref);
TRACE("%p's ref count is %ld\n", context, linkContext->ref);
TRACE("%p's ref count is %d\n", context, linkContext->ref);
}
return context;
}
@ -161,7 +161,7 @@ void Context_Release(void *context, size_t contextSize,
CryptMemFree(context);
}
else
TRACE("%p's ref count is %ld\n", context, base->ref);
TRACE("%p's ref count is %d\n", context, base->ref);
}
void Context_CopyProperties(const void *to, const void *from,
@ -192,6 +192,7 @@ struct ContextList *ContextList_Create(
list->contextInterface = contextInterface;
list->contextSize = contextSize;
InitializeCriticalSection(&list->cs);
list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
list_init(&list->contexts);
}
return list;
@ -303,6 +304,7 @@ void ContextList_Empty(struct ContextList *list)
void ContextList_Free(struct ContextList *list)
{
ContextList_Empty(list);
list->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&list->cs);
CryptMemFree(list);
}

View file

@ -35,7 +35,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
PCRL_INFO crlInfo = NULL;
DWORD size = 0;
TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCrlEncoded,
TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded,
cbCrlEncoded);
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
@ -80,7 +80,7 @@ BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
pbCrlEncoded, cbCrlEncoded);
BOOL ret;
TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType,
TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType,
pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext);
if (crl)
@ -144,7 +144,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore,
PCCRL_CONTEXT ret;
CrlCompareFunc compare;
TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType,
TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType,
dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext);
switch (dwFindType)
@ -159,7 +159,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore,
compare = compare_crl_existing;
break;
default:
FIXME("find type %08lx unimplemented\n", dwFindType);
FIXME("find type %08x unimplemented\n", dwFindType);
compare = NULL;
}
@ -192,7 +192,7 @@ PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore,
CERT_STORE_DELTA_CRL_FLAG;
PCCRL_CONTEXT ret;
TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pIssuerContext, pPrevCrlContext,
TRACE("(%p, %p, %p, %08x)\n", hCertStore, pIssuerContext, pPrevCrlContext,
*pdwFlags);
if (*pdwFlags & ~supportedFlags)
@ -257,7 +257,7 @@ DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
(void *)pCRLContext, sizeof(CRL_CONTEXT));
DWORD ret;
TRACE("(%p, %ld)\n", pCRLContext, dwPropId);
TRACE("(%p, %d)\n", pCRLContext, dwPropId);
if (properties)
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
@ -293,7 +293,7 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
BOOL ret;
CRYPT_DATA_BLOB blob;
TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData);
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
if (properties)
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
@ -346,7 +346,7 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
{
BOOL ret;
TRACE("(%p, %ld, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData);
TRACE("(%p, %d, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData);
switch (dwPropId)
{
@ -390,7 +390,7 @@ static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
Context_GetProperties(context, sizeof(CERT_CONTEXT));
BOOL ret;
TRACE("(%p, %ld, %08lx, %p)\n", context, dwPropId, dwFlags, pvData);
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
if (!properties)
ret = FALSE;
@ -429,10 +429,10 @@ static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
}
case CERT_DATE_STAMP_PROP_ID:
ret = ContextPropertyList_SetProperty(properties, dwPropId,
(LPBYTE)pvData, sizeof(FILETIME));
(const BYTE *)pvData, sizeof(FILETIME));
break;
default:
FIXME("%ld: stub\n", dwPropId);
FIXME("%d: stub\n", dwPropId);
ret = FALSE;
}
}
@ -445,7 +445,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
{
BOOL ret;
TRACE("(%p, %ld, %08lx, %p)\n", pCRLContext, dwPropId, dwFlags, pvData);
TRACE("(%p, %d, %08x, %p)\n", pCRLContext, dwPropId, dwFlags, pvData);
/* Handle special cases for "read-only"/invalid prop IDs. Windows just
* crashes on most of these, I'll be safer.
@ -469,11 +469,11 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert,
PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved)
{
TRACE("(%p, %p, %08lx, %p)\n", pCert, pCrl, dwFlags, pvReserved);
TRACE("(%p, %p, %08x, %p)\n", pCert, pCrl, dwFlags, pvReserved);
return TRUE;
}
static PCRL_ENTRY CRYPT_FindCertificateInCRL(PCERT_INFO cert, PCRL_INFO crl)
static PCRL_ENTRY CRYPT_FindCertificateInCRL(PCERT_INFO cert, const CRL_INFO *crl)
{
DWORD i;
PCRL_ENTRY entry = NULL;
@ -489,7 +489,7 @@ BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert,
PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved,
PCRL_ENTRY *ppCrlEntry)
{
TRACE("(%p, %p, %08lx, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved,
TRACE("(%p, %p, %08x, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved,
ppCrlEntry);
*ppCrlEntry = CRYPT_FindCertificateInCRL(pCert->pCertInfo,
@ -503,7 +503,7 @@ BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType,
DWORD i;
PCRL_ENTRY entry = NULL;
TRACE("(%08lx, %p, %ld, %p)\n", dwCertEncodingType, pCertId, cCrlInfo,
TRACE("(%08x, %p, %d, %p)\n", dwCertEncodingType, pCertId, cCrlInfo,
rgpCrlInfo);
for (i = 0; !entry && i < cCrlInfo; i++)

View file

@ -15,6 +15,7 @@
<library>ntdll</library>
<file>base64.c</file>
<file>cert.c</file>
<file>chain.c</file>
<file>crl.c</file>
<file>context.c</file>
<file>decode.c</file>
@ -23,6 +24,7 @@
<file>proplist.c</file>
<file>protectdata.c</file>
<file>serialize.c</file>
<file>sip.c</file>
<file>store.c</file>
<file>str.c</file>
<file>main.c</file>

View file

@ -32,5 +32,6 @@
#include "crypt32_De.rc"
#include "crypt32_En.rc"
#include "crypt32_Fr.rc"
#include "crypt32_Ko.rc"
#include "crypt32_No.rc"

View file

@ -18,7 +18,7 @@
@ stdcall CertControlStore(long long long ptr)
@ stdcall CertCreateCRLContext(long ptr long)
@ stdcall CertCreateCTLContext(long ptr long)
@ stub CertCreateCertificateChainEngine
@ stdcall CertCreateCertificateChainEngine(ptr ptr)
@ stdcall CertCreateCertificateContext(long ptr long)
@ stdcall CertCreateSelfSignCertificate(long ptr long ptr ptr ptr ptr ptr)
@ stdcall CertDeleteCRLFromStore(ptr)
@ -45,7 +45,7 @@
@ stdcall CertFreeCRLContext(ptr)
@ stdcall CertFreeCTLContext(ptr)
@ stub CertFreeCertificateChain
@ stub CertFreeCertificateChainEngine
@ stdcall CertFreeCertificateChainEngine(ptr)
@ stdcall CertFreeCertificateContext(ptr)
@ stdcall CertGetCRLContextProperty(ptr long ptr ptr)
@ stdcall CertGetCRLFromStore(ptr ptr ptr ptr)
@ -57,7 +57,7 @@
@ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr)
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
@ stub CertGetPublicKeyLength
@ stdcall CertGetPublicKeyLength(long ptr)
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
@ stub CertIsRDNAttrsInCertificateName
@ -80,21 +80,21 @@
@ stdcall CertSetCTLContextProperty(ptr long long ptr)
@ stdcall CertSetCertificateContextProperty(ptr long long ptr)
@ stdcall CertSetEnhancedKeyUsage(ptr ptr)
@ stub CertStrToNameA
@ stub CertStrToNameW
@ stdcall CertStrToNameA(long str long ptr ptr ptr ptr)
@ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr)
@ stdcall CertVerifyCRLRevocation(long ptr long ptr)
@ stdcall CertVerifyCRLTimeValidity(ptr ptr)
@ stub CertVerifyCTLUsage
@ stub CertVerifyRevocation
@ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr)
@ stdcall CertVerifyTimeValidity(ptr ptr)
@ stub CertVerifyValidityNesting
@ 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 CryptStringToBinaryA(str long long ptr ptr ptr ptr)
@ stub CryptStringToBinaryW # (wstr long long ptr ptr ptr ptr)
@ stub CryptAcquireContextU
@ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW
@ stdcall CryptAcquireCertificatePrivateKey(ptr long ptr ptr ptr ptr)
@ stub CryptCloseAsyncHandle
@ stub CryptCreateAsyncHandle
@ -113,7 +113,7 @@
@ stdcall CryptExportPublicKeyInfo(long long long ptr ptr)
@ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr)
@ stdcall CryptFindOIDInfo(long ptr long)
@ stub CryptFormatObject
@ stdcall CryptFormatObject(long long long ptr str ptr long ptr ptr)
@ stdcall CryptFreeOIDFunctionAddress(long long)
@ stub CryptGetAsyncParam
@ stdcall CryptGetDefaultOIDDllList(long long ptr ptr)
@ -124,7 +124,7 @@
@ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr)
@ stdcall CryptHashCertificate(long long long ptr long ptr ptr)
@ stub CryptHashMessage
@ stub CryptHashPublicKeyInfo
@ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr)
@ stub CryptHashToBeSigned
@ stub CryptImportPKCS8
@ stdcall CryptImportPublicKeyInfo(long long ptr ptr)
@ -154,13 +154,18 @@
@ stdcall CryptRegisterOIDFunction(long str str wstr str)
@ stub CryptRegisterOIDInfo
@ stdcall CryptSIPAddProvider(ptr)
@ stdcall CryptSIPCreateIndirectData(ptr ptr ptr)
@ stdcall CryptSIPGetSignedDataMsg(ptr ptr long ptr ptr)
@ stdcall CryptSIPLoad(ptr long ptr)
@ stdcall CryptSIPPutSignedDataMsg(ptr long ptr long ptr)
@ stdcall CryptSIPRemoveProvider(ptr)
@ stdcall CryptSIPRemoveSignedDataMsg(ptr long)
@ stdcall CryptSIPRetrieveSubjectGuid(wstr long ptr)
@ stdcall CryptSIPVerifyIndirectData(ptr ptr)
@ stub CryptSetAsyncParam
@ stdcall CryptSetOIDFunctionValue(long str str wstr long ptr long)
@ stub CryptSetProviderU
@ stub CryptSignAndEncodeCertificate
@ stdcall CryptSignAndEncodeCertificate(long long long str ptr ptr ptr ptr ptr)
@ stub CryptSignAndEncryptMessage
@ stdcall CryptSignCertificate(long long long ptr long ptr ptr ptr ptr)
@ stub CryptSignHashU
@ -186,15 +191,17 @@
@ stdcall I_CryptFlushLruCache(ptr long long)
@ stdcall I_CryptFreeLruCache(ptr long long)
@ stdcall I_CryptFreeTls(long long)
@ stub I_CryptGetDefaultCryptProv
@ stdcall I_CryptGetDefaultCryptProv(long)
@ stub I_CryptGetDefaultCryptProvForEncrypt
@ stdcall I_CryptGetOssGlobal(long)
@ stdcall I_CryptGetTls(long)
@ stub I_CryptInsertLruEntry
@ stdcall I_CryptInstallAsn1Module(long long long)
@ stdcall I_CryptInstallOssGlobal(long long long)
@ stdcall I_CryptReadTrustedPublisherDWORDValueFromRegistry(wstr ptr)
@ stub I_CryptReleaseLruEntry
@ stdcall I_CryptSetTls(long ptr)
@ stdcall I_CryptUninstallAsn1Module(ptr)
@ stub I_CryptUninstallOssGlobal
@ stub PFXExportCertStore
@ stub PFXImportCertStore

View file

@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View file

@ -0,0 +1,166 @@
/*
* crypt32 dll French resources
*
* Copyright 2006 Jonathan Ernst
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
IDS_AUTHORITY_KEY_ID "Authority Key Identifier"
IDS_KEY_ATTRIBUTES "Key Attributes"
IDS_KEY_USAGE_RESTRICTION "Key Usage Restriction"
IDS_SUBJECT_ALT_NAME "Subject Alternative Name"
IDS_ISSUER_ALT_NAME "Issuer Alternative Name"
IDS_BASIC_CONSTRAINTS "Basic Constraints"
IDS_KEY_USAGE "Key Usage"
IDS_CERT_POLICIES "Certificate Policies"
IDS_SUBJECT_KEY_IDENTIFIER "Subject Key Identifier"
IDS_CRL_REASON_CODE "CRL Reason Code"
IDS_CRL_DIST_POINTS "CRL Distribution Points"
IDS_ENHANCED_KEY_USAGE "Enhanced Key Usage"
IDS_AUTHORITY_INFO_ACCESS "Authority Information Access"
IDS_CERT_EXTENSIONS "Certificate Extensions"
IDS_NEXT_UPDATE_LOCATION "Next Update Location"
IDS_YES_OR_NO_TRUST "Yes or No Trust"
IDS_EMAIL_ADDRESS "Email Address"
IDS_UNSTRUCTURED_NAME "Unstructured Name"
IDS_CONTENT_TYPE "Content Type"
IDS_MESSAGE_DIGEST "Message Digest"
IDS_SIGNING_TIME "Signing Time"
IDS_COUNTER_SIGN "Counter Sign"
IDS_CHALLENGE_PASSWORD "Challenge Password"
IDS_UNSTRUCTURED_ADDRESS "Unstructured Address"
IDS_SMIME_CAPABILITIES "SMIME Capabilities"
IDS_PREFER_SIGNED_DATA "Prefer Signed Data"
IDS_CPS "CPS"
IDS_USER_NOTICE "User Notice"
IDS_OCSP "On-line Certificate Status Protocol"
IDS_CA_ISSUER "Certification Authority Issuer"
IDS_CERT_TEMPLATE_NAME "Certification Template Name"
IDS_CERT_TYPE "Certificate Type"
IDS_CERT_MANIFOLD "Certificate Manifold"
IDS_NETSCAPE_CERT_TYPE "Type de certificat Netscape"
IDS_NETSCAPE_BASE_URL "URL Netscape de base"
IDS_NETSCAPE_REVOCATION_URL "URL Netscape de révocation"
IDS_NETSCAPE_CA_REVOCATION_URL "URL Netscape de révocation du certificat"
IDS_NETSCAPE_CERT_RENEWAL_URL "URL Netscape de renouvellement du certificat"
IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Policy URL"
IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL ServerName"
IDS_NETSCAPE_COMMENT "Commentaire Netscape"
IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
IDS_COUNTRY "Pays/Région"
IDS_ORGANIZATION "Organisation"
IDS_ORGANIZATIONAL_UNIT "Unité d'organisation"
IDS_COMMON_NAME "Nom commun"
IDS_LOCALITY "Locality"
IDS_STATE_OR_PROVINCE "État ou province"
IDS_TITLE "Titre"
IDS_GIVEN_NAME "Nom donné"
IDS_INITIALS "Initiales"
IDS_SUR_NAME "Nom de famille"
IDS_DOMAIN_COMPONENT "Domain Component"
IDS_STREET_ADDRESS "Adresse"
IDS_SERIAL_NUMBER "Numéro de série"
IDS_CA_VERSION "Version du CA"
IDS_CROSS_CA_VERSION "Cross CA Version"
IDS_SERIALIZED_SIG_SERIAL_NUMBER "Serialized Signature Serial Number"
IDS_PRINCIPAL_NAME "Nom principal"
IDS_WINDOWS_PRODUCT_UPDATE "Mise à jour de Windows"
IDS_ENROLLMENT_NAME_VALUE_PAIR "Enrollment Name Value Pair"
IDS_OS_VERSION "Version du système d'exploitation"
IDS_ENROLLMENT_CSP "Enrollment CSP"
IDS_CRL_NUMBER "CRL Number"
IDS_DELTA_CRL_INDICATOR "Delta CRL Indicator"
IDS_ISSUING_DIST_POINT "Issuing Distribution Point"
IDS_FRESHEST_CRL "Freshest CRL"
IDS_NAME_CONSTRAINTS "Contraintes de nom"
IDS_POLICY_MAPPINGS "Policy Mappings"
IDS_POLICY_CONSTRAINTS "Policy Constraints"
IDS_CROSS_CERT_DIST_POINTS "Cross-Certificate Distribution Points"
IDS_APPLICATION_POLICIES "Application Policies"
IDS_APPLICATION_POLICY_MAPPINGS "Application Policy Mappings"
IDS_APPLICATION_POLICY_CONSTRAINTS "Application Policy Constraints"
IDS_CMC_DATA "CMC Data"
IDS_CMC_RESPONSE "CMC Response"
IDS_UNSIGNED_CMC_REQUEST "Unsigned CMC Request"
IDS_CMC_STATUS_INFO "CMC Status Info"
IDS_CMC_EXTENSIONS "CMC Extensions"
IDS_CMC_ATTRIBUTES "CMC Attributes"
IDS_PKCS_7_DATA "Données PKCS 7"
IDS_PKCS_7_SIGNED "Signé avec PKCS 7"
IDS_PKCS_7_ENVELOPED "Enveloppé avec PKCS 7"
IDS_PKCS_7_SIGNED_ENVELOPED "Enveloppé et signé avec PKCS 7"
IDS_PKCS_7_DIGESTED "Haché avec PKCS 7"
IDS_PKCS_7_ENCRYPTED "Chiffré avec PKCS 7"
IDS_PREVIOUS_CA_CERT_HASH "Previous CA Certificate Hash"
IDS_CRL_VIRTUAL_BASE "Virtual Base CRL Number"
IDS_CRL_NEXT_PUBLISH "Next CRL Publish"
IDS_CA_EXCHANGE "Certificat de chiffrement CA"
IDS_KEY_RECOVERY_AGENT "Key Recovery Agent"
IDS_CERTIFICATE_TEMPLATE "Certificate Template Information"
IDS_ENTERPRISE_ROOT_OID "Enterprise Root OID"
IDS_RDN_DUMMY_SIGNER "Signataire factice"
IDS_ARCHIVED_KEY_ATTR "Clé de chiffrement privée"
IDS_CRL_SELF_CDP "Published CRL Locations"
IDS_REQUIRE_CERT_CHAIN_POLICY "Enforce Certificate Chain Policy"
IDS_TRANSACTION_ID "Transaction Id"
IDS_SENDER_NONCE "Sender Nonce"
IDS_RECIPIENT_NONCE "Recipient Nonce"
IDS_REG_INFO "Reg Info"
IDS_GET_CERTIFICATE "Get Certificate"
IDS_GET_CRL "Get CRL"
IDS_REVOKE_REQUEST "Revoke Request"
IDS_QUERY_PENDING "Query Pending"
IDS_SORTED_CTL "Certificate Trust List"
IDS_ARCHIVED_KEY_CERT_HASH "Archived Key Certificate Hash"
IDS_PRIVATE_KEY_USAGE_PERIOD "Private Key Usage Period"
IDS_CLIENT_INFORMATION "Client Information"
IDS_SERVER_AUTHENTICATION "Server Authentication"
IDS_CLIENT_AUTHENTICATION "Client Authentication"
IDS_CODE_SIGNING "Code Signing"
IDS_SECURE_EMAIL "Secure Email"
IDS_TIME_STAMPING "Time Stamping"
IDS_MICROSOFT_TRUST_LIST_SIGNING "Microsoft Trust List Signing"
IDS_MICROSOFT_TIME_STAMPING "Microsoft Time Stamping"
IDS_IPSEC_END_SYSTEM "IP security end system"
IDS_IPSEC_TUNNEL "IP security tunnel termination"
IDS_IPSEC_USER "IP security user"
IDS_EFS "Encrypting File System"
IDS_WHQL_CRYPTO "Windows Hardware Driver Verification"
IDS_NT5_CRYPTO "Windows System Component Verification"
IDS_OEM_WHQL_CRYPTO "OEM Windows System Component Verification"
IDS_EMBEDDED_NT_CRYPTO "Embedded Windows System Component Verification"
IDS_KEY_PACK_LICENSES "Key Pack Licenses"
IDS_LICENSE_SERVER "License Server Verification"
IDS_SMART_CARD_LOGON "Smart Card Logon"
IDS_DIGITAL_RIGHTS "Digital Rights"
IDS_QUALIFIED_SUBORDINATION "Qualified Subordination"
IDS_KEY_RECOVERY "Récupération de clé"
IDS_DOCUMENT_SIGNING "Signature de document"
IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate"
IDS_FILE_RECOVERY "Récupération de fichier"
IDS_ROOT_LIST_SIGNER "Root List Signer"
IDS_ANY_APPLICATION_POLICIES "All application policies"
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replication"
IDS_ENROLLMENT_AGENT "Certificate Request Agent"
IDS_LIFETIME_SIGNING "Lifetime Signing"
IDS_ANY_CERT_POLICY "All issuance policies"
}

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View file

@ -104,6 +104,14 @@ extern PCWINE_CONTEXT_INTERFACE pCTLInterface;
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
/* Writes contexts from the memory store to the file. */
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store);
/* Reads contexts serialized in the file into the memory store. Returns FALSE
* if the file is not of the expected format.
*/
BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store);
/* Fixes up the 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

File diff suppressed because it is too large Load diff

View file

@ -106,7 +106,7 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
HCRYPTOIDFUNCADDR hFunc;
CryptEncodeObjectFunc pCryptEncodeObject;
TRACE("(0x%08lx, %s, %p, %p, %p)\n", dwCertEncodingType,
TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
debugstr_a(lpszStructType), pvStructInfo, pbEncoded,
pcbEncoded);
@ -225,7 +225,7 @@ static BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
BOOL ret;
DWORD i, dataLen = 0;
TRACE("%p, %ld, %08lx, %p, %p, %ld\n", items, cItem, dwFlags, pEncodePara,
TRACE("%p, %d, %08x, %p, %p, %d\n", items, cItem, dwFlags, pEncodePara,
pbEncoded, *pcbEncoded);
for (i = 0, ret = TRUE; ret && i < cItem; i++)
{
@ -268,7 +268,7 @@ static BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
}
}
}
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
@ -590,7 +590,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry,
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
pbEncoded, pcbEncoded);
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
@ -600,7 +600,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType,
{
DWORD cCRLEntry = *(const DWORD *)pvStructInfo;
DWORD bytesNeeded, dataLen, lenBytes, i;
const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY **)
const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY *const *)
((const BYTE *)pvStructInfo + sizeof(DWORD));
BOOL ret = TRUE;
@ -727,7 +727,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded,
};
DWORD cItem = 1;
TRACE("%p, %p, %ld\n", ext, pbEncoded, *pcbEncoded);
TRACE("%p, %p, %d\n", ext, pbEncoded, *pcbEncoded);
if (ext->fCritical)
{
@ -741,7 +741,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded,
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
pbEncoded, pcbEncoded);
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
@ -1019,7 +1019,7 @@ static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType,
__TRY
{
const CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo;
switch (value->dwValueType)
{
@ -1095,6 +1095,262 @@ static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
CERT_RDN_ATTR *attr, CryptEncodeObjectExFunc nameValueEncodeFunc,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
DWORD bytesNeeded = 0, lenBytes, size;
BOOL ret;
ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, attr->pszObjId,
0, NULL, NULL, &size);
if (ret)
{
bytesNeeded += size;
/* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning
* with dwValueType, so "cast" it to get its encoded size
*/
ret = nameValueEncodeFunc(dwCertEncodingType, NULL,
(CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size);
if (ret)
{
bytesNeeded += size;
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (pbEncoded)
{
if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
*pbEncoded++ = ASN_SEQUENCE;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
size = bytesNeeded - 1 - lenBytes;
ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL,
attr->pszObjId, 0, NULL, pbEncoded, &size);
if (ret)
{
pbEncoded += size;
size = bytesNeeded - 1 - lenBytes - size;
ret = nameValueEncodeFunc(dwCertEncodingType,
NULL, (CERT_NAME_VALUE *)&attr->dwValueType,
0, NULL, pbEncoded, &size);
if (!ret)
*pcbEncoded = size;
}
}
}
if (ret)
*pcbEncoded = bytesNeeded;
}
else
{
/* Have to propagate index of failing character */
*pcbEncoded = size;
}
}
return ret;
}
static int BLOBComp(const void *l, const void *r)
{
const CRYPT_DER_BLOB *a = (const CRYPT_DER_BLOB *)l, *b = (const CRYPT_DER_BLOB *)r;
int ret;
if (!(ret = memcmp(a->pbData, b->pbData, min(a->cbData, b->cbData))))
ret = a->cbData - b->cbData;
return ret;
}
/* This encodes as a SET OF, which in DER must be lexicographically sorted.
*/
static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
CryptEncodeObjectExFunc nameValueEncodeFunc, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret;
CRYPT_DER_BLOB *blobs = NULL;
__TRY
{
DWORD bytesNeeded = 0, lenBytes, i;
blobs = NULL;
ret = TRUE;
if (rdn->cRDNAttr)
{
blobs = CryptMemAlloc(rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
if (!blobs)
ret = FALSE;
else
memset(blobs, 0, rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
}
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, &rdn->rgRDNAttr[i],
nameValueEncodeFunc, NULL, &blobs[i].cbData);
if (ret)
bytesNeeded += blobs[i].cbData;
else
{
/* Have to propagate index of failing character */
*pcbEncoded = blobs[i].cbData;
}
}
if (ret)
{
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (pbEncoded)
{
if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
blobs[i].pbData = CryptMemAlloc(blobs[i].cbData);
if (!blobs[i].pbData)
ret = FALSE;
else
{
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType,
&rdn->rgRDNAttr[i], nameValueEncodeFunc,
blobs[i].pbData, &blobs[i].cbData);
if (!ret)
*pcbEncoded = blobs[i].cbData;
}
}
if (ret)
{
qsort(blobs, rdn->cRDNAttr, sizeof(CRYPT_DER_BLOB),
BLOBComp);
*pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
memcpy(pbEncoded, blobs[i].pbData, blobs[i].cbData);
pbEncoded += blobs[i].cbData;
}
}
}
}
if (ret)
*pcbEncoded = bytesNeeded;
}
if (blobs)
{
for (i = 0; i < rdn->cRDNAttr; i++)
CryptMemFree(blobs[i].pbData);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
CryptMemFree(blobs);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeOrCopyUnicodeNameValue(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo;
BOOL ret;
if (value->dwValueType == CERT_RDN_ENCODED_BLOB)
ret = CRYPT_CopyEncodedBlob(dwCertEncodingType, NULL, &value->Value,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
else
ret = CRYPT_AsnEncodeUnicodeNameValue(dwCertEncodingType, NULL, value,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = TRUE;
__TRY
{
const CERT_NAME_INFO *info = (const CERT_NAME_INFO *)pvStructInfo;
DWORD bytesNeeded = 0, lenBytes, size, i;
TRACE("encoding name with %d RDNs\n", info->cRDN);
ret = TRUE;
for (i = 0; ret && i < info->cRDN; i++)
{
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i],
CRYPT_AsnEncodeOrCopyUnicodeNameValue, NULL, &size);
if (ret)
bytesNeeded += size;
else
*pcbEncoded = 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->cRDN; i++)
{
size = bytesNeeded;
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType,
&info->rgRDN[i], CRYPT_AsnEncodeOrCopyUnicodeNameValue,
pbEncoded, &size);
if (ret)
{
pbEncoded += size;
bytesNeeded -= size;
}
else
*pcbEncoded = size;
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value,
BYTE tag, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
@ -1308,7 +1564,7 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType,
__TRY
{
const CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo;
switch (value->dwValueType)
{
@ -1373,155 +1629,6 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
CERT_RDN_ATTR *attr, BYTE *pbEncoded, DWORD *pcbEncoded)
{
DWORD bytesNeeded = 0, lenBytes, size;
BOOL ret;
ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, attr->pszObjId,
0, NULL, NULL, &size);
if (ret)
{
bytesNeeded += size;
/* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning
* with dwValueType, so "cast" it to get its encoded size
*/
ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, X509_NAME_VALUE,
(CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size);
if (ret)
{
bytesNeeded += size;
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (pbEncoded)
{
if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
*pbEncoded++ = ASN_SEQUENCE;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
size = bytesNeeded - 1 - lenBytes;
ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL,
attr->pszObjId, 0, NULL, pbEncoded, &size);
if (ret)
{
pbEncoded += size;
size = bytesNeeded - 1 - lenBytes - size;
ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType,
X509_NAME_VALUE, (CERT_NAME_VALUE *)&attr->dwValueType,
0, NULL, pbEncoded, &size);
}
}
}
*pcbEncoded = bytesNeeded;
}
}
return ret;
}
static int BLOBComp(const void *l, const void *r)
{
CRYPT_DER_BLOB *a = (CRYPT_DER_BLOB *)l, *b = (CRYPT_DER_BLOB *)r;
int ret;
if (!(ret = memcmp(a->pbData, b->pbData, min(a->cbData, b->cbData))))
ret = a->cbData - b->cbData;
return ret;
}
/* This encodes as a SET OF, which in DER must be lexicographically sorted.
*/
static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
CRYPT_DER_BLOB *blobs = NULL;
__TRY
{
DWORD bytesNeeded = 0, lenBytes, i;
blobs = NULL;
ret = TRUE;
if (rdn->cRDNAttr)
{
blobs = CryptMemAlloc(rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
if (!blobs)
ret = FALSE;
else
memset(blobs, 0, rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
}
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, &rdn->rgRDNAttr[i],
NULL, &blobs[i].cbData);
if (ret)
bytesNeeded += blobs[i].cbData;
}
if (ret)
{
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (pbEncoded)
{
if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
blobs[i].pbData = CryptMemAlloc(blobs[i].cbData);
if (!blobs[i].pbData)
ret = FALSE;
else
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType,
&rdn->rgRDNAttr[i], blobs[i].pbData,
&blobs[i].cbData);
}
if (ret)
{
qsort(blobs, rdn->cRDNAttr, sizeof(CRYPT_DER_BLOB),
BLOBComp);
*pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
memcpy(pbEncoded, blobs[i].pbData, blobs[i].cbData);
pbEncoded += blobs[i].cbData;
}
}
}
}
*pcbEncoded = bytesNeeded;
}
if (blobs)
{
for (i = 0; i < rdn->cRDNAttr; i++)
CryptMemFree(blobs[i].pbData);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
CryptMemFree(blobs);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@ -1533,12 +1640,12 @@ static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType,
const CERT_NAME_INFO *info = (const CERT_NAME_INFO *)pvStructInfo;
DWORD bytesNeeded = 0, lenBytes, size, i;
TRACE("encoding name with %ld RDNs\n", info->cRDN);
TRACE("encoding name with %d RDNs\n", info->cRDN);
ret = TRUE;
for (i = 0; ret && i < info->cRDN; i++)
{
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i], NULL,
&size);
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i],
CRYPT_AsnEncodeNameValue, NULL, &size);
if (ret)
bytesNeeded += size;
}
@ -1563,7 +1670,8 @@ static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType,
{
size = bytesNeeded;
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType,
&info->rgRDN[i], pbEncoded, &size);
&info->rgRDN[i], CRYPT_AsnEncodeNameValue, pbEncoded,
&size);
if (ret)
{
pbEncoded += size;
@ -1610,7 +1718,7 @@ static BOOL WINAPI CRYPT_AsnEncodeBool(DWORD dwCertEncodingType,
*pbEncoded++ = val ? 0xff : 0;
ret = TRUE;
}
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
@ -1652,7 +1760,7 @@ static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry,
/* FIXME: encode OID */
case CERT_ALT_NAME_OTHER_NAME:
case CERT_ALT_NAME_DIRECTORY_NAME:
FIXME("name type %ld unimplemented\n", entry->dwAltNameChoice);
FIXME("name type %d unimplemented\n", entry->dwAltNameChoice);
return FALSE;
default:
SetLastError(E_INVALIDARG);
@ -1697,7 +1805,63 @@ static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry,
*pcbEncoded = bytesNeeded;
}
}
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_AUTHORITY_KEY_ID_INFO *info =
(const CERT_AUTHORITY_KEY_ID_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[3] = { { 0 } };
struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } };
struct AsnConstructedItem constructed = { 0 };
DWORD cItem = 0, cSwapped = 0;
if (info->KeyId.cbData)
{
swapped[cSwapped].tag = ASN_CONTEXT | 0;
swapped[cSwapped].pvStructInfo = &info->KeyId;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
if (info->CertIssuer.cbData)
{
constructed.tag = 1;
constructed.pvStructInfo = &info->CertIssuer;
constructed.encodeFunc = CRYPT_CopyEncodedBlob;
items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cItem++;
}
if (info->CertSerialNumber.cbData)
{
swapped[cSwapped].tag = ASN_CONTEXT | 2;
swapped[cSwapped].pvStructInfo = &info->CertSerialNumber;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, dwFlags,
pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
@ -1908,7 +2072,7 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType,
const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvStructInfo;
DWORD bytesNeeded, lenBytes;
TRACE("(%ld, %p), %08lx, %p, %p, %ld\n", blob->cbData, blob->pbData,
TRACE("(%d, %p), %08x, %p, %p, %d\n", blob->cbData, blob->pbData,
dwFlags, pEncodePara, pbEncoded, *pcbEncoded);
CRYPT_EncodeLen(blob->cbData, NULL, &lenBytes);
@ -1939,7 +2103,7 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType,
ret = FALSE;
}
__ENDTRY
TRACE("returning %d (%08lx)\n", ret, GetLastError());
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
@ -2731,7 +2895,7 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
CryptEncodeObjectExFunc encodeFunc = NULL;
HCRYPTOIDFUNCADDR hFunc = NULL;
TRACE("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType,
TRACE("(0x%08x, %s, %p, 0x%08x, %p, %p, %p)\n", dwCertEncodingType,
debugstr_a(lpszStructType), pvStructInfo, dwFlags, pEncodePara,
pvEncoded, pcbEncoded);
@ -2775,6 +2939,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
case (WORD)X509_PUBLIC_KEY_INFO:
encodeFunc = CRYPT_AsnEncodePubKeyInfo;
break;
case (WORD)X509_AUTHORITY_KEY_ID:
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId;
break;
case (WORD)X509_ALTERNATE_NAME:
encodeFunc = CRYPT_AsnEncodeAltName;
break;
@ -2787,6 +2954,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
case (WORD)RSA_CSP_PUBLICKEYBLOB:
encodeFunc = CRYPT_AsnEncodeRsaPubKey;
break;
case (WORD)X509_UNICODE_NAME:
encodeFunc = CRYPT_AsnEncodeUnicodeName;
break;
case (WORD)X509_UNICODE_NAME_VALUE:
encodeFunc = CRYPT_AsnEncodeUnicodeNameValue;
break;
@ -2835,6 +3005,8 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
encodeFunc = CRYPT_AsnEncodeExtensions;
else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
encodeFunc = CRYPT_AsnEncodeUtcTime;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
encodeFunc = CRYPT_AsnEncodeEnumerated;
else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
@ -2896,7 +3068,7 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv,
HCRYPTKEY key;
static CHAR oid[] = szOID_RSA_RSA;
TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec,
TRACE("(%08lx, %d, %08x, %s, %08x, %p, %p, %p)\n", hCryptProv, dwKeySpec,
dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo,
pInfo, pcbInfo);
@ -2976,7 +3148,7 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
ExportPublicKeyInfoExFunc exportFunc = NULL;
HCRYPTOIDFUNCADDR hFunc = NULL;
TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec,
TRACE("(%08lx, %d, %08x, %s, %08x, %p, %p, %p)\n", hCryptProv, dwKeySpec,
dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo,
pInfo, pcbInfo);
@ -3017,7 +3189,7 @@ static BOOL WINAPI CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv,
BOOL ret;
DWORD pubKeySize = 0;
TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv,
TRACE("(%08lx, %d, %p, %d, %08x, %p, %p)\n", hCryptProv,
dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey);
ret = CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
@ -3055,7 +3227,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
ImportPublicKeyInfoExFunc importFunc = NULL;
HCRYPTOIDFUNCADDR hFunc = NULL;
TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv,
TRACE("(%08lx, %d, %p, %d, %08x, %p, %p)\n", hCryptProv,
dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey);
if (!set)

View file

@ -27,6 +27,8 @@
#include "winreg.h"
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"
#include "advpub.h"
#include "crypt32_private.h"
#include "wine/debug.h"
@ -75,149 +77,22 @@ BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out)
BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2)
{
FIXME("(%08lx, %08lx, %08lx): stub!\n", unk0, unk1, unk2);
FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2);
return FALSE;
}
DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
{
FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1);
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
return 0;
}
HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
{
FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1);
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
return h;
}
BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
{
FIXME("stub!\n");
return FALSE;
}
/* convert a guid to a wide character string */
static void CRYPT_guid2wstr( LPGUID guid, LPWSTR wstr )
{
char str[40];
sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
}
/*
* Helper for CryptSIPAddProvider
*
* Add a registry key containing a dll name and function under
* "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\<func>\\<guid>"
*/
static LONG CRYPT_SIPWriteFunction( LPGUID guid, LPCWSTR szKey,
LPCWSTR szDll, LPCWSTR szFunction )
{
static const WCHAR szOID[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'C','r','y','p','t','o','g','r','a','p','h','y','\\',
'O','I','D','\\',
'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\',
'C','r','y','p','t','S','I','P','D','l','l', 0 };
static const WCHAR szBackSlash[] = { '\\', 0 };
static const WCHAR szDllName[] = { 'D','l','l',0 };
static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 };
WCHAR szFullKey[ 0x100 ];
LONG r;
HKEY hKey;
if( !szFunction )
return ERROR_SUCCESS;
/* max length of szFullKey depends on our code only, so we won't overrun */
lstrcpyW( szFullKey, szOID );
lstrcatW( szFullKey, szKey );
lstrcatW( szFullKey, szBackSlash );
CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );
lstrcatW( szFullKey, szBackSlash );
TRACE("key is %s\n", debugstr_w( szFullKey ) );
r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey );
if( r != ERROR_SUCCESS )
return r;
/* write the values */
RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction,
( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) );
RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll,
( lstrlenW( szDll ) + 1) * sizeof (WCHAR) );
RegCloseKey( hKey );
return ERROR_SUCCESS;
}
BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv)
{
static const WCHAR szCreate[] = {
'C','r','e','a','t','e',
'I','n','d','i','r','e','c','t','D','a','t','a',0};
static const WCHAR szGetSigned[] = {
'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g',0};
static const WCHAR szIsMyFile[] = {
'I','s','M','y','F','i','l','e','T','y','p','e', 0 };
static const WCHAR szPutSigned[] = {
'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g',0};
static const WCHAR szRemoveSigned[] = {
'R','e','m','o','v','e',
'S','i','g','n','e','d','D','a','t','a','M','s','g',0};
static const WCHAR szVerify[] = {
'V','e','r','i','f','y',
'I','n','d','i','r','e','c','t','D','a','t','a',0};
TRACE("%p\n", psNewProv);
if( !psNewProv )
return FALSE;
TRACE("%s %s %s %s\n",
debugstr_guid( psNewProv->pgSubject ),
debugstr_w( psNewProv->pwszDLLFileName ),
debugstr_w( psNewProv->pwszMagicNumber ),
debugstr_w( psNewProv->pwszIsFunctionName ) );
#define CRYPT_SIPADDPROV( key, field ) \
CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \
psNewProv->pwszDLLFileName, psNewProv->field)
CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName );
CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName );
CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName );
CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName );
CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName );
CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionNameFmt2 );
#undef CRYPT_SIPADDPROV
return TRUE;
}
BOOL WINAPI CryptSIPRetrieveSubjectGuid
(LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
{
FIXME("stub!\n");
return FALSE;
}
BOOL WINAPI CryptSIPLoad
(const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
{
FIXME("stub!\n");
return FALSE;
}
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
{
return HeapAlloc(GetProcessHeap(), 0, cbSize);
@ -259,35 +134,97 @@ BOOL WINAPI I_CryptSetTls(DWORD dwTlsIndex, LPVOID lpTlsValue)
BOOL WINAPI I_CryptFreeTls(DWORD dwTlsIndex, DWORD unknown)
{
TRACE("(%ld, %ld)\n", dwTlsIndex, unknown);
TRACE("(%d, %d)\n", dwTlsIndex, unknown);
return TlsFree(dwTlsIndex);
}
BOOL WINAPI I_CryptGetOssGlobal(DWORD x)
{
FIXME("%08lx\n", x);
FIXME("%08x\n", x);
return FALSE;
}
BOOL WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved)
{
FIXME("%08lx %08lx %08lx\n", x, y, z);
return FALSE;
HCRYPTPROV ret;
TRACE("(%08x)\n", reserved);
if (reserved)
{
SetLastError(E_INVALIDARG);
return (HCRYPTPROV)0;
}
ret = CRYPT_GetDefaultProvider();
CryptContextAddRef(ret, NULL, 0);
return ret;
}
BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name,
DWORD *value)
{
static const WCHAR safer[] = {
'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\',
'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m',
'C','e','r','t','i','f','i','c','a','t','e','s','\\',
'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r','\\',
'S','a','f','e','r',0 };
HKEY key;
LONG rc;
BOOL ret = FALSE;
TRACE("(%s, %p)\n", debugstr_w(name), value);
*value = 0;
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, safer, &key);
if (rc == ERROR_SUCCESS)
{
DWORD size = sizeof(DWORD);
if (!RegQueryValueExW(key, name, NULL, NULL, (LPBYTE)value, &size))
ret = TRUE;
RegCloseKey(key);
}
return ret;
}
int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
{
static int ret = 8;
ret++;
FIXME("%08x %08x %08x, return value %d\n", x, y, z,ret);
return ret;
}
BOOL WINAPI I_CryptInstallAsn1Module(void *x, DWORD y, DWORD z)
{
FIXME("%p %08lx %08lx\n", x, y, z);
FIXME("%p %08x %08x\n", x, y, z);
return TRUE;
}
BOOL WINAPI I_CryptUninstallAsn1Module(void *x)
{
FIXME("%p\n", x);
return TRUE;
}
BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
{
FIXME("(%08x, %d, %d, %p, %s, %p, %d, %p, %p): stub\n",
dwCertEncodingType, dwFormatType, dwFormatStrType, pFormatStruct,
debugstr_a(lpszStructType), pbEncoded, cbEncoded, pbFormat, pcbFormat);
return FALSE;
}
BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void* pvObject,
DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType,
DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg,
const void** ppvContext)
{
FIXME( "%08lx %p %08lx %08lx %08lx %p %p %p %p %p %p", dwObjectType,
FIXME( "%08x %p %08x %08x %08x %p %p %p %p %p %p\n", dwObjectType,
pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
phCertStore, phMsg, ppvContext);
@ -298,8 +235,10 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
{
FIXME("stub: %p, %ld, %p, %ld, %p, %p, %p\n",
FIXME("stub: %p, %d, %p, %d, %p, %p, %p\n",
pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
pbDecoded, pcbDecoded, ppSignerCert);
if (ppSignerCert)
*ppSignerCert = NULL;
return FALSE;
}

View file

@ -16,6 +16,10 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdio.h>
#include <stdarg.h>
#define NONAMELESSUNION
@ -71,6 +75,7 @@ struct OIDFunction
static void init_function_sets(void)
{
InitializeCriticalSection(&funcSetCS);
funcSetCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": funcSetCS");
list_init(&funcSets);
}
@ -91,9 +96,11 @@ static void free_function_sets(void)
list_remove(&functionCursor->next);
CryptMemFree(functionCursor);
}
setCursor->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&setCursor->cs);
CryptMemFree(setCursor);
}
funcSetCS.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&funcSetCS);
}
@ -105,7 +112,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
{
struct OIDFunctionSet *cursor, *ret = NULL;
TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags);
TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags);
EnterCriticalSection(&funcSetCS);
LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next)
@ -126,6 +133,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
if (ret->name)
{
InitializeCriticalSection(&ret->cs);
ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs");
list_init(&ret->functions);
strcpy(ret->name, pszFuncName);
list_add_tail(&funcSets, &ret->next);
@ -146,7 +154,7 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
LPCSTR pszOID)
{
static const char szEncodingTypeFmt[] =
"Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s";
"Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s";
UINT len;
char numericOID[7]; /* enough for "#65535" */
const char *oid;
@ -186,7 +194,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
HKEY key;
long rc;
TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
pcchDllList);
keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT");
@ -226,7 +234,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
BOOL ret = TRUE;
struct OIDFunctionSet *set;
TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType,
TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType,
debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags);
set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0);
@ -249,8 +257,11 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
func->encoding = dwEncodingType;
if (HIWORD(rgFuncEntry[i].pszOID))
{
func->entry.pszOID = (LPSTR)((LPBYTE)func + sizeof(*func));
strcpy((LPSTR)func->entry.pszOID, rgFuncEntry[i].pszOID);
LPSTR oid;
oid = (LPSTR)((LPBYTE)func + sizeof(*func));
strcpy(oid, rgFuncEntry[i].pszOID);
func->entry.pszOID = oid;
}
else
func->entry.pszOID = rgFuncEntry[i].pszOID;
@ -350,7 +361,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
BOOL ret = FALSE;
struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType,
TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr);
*ppvFuncAddr = NULL;
@ -365,8 +376,8 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
{
if (HIWORD(pszOID))
{
if (HIWORD(function->entry.pszOID &&
!strcasecmp(function->entry.pszOID, pszOID)))
if (HIWORD(function->entry.pszOID) &&
!strcasecmp(function->entry.pszOID, pszOID))
{
*ppvFuncAddr = function->entry.pvFuncAddr;
*phFuncAddr = NULL; /* FIXME: what should it be? */
@ -394,7 +405,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
DWORD dwFlags)
{
TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags);
TRACE("(%p, %08x)\n", hFuncAddr, dwFlags);
/* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL,
* and only unload it if it can be unloaded. Also need to implement ref
@ -404,31 +415,35 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
return TRUE;
}
BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
{
FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex,
debugstr_w(pwszDll));
return FALSE;
}
BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
LPCSTR pszFuncName, LPCWSTR pwszDll)
{
FIXME("(%lx %s %s): stub\n", dwEncodingType, debugstr_a(pszFuncName),
debugstr_w(pwszDll));
return FALSE;
}
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
HCRYPTOIDFUNCADDR *phFuncAddr)
{
FIXME("(%p, %ld, %s, %08lx, %p, %p): stub\n", hFuncSet, dwEncodingType,
FIXME("(%p, %d, %s, %08x, %p, %p): stub\n", hFuncSet, dwEncodingType,
debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
return FALSE;
}
/***********************************************************************
* CryptRegisterOIDFunction (CRYPT32.@)
*
* Register the DLL and the functions it uses to cover the combination
* of encoding type, functionname and OID.
*
* PARAMS
* dwEncodingType [I] Encoding type to be used.
* pszFuncName [I] Name of the function to be registered.
* pszOID [I] OID of the function (numeric or string).
* pwszDll [I] The DLL that is to be registered.
* pszOverrideFuncName [I] Name of the function in the DLL.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE. (Look at GetLastError()).
*
* NOTES
* Registry errors are always reported via SetLastError().
*/
BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
{
@ -436,8 +451,8 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
HKEY hKey;
LPSTR szKey;
TRACE("(%lx, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName, pszOID,
debugstr_w(pwszDll), pszOverrideFuncName);
TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName,
debugstr_a(pszOID), debugstr_w(pwszDll), pszOverrideFuncName);
/* This only registers functions for encoding certs, not messages */
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
@ -465,27 +480,42 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
CryptMemFree(szKey);
if(r != ERROR_SUCCESS)
return FALSE;
if (r != ERROR_SUCCESS) goto error_close_key;
/* write the values */
if (pszOverrideFuncName)
RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
(const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll,
(lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
{
r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
(const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
if (r != ERROR_SUCCESS) goto error_close_key;
}
r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll,
(lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
error_close_key:
RegCloseKey(hKey);
if (r != ERROR_SUCCESS)
{
SetLastError(r);
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CryptUnregisterOIDFunction (CRYPT32.@)
*/
BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
LPCSTR pszOID)
{
LPSTR szKey;
LONG rc;
TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID);
TRACE("%x %s %s\n", dwEncodingType, pszFuncName, pszOID);
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
return TRUE;
@ -512,7 +542,7 @@ BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
LONG rc;
HKEY hKey;
TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
pcbValueData);
@ -549,7 +579,7 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
LONG rc;
HKEY hKey;
TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName),
TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName),
debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
cbValueData);
@ -578,6 +608,237 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
return rc ? FALSE : TRUE;
}
static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind)
{
LPCWSTR ret = NULL, ptr;
for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1)
{
if (!lstrcmpiW(ptr, toFind))
ret = ptr;
}
return ret;
}
static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi)
{
DWORD ret;
if (multi)
{
LPCWSTR ptr;
/* Count terminating empty string */
ret = 1;
for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1)
ret += lstrlenW(ptr) + 1;
}
else
ret = 0;
return ret;
}
static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd,
DWORD index)
{
LPWSTR ret;
if (!multi)
{
/* FIXME: ignoring index, is that okay? */
ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR));
if (ret)
{
/* copy string, including NULL terminator */
memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
/* add terminating empty string */
*(ret + lstrlenW(toAdd) + 1) = 0;
}
}
else
{
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) *
sizeof(WCHAR));
if (ret)
{
LPWSTR spotToAdd;
if (index == CRYPT_REGISTER_LAST_INDEX)
spotToAdd = ret + len - 1;
else
{
DWORD i;
/* FIXME: if index is too large for the string, toAdd is
* added to the end. Is that okay?
*/
for (i = 0, spotToAdd = ret; i < index && *spotToAdd;
spotToAdd += lstrlenW(spotToAdd) + 1)
;
}
if (spotToAdd)
{
/* Copy existing string "right" */
memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd,
(len - (spotToAdd - ret)) * sizeof(WCHAR));
/* Copy new string */
memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
}
else
{
CryptMemFree(ret);
ret = NULL;
}
}
}
return ret;
}
static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
{
LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi,
toRemove);
BOOL ret;
if (spotToRemove)
{
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
/* Copy remainder of string "left" */
memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
(len - (spotToRemove - multi)) * sizeof(WCHAR));
ret = TRUE;
}
else
{
SetLastError(ERROR_FILE_NOT_FOUND);
ret = FALSE;
}
return ret;
}
static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName,
PHKEY key)
{
LPSTR keyName;
LONG r;
keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT");
TRACE("Key name is %s\n", debugstr_a(keyName));
if (!keyName)
return FALSE;
r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS,
NULL, key, NULL);
CryptMemFree(keyName);
if (r != ERROR_SUCCESS)
{
SetLastError(r);
return FALSE;
}
return TRUE;
}
static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key)
{
LONG r;
DWORD type, size;
LPWSTR dlls;
r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
if (r == ERROR_SUCCESS && type == REG_MULTI_SZ)
{
dlls = CryptMemAlloc(size);
r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size);
if (r != ERROR_SUCCESS)
{
CryptMemFree(dlls);
dlls = NULL;
}
}
else
dlls = NULL;
return dlls;
}
static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls)
{
DWORD len = CRYPT_GetMultiStringCharacterLen(dlls);
LONG r;
if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls,
len * sizeof (WCHAR))))
SetLastError(r);
return r == ERROR_SUCCESS;
}
/***********************************************************************
* CryptRegisterDefaultOIDFunction (CRYPT32.@)
*/
BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
{
HKEY key;
LPWSTR dlls;
LPCWSTR existing;
BOOL ret = FALSE;
TRACE("(%x, %s, %x, %s)\n", dwEncodingType, pszFuncName, dwIndex,
debugstr_w(pwszDll));
if (!pwszDll)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
return FALSE;
dlls = CRYPT_GetDefaultOIDDlls(key);
if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll)))
SetLastError(ERROR_FILE_EXISTS);
else
{
dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex);
if (dlls)
ret = CRYPT_SetDefaultOIDDlls(key, dlls);
}
CryptMemFree(dlls);
RegCloseKey(key);
return ret;
}
BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
LPCSTR pszFuncName, LPCWSTR pwszDll)
{
HKEY key;
LPWSTR dlls;
BOOL ret;
TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
debugstr_w(pwszDll));
if (!pwszDll)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
return FALSE;
dlls = CRYPT_GetDefaultOIDDlls(key);
if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll)))
ret = CRYPT_SetDefaultOIDDlls(key, dlls);
CryptMemFree(dlls);
RegCloseKey(key);
return ret;
}
static CRITICAL_SECTION oidInfoCS;
static struct list oidInfo;
@ -921,6 +1182,7 @@ static void init_oid_info(HINSTANCE hinst)
DWORD i;
InitializeCriticalSection(&oidInfoCS);
oidInfoCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": oidInfoCS");
list_init(&oidInfo);
for (i = 0; i < sizeof(oidInfoConstructors) /
sizeof(oidInfoConstructors[0]); i++)
@ -993,16 +1255,20 @@ static void free_oid_info(void)
list_remove(&info->entry);
CryptMemFree(info);
}
oidInfoCS.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&oidInfoCS);
}
/***********************************************************************
* CryptEnumOIDInfo (CRYPT32.@)
*/
BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg,
PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo)
{
BOOL ret = TRUE;
struct OIDInfo *info;
TRACE("(%ld, %08lx, %p, %p)\n", dwGroupId, dwFlags, pvArg,
TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg,
pfnEnumOIDInfo);
EnterCriticalSection(&oidInfoCS);
@ -1024,7 +1290,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
{
PCCRYPT_OID_INFO ret = NULL;
TRACE("(%ld, %p, %ld)\n", dwKeyType, pvKey, dwGroupId);
TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId);
switch(dwKeyType)
{
@ -1032,6 +1298,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
{
struct OIDInfo *info;
TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey);
EnterCriticalSection(&oidInfoCS);
LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
{
@ -1049,6 +1316,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
{
struct OIDInfo *info;
TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w((LPWSTR)pvKey));
EnterCriticalSection(&oidInfoCS);
LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
{
@ -1067,6 +1335,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
struct OIDInfo *info;
LPSTR oid = (LPSTR)pvKey;
TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid));
EnterCriticalSection(&oidInfoCS);
LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
{
@ -1084,6 +1353,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
{
struct OIDInfo *info;
TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey);
EnterCriticalSection(&oidInfoCS);
LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
{

View file

@ -47,6 +47,7 @@ PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
if (list)
{
InitializeCriticalSection(&list->cs);
list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs");
list_init(&list->properties);
}
return list;
@ -63,6 +64,7 @@ void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
CryptMemFree(prop->pbData);
CryptMemFree(prop);
}
list->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&list->cs);
CryptMemFree(list);
}
@ -73,7 +75,7 @@ BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
PCONTEXT_PROPERTY prop;
BOOL ret = FALSE;
TRACE("(%p, %ld, %p)\n", list, id, blob);
TRACE("(%p, %d, %p)\n", list, id, blob);
EnterCriticalSection(&list->cs);
LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)

View file

@ -111,7 +111,7 @@ static const char crypt_magic_str[] = "Wine Crypt32 ok";
/* debugging tool to print strings of hex chars */
static const char *
hex_str(unsigned char *p, int n)
hex_str(const unsigned char *p, int n)
{
const char * ptr;
char report[80];
@ -146,7 +146,7 @@ void serialize_dword(DWORD value,BYTE ** ptr)
}
static
void serialize_string(BYTE * str,BYTE ** ptr,DWORD len, DWORD width,
void serialize_string(const BYTE *str, BYTE **ptr, DWORD len, DWORD width,
BOOL prepend_len)
{
/*TRACE("called %ux%u\n",(unsigned int)len,(unsigned int)width);*/
@ -160,7 +160,7 @@ void serialize_string(BYTE * str,BYTE ** ptr,DWORD len, DWORD width,
}
static
BOOL unserialize_dword(BYTE * ptr, DWORD *index, DWORD size, DWORD * value)
BOOL unserialize_dword(const BYTE *ptr, DWORD *index, DWORD size, DWORD *value)
{
/*TRACE("called\n");*/
@ -178,7 +178,7 @@ BOOL unserialize_dword(BYTE * ptr, DWORD *index, DWORD size, DWORD * value)
}
static
BOOL unserialize_string(BYTE * ptr, DWORD *index, DWORD size,
BOOL unserialize_string(const BYTE *ptr, DWORD *index, DWORD size,
DWORD len, DWORD width, BOOL inline_len,
BYTE ** data, DWORD * stored)
{
@ -212,7 +212,7 @@ BOOL unserialize_string(BYTE * ptr, DWORD *index, DWORD size,
}
static
BOOL serialize(struct protect_data_t * pInfo, DATA_BLOB * pSerial)
BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
{
BYTE * ptr;
DWORD dwStrLen;
@ -340,7 +340,7 @@ BOOL serialize(struct protect_data_t * pInfo, DATA_BLOB * pSerial)
}
static
BOOL unserialize(DATA_BLOB * pSerial, struct protect_data_t * pInfo)
BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
{
BYTE * ptr;
DWORD index;
@ -484,7 +484,7 @@ BOOL unserialize(DATA_BLOB * pSerial, struct protect_data_t * pInfo)
/* perform sanity checks */
static
BOOL valid_protect_data(struct protect_data_t * pInfo)
BOOL valid_protect_data(const struct protect_data_t *pInfo)
{
BOOL status=TRUE;
@ -537,25 +537,18 @@ void free_protect_data(struct protect_data_t * pInfo)
if (!pInfo) return;
if (pInfo->info0.pbData)
CryptMemFree(pInfo->info0.pbData);
if (pInfo->info1.pbData)
CryptMemFree(pInfo->info1.pbData);
if (pInfo->szDataDescr)
CryptMemFree(pInfo->szDataDescr);
if (pInfo->data0.pbData)
CryptMemFree(pInfo->data0.pbData);
if (pInfo->salt.pbData)
CryptMemFree(pInfo->salt.pbData);
if (pInfo->cipher.pbData)
CryptMemFree(pInfo->cipher.pbData);
if (pInfo->fingerprint.pbData)
CryptMemFree(pInfo->fingerprint.pbData);
CryptMemFree(pInfo->info0.pbData);
CryptMemFree(pInfo->info1.pbData);
CryptMemFree(pInfo->szDataDescr);
CryptMemFree(pInfo->data0.pbData);
CryptMemFree(pInfo->salt.pbData);
CryptMemFree(pInfo->cipher.pbData);
CryptMemFree(pInfo->fingerprint.pbData);
}
/* copies a string into a data blob */
static
BYTE * convert_str_to_blob(char* str, DATA_BLOB* blob)
BYTE *convert_str_to_blob(LPCSTR str, DATA_BLOB *blob)
{
if (!str || !blob) return NULL;
@ -590,11 +583,11 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
pInfo->count0=0x0001;
convert_str_to_blob((char*)crypt_magic_str,&pInfo->info0);
convert_str_to_blob(crypt_magic_str, &pInfo->info0);
pInfo->count1=0x0001;
convert_str_to_blob((char*)crypt_magic_str,&pInfo->info1);
convert_str_to_blob(crypt_magic_str, &pInfo->info1);
pInfo->null0=0x0000;
@ -606,7 +599,7 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
pInfo->unknown0=0x0000;
pInfo->unknown1=0x0000;
convert_str_to_blob((char*)crypt_magic_str,&pInfo->data0);
convert_str_to_blob(crypt_magic_str, &pInfo->data0);
pInfo->null1=0x0000;
pInfo->unknown2=0x0000;
@ -688,7 +681,7 @@ BOOL convert_hash_to_blob(HCRYPTHASH hHash, DATA_BLOB * blob)
/* test that a given hash matches an exported-to-blob hash value */
static
BOOL hash_matches_blob(HCRYPTHASH hHash, DATA_BLOB * two)
BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two)
{
BOOL rc = FALSE;
DATA_BLOB one;
@ -711,8 +704,8 @@ BOOL hash_matches_blob(HCRYPTHASH hHash, DATA_BLOB * two)
/* create an encryption key from a given salt and optional entropy */
static
BOOL load_encryption_key(HCRYPTPROV hProv, DATA_BLOB * salt,
DATA_BLOB * pOptionalEntropy, HCRYPTKEY * phKey)
BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
{
BOOL rc = TRUE;
HCRYPTHASH hSaltHash;
@ -768,14 +761,14 @@ BOOL load_encryption_key(HCRYPTPROV hProv, DATA_BLOB * salt,
/* clean up */
CryptDestroyHash(hSaltHash);
if (szUsername) CryptMemFree(szUsername);
CryptMemFree(szUsername);
return rc;
}
/* debugging tool to print the structures of a ProtectData call */
static void
report(DATA_BLOB* pDataIn, DATA_BLOB* pOptionalEntropy,
report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy,
CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags)
{
TRACE("pPromptStruct: %p\n", pPromptStruct);

View file

@ -38,13 +38,13 @@ typedef struct _WINE_CERT_PROP_HEADER
static BOOL CRYPT_SerializeStoreElement(const void *context,
const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID,
PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BYTE *pbElement,
DWORD *pcbElement)
PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BOOL omitHashes,
BYTE *pbElement, DWORD *pcbElement)
{
BOOL ret;
TRACE("(%p, %p, %08lx, %p, %p)\n", context, contextInterface, dwFlags,
pbElement, pcbElement);
TRACE("(%p, %p, %08x, %d, %p, %p)\n", context, contextInterface, dwFlags,
omitHashes, pbElement, pcbElement);
if (context)
{
@ -54,7 +54,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
ret = TRUE;
do {
prop = contextInterface->enumProps(context, prop);
if (prop)
if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop)))
{
DWORD propSize = 0;
@ -84,7 +84,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
prop = 0;
do {
prop = contextInterface->enumProps(context, prop);
if (prop)
if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop)))
{
DWORD propSize = 0;
@ -143,7 +143,7 @@ BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext,
{
return CRYPT_SerializeStoreElement(pCertContext,
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded,
CERT_CERT_PROP_ID, pCertInterface, dwFlags, pbElement, pcbElement);
CERT_CERT_PROP_ID, pCertInterface, dwFlags, FALSE, pbElement, pcbElement);
}
BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext,
@ -151,7 +151,7 @@ BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext,
{
return CRYPT_SerializeStoreElement(pCrlContext,
pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded,
CERT_CRL_PROP_ID, pCRLInterface, dwFlags, pbElement, pcbElement);
CERT_CRL_PROP_ID, pCRLInterface, dwFlags, FALSE, pbElement, pcbElement);
}
BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext,
@ -159,7 +159,7 @@ BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext,
{
return CRYPT_SerializeStoreElement(pCtlContext,
pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded,
CERT_CTL_PROP_ID, pCRLInterface, dwFlags, pbElement, pcbElement);
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, FALSE, pbElement, pcbElement);
}
/* Looks for the property with ID propID in the buffer buf. Returns a pointer
@ -215,12 +215,86 @@ static const WINE_CERT_PROP_HEADER *CRYPT_findPropID(const BYTE *buf,
return ret;
}
static BOOL CRYPT_ReadContextProp(
const WINE_CONTEXT_INTERFACE *contextInterface, const void *context,
const WINE_CERT_PROP_HEADER *hdr, const BYTE *pbElement, DWORD cbElement)
{
BOOL ret;
if (cbElement < hdr->cb)
{
SetLastError(E_INVALIDARG);
ret = FALSE;
}
else if (hdr->unknown != 1)
{
SetLastError(ERROR_FILE_NOT_FOUND);
ret = FALSE;
}
else if (hdr->propID != CERT_CERT_PROP_ID &&
hdr->propID != CERT_CRL_PROP_ID && hdr->propID != CERT_CTL_PROP_ID)
{
/* Have to create a blob for most types, but not
* for all.. arghh.
*/
switch (hdr->propID)
{
case CERT_AUTO_ENROLL_PROP_ID:
case CERT_CTL_USAGE_PROP_ID:
case CERT_DESCRIPTION_PROP_ID:
case CERT_FRIENDLY_NAME_PROP_ID:
case CERT_HASH_PROP_ID:
case CERT_KEY_IDENTIFIER_PROP_ID:
case CERT_MD5_HASH_PROP_ID:
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
case CERT_PUBKEY_ALG_PARA_PROP_ID:
case CERT_PVK_FILE_PROP_ID:
case CERT_SIGNATURE_HASH_PROP_ID:
case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_ENROLLMENT_PROP_ID:
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
case CERT_RENEWAL_PROP_ID:
{
CRYPT_DATA_BLOB blob = { hdr->cb,
(LPBYTE)pbElement };
ret = contextInterface->setProp(context,
hdr->propID, 0, &blob);
break;
}
case CERT_DATE_STAMP_PROP_ID:
ret = contextInterface->setProp(context,
hdr->propID, 0, pbElement);
break;
case CERT_KEY_PROV_INFO_PROP_ID:
{
PCRYPT_KEY_PROV_INFO info =
(PCRYPT_KEY_PROV_INFO)pbElement;
CRYPT_FixKeyProvInfoPointers(info);
ret = contextInterface->setProp(context,
hdr->propID, 0, pbElement);
break;
}
default:
ret = FALSE;
}
}
else
{
/* ignore the context itself */
ret = TRUE;
}
return ret;
}
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
DWORD dwContextTypeFlags, DWORD *pdwContentType)
{
const void *context;
TRACE("(%p, %ld, %08lx, %p)\n", pbElement, cbElement, dwContextTypeFlags,
TRACE("(%p, %d, %08x, %p)\n", pbElement, cbElement, dwContextTypeFlags,
pdwContentType);
if (!cbElement)
@ -307,76 +381,18 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
const WINE_CERT_PROP_HEADER *hdr =
(const WINE_CERT_PROP_HEADER *)pbElement;
TRACE("prop is %ld\n", hdr->propID);
TRACE("prop is %d\n", hdr->propID);
cbElement -= sizeof(WINE_CERT_PROP_HEADER);
pbElement += sizeof(WINE_CERT_PROP_HEADER);
if (cbElement < hdr->cb)
{
SetLastError(E_INVALIDARG);
ret = FALSE;
}
else if (!hdr->propID)
if (!hdr->propID)
{
/* Like in CRYPT_findPropID, stop if the propID is zero
*/
noMoreProps = TRUE;
}
else if (hdr->unknown != 1)
{
SetLastError(ERROR_FILE_NOT_FOUND);
ret = FALSE;
}
else if (hdr->propID != CERT_CERT_PROP_ID &&
hdr->propID != CERT_CRL_PROP_ID && hdr->propID !=
CERT_CTL_PROP_ID)
{
/* Have to create a blob for most types, but not
* for all.. arghh.
*/
switch (hdr->propID)
{
case CERT_AUTO_ENROLL_PROP_ID:
case CERT_CTL_USAGE_PROP_ID:
case CERT_DESCRIPTION_PROP_ID:
case CERT_FRIENDLY_NAME_PROP_ID:
case CERT_HASH_PROP_ID:
case CERT_KEY_IDENTIFIER_PROP_ID:
case CERT_MD5_HASH_PROP_ID:
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
case CERT_PUBKEY_ALG_PARA_PROP_ID:
case CERT_PVK_FILE_PROP_ID:
case CERT_SIGNATURE_HASH_PROP_ID:
case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_ENROLLMENT_PROP_ID:
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
case CERT_RENEWAL_PROP_ID:
{
CRYPT_DATA_BLOB blob = { hdr->cb,
(LPBYTE)pbElement };
ret = contextInterface->setProp(context,
hdr->propID, 0, &blob);
break;
}
case CERT_DATE_STAMP_PROP_ID:
ret = contextInterface->setProp(context,
hdr->propID, 0, pbElement);
break;
case CERT_KEY_PROV_INFO_PROP_ID:
{
PCRYPT_KEY_PROV_INFO info =
(PCRYPT_KEY_PROV_INFO)pbElement;
CRYPT_FixKeyProvInfoPointers(info);
ret = contextInterface->setProp(context,
hdr->propID, 0, pbElement);
break;
}
default:
FIXME("prop ID %ld: stub\n", hdr->propID);
}
}
else
ret = CRYPT_ReadContextProp(contextInterface, context,
hdr, pbElement, cbElement);
pbElement += hdr->cb;
cbElement -= hdr->cb;
if (!cbElement)
@ -404,6 +420,184 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
return context;
}
static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };
BOOL CRYPT_ReadSerializedFile(HANDLE file, 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);
if (ret)
{
if (!memcmp(fileHeaderBuf, fileHeader, read))
{
WINE_CERT_PROP_HEADER propHdr;
const void *context = NULL;
const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
LPBYTE buf = NULL;
DWORD bufSize = 0;
do {
ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL);
if (ret && read == sizeof(propHdr))
{
if (contextInterface && context &&
(propHdr.propID == CERT_CERT_PROP_ID ||
propHdr.propID == CERT_CRL_PROP_ID ||
propHdr.propID == CERT_CTL_PROP_ID))
{
/* We have a new context, so free the existing one */
contextInterface->free(context);
}
if (propHdr.cb > bufSize)
{
/* Not reusing realloc, because the old data aren't
* needed any longer.
*/
CryptMemFree(buf);
buf = CryptMemAlloc(propHdr.cb);
bufSize = propHdr.cb;
}
if (buf)
{
ret = ReadFile(file, buf, propHdr.cb, &read, NULL);
if (ret && read == propHdr.cb)
{
if (propHdr.propID == CERT_CERT_PROP_ID)
{
contextInterface = pCertInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else if (propHdr.propID == CERT_CRL_PROP_ID)
{
contextInterface = pCRLInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else if (propHdr.propID == CERT_CTL_PROP_ID)
{
contextInterface = pCTLInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else
ret = CRYPT_ReadContextProp(contextInterface,
context, &propHdr, buf, read);
}
}
else
ret = FALSE;
}
} while (ret && read > 0);
if (contextInterface && context)
{
/* Free the last context added */
contextInterface->free(context);
}
CryptMemFree(buf);
ret = TRUE;
}
}
else
ret = TRUE;
return ret;
}
static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCertContext,
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded,
CERT_CERT_PROP_ID, pCertInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL WINAPI CRYPT_SerializeCRLNoHash(PCCRL_CONTEXT pCrlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCrlContext,
pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded,
CERT_CRL_PROP_ID, pCRLInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCtlContext,
pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded,
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
{
const void *context = NULL;
BOOL ret;
do {
context = contextInterface->enumContextsInStore(store, context);
if (context)
{
DWORD size = 0;
LPBYTE buf = NULL;
ret = contextInterface->serialize(context, 0, NULL, &size);
if (size)
buf = CryptMemAlloc(size);
if (buf)
{
ret = contextInterface->serialize(context, 0, buf, &size);
if (ret)
ret = WriteFile(file, buf, size, &size, NULL);
}
CryptMemFree(buf);
}
else
ret = TRUE;
} while (ret && context != NULL);
if (context)
contextInterface->free(context);
return ret;
}
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store)
{
static const BYTE fileTrailer[12] = { 0 };
WINE_CONTEXT_INTERFACE interface;
BOOL ret;
DWORD size;
SetFilePointer(file, 0, NULL, FILE_BEGIN);
ret = WriteFile(file, fileHeader, sizeof(fileHeader), &size, NULL);
if (ret)
{
memcpy(&interface, pCertInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
{
memcpy(&interface, pCRLInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
{
memcpy(&interface, pCTLInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL);
return ret;
}
BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
@ -412,7 +606,7 @@ BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
DWORD type;
BOOL ret;
TRACE("(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore,
TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore,
pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags,
pdwContentType, ppvContext);

View file

@ -0,0 +1,451 @@
/*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2005 Juan Lang
* Copyright 2006 Paul Vriens
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winreg.h"
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
static const WCHAR szOID[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'C','r','y','p','t','o','g','r','a','p','h','y','\\',
'O','I','D','\\',
'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\',
'C','r','y','p','t','S','I','P','D','l','l', 0 };
static const WCHAR szPutSigned[] = {
'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szGetSigned[] = {
'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szRemoveSigned[] = {
'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szCreate[] = {
'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szVerify[] = {
'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szIsMyFile[] = {
'I','s','M','y','F','i','l','e','T','y','p','e','\\',0};
static const WCHAR szIsMyFile2[] = {
'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0};
static const WCHAR szDllName[] = { 'D','l','l',0 };
static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 };
/* convert a guid to a wide character string */
static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr )
{
char str[40];
sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
}
/***********************************************************************
* CRYPT_SIPDeleteFunction
*
* Helper function for CryptSIPRemoveProvider
*/
static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey )
{
WCHAR szFullKey[ 0x100 ];
LONG r = ERROR_SUCCESS;
/* max length of szFullKey depends on our code only, so we won't overrun */
lstrcpyW( szFullKey, szOID );
lstrcatW( szFullKey, szKey );
CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );
r = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szFullKey);
return r;
}
/***********************************************************************
* CryptSIPRemoveProvider (CRYPT32.@)
*
* Remove a SIP provider and its functions from the registry.
*
* PARAMS
* pgProv [I] Pointer to a GUID for this SIP provider
*
* RETURNS
* Success: TRUE.
* Failure: FALSE. (Look at GetLastError()).
*
* NOTES
* Registry errors are always reported via SetLastError(). Every registry
* deletion will be tried.
*/
BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
{
LONG r = ERROR_SUCCESS;
LONG remove_error = ERROR_SUCCESS;
TRACE("%s\n", debugstr_guid(pgProv));
if (!pgProv)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
#define CRYPT_SIPREMOVEPROV( key ) \
r = CRYPT_SIPDeleteFunction( pgProv, key); \
if (r != ERROR_SUCCESS) remove_error = r
CRYPT_SIPREMOVEPROV( szPutSigned);
CRYPT_SIPREMOVEPROV( szGetSigned);
CRYPT_SIPREMOVEPROV( szRemoveSigned);
CRYPT_SIPREMOVEPROV( szCreate);
CRYPT_SIPREMOVEPROV( szVerify);
CRYPT_SIPREMOVEPROV( szIsMyFile);
CRYPT_SIPREMOVEPROV( szIsMyFile2);
#undef CRYPT_SIPREMOVEPROV
if (remove_error != ERROR_SUCCESS)
{
SetLastError(remove_error);
return FALSE;
}
return TRUE;
}
/*
* Helper for CryptSIPAddProvider
*
* Add a registry key containing a dll name and function under
* "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\<func>\\<guid>"
*/
static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey,
LPCWSTR szDll, LPCWSTR szFunction )
{
WCHAR szFullKey[ 0x100 ];
LONG r = ERROR_SUCCESS;
HKEY hKey;
if( !szFunction )
return ERROR_SUCCESS;
/* max length of szFullKey depends on our code only, so we won't overrun */
lstrcpyW( szFullKey, szOID );
lstrcatW( szFullKey, szKey );
CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );
TRACE("key is %s\n", debugstr_w( szFullKey ) );
r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey );
if( r != ERROR_SUCCESS ) goto error_close_key;
/* write the values */
r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction,
( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) );
if( r != ERROR_SUCCESS ) goto error_close_key;
r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll,
( lstrlenW( szDll ) + 1) * sizeof (WCHAR) );
error_close_key:
RegCloseKey( hKey );
return r;
}
/***********************************************************************
* CryptSIPAddProvider (CRYPT32.@)
*
* Add a SIP provider and its functions to the registry.
*
* PARAMS
* psNewProv [I] Pointer to a structure with information about
* the functions this SIP provider can perform.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE. (Look at GetLastError()).
*
* NOTES
* Registry errors are always reported via SetLastError(). If a
* registry error occurs the rest of the registry write operations
* will be skipped.
*/
BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv)
{
LONG r = ERROR_SUCCESS;
TRACE("%p\n", psNewProv);
if (!psNewProv ||
psNewProv->cbStruct != sizeof(SIP_ADD_NEWPROVIDER) ||
!psNewProv->pwszGetFuncName ||
!psNewProv->pwszPutFuncName ||
!psNewProv->pwszCreateFuncName ||
!psNewProv->pwszVerifyFuncName ||
!psNewProv->pwszRemoveFuncName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
TRACE("%s %s %s %s %s\n",
debugstr_guid( psNewProv->pgSubject ),
debugstr_w( psNewProv->pwszDLLFileName ),
debugstr_w( psNewProv->pwszMagicNumber ),
debugstr_w( psNewProv->pwszIsFunctionName ),
debugstr_w( psNewProv->pwszIsFunctionNameFmt2 ) );
#define CRYPT_SIPADDPROV( key, field ) \
r = CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \
psNewProv->pwszDLLFileName, psNewProv->field); \
if (r != ERROR_SUCCESS) goto end_function
CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName );
CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName );
CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName );
CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName );
CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName );
CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName );
CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 );
#undef CRYPT_SIPADDPROV
end_function:
if (r != ERROR_SUCCESS)
{
SetLastError(r);
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CryptSIPRetrieveSubjectGuid (CRYPT32.@)
*
* Determine the right SIP GUID for the given file.
*
* PARAMS
* FileName [I] Filename.
* hFileIn [I] Optional handle to the file.
* pgSubject [O] The SIP's GUID.
*
* RETURNS
* Success: TRUE. pgSubject contains the SIP GUID.
* Failure: FALSE. (Look at GetLastError()).
*
* NOTES
* On failure pgSubject will contain a NULL GUID.
* The handle is always preferred above the filename.
*/
BOOL WINAPI CryptSIPRetrieveSubjectGuid
(LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
{
HANDLE hFile;
HANDLE hFilemapped;
LPVOID pMapped;
BOOL bRet = FALSE;
DWORD fileSize;
IMAGE_DOS_HEADER *dos;
/* FIXME, find out if there is a name for this GUID */
static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject);
if (!pgSubject || (!FileName && !hFileIn))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Set pgSubject to zero's */
memset(pgSubject, 0 , sizeof(GUID));
if (hFileIn)
/* Use the given handle, make sure not to close this one ourselves */
hFile = hFileIn;
else
{
hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
/* Last error is set by CreateFile */
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
}
hFilemapped = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
/* Last error is set by CreateFileMapping */
if (!hFilemapped) goto cleanup3;
pMapped = MapViewOfFile(hFilemapped, FILE_MAP_READ, 0, 0, 0);
/* Last error is set by MapViewOfFile */
if (!pMapped) goto cleanup2;
/* Native checks it right here */
fileSize = GetFileSize(hFile, NULL);
if (fileSize < 4)
{
SetLastError(ERROR_INVALID_PARAMETER);
goto cleanup1;
}
/* As everything is in place now we start looking at the file header */
dos = (IMAGE_DOS_HEADER *)pMapped;
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
{
memcpy(pgSubject, &unknown, sizeof(GUID));
SetLastError(S_OK);
bRet = TRUE;
goto cleanup1;
}
/* FIXME
* There is a lot more to be checked:
* - Check for MSFC in the header
* - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2
* under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are
* functions listed that need check if a SIP Provider can deal with the
* given file.
*/
/* Let's set the most common error for now */
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
/* The 3 different cleanups are here because we shouldn't overwrite the last error */
cleanup1:
UnmapViewOfFile(pMapped);
cleanup2:
CloseHandle(hFilemapped);
cleanup3:
/* If we didn't open this one we shouldn't close it (hFile is a copy) */
if (!hFileIn) CloseHandle(hFile);
return bRet;
}
/***********************************************************************
* CryptSIPLoad (CRYPT32.@)
*
* Load some internal crypt32 functions into a SIP_DISPATCH_INFO structure.
*
* PARAMS
* pgSubject [I] The GUID.
* dwFlags [I] Flags.
* pSipDispatch [I] The loaded functions.
*
* RETURNS
* Success: TRUE. pSipDispatch contains the functions.
* Failure: FALSE. (Look at GetLastError()).
*
* NOTES
* CryptSIPLoad uses caching for the list of GUIDs and whether a SIP is
* already loaded.
*
* An application calls CryptSipLoad which will return a structure with the
* function addresses of some internal crypt32 functions. The application will
* then call these functions which will be forwarded to the appropriate SIP.
*
* CryptSIPLoad will load the needed SIP but doesn't unload this dll. The unloading
* is done when crypt32 is unloaded.
*/
BOOL WINAPI CryptSIPLoad
(const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
{
FIXME("(%s %d %p) stub!\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
if (!pgSubject || dwFlags != 0 || !pSipDispatch)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return FALSE;
}
/***********************************************************************
* CryptSIPCreateIndirectData (CRYPT32.@)
*/
BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
SIP_INDIRECT_DATA* pIndirectData)
{
FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData);
return FALSE;
}
/***********************************************************************
* CryptSIPGetSignedDataMsg (CRYPT32.@)
*/
BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
{
FIXME("(%p %p %d %p %p) stub\n", pSubjectInfo, pdwEncodingType, dwIndex,
pcbSignedDataMsg, pbSignedDataMsg);
return FALSE;
}
/***********************************************************************
* CryptSIPPutSignedDataMsg (CRYPT32.@)
*/
BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
{
FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex,
cbSignedDataMsg, pbSignedDataMsg);
return FALSE;
}
/***********************************************************************
* CryptSIPRemoveSignedDataMsg (CRYPT32.@)
*/
BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
DWORD dwIndex)
{
FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex);
return FALSE;
}
/***********************************************************************
* CryptSIPVerifyIndirectData (CRYPT32.@)
*/
BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
SIP_INDIRECT_DATA* pIndirectData)
{
FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData);
return FALSE;
}

View file

@ -23,6 +23,9 @@
* - Many flags, options and whatnot are unimplemented.
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
@ -163,6 +166,15 @@ typedef struct _WINE_REGSTOREINFO
struct list crlsToDelete;
} WINE_REGSTOREINFO, *PWINE_REGSTOREINFO;
typedef struct _WINE_FILESTOREINFO
{
DWORD dwOpenFlags;
HCRYPTPROV cryptProv;
PWINECRYPT_CERTSTORE memStore;
HANDLE file;
BOOL dirty;
} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
typedef struct _WINE_STORE_LIST_ENTRY
{
PWINECRYPT_CERTSTORE store;
@ -299,9 +311,9 @@ static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
TRACE("(%p, %08lx)\n", store, dwFlags);
TRACE("(%p, %08x)\n", store, dwFlags);
if (dwFlags)
FIXME("Unimplemented flags: %08lx\n", dwFlags);
FIXME("Unimplemented flags: %08x\n", dwFlags);
ContextList_Free(store->certs);
ContextList_Free(store->crls);
@ -313,7 +325,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
{
PWINE_MEMSTORE store;
TRACE("(%ld, %08lx, %p)\n", hCryptProv, dwFlags, pvPara);
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
if (dwFlags & CERT_STORE_DELETE_FLAG)
{
@ -349,7 +361,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
PWINE_STORE_LIST_ENTRY entry, next;
TRACE("(%p, %08lx)\n", store, dwFlags);
TRACE("(%p, %08x)\n", store, dwFlags);
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
entry)
@ -358,6 +370,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
CertCloseStore((HCERTSTORE)entry->store, dwFlags);
CryptMemFree(entry);
}
cs->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&cs->cs);
CryptMemFree(cs);
}
@ -663,6 +676,7 @@ static WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
InitializeCriticalSection(&store->cs);
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
list_init(&store->stores);
}
}
@ -673,7 +687,7 @@ static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
TRACE("(%p, %08lx)\n", store, dwFlags);
TRACE("(%p, %08x)\n", store, dwFlags);
if (store->provCloseStore)
store->provCloseStore(store->hStoreProv, dwFlags);
@ -695,21 +709,13 @@ static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
(const void **)ppStoreContext);
else
{
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
{
SetLastError(ERROR_ACCESS_DENIED);
ret = FALSE;
}
else
{
ret = TRUE;
if (ps->provWriteCert)
ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert,
CERT_STORE_PROV_WRITE_ADD_FLAG);
if (ret)
ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
(const void **)ppStoreContext);
}
ret = TRUE;
if (ps->provWriteCert)
ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert,
CERT_STORE_PROV_WRITE_ADD_FLAG);
if (ret)
ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
(const void **)ppStoreContext);
}
/* dirty trick: replace the returned context's hCertStore with
* store.
@ -822,7 +828,7 @@ static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
BOOL ret = TRUE;
TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType,
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
if (store->provControl)
@ -832,7 +838,7 @@ static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
}
static PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, PWINECRYPT_CERTSTORE memStore, PCERT_STORE_PROV_INFO pProvInfo)
DWORD dwFlags, PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo)
{
PWINE_PROVIDERSTORE ret = (PWINE_PROVIDERSTORE)CryptMemAlloc(
sizeof(WINE_PROVIDERSTORE));
@ -940,7 +946,7 @@ static PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
return ret;
}
static void CRYPT_HashToStr(LPBYTE hash, LPWSTR asciiHash)
static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash)
{
static const WCHAR fmt[] = { '%','0','2','X',0 };
DWORD i;
@ -958,7 +964,7 @@ static const WCHAR CRLsW[] = { 'C','R','L','s',0 };
static const WCHAR CTLsW[] = { 'C','T','L','s',0 };
static const WCHAR BlobW[] = { 'B','l','o','b',0 };
static void CRYPT_RegReadSerializedFromReg(PWINE_REGSTOREINFO store, HKEY key,
static void CRYPT_RegReadSerializedFromReg(const WINE_REGSTOREINFO *store, HKEY key,
DWORD contextType)
{
LONG rc;
@ -1051,9 +1057,9 @@ static void CRYPT_RegReadSerializedFromReg(PWINE_REGSTOREINFO store, HKEY key,
} while (!rc);
}
static void CRYPT_RegReadFromReg(PWINE_REGSTOREINFO store)
static void CRYPT_RegReadFromReg(const WINE_REGSTOREINFO *store)
{
static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW };
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
static const DWORD contextFlags[] = { CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG };
DWORD i;
@ -1074,7 +1080,7 @@ static void CRYPT_RegReadFromReg(PWINE_REGSTOREINFO store)
}
/* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */
static BOOL CRYPT_WriteSerializedToReg(HKEY key, LPBYTE hash, LPBYTE buf,
static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *buf,
DWORD len)
{
WCHAR asciiHash[20 * 2 + 1];
@ -1142,8 +1148,8 @@ static BOOL CRYPT_SerializeContextsToReg(HKEY key,
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
{
static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW };
static const WINE_CONTEXT_INTERFACE *interfaces[] = { &gCertInterface,
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
static const WINE_CONTEXT_INTERFACE * const interfaces[] = { &gCertInterface,
&gCRLInterface, &gCTLInterface };
struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete,
NULL };
@ -1215,12 +1221,13 @@ static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %08lx)\n", store, dwFlags);
TRACE("(%p, %08x)\n", store, dwFlags);
if (dwFlags)
FIXME("Unimplemented flags: %08lx\n", dwFlags);
FIXME("Unimplemented flags: %08x\n", dwFlags);
CRYPT_RegFlushStore(store, FALSE);
RegCloseKey(store->key);
store->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&store->cs);
CryptMemFree(store);
}
@ -1287,7 +1294,7 @@ static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore,
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %ld)\n", hCertStore, cert, dwFlags);
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
return CRYPT_RegWriteContext(store, cert, dwFlags);
}
@ -1297,7 +1304,7 @@ static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore,
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %08lx)\n", store, pCertContext, dwFlags);
TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags);
return CRYPT_RegDeleteContext(store, &store->certsToDelete, pCertContext,
pCertInterface);
@ -1308,7 +1315,7 @@ static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore,
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %ld)\n", hCertStore, crl, dwFlags);
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
return CRYPT_RegWriteContext(store, crl, dwFlags);
}
@ -1318,7 +1325,7 @@ static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %08lx)\n", store, pCrlContext, dwFlags);
TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags);
return CRYPT_RegDeleteContext(store, &store->crlsToDelete, pCrlContext,
pCRLInterface);
@ -1330,7 +1337,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
BOOL ret;
TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType,
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
switch (dwCtrlType)
@ -1346,7 +1353,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG);
break;
default:
FIXME("%ld: stub\n", dwCtrlType);
FIXME("%d: stub\n", dwCtrlType);
ret = FALSE;
}
return ret;
@ -1427,7 +1434,7 @@ static WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv,
{
PWINECRYPT_CERTSTORE store = NULL;
TRACE("(%ld, %08lx, %p)\n", hCryptProv, dwFlags, pvPara);
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
if (dwFlags & CERT_STORE_DELETE_FLAG)
{
@ -1467,6 +1474,7 @@ static WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv,
regInfo->memStore = memStore;
regInfo->key = key;
InitializeCriticalSection(&regInfo->cs);
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
list_init(&regInfo->certsToDelete);
list_init(&regInfo->crlsToDelete);
CRYPT_RegReadFromReg(regInfo);
@ -1502,7 +1510,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
LPCWSTR base;
BOOL ret;
TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags,
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
debugstr_w((LPCWSTR)pvPara));
if (!pvPara)
@ -1602,7 +1610,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
int len;
PWINECRYPT_CERTSTORE ret = NULL;
TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags,
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
debugstr_a((LPCSTR)pvPara));
if (!pvPara)
@ -1631,7 +1639,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
HCERTSTORE store = 0;
BOOL ret;
TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags,
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
debugstr_w((LPCWSTR)pvPara));
if (!pvPara)
@ -1700,7 +1708,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
int len;
PWINECRYPT_CERTSTORE ret = NULL;
TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags,
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
debugstr_a((LPCSTR)pvPara));
if (!pvPara)
@ -1723,12 +1731,215 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
return ret;
}
static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %08x)\n", store, dwFlags);
if (store->dirty)
CRYPT_WriteSerializedFile(store->file, store->memStore);
CertCloseStore(store->memStore, dwFlags);
CloseHandle(store->file);
CryptMemFree(store);
}
static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
PCCERT_CONTEXT cert, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
PCCRL_CONTEXT crl, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
BOOL ret;
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
switch (dwCtrlType)
{
case CERT_STORE_CTRL_RESYNC:
CRYPT_MemEmptyStore((PWINE_MEMSTORE)store->memStore);
CRYPT_ReadSerializedFile(store->file, store);
ret = TRUE;
break;
case CERT_STORE_CTRL_COMMIT:
if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
ret = FALSE;
}
else if (store->dirty)
ret = CRYPT_WriteSerializedFile(store->file, store->memStore);
else
ret = TRUE;
break;
default:
FIXME("%d: stub\n", dwCtrlType);
ret = FALSE;
}
return ret;
}
static void *fileProvFuncs[] = {
CRYPT_FileCloseStore,
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
CRYPT_FileWriteCert,
CRYPT_FileDeleteCert,
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
CRYPT_FileWriteCRL,
CRYPT_FileDeleteCRL,
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
CRYPT_FileControl,
};
static PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
PWINECRYPT_CERTSTORE store = NULL;
HANDLE file = (HANDLE)pvPara;
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
if (!pvPara)
{
SetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
if (dwFlags & CERT_STORE_DELETE_FLAG)
{
SetLastError(E_INVALIDARG);
return NULL;
}
if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
(dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
{
SetLastError(E_INVALIDARG);
return NULL;
}
if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
{
PWINECRYPT_CERTSTORE memStore;
memStore = CRYPT_MemOpenStore(hCryptProv, dwFlags, NULL);
if (memStore)
{
if (CRYPT_ReadSerializedFile(file, memStore))
{
PWINE_FILESTOREINFO info = CryptMemAlloc(
sizeof(WINE_FILESTOREINFO));
if (info)
{
CERT_STORE_PROV_INFO provInfo = { 0 };
info->dwOpenFlags = dwFlags;
info->cryptProv = hCryptProv;
info->memStore = memStore;
info->file = file;
info->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);
provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
sizeof(fileProvFuncs[0]);
provInfo.rgpvStoreProvFunc = fileProvFuncs;
provInfo.hStoreProv = info;
store = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore,
&provInfo);
}
}
}
}
TRACE("returning %p\n", store);
return store;
}
static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
FIXME("(%ld, %08lx, %s): stub\n", hCryptProv, dwFlags,
debugstr_w((LPCWSTR)pvPara));
return NULL;
HCERTSTORE store = 0;
LPCWSTR fileName = (LPCWSTR)pvPara;
DWORD access, create;
HANDLE file;
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
if (!fileName)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return NULL;
}
if (!(dwFlags & (CERT_FILE_STORE_COMMIT_ENABLE_FLAG |
CERT_STORE_READONLY_FLAG)))
{
SetLastError(ERROR_FILE_NOT_FOUND);
return NULL;
}
access = GENERIC_READ;
if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
access |= GENERIC_WRITE;
if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
create = CREATE_NEW;
else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
create = OPEN_EXISTING;
else
create = OPEN_ALWAYS;
file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file != INVALID_HANDLE_VALUE)
{
/* FIXME: need to check whether it's a serialized store; if not, fall
* back to a PKCS#7 signed message, then to a single serialized cert.
*/
store = CertOpenStore(CERT_STORE_PROV_FILE, 0, hCryptProv, dwFlags,
file);
CloseHandle(file);
}
return (PWINECRYPT_CERTSTORE)store;
}
static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
@ -1737,7 +1948,7 @@ static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
int len;
PWINECRYPT_CERTSTORE ret = NULL;
TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags,
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
debugstr_a((LPCSTR)pvPara));
if (!pvPara)
@ -1764,9 +1975,9 @@ static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
FIXME("(%ld, %08lx, %p): stub\n", hCryptProv, dwFlags, pvPara);
FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
else
FIXME("(%ld, %08lx, %s): stub\n", hCryptProv, dwFlags,
FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
debugstr_w((LPCWSTR)pvPara));
return NULL;
}
@ -1778,7 +1989,7 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
WINECRYPT_CERTSTORE *hcs;
StoreOpenFunc openFunc = NULL;
TRACE("(%s, %08lx, %08lx, %08lx, %p)\n", debugstr_a(lpszStoreProvider),
TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
if (!HIWORD(lpszStoreProvider))
@ -1788,6 +1999,9 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
case (int)CERT_STORE_PROV_MEMORY:
openFunc = CRYPT_MemOpenStore;
break;
case (int)CERT_STORE_PROV_FILE:
openFunc = CRYPT_FileOpenStore;
break;
case (int)CERT_STORE_PROV_REG:
openFunc = CRYPT_RegOpenStore;
break;
@ -1822,6 +2036,8 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
}
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
openFunc = CRYPT_MemOpenStore;
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
openFunc = CRYPT_FileOpenStore;
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
openFunc = CRYPT_SysOpenStoreW;
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
@ -1869,7 +2085,7 @@ HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV hProv,
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags)
{
FIXME("(%p,%ld,%ld,%ld,%p,%08lx) stub!\n", hCertStore,
FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore,
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
return TRUE;
}
@ -1900,7 +2116,7 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
BOOL ret = TRUE;
PCCERT_CONTEXT toAdd = NULL, existing = NULL;
TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCertContext,
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
dwAddDisposition, ppStoreContext);
/* Weird case to pass a test */
@ -1954,7 +2170,7 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
CertContext_CopyProperties(existing, pCertContext);
break;
default:
FIXME("Unimplemented add disposition %ld\n", dwAddDisposition);
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
ret = FALSE;
}
@ -2027,7 +2243,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
BOOL ret = TRUE;
PCCRL_CONTEXT toAdd = NULL, existing = NULL;
TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCrlContext,
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
dwAddDisposition, ppStoreContext);
/* Weird case to pass a test */
@ -2088,7 +2304,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
CrlContext_CopyProperties(existing, pCrlContext);
break;
default:
FIXME("Unimplemented add disposition %ld\n", dwAddDisposition);
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
ret = FALSE;
}
@ -2153,7 +2369,7 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
{
FIXME("(%08lx, %p, %08lx): stub\n", dwCertEncodingType, pbCtlEncoded,
FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
cbCtlEncoded);
return NULL;
}
@ -2162,7 +2378,7 @@ BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
{
FIXME("(%p, %08lx, %p, %ld, %08lx, %p): stub\n", hCertStore,
FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
ppCtlContext);
return FALSE;
@ -2172,7 +2388,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
PCCTL_CONTEXT* ppStoreContext)
{
FIXME("(%p, %p, %08lx, %p): stub\n", hCertStore, pCtlContext,
FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
dwAddDisposition, ppStoreContext);
return TRUE;
}
@ -2217,7 +2433,7 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
TRACE("(%p, %08lx)\n", hCertStore, dwFlags);
TRACE("(%p, %08x)\n", hCertStore, dwFlags);
if( ! hCertStore )
return TRUE;
@ -2234,7 +2450,7 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
hcs->closeStore(hcs, dwFlags);
}
else
TRACE("%p's ref count is %ld\n", hcs, hcs->ref);
TRACE("%p's ref count is %d\n", hcs, hcs->ref);
return TRUE;
}
@ -2244,7 +2460,7 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
BOOL ret;
TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType,
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
pvCtrlPara);
if (!hcs)
@ -2264,21 +2480,21 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId)
{
FIXME("(%p, %ld): stub\n", pCTLContext, dwPropId);
FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
return 0;
}
BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, void *pvData, DWORD *pcbData)
{
FIXME("(%p, %ld, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
return FALSE;
}
BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, DWORD dwFlags, const void *pvData)
{
FIXME("(%p, %ld, %08lx, %p): stub\n", pCTLContext, dwPropId, dwFlags,
FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
pvData);
return FALSE;
}
@ -2291,7 +2507,7 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
PWINE_STORE_LIST_ENTRY entry;
BOOL ret;
TRACE("(%p, %p, %08lx, %ld)\n", hCollectionStore, hSiblingStore,
TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
dwUpdateFlags, dwPriority);
if (!collection || !sibling)
@ -2316,12 +2532,12 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
if (entry)
{
InterlockedIncrement(&sibling->ref);
TRACE("sibling %p's ref count is %ld\n", sibling, sibling->ref);
TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
entry->store = sibling;
entry->dwUpdateFlags = dwUpdateFlags;
entry->dwPriority = dwPriority;
list_init(&entry->entry);
TRACE("%p: adding %p, priority %ld\n", collection, entry, dwPriority);
TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
EnterCriticalSection(&collection->cs);
if (dwPriority)
{

View file

@ -19,8 +19,10 @@
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winuser.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@ -29,14 +31,20 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
{
DWORD ret = 0;
TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);
switch (dwValueType)
{
case CERT_RDN_ANY_TYPE:
break;
case CERT_RDN_NUMERIC_STRING:
case CERT_RDN_PRINTABLE_STRING:
case CERT_RDN_TELETEX_STRING:
case CERT_RDN_VIDEOTEX_STRING:
case CERT_RDN_IA5_STRING:
case CERT_RDN_GRAPHIC_STRING:
case CERT_RDN_VISIBLE_STRING:
case CERT_RDN_GENERAL_STRING:
if (!psz || !csz)
ret = pValue->cbData;
else
@ -52,7 +60,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
}
break;
default:
FIXME("string type %ld unimplemented\n", dwValueType);
FIXME("string type %d unimplemented\n", dwValueType);
}
if (psz && csz)
{
@ -62,7 +70,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
}
else
ret++;
TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
TRACE("returning %d (%s)\n", ret, debugstr_a(psz));
return ret;
}
@ -71,14 +79,20 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
{
DWORD ret = 0;
TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);
switch (dwValueType)
{
case CERT_RDN_ANY_TYPE:
break;
case CERT_RDN_NUMERIC_STRING:
case CERT_RDN_PRINTABLE_STRING:
case CERT_RDN_TELETEX_STRING:
case CERT_RDN_VIDEOTEX_STRING:
case CERT_RDN_IA5_STRING:
case CERT_RDN_GRAPHIC_STRING:
case CERT_RDN_VISIBLE_STRING:
case CERT_RDN_GENERAL_STRING:
if (!psz || !csz)
ret = pValue->cbData;
else
@ -97,7 +111,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
}
break;
default:
FIXME("string type %ld unimplemented\n", dwValueType);
FIXME("string type %d unimplemented\n", dwValueType);
}
if (psz && csz)
{
@ -107,7 +121,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
}
else
ret++;
TRACE("returning %ld (%s)\n", ret, debugstr_w(psz));
TRACE("returning %d (%s)\n", ret, debugstr_w(psz));
return ret;
}
@ -120,7 +134,7 @@ static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
{
DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz);
if (psz)
{
@ -150,10 +164,10 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
BOOL bRet;
CERT_NAME_INFO *info;
TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType,
TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
psz, csz);
if (dwStrType & unsupportedFlags)
FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);
FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags);
bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
@ -253,7 +267,7 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
{
DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz);
if (psz)
{
@ -281,7 +295,7 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
{
DWORD chars;
TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz);
TRACE("(%s, %p, %d)\n", debugstr_w(prefix), psz, csz);
if (psz)
{
@ -311,10 +325,10 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
BOOL bRet;
CERT_NAME_INFO *info;
TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType,
TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
psz, csz);
if (dwStrType & unsupportedFlags)
FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);
FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags);
bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
@ -408,12 +422,383 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
return ret;
}
BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
LPCSTR *ppszError)
{
LPWSTR x500, errorStr;
BOOL ret;
int len;
TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded,
ppszError);
len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0);
x500 = CryptMemAlloc(len * sizeof(WCHAR));
if (x500)
{
MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len);
ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved,
pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL);
if (ppszError)
{
DWORD i;
*ppszError = pszX500;
for (i = 0; i < errorStr - x500; i++)
CharNextA(*ppszError);
}
CryptMemFree(x500);
}
else
ret = FALSE;
return ret;
}
struct KeynameKeeper
{
WCHAR buf[10]; /* big enough for L"GivenName" */
LPWSTR keyName; /* usually = buf, but may be allocated */
DWORD keyLen;
};
static void CRYPT_InitializeKeynameKeeper(struct KeynameKeeper *keeper)
{
keeper->keyName = keeper->buf;
keeper->keyLen = sizeof(keeper->buf) / sizeof(keeper->buf[0]);
}
static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper)
{
if (keeper->keyName != keeper->buf)
CryptMemFree(keeper->keyName);
}
struct X500TokenW
{
LPCWSTR start;
LPCWSTR end;
};
static void CRYPT_KeynameKeeperFromTokenW(struct KeynameKeeper *keeper,
const struct X500TokenW *key)
{
DWORD len = key->end - key->start;
if (len > keeper->keyLen)
{
if (keeper->keyName == keeper->buf)
keeper->keyName = CryptMemAlloc(len * sizeof(WCHAR));
else
keeper->keyName = CryptMemRealloc(keeper->keyName,
len * sizeof(WCHAR));
keeper->keyLen = len;
}
memcpy(keeper->keyName, key->start, (key->end - key->start) *
sizeof(WCHAR));
keeper->keyName[len] = '\0';
TRACE("Keyname is %s\n", debugstr_w(keeper->keyName));
}
static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
LPCWSTR *ppszError)
{
DWORD ret = ERROR_SUCCESS;
while (*str && isspaceW(*str))
str++;
if (*str)
{
token->start = str;
while (*str && *str != '=' && !isspaceW(*str))
str++;
if (*str && (*str == '=' || isspaceW(*str)))
token->end = str;
else
{
TRACE("missing equals char at %s\n", debugstr_w(token->start));
if (ppszError)
*ppszError = token->start;
ret = CRYPT_E_INVALID_X500_STRING;
}
}
else
token->start = NULL;
return ret;
}
/* Assumes separators are characters in the 0-255 range */
static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
struct X500TokenW *token, LPCWSTR *ppszError)
{
DWORD ret = ERROR_SUCCESS;
TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token,
ppszError);
while (*str && isspaceW(*str))
str++;
if (*str)
{
token->start = str;
if (!(dwFlags & CERT_NAME_STR_NO_QUOTING_FLAG) && *str == '"')
{
token->end = NULL;
str++;
while (!token->end && !ret)
{
while (*str && *str != '"')
str++;
if (*str == '"')
{
if (*(str + 1) != '"')
token->end = str + 1;
else
str += 2;
}
else
{
TRACE("unterminated quote at %s\n", debugstr_w(str));
if (ppszError)
*ppszError = str;
ret = CRYPT_E_INVALID_X500_STRING;
}
}
}
else
{
WCHAR map[256] = { 0 };
while (*separators)
map[*separators++] = 1;
while (*str && (*str >= 0xff || !map[*(const unsigned short *)str]))
str++;
token->end = str;
}
}
else
{
TRACE("missing value at %s\n", debugstr_w(str));
if (ppszError)
*ppszError = str;
ret = CRYPT_E_INVALID_X500_STRING;
}
return ret;
}
/* Encodes the string represented by value as the string type type into the
* CERT_NAME_BLOB output. If there is an error and ppszError is not NULL,
* *ppszError is set to the first failing character. If there is no error,
* output's pbData must be freed with LocalFree.
*/
static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
const struct X500TokenW *value, PCERT_NAME_BLOB output, DWORD type,
LPCWSTR *ppszError)
{
CERT_NAME_VALUE nameValue = { type, { 0, NULL } };
BOOL ret = FALSE;
nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
sizeof(WCHAR));
if (nameValue.Value.pbData)
{
DWORD i;
LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;
for (i = 0; i < value->end - value->start; i++)
{
*ptr++ = value->start[i];
if (value->start[i] == '"')
i++;
}
nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData;
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE,
&nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData,
&output->cbData);
if (!ret && ppszError)
{
if (type == CERT_RDN_NUMERIC_STRING &&
GetLastError() == CRYPT_E_INVALID_NUMERIC_STRING)
*ppszError = value->start + output->cbData;
else if (type == CERT_RDN_PRINTABLE_STRING &&
GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING)
*ppszError = value->start + output->cbData;
else if (type == CERT_RDN_IA5_STRING &&
GetLastError() == CRYPT_E_INVALID_IA5_STRING)
*ppszError = value->start + output->cbData;
}
CryptMemFree(nameValue.Value.pbData);
}
return ret;
}
static BOOL CRYPT_EncodeValue(DWORD dwCertEncodingType,
const struct X500TokenW *value, PCERT_NAME_BLOB output, const DWORD *types,
LPCWSTR *ppszError)
{
DWORD i;
BOOL ret;
ret = FALSE;
for (i = 0; !ret && types[i]; i++)
ret = CRYPT_EncodeValueWithType(dwCertEncodingType, value, output,
types[i], ppszError);
return ret;
}
static BOOL CRYPT_ValueToRDN(DWORD dwCertEncodingType, PCERT_NAME_INFO info,
PCCRYPT_OID_INFO keyOID, struct X500TokenW *value, LPCWSTR *ppszError)
{
BOOL ret = FALSE;
TRACE("OID %s, value %s\n", debugstr_a(keyOID->pszOID),
debugstr_wn(value->start, value->end - value->start));
if (!info->rgRDN)
info->rgRDN = CryptMemAlloc(sizeof(CERT_RDN));
else
info->rgRDN = CryptMemRealloc(info->rgRDN,
(info->cRDN + 1) * sizeof(CERT_RDN));
if (info->rgRDN)
{
/* FIXME: support multiple RDN attrs */
info->rgRDN[info->cRDN].rgRDNAttr =
CryptMemAlloc(sizeof(CERT_RDN_ATTR));
if (info->rgRDN[info->cRDN].rgRDNAttr)
{
static const DWORD defaultTypes[] = { CERT_RDN_PRINTABLE_STRING,
CERT_RDN_BMP_STRING, 0 };
const DWORD *types;
info->rgRDN[info->cRDN].cRDNAttr = 1;
info->rgRDN[info->cRDN].rgRDNAttr[0].pszObjId =
(LPSTR)keyOID->pszOID;
info->rgRDN[info->cRDN].rgRDNAttr[0].dwValueType =
CERT_RDN_ENCODED_BLOB;
if (keyOID->ExtraInfo.cbData)
types = (const DWORD *)keyOID->ExtraInfo.pbData;
else
types = defaultTypes;
/* Remove surrounding quotes */
if (value->start[0] == '"')
{
value->start++;
value->end--;
}
ret = CRYPT_EncodeValue(dwCertEncodingType, value,
&info->rgRDN[info->cRDN].rgRDNAttr[0].Value, types, ppszError);
}
}
if (ret)
info->cRDN++;
return ret;
}
BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
LPCWSTR *ppszError)
{
CERT_NAME_INFO info = { 0, NULL };
LPCWSTR str;
struct KeynameKeeper keeper;
DWORD i, error = ERROR_SUCCESS;
BOOL ret = TRUE;
TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded,
ppszError);
CRYPT_InitializeKeynameKeeper(&keeper);
str = pszX500;
while (str && *str && !error && ret)
{
struct X500TokenW token;
error = CRYPT_GetNextKeyW(str, &token, ppszError);
if (!error && token.start)
{
PCCRYPT_OID_INFO keyOID;
CRYPT_KeynameKeeperFromTokenW(&keeper, &token);
keyOID = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, keeper.keyName,
CRYPT_RDN_ATTR_OID_GROUP_ID);
if (!keyOID)
{
if (ppszError)
*ppszError = token.start;
error = CRYPT_E_INVALID_X500_STRING;
}
else
{
str = token.end;
while (isspace(*str))
str++;
if (*str != '=')
{
if (ppszError)
*ppszError = str;
error = CRYPT_E_INVALID_X500_STRING;
}
else
{
static const WCHAR commaSep[] = { ',',0 };
static const WCHAR semiSep[] = { ';',0 };
static const WCHAR crlfSep[] = { '\r','\n',0 };
static const WCHAR allSeps[] = { ',',';','\r','\n',0 };
LPCWSTR sep;
str++;
if (dwStrType & CERT_NAME_STR_COMMA_FLAG)
sep = commaSep;
else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
sep = semiSep;
else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
sep = crlfSep;
else
sep = allSeps;
error = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
ppszError);
if (!error)
{
str = token.end;
ret = CRYPT_ValueToRDN(dwCertEncodingType, &info,
keyOID, &token, ppszError);
}
}
}
}
}
CRYPT_FreeKeynameKeeper(&keeper);
if (!error)
{
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info,
0, NULL, pbEncoded, pcbEncoded);
for (i = 0; i < info.cRDN; i++)
{
DWORD j;
for (j = 0; j < info.rgRDN[i].cRDNAttr; j++)
LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData);
CryptMemFree(info.rgRDN[i].rgRDNAttr);
}
CryptMemFree(info.rgRDN);
}
else
{
SetLastError(error);
ret = FALSE;
}
return ret;
}
DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString)
{
DWORD ret;
TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType, dwFlags,
TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, dwFlags,
pvTypePara, pszNameString, cchNameString);
if (pszNameString)
@ -458,7 +843,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
PCERT_NAME_BLOB name;
LPCSTR altNameOID;
TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType,
TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType,
dwFlags, pvTypePara, pszNameString, cchNameString);
if (dwFlags & CERT_NAME_ISSUER_FLAG)
@ -534,7 +919,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
break;
}
default:
FIXME("unimplemented for type %ld\n", dwType);
FIXME("unimplemented for type %d\n", dwType);
ret = 0;
}
return ret;