mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 00:55:48 +00:00
Samuel Serapión (samdwise51 AT gmail DOT com):
- Winesync of crypt32 The function import_certs_from_dir had to be killed, because it uses UNIX-only functions. (see "crypt32_ros.diff") - This gets MSN Messenger a bit more to work svn path=/trunk/; revision=33417
This commit is contained in:
parent
7e4da4bd18
commit
b1c2a48e3b
35 changed files with 12733 additions and 3345 deletions
|
@ -158,7 +158,7 @@ static BOOL CertContext_GetHashProp(void *context, DWORD dwPropId,
|
|||
{
|
||||
BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
|
||||
pcbData);
|
||||
if (ret)
|
||||
if (ret && pvData)
|
||||
{
|
||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||
|
||||
|
@ -167,6 +167,27 @@ static BOOL CertContext_GetHashProp(void *context, DWORD dwPropId,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb,
|
||||
DWORD cb)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!pvData)
|
||||
*pcbData = cb;
|
||||
else if (*pcbData < cb)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = cb;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pvData, pb, cb);
|
||||
*pcbData = cb;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
|
@ -183,24 +204,7 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
|
|||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
{
|
||||
if (!pvData)
|
||||
{
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (*pcbData < blob.cbData)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = blob.cbData;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pvData, blob.pbData, blob.cbData);
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
ret = CertContext_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
|
||||
else
|
||||
{
|
||||
/* Implicit properties */
|
||||
|
@ -238,6 +242,32 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
|
|||
FIXME("CERT_SIGNATURE_HASH_PROP_ID unimplemented\n");
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
break;
|
||||
case CERT_KEY_IDENTIFIER_PROP_ID:
|
||||
{
|
||||
PCERT_EXTENSION ext = CertFindExtension(
|
||||
szOID_SUBJECT_KEY_IDENTIFIER, pCertContext->pCertInfo->cExtension,
|
||||
pCertContext->pCertInfo->rgExtension);
|
||||
|
||||
if (ext)
|
||||
{
|
||||
CRYPT_DATA_BLOB value;
|
||||
DWORD size = sizeof(value);
|
||||
|
||||
ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
|
||||
szOID_SUBJECT_KEY_IDENTIFIER, ext->Value.pbData,
|
||||
ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &value,
|
||||
&size);
|
||||
if (ret)
|
||||
{
|
||||
ret = CertContext_CopyParam(pvData, pcbData, value.pbData,
|
||||
value.cbData);
|
||||
CertContext_SetProperty(context, dwPropId, 0, &value);
|
||||
}
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
}
|
||||
|
@ -286,30 +316,16 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
|||
ret = FALSE;
|
||||
break;
|
||||
case CERT_ACCESS_STATE_PROP_ID:
|
||||
if (!pvData)
|
||||
{
|
||||
*pcbData = sizeof(DWORD);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (*pcbData < sizeof(DWORD))
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = sizeof(DWORD);
|
||||
ret = FALSE;
|
||||
}
|
||||
if (pCertContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCertContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
{
|
||||
*(DWORD *)pvData =
|
||||
CertStore_GetAccessState(pCertContext->hCertStore);
|
||||
ret = TRUE;
|
||||
DWORD state = 0;
|
||||
|
||||
ret = CertContext_CopyParam(pvData, pcbData, &state, sizeof(state));
|
||||
}
|
||||
break;
|
||||
case CERT_KEY_IDENTIFIER_PROP_ID:
|
||||
ret = CertContext_GetProperty((void *)pCertContext, dwPropId,
|
||||
pvData, pcbData);
|
||||
if (!ret)
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
break;
|
||||
case CERT_KEY_PROV_HANDLE_PROP_ID:
|
||||
{
|
||||
CERT_KEY_CONTEXT keyContext;
|
||||
|
@ -318,24 +334,8 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
|||
ret = CertContext_GetProperty((void *)pCertContext,
|
||||
CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
|
||||
if (ret)
|
||||
{
|
||||
if (!pvData)
|
||||
{
|
||||
*pcbData = sizeof(HCRYPTPROV);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (*pcbData < sizeof(HCRYPTPROV))
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = sizeof(HCRYPTPROV);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(HCRYPTPROV *)pvData = keyContext.hCryptProv;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
ret = CertContext_CopyParam(pvData, pcbData, &keyContext.hCryptProv,
|
||||
sizeof(keyContext.hCryptProv));
|
||||
break;
|
||||
}
|
||||
case CERT_KEY_PROV_INFO_PROP_ID:
|
||||
|
@ -496,6 +496,12 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId,
|
|||
{
|
||||
const CERT_KEY_CONTEXT *keyContext = (const CERT_KEY_CONTEXT *)pvData;
|
||||
|
||||
if (keyContext->cbSize != sizeof(CERT_KEY_CONTEXT))
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
(const BYTE *)keyContext, keyContext->cbSize);
|
||||
}
|
||||
|
@ -623,8 +629,8 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert,
|
|||
}
|
||||
|
||||
BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec,
|
||||
BOOL *pfCallerFreeProv)
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv,
|
||||
DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
|
||||
{
|
||||
BOOL ret = FALSE, cache = FALSE;
|
||||
PCRYPT_KEY_PROV_INFO info = NULL;
|
||||
|
@ -700,11 +706,15 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
|
|||
BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType,
|
||||
PCERT_INFO pCertId1, PCERT_INFO pCertId2)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2);
|
||||
|
||||
return CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer,
|
||||
ret = CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer,
|
||||
&pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber,
|
||||
&pCertId2->SerialNumber);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType,
|
||||
|
@ -724,6 +734,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType,
|
|||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -760,12 +771,13 @@ BOOL WINAPI CertCompareIntegerBlob(PCRYPT_INTEGER_BLOB pInt1,
|
|||
if (cb1 == cb2)
|
||||
{
|
||||
if (cb1)
|
||||
ret = !memcmp(pInt1->pbData, pInt1->pbData, cb1);
|
||||
ret = !memcmp(pInt1->pbData, pInt2->pbData, cb1);
|
||||
else
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -819,8 +831,7 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
|
|||
|
||||
if (ret)
|
||||
{
|
||||
RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)((LPBYTE)buf +
|
||||
sizeof(BLOBHEADER));
|
||||
RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
|
||||
|
||||
len = rsaPubKey->bitlen;
|
||||
LocalFree(buf);
|
||||
|
@ -899,16 +910,185 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext,
|
|||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
CERT_INFO *pCertInfo = (CERT_INFO *)pvPara;
|
||||
BOOL ret;
|
||||
|
||||
return CertCompareCertificateName(pCertContext->dwCertEncodingType,
|
||||
/* Matching serial number and subject match.. */
|
||||
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
|
||||
&pCertInfo->Issuer, &pCertContext->pCertInfo->Subject);
|
||||
if (ret)
|
||||
ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber,
|
||||
&pCertInfo->SerialNumber);
|
||||
else
|
||||
{
|
||||
/* failing that, if the serial number and issuer match, we match */
|
||||
ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber,
|
||||
&pCertInfo->SerialNumber);
|
||||
if (ret)
|
||||
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
|
||||
&pCertInfo->Issuer, &pCertContext->pCertInfo->Issuer);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwType, DWORD dwFlags, const void *pvPara)
|
||||
static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
return compare_cert_by_subject_cert(pCertContext, dwType, dwFlags,
|
||||
((PCCERT_CONTEXT)pvPara)->pCertInfo);
|
||||
CERT_ID *id = (CERT_ID *)pvPara;
|
||||
BOOL ret;
|
||||
|
||||
switch (id->dwIdChoice)
|
||||
{
|
||||
case CERT_ID_ISSUER_SERIAL_NUMBER:
|
||||
ret = CertCompareCertificateName(pCertContext->dwCertEncodingType,
|
||||
&pCertContext->pCertInfo->Issuer, &id->u.IssuerSerialNumber.Issuer);
|
||||
if (ret)
|
||||
ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber,
|
||||
&id->u.IssuerSerialNumber.SerialNumber);
|
||||
break;
|
||||
case CERT_ID_SHA1_HASH:
|
||||
ret = compare_cert_by_sha1_hash(pCertContext, dwType, dwFlags,
|
||||
&id->u.HashId);
|
||||
break;
|
||||
case CERT_ID_KEY_IDENTIFIER:
|
||||
{
|
||||
DWORD size = 0;
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
|
||||
if (ret && size == id->u.KeyId.cbData)
|
||||
{
|
||||
LPBYTE buf = CryptMemAlloc(size);
|
||||
|
||||
if (buf)
|
||||
{
|
||||
CertGetCertificateContextProperty(pCertContext,
|
||||
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
|
||||
ret = !memcmp(buf, id->u.KeyId.pbData, size);
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
PCCERT_CONTEXT subject = (PCCERT_CONTEXT)pvPara;
|
||||
PCERT_EXTENSION ext;
|
||||
DWORD size;
|
||||
|
||||
if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
|
||||
subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
|
||||
{
|
||||
CERT_AUTHORITY_KEY_ID_INFO *info;
|
||||
|
||||
ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
|
||||
X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
|
||||
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
|
||||
&info, &size);
|
||||
if (ret)
|
||||
{
|
||||
CERT_ID id;
|
||||
|
||||
if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
|
||||
{
|
||||
id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
|
||||
memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer,
|
||||
sizeof(CERT_NAME_BLOB));
|
||||
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
|
||||
&info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
|
||||
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
|
||||
&id);
|
||||
}
|
||||
else if (info->KeyId.cbData)
|
||||
{
|
||||
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
|
||||
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
|
||||
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
|
||||
&id);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
LocalFree(info);
|
||||
}
|
||||
}
|
||||
else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
|
||||
subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
|
||||
{
|
||||
CERT_AUTHORITY_KEY_ID2_INFO *info;
|
||||
|
||||
ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
|
||||
X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
|
||||
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
|
||||
&info, &size);
|
||||
if (ret)
|
||||
{
|
||||
CERT_ID id;
|
||||
|
||||
if (info->AuthorityCertIssuer.cAltEntry &&
|
||||
info->AuthorityCertSerialNumber.cbData)
|
||||
{
|
||||
PCERT_ALT_NAME_ENTRY directoryName = NULL;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; !directoryName &&
|
||||
i < info->AuthorityCertIssuer.cAltEntry; i++)
|
||||
if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
|
||||
== CERT_ALT_NAME_DIRECTORY_NAME)
|
||||
directoryName =
|
||||
&info->AuthorityCertIssuer.rgAltEntry[i];
|
||||
if (directoryName)
|
||||
{
|
||||
id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
|
||||
memcpy(&id.u.IssuerSerialNumber.Issuer,
|
||||
&directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB));
|
||||
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
|
||||
&info->AuthorityCertSerialNumber,
|
||||
sizeof(CRYPT_INTEGER_BLOB));
|
||||
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
|
||||
&id);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("no supported name type in authority key id2\n");
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else if (info->KeyId.cbData)
|
||||
{
|
||||
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
|
||||
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
|
||||
ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags,
|
||||
&id);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
LocalFree(info);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = compare_cert_by_name(pCertContext,
|
||||
CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags,
|
||||
&subject->pCertInfo->Issuer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PCCERT_CONTEXT toCompare = (PCCERT_CONTEXT)pvPara;
|
||||
return CertCompareCertificate(pCertContext->dwCertEncodingType,
|
||||
pCertContext->pCertInfo, toCompare->pCertInfo);
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
||||
|
@ -918,7 +1098,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
|||
PCCERT_CONTEXT ret;
|
||||
CertCompareFunc compare;
|
||||
|
||||
TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType,
|
||||
TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType,
|
||||
dwFlags, dwType, pvPara, pPrevCertContext);
|
||||
|
||||
switch (dwType >> CERT_COMPARE_SHIFT)
|
||||
|
@ -938,9 +1118,15 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
|||
case CERT_COMPARE_SUBJECT_CERT:
|
||||
compare = compare_cert_by_subject_cert;
|
||||
break;
|
||||
case CERT_COMPARE_CERT_ID:
|
||||
compare = compare_cert_by_cert_id;
|
||||
break;
|
||||
case CERT_COMPARE_ISSUER_OF:
|
||||
compare = compare_cert_by_issuer;
|
||||
break;
|
||||
case CERT_COMPARE_EXISTING:
|
||||
compare = compare_existing_cert;
|
||||
break;
|
||||
default:
|
||||
FIXME("find type %08x unimplemented\n", dwType);
|
||||
compare = NULL;
|
||||
|
@ -964,6 +1150,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
|
|||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1237,89 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
|
|||
ret = NULL;
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct _OLD_CERT_REVOCATION_STATUS {
|
||||
DWORD cbSize;
|
||||
DWORD dwIndex;
|
||||
DWORD dwError;
|
||||
DWORD dwReason;
|
||||
} OLD_CERT_REVOCATION_STATUS, *POLD_CERT_REVOCATION_STATUS;
|
||||
|
||||
typedef BOOL (WINAPI *CertVerifyRevocationFunc)(DWORD, DWORD, DWORD,
|
||||
void **, DWORD, PCERT_REVOCATION_PARA, PCERT_REVOCATION_STATUS);
|
||||
|
||||
BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType,
|
||||
DWORD cContext, PVOID rgpvContext[], DWORD dwFlags,
|
||||
PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType,
|
||||
cContext, rgpvContext, dwFlags, pRevPara, pRevStatus);
|
||||
|
||||
if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) &&
|
||||
pRevStatus->cbSize != sizeof(CERT_REVOCATION_STATUS))
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
if (cContext)
|
||||
{
|
||||
static HCRYPTOIDFUNCSET set = NULL;
|
||||
DWORD size;
|
||||
|
||||
if (!set)
|
||||
set = CryptInitOIDFunctionSet(CRYPT_OID_VERIFY_REVOCATION_FUNC, 0);
|
||||
ret = CryptGetDefaultOIDDllList(set, dwEncodingType, NULL, &size);
|
||||
if (ret)
|
||||
{
|
||||
if (size == 1)
|
||||
{
|
||||
/* empty list */
|
||||
SetLastError(CRYPT_E_NO_REVOCATION_DLL);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR)), ptr;
|
||||
|
||||
if (dllList)
|
||||
{
|
||||
ret = CryptGetDefaultOIDDllList(set, dwEncodingType,
|
||||
dllList, &size);
|
||||
if (ret)
|
||||
{
|
||||
for (ptr = dllList; ret && *ptr;
|
||||
ptr += lstrlenW(ptr) + 1)
|
||||
{
|
||||
CertVerifyRevocationFunc func;
|
||||
HCRYPTOIDFUNCADDR hFunc;
|
||||
|
||||
ret = CryptGetDefaultOIDFunctionAddress(set,
|
||||
dwEncodingType, ptr, 0, (void **)&func, &hFunc);
|
||||
if (ret)
|
||||
{
|
||||
ret = func(dwEncodingType, dwRevType, cContext,
|
||||
rgpvContext, dwFlags, pRevPara, pRevStatus);
|
||||
CryptFreeOIDFunctionAddress(hFunc, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(dllList);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1128,10 +1397,7 @@ LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify,
|
|||
|
||||
if (!pTimeToVerify)
|
||||
{
|
||||
SYSTEMTIME sysTime;
|
||||
|
||||
GetSystemTime(&sysTime);
|
||||
SystemTimeToFileTime(&sysTime, &fileTime);
|
||||
GetSystemTimeAsFileTime(&fileTime);
|
||||
pTimeToVerify = &fileTime;
|
||||
}
|
||||
if ((ret = CompareFileTime(pTimeToVerify, &pCertInfo->NotBefore)) >= 0)
|
||||
|
@ -1152,7 +1418,7 @@ BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo,
|
|||
&& CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
|
||||
BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
|
||||
DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
|
||||
DWORD *pcbComputedHash)
|
||||
{
|
||||
|
@ -1181,7 +1447,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid,
|
||||
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
|
||||
DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo,
|
||||
BYTE *pbComputedHash, DWORD *pcbComputedHash)
|
||||
{
|
||||
|
@ -1219,8 +1485,8 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptSignCertificate(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
|
||||
DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
|
||||
BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
|
||||
DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
|
||||
DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
|
||||
const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
|
||||
{
|
||||
|
@ -1278,10 +1544,10 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV hCryptProv,
|
||||
BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
|
||||
DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
|
||||
const void *pvHashAuxInfo, PBYTE pbEncoded, DWORD *pcbEncoded)
|
||||
const void *pvHashAuxInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
|
||||
{
|
||||
BOOL ret;
|
||||
DWORD encodedSize, hashSize;
|
||||
|
@ -1339,7 +1605,7 @@ BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV hCryptProv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV hCryptProv,
|
||||
BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
PCERT_PUBLIC_KEY_INFO pPublicKey)
|
||||
{
|
||||
|
@ -1348,7 +1614,7 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV hCryptProv,
|
|||
CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pPublicKey, 0, NULL);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV hCryptProv,
|
||||
static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
|
||||
const CERT_SIGNED_CONTENT_INFO *signedCert)
|
||||
{
|
||||
|
@ -1358,38 +1624,17 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV hCryptProv,
|
|||
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))
|
||||
signedCert->SignatureAlgorithm.pszObjId, 0);
|
||||
if (!info || 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();
|
||||
|
@ -1414,7 +1659,7 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV hCryptProv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv,
|
||||
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
|
||||
DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
|
||||
{
|
||||
|
@ -1656,6 +1901,18 @@ BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext,
|
|||
ret = CertGetEnhancedKeyUsage(pCertContext,
|
||||
CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, usage, &size);
|
||||
if (ret)
|
||||
{
|
||||
DWORD i;
|
||||
BOOL exists = FALSE;
|
||||
|
||||
/* Make sure usage doesn't already exist */
|
||||
for (i = 0; !exists && i < usage->cUsageIdentifier; i++)
|
||||
{
|
||||
if (!strcmp(usage->rgpszUsageIdentifier[i],
|
||||
pszUsageIdentifier))
|
||||
exists = TRUE;
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
PCERT_ENHKEY_USAGE newUsage = CryptMemAlloc(size +
|
||||
sizeof(LPSTR) + strlen(pszUsageIdentifier) + 1);
|
||||
|
@ -1663,12 +1920,11 @@ BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext,
|
|||
if (newUsage)
|
||||
{
|
||||
LPSTR nextOID;
|
||||
DWORD i;
|
||||
|
||||
newUsage->rgpszUsageIdentifier =
|
||||
(LPSTR *)((LPBYTE)newUsage + sizeof(CERT_ENHKEY_USAGE));
|
||||
nextOID = (LPSTR)((LPBYTE)newUsage->rgpszUsageIdentifier +
|
||||
(usage->cUsageIdentifier + 1) * sizeof(LPSTR));
|
||||
newUsage->rgpszUsageIdentifier = (LPSTR *)
|
||||
((LPBYTE)newUsage + sizeof(CERT_ENHKEY_USAGE));
|
||||
nextOID = (LPSTR)((LPBYTE)newUsage->rgpszUsageIdentifier
|
||||
+ (usage->cUsageIdentifier + 1) * sizeof(LPSTR));
|
||||
for (i = 0; i < usage->cUsageIdentifier; i++)
|
||||
{
|
||||
newUsage->rgpszUsageIdentifier[i] = nextOID;
|
||||
|
@ -1681,6 +1937,9 @@ BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext,
|
|||
ret = CertSetEnhancedKeyUsage(pCertContext, newUsage);
|
||||
CryptMemFree(newUsage);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
CryptMemFree(usage);
|
||||
}
|
||||
|
@ -1766,18 +2025,57 @@ BOOL WINAPI CertRemoveEnhancedKeyUsageIdentifier(PCCERT_CONTEXT pCertContext,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct BitField
|
||||
{
|
||||
DWORD cIndexes;
|
||||
DWORD *indexes;
|
||||
};
|
||||
|
||||
#define BITS_PER_DWORD (sizeof(DWORD) * 8)
|
||||
|
||||
static void CRYPT_SetBitInField(struct BitField *field, DWORD bit)
|
||||
{
|
||||
DWORD indexIndex = bit / BITS_PER_DWORD;
|
||||
|
||||
if (indexIndex + 1 > field->cIndexes)
|
||||
{
|
||||
if (field->cIndexes)
|
||||
field->indexes = CryptMemRealloc(field->indexes,
|
||||
(indexIndex + 1) * sizeof(DWORD));
|
||||
else
|
||||
field->indexes = CryptMemAlloc(sizeof(DWORD));
|
||||
if (field->indexes)
|
||||
{
|
||||
field->indexes[indexIndex] = 0;
|
||||
field->cIndexes = indexIndex + 1;
|
||||
}
|
||||
}
|
||||
if (field->indexes)
|
||||
field->indexes[indexIndex] |= 1 << (bit % BITS_PER_DWORD);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_IsBitInFieldSet(struct BitField *field, DWORD bit)
|
||||
{
|
||||
BOOL set = FALSE;
|
||||
DWORD indexIndex = bit / BITS_PER_DWORD;
|
||||
|
||||
assert(field->cIndexes);
|
||||
set = field->indexes[indexIndex] & (1 << (bit % BITS_PER_DWORD));
|
||||
return set;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
||||
int *cNumOIDSs, LPSTR *rghOIDs, DWORD *pcbOIDs)
|
||||
int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
DWORD i, cbOIDs = 0;
|
||||
BOOL allUsagesValid = TRUE;
|
||||
CERT_ENHKEY_USAGE validUsages = { 0, NULL };
|
||||
|
||||
TRACE("(%d, %p, %p, %p, %d)\n", cCerts, *rghCerts, cNumOIDSs,
|
||||
TRACE("(%d, %p, %d, %p, %d)\n", cCerts, rghCerts, *cNumOIDs,
|
||||
rghOIDs, *pcbOIDs);
|
||||
|
||||
for (i = 0; ret && i < cCerts; i++)
|
||||
for (i = 0; i < cCerts; i++)
|
||||
{
|
||||
CERT_ENHKEY_USAGE usage;
|
||||
DWORD size = sizeof(usage);
|
||||
|
@ -1819,12 +2117,11 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
nextOID += lstrlenA(nextOID) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD j, k, validIndexes = 0, numRemoved = 0;
|
||||
struct BitField validIndexes = { 0, NULL };
|
||||
DWORD j, k, numRemoved = 0;
|
||||
|
||||
/* Merge: build a bitmap of all the indexes of
|
||||
* validUsages.rgpszUsageIdentifier that are in pUsage.
|
||||
|
@ -1836,7 +2133,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
if (!strcmp(pUsage->rgpszUsageIdentifier[j],
|
||||
validUsages.rgpszUsageIdentifier[k]))
|
||||
{
|
||||
validIndexes |= (1 << k);
|
||||
CRYPT_SetBitInField(&validIndexes, k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1846,11 +2143,11 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
*/
|
||||
for (j = 0; j < validUsages.cUsageIdentifier; j++)
|
||||
{
|
||||
if (!(validIndexes & (1 << j)))
|
||||
if (!CRYPT_IsBitInFieldSet(&validIndexes, j))
|
||||
{
|
||||
if (j < validUsages.cUsageIdentifier - 1)
|
||||
{
|
||||
memcpy(&validUsages.rgpszUsageIdentifier[j],
|
||||
memmove(&validUsages.rgpszUsageIdentifier[j],
|
||||
&validUsages.rgpszUsageIdentifier[j +
|
||||
numRemoved + 1],
|
||||
(validUsages.cUsageIdentifier - numRemoved
|
||||
|
@ -1858,30 +2155,32 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
cbOIDs -= lstrlenA(
|
||||
validUsages.rgpszUsageIdentifier[j]) + 1 +
|
||||
sizeof(LPSTR);
|
||||
validUsages.cUsageIdentifier--;
|
||||
numRemoved++;
|
||||
}
|
||||
else
|
||||
validUsages.cUsageIdentifier--;
|
||||
}
|
||||
}
|
||||
CryptMemFree(validIndexes.indexes);
|
||||
}
|
||||
}
|
||||
CryptMemFree(pUsage);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
ret = TRUE;
|
||||
if (allUsagesValid)
|
||||
{
|
||||
*cNumOIDSs = -1;
|
||||
*cNumOIDs = -1;
|
||||
*pcbOIDs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!rghOIDs || *pcbOIDs < cbOIDs)
|
||||
*cNumOIDs = validUsages.cUsageIdentifier;
|
||||
if (!rghOIDs)
|
||||
*pcbOIDs = cbOIDs;
|
||||
else if (*pcbOIDs < cbOIDs)
|
||||
{
|
||||
*pcbOIDs = cbOIDs;
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
|
@ -1893,7 +2192,6 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
validUsages.cUsageIdentifier * sizeof(LPSTR));
|
||||
|
||||
*pcbOIDs = cbOIDs;
|
||||
*cNumOIDSs = validUsages.cUsageIdentifier;
|
||||
for (i = 0; i < validUsages.cUsageIdentifier; i++)
|
||||
{
|
||||
rghOIDs[i] = nextOID;
|
||||
|
@ -1902,8 +2200,9 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(validUsages.rgpszUsageIdentifier);
|
||||
TRACE("cNumOIDs: %d\n", *cNumOIDs);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1970,9 +2269,9 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
|
|||
}
|
||||
}
|
||||
size = sizeof(info.dwKeySpec);
|
||||
ret = CryptGetProvParam(hProv, PP_KEYSPEC, (LPBYTE)&info.dwKeySpec,
|
||||
&size, 0);
|
||||
if (!ret)
|
||||
/* in case no CRYPT_KEY_PROV_INFO given,
|
||||
* we always use AT_SIGNATURE key spec
|
||||
*/
|
||||
info.dwKeySpec = AT_SIGNATURE;
|
||||
size = sizeof(info.dwProvType);
|
||||
ret = CryptGetProvParam(hProv, PP_PROVTYPE, (LPBYTE)&info.dwProvType,
|
||||
|
@ -1996,19 +2295,19 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context,
|
|||
* in blob, using the crypto provider hProv and the signature algorithm sigAlgo.
|
||||
*/
|
||||
static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob,
|
||||
HCRYPTPROV hProv, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
|
||||
HCRYPTPROV hProv, DWORD dwKeySpec, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo)
|
||||
{
|
||||
PCCERT_CONTEXT context = NULL;
|
||||
BOOL ret;
|
||||
DWORD sigSize = 0;
|
||||
|
||||
ret = CryptSignCertificate(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
||||
ret = CryptSignCertificate(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, sigAlgo, NULL, NULL, &sigSize);
|
||||
if (ret)
|
||||
{
|
||||
LPBYTE sig = CryptMemAlloc(sigSize);
|
||||
|
||||
ret = CryptSignCertificate(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
||||
ret = CryptSignCertificate(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, sigAlgo, NULL, sig, &sigSize);
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2159,7 +2458,7 @@ static HCRYPTPROV CRYPT_CreateKeyProv(void)
|
|||
return hProv;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
||||
PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv,
|
||||
PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD dwFlags,
|
||||
PCRYPT_KEY_PROV_INFO pKeyProvInfo,
|
||||
PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime,
|
||||
|
@ -2168,24 +2467,80 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
|||
PCCERT_CONTEXT context = NULL;
|
||||
BOOL ret, releaseContext = FALSE;
|
||||
PCERT_PUBLIC_KEY_INFO pubKey = NULL;
|
||||
DWORD pubKeySize = 0;
|
||||
DWORD pubKeySize = 0,dwKeySpec = AT_SIGNATURE;
|
||||
|
||||
TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
|
||||
pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
|
||||
pExtensions, pExtensions);
|
||||
|
||||
if(!pSubjectIssuerBlob)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!hProv)
|
||||
{
|
||||
if (!pKeyProvInfo)
|
||||
{
|
||||
hProv = CRYPT_CreateKeyProv();
|
||||
releaseContext = TRUE;
|
||||
}
|
||||
else if (pKeyProvInfo->dwFlags & CERT_SET_KEY_PROV_HANDLE_PROP_ID)
|
||||
{
|
||||
SetLastError(NTE_BAD_FLAGS);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HCRYPTKEY hKey = 0;
|
||||
/* acquire the context using the given information*/
|
||||
ret = CryptAcquireContextW(&hProv,pKeyProvInfo->pwszContainerName,
|
||||
pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
|
||||
pKeyProvInfo->dwFlags);
|
||||
if (!ret)
|
||||
{
|
||||
if(GetLastError() != NTE_BAD_KEYSET)
|
||||
return NULL;
|
||||
/* create the key set */
|
||||
ret = CryptAcquireContextW(&hProv,pKeyProvInfo->pwszContainerName,
|
||||
pKeyProvInfo->pwszProvName,pKeyProvInfo->dwProvType,
|
||||
pKeyProvInfo->dwFlags|CRYPT_NEWKEYSET);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
}
|
||||
dwKeySpec = pKeyProvInfo->dwKeySpec;
|
||||
/* check if the key is here */
|
||||
ret = CryptGetUserKey(hProv,dwKeySpec,&hKey);
|
||||
if(!ret)
|
||||
{
|
||||
if (NTE_NO_KEY == GetLastError())
|
||||
{ /* generate the key */
|
||||
ret = CryptGenKey(hProv,dwKeySpec,0,&hKey);
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
CryptReleaseContext(hProv,0);
|
||||
SetLastError(NTE_BAD_KEYSET);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
CryptDestroyKey(hKey);
|
||||
releaseContext = TRUE;
|
||||
}
|
||||
}
|
||||
else if (pKeyProvInfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
|
||||
CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING, NULL,
|
||||
&pubKeySize);
|
||||
pubKey = CryptMemAlloc(pubKeySize);
|
||||
if (pubKey)
|
||||
{
|
||||
ret = CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING,
|
||||
ret = CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING,
|
||||
pubKey, &pubKeySize);
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2203,7 +2558,7 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
|||
if (ret)
|
||||
{
|
||||
if (!(dwFlags & CERT_CREATE_SELFSIGN_NO_SIGN))
|
||||
context = CRYPT_CreateSignedCert(&blob, hProv,
|
||||
context = CRYPT_CreateSignedCert(&blob, hProv,dwKeySpec,
|
||||
&info.SignatureAlgorithm);
|
||||
else
|
||||
context = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||||
|
@ -2219,3 +2574,15 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv,
|
|||
CryptReleaseContext(hProv, 0);
|
||||
return context;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType,
|
||||
void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags,
|
||||
PCTL_VERIFY_USAGE_PARA pVerifyUsagePara,
|
||||
PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus)
|
||||
{
|
||||
FIXME("(0x%x, %d, %p, %p, 0x%x, %p, %p): stub\n", dwEncodingType,
|
||||
dwSubjectType, pvSubject, pSubjectUsage, dwFlags, pVerifyUsagePara,
|
||||
pVerifyUsageStatus);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
480
reactos/dll/win32/crypt32/collectionstore.c
Normal file
480
reactos/dll/win32/crypt32/collectionstore.c
Normal file
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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 "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_STORE_LIST_ENTRY
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store;
|
||||
DWORD dwUpdateFlags;
|
||||
DWORD dwPriority;
|
||||
struct list entry;
|
||||
} WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
|
||||
|
||||
typedef struct _WINE_COLLECTIONSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list stores;
|
||||
} WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
|
||||
|
||||
static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
|
||||
entry)
|
||||
{
|
||||
TRACE("closing %p\n", entry);
|
||||
CertCloseStore((HCERTSTORE)entry->store, dwFlags);
|
||||
CryptMemFree(entry);
|
||||
}
|
||||
cs->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&cs->cs);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
|
||||
BOOL addRef)
|
||||
{
|
||||
void *ret = Context_CreateLinkContext(contextSize, child,
|
||||
sizeof(PWINE_STORE_LIST_ENTRY), addRef);
|
||||
|
||||
if (ret)
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
|
||||
= storeEntry;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
|
||||
unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
|
||||
void **pChildContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = NULL;
|
||||
|
||||
TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
|
||||
toReplace, contextSize);
|
||||
|
||||
ret = FALSE;
|
||||
if (toReplace)
|
||||
{
|
||||
void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
|
||||
PCONTEXT_FUNCS contextFuncs;
|
||||
|
||||
storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
|
||||
contextSize);
|
||||
contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
|
||||
contextFuncsOffset);
|
||||
ret = contextFuncs->addContext(storeEntry->store, context,
|
||||
existingLinked, childContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
|
||||
{
|
||||
PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
|
||||
(LPBYTE)entry->store + contextFuncsOffset);
|
||||
|
||||
storeEntry = entry;
|
||||
ret = contextFuncs->addContext(entry->store, context, NULL,
|
||||
(const void **)&childContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
if (!storeEntry)
|
||||
SetLastError(E_ACCESSDENIED);
|
||||
}
|
||||
*pChildContext = childContext;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Advances a collection enumeration by one context, if possible, where
|
||||
* advancing means:
|
||||
* - calling the current store's enumeration function once, and returning
|
||||
* the enumerated context if one is returned
|
||||
* - moving to the next store if the current store has no more items, and
|
||||
* recursively calling itself to get the next item.
|
||||
* Returns NULL if the collection contains no more items or on error.
|
||||
* Assumes the collection store's lock is held.
|
||||
*/
|
||||
static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, PCONTEXT_FUNCS contextFuncs,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
|
||||
{
|
||||
void *ret, *child;
|
||||
struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
|
||||
|
||||
TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
|
||||
|
||||
if (pPrev)
|
||||
{
|
||||
/* Ref-counting funny business: "duplicate" (addref) the child, because
|
||||
* the free(pPrev) below can cause the ref count to become negative.
|
||||
*/
|
||||
child = Context_GetLinkedContext(pPrev, contextSize);
|
||||
contextInterface->duplicate(child);
|
||||
child = contextFuncs->enumContext(storeEntry->store, child);
|
||||
contextInterface->free(pPrev);
|
||||
pPrev = NULL;
|
||||
}
|
||||
else
|
||||
child = contextFuncs->enumContext(storeEntry->store, NULL);
|
||||
if (child)
|
||||
ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
|
||||
contextSize, FALSE);
|
||||
else
|
||||
{
|
||||
if (storeNext)
|
||||
{
|
||||
/* We always want the same function pointers (from certs, crls)
|
||||
* in the next store, so use the same offset into the next store.
|
||||
*/
|
||||
size_t offset = (LPBYTE)contextFuncs - (LPBYTE)storeEntry->store;
|
||||
PWINE_STORE_LIST_ENTRY storeNextEntry =
|
||||
LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
|
||||
PCONTEXT_FUNCS storeNextContexts =
|
||||
(PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
|
||||
storeNextContexts, contextInterface, NULL, contextSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
|
||||
cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
|
||||
PCERT_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CERT_CONTEXT), TRUE);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
}
|
||||
CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, NULL,
|
||||
sizeof(CERT_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
|
||||
void *pCertContext)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCertContext);
|
||||
|
||||
ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
|
||||
Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
|
||||
crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
|
||||
PCRL_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CRL_CONTEXT), TRUE);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
}
|
||||
CertFreeCRLContext((PCCRL_CONTEXT)childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CRL_CONTEXT));
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, NULL,
|
||||
sizeof(CRL_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
|
||||
void *pCrlContext)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCrlContext);
|
||||
|
||||
ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
|
||||
Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE store;
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
store = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
|
||||
if (store)
|
||||
{
|
||||
memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection);
|
||||
store->hdr.closeStore = CRYPT_CollectionCloseStore;
|
||||
store->hdr.certs.addContext = CRYPT_CollectionAddCert;
|
||||
store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
|
||||
store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
|
||||
store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
|
||||
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);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY entry;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
|
||||
dwUpdateFlags, dwPriority);
|
||||
|
||||
if (!collection || !sibling)
|
||||
return TRUE;
|
||||
if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
if (collection->hdr.type != StoreTypeCollection)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
|
||||
if (entry)
|
||||
{
|
||||
InterlockedIncrement(&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 %d\n", collection, entry, dwPriority);
|
||||
EnterCriticalSection(&collection->cs);
|
||||
if (dwPriority)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY cursor;
|
||||
BOOL added = FALSE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (cursor->dwPriority < dwPriority)
|
||||
{
|
||||
list_add_before(&cursor->entry, &entry->entry);
|
||||
added = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added)
|
||||
list_add_tail(&collection->stores, &entry->entry);
|
||||
}
|
||||
else
|
||||
list_add_tail(&collection->stores, &entry->entry);
|
||||
LeaveCriticalSection(&collection->cs);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY store, next;
|
||||
|
||||
TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
|
||||
|
||||
if (!collection || !sibling)
|
||||
return;
|
||||
if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
if (collection->hdr.type != StoreTypeCollection)
|
||||
return;
|
||||
if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
EnterCriticalSection(&collection->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (store->store == sibling)
|
||||
{
|
||||
list_remove(&store->entry);
|
||||
CertCloseStore(store->store, 0);
|
||||
CryptMemFree(store);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&collection->cs);
|
||||
}
|
|
@ -71,6 +71,7 @@ void *Context_CreateDataContext(size_t contextSize)
|
|||
ret = NULL;
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -96,6 +97,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned
|
|||
InterlockedIncrement(&linkedBase->ref);
|
||||
TRACE("%p's ref count is %d\n", context, linkContext->ref);
|
||||
}
|
||||
TRACE("returning %p\n", context);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -123,7 +125,7 @@ void *Context_GetLinkedContext(void *context, size_t contextSize)
|
|||
contextSize);
|
||||
}
|
||||
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(void *context, size_t contextSize)
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize)
|
||||
{
|
||||
PBASE_CONTEXT ptr = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
|
||||
|
@ -242,7 +244,7 @@ void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace)
|
|||
list->contextInterface->free(toReplace);
|
||||
}
|
||||
else
|
||||
list_add_tail(&list->contexts, entry);
|
||||
list_add_head(&list->contexts, entry);
|
||||
LeaveCriticalSection(&list->cs);
|
||||
}
|
||||
return context;
|
||||
|
|
|
@ -266,10 +266,10 @@ DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
|
||||
static BOOL CRLContext_GetHashProp(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_GetHashProp(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||
DWORD *pcbData)
|
||||
{
|
||||
|
@ -284,10 +284,9 @@ static BOOL CRLContext_GetHashProp(void *context, DWORD dwPropId,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_GetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PCCRL_CONTEXT pCRLContext = (PCCRL_CONTEXT)context;
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CRL_CONTEXT));
|
||||
BOOL ret;
|
||||
|
@ -302,20 +301,17 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
|||
if (ret)
|
||||
{
|
||||
if (!pvData)
|
||||
{
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (*pcbData < blob.cbData)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = blob.cbData;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pvData, blob.pbData, blob.cbData);
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -325,12 +321,12 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
|||
{
|
||||
case CERT_SHA1_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_SHA1,
|
||||
pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
case CERT_MD5_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
default:
|
||||
|
@ -371,19 +367,22 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
}
|
||||
else
|
||||
{
|
||||
*(DWORD *)pvData =
|
||||
CertStore_GetAccessState(pCRLContext->hCertStore);
|
||||
if (pCRLContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCRLContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
*(DWORD *)pvData = 0;
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = CRLContext_GetProperty((void *)pCRLContext, dwPropId, pvData,
|
||||
ret = CRLContext_GetProperty(pCRLContext, dwPropId, pvData,
|
||||
pcbData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
|
@ -460,8 +459,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
ret = CRLContext_SetProperty((void *)pCRLContext, dwPropId, dwFlags,
|
||||
pvData);
|
||||
ret = CRLContext_SetProperty(pCRLContext, dwPropId, dwFlags, pvData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -519,10 +517,7 @@ LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify,
|
|||
|
||||
if (!pTimeToVerify)
|
||||
{
|
||||
SYSTEMTIME sysTime;
|
||||
|
||||
GetSystemTime(&sysTime);
|
||||
SystemTimeToFileTime(&sysTime, &fileTime);
|
||||
GetSystemTimeAsFileTime(&fileTime);
|
||||
pTimeToVerify = &fileTime;
|
||||
}
|
||||
if ((ret = CompareFileTime(pTimeToVerify, &pCrlInfo->ThisUpdate)) >= 0)
|
||||
|
|
|
@ -5,28 +5,36 @@
|
|||
<define name="__WINESRC__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="_WIN32_WINNT">0x600</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<library>wine</library>
|
||||
<library>user32</library>
|
||||
<library>advapi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
<library>imagehlp</library>
|
||||
<file>base64.c</file>
|
||||
<file>cert.c</file>
|
||||
<file>chain.c</file>
|
||||
<file>crl.c</file>
|
||||
<file>collectionstore.c</file>
|
||||
<file>context.c</file>
|
||||
<file>crl.c</file>
|
||||
<file>decode.c</file>
|
||||
<file>encode.c</file>
|
||||
<file>filestore.c</file>
|
||||
<file>main.c</file>
|
||||
<file>msg.c</file>
|
||||
<file>object.c</file>
|
||||
<file>oid.c</file>
|
||||
<file>proplist.c</file>
|
||||
<file>protectdata.c</file>
|
||||
<file>provstore.c</file>
|
||||
<file>regstore.c</file>
|
||||
<file>rootstore.c</file>
|
||||
<file>serialize.c</file>
|
||||
<file>sip.c</file>
|
||||
<file>store.c</file>
|
||||
<file>str.c</file>
|
||||
<file>main.c</file>
|
||||
<file>crypt32.rc</file>
|
||||
<file>crypt32.spec</file>
|
||||
</module>
|
||||
|
|
|
@ -17,21 +17,17 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "CryptoAPI Library\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "crypt32\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "crypt32.dll\0"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "cryptres.h"
|
||||
|
||||
#include <reactos/version.rc>
|
||||
#include "version.rc"
|
||||
|
||||
#include "crypt32_De.rc"
|
||||
#include "crypt32_En.rc"
|
||||
#include "crypt32_Fr.rc"
|
||||
#include "crypt32_Ko.rc"
|
||||
#include "crypt32_Nl.rc"
|
||||
#include "crypt32_No.rc"
|
||||
#include "crypt32_Sv.rc"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
@ stdcall CertDeleteCertificateFromStore(ptr)
|
||||
@ stdcall CertDuplicateCRLContext(ptr)
|
||||
@ stdcall CertDuplicateCTLContext(ptr)
|
||||
@ stdcall CertDuplicateCertificateChain(ptr)
|
||||
@ stdcall CertDuplicateCertificateContext(ptr)
|
||||
@ stdcall CertDuplicateStore(ptr)
|
||||
@ stdcall CertEnumCRLContextProperties(ptr long)
|
||||
|
@ -34,6 +35,7 @@
|
|||
@ stdcall CertEnumCTLsInStore(ptr ptr)
|
||||
@ stdcall CertEnumCertificateContextProperties(ptr long)
|
||||
@ stdcall CertEnumCertificatesInStore(long ptr)
|
||||
@ stdcall CertEnumSystemStore(long ptr ptr ptr)
|
||||
@ stdcall CertFindAttribute(str long ptr)
|
||||
@ stdcall CertFindCRLInStore(long long long long ptr ptr)
|
||||
@ stub CertFindCTLInStore
|
||||
|
@ -44,13 +46,13 @@
|
|||
@ stub CertFindSubjectInCTL
|
||||
@ stdcall CertFreeCRLContext(ptr)
|
||||
@ stdcall CertFreeCTLContext(ptr)
|
||||
@ stub CertFreeCertificateChain
|
||||
@ stdcall CertFreeCertificateChain(ptr)
|
||||
@ stdcall CertFreeCertificateChainEngine(ptr)
|
||||
@ stdcall CertFreeCertificateContext(ptr)
|
||||
@ stdcall CertGetCRLContextProperty(ptr long ptr ptr)
|
||||
@ stdcall CertGetCRLFromStore(ptr ptr ptr ptr)
|
||||
@ stdcall CertGetCTLContextProperty(ptr long ptr ptr)
|
||||
@ stub CertGetCertificateChain
|
||||
@ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr)
|
||||
@ stdcall CertGetCertificateContextProperty(ptr long ptr ptr)
|
||||
@ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr)
|
||||
@ stub CertGetIntendedKeyUsage
|
||||
|
@ -58,6 +60,7 @@
|
|||
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetPublicKeyLength(long ptr)
|
||||
@ stdcall CertGetStoreProperty(long long ptr ptr)
|
||||
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
|
||||
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
|
||||
@ stub CertIsRDNAttrsInCertificateName
|
||||
|
@ -80,12 +83,14 @@
|
|||
@ stdcall CertSetCTLContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetCertificateContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetEnhancedKeyUsage(ptr ptr)
|
||||
@ stdcall CertSetStoreProperty(ptr long long ptr)
|
||||
@ stdcall CertStrToNameA(long str long ptr ptr ptr ptr)
|
||||
@ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr)
|
||||
@ stdcall CertVerifyCertificateChainPolicy(str ptr ptr ptr)
|
||||
@ stdcall CertVerifyCRLRevocation(long ptr long ptr)
|
||||
@ stdcall CertVerifyCRLTimeValidity(ptr ptr)
|
||||
@ stub CertVerifyCTLUsage
|
||||
@ stub CertVerifyRevocation
|
||||
@ stdcall CertVerifyCTLUsage(long long ptr ptr long ptr ptr)
|
||||
@ stdcall CertVerifyRevocation(long long long ptr long ptr ptr)
|
||||
@ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr)
|
||||
@ stdcall CertVerifyTimeValidity(ptr ptr)
|
||||
@ stdcall CertVerifyValidityNesting(ptr ptr)
|
||||
|
@ -112,14 +117,15 @@
|
|||
@ stub CryptExportPKCS8
|
||||
@ stdcall CryptExportPublicKeyInfo(long long long ptr ptr)
|
||||
@ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr)
|
||||
@ stdcall CryptFindLocalizedName(wstr)
|
||||
@ stdcall CryptFindOIDInfo(long ptr long)
|
||||
@ stdcall CryptFormatObject(long long long ptr str ptr long ptr ptr)
|
||||
@ stdcall CryptFreeOIDFunctionAddress(long long)
|
||||
@ stub CryptGetAsyncParam
|
||||
@ stdcall CryptGetDefaultOIDDllList(long long ptr ptr)
|
||||
@ stdcall CryptGetDefaultOIDFunctionAddress(long long wstr long ptr ptr)
|
||||
@ stub CryptGetMessageCertificates
|
||||
@ stub CryptGetMessageSignerCount
|
||||
@ stdcall CryptGetMessageCertificates(long ptr long ptr long)
|
||||
@ stdcall CryptGetMessageSignerCount(long ptr long)
|
||||
@ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr)
|
||||
@ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr)
|
||||
@ stdcall CryptHashCertificate(long long long ptr long ptr ptr)
|
||||
|
@ -136,17 +142,18 @@
|
|||
@ stdcall CryptMemFree(ptr)
|
||||
@ stdcall CryptMemRealloc(ptr long)
|
||||
@ stub CryptMsgCalculateEncodedLength
|
||||
@ stub CryptMsgClose
|
||||
@ stub CryptMsgControl
|
||||
@ stdcall CryptMsgClose(ptr)
|
||||
@ stdcall CryptMsgControl(ptr long long ptr)
|
||||
@ stub CryptMsgCountersign
|
||||
@ stub CryptMsgCountersignEncoded
|
||||
@ stdcall CryptMsgDuplicate(ptr)
|
||||
@ stub CryptMsgEncodeAndSignCTL
|
||||
@ stub CryptMsgGetAndVerifySigner
|
||||
@ stub CryptMsgGetParam
|
||||
@ stub CryptMsgOpenToDecode
|
||||
@ stub CryptMsgOpenToEncode
|
||||
@ stdcall CryptMsgGetParam(ptr long long ptr ptr)
|
||||
@ stdcall CryptMsgOpenToDecode(long long long long ptr ptr)
|
||||
@ stdcall CryptMsgOpenToEncode(long long long ptr str ptr)
|
||||
@ stub CryptMsgSignCTL
|
||||
@ stub CryptMsgUpdate
|
||||
@ stdcall CryptMsgUpdate(ptr ptr long long)
|
||||
@ stub CryptMsgVerifyCountersignatureEncoded
|
||||
@ stdcall CryptProtectData(ptr wstr ptr ptr ptr long ptr)
|
||||
@ stdcall CryptQueryObject(long ptr long long long ptr ptr ptr ptr ptr ptr)
|
||||
|
@ -183,25 +190,29 @@
|
|||
@ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr)
|
||||
@ stub CryptVerifyMessageSignatureWithKey
|
||||
@ stub CryptVerifySignatureU
|
||||
@ stdcall I_CertUpdateStore(ptr ptr long long)
|
||||
@ stdcall I_CryptAllocTls()
|
||||
@ stdcall I_CryptCreateLruCache(ptr ptr)
|
||||
@ stub I_CryptCreateLruEntry
|
||||
@ stdcall I_CryptCreateLruEntry(ptr long long)
|
||||
@ stdcall I_CryptDetachTls(long)
|
||||
@ stdcall I_CryptFindLruEntry(long long)
|
||||
@ stdcall I_CryptFindLruEntryData(long long long)
|
||||
@ stdcall I_CryptFlushLruCache(ptr long long)
|
||||
@ stdcall I_CryptFreeLruCache(ptr long long)
|
||||
@ stdcall I_CryptFreeTls(long long)
|
||||
@ stdcall I_CryptGetAsn1Decoder(long)
|
||||
@ stdcall I_CryptGetAsn1Encoder(long)
|
||||
@ 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_CryptInstallAsn1Module(ptr long ptr)
|
||||
@ stdcall I_CryptInstallOssGlobal(long long long)
|
||||
@ stdcall I_CryptReadTrustedPublisherDWORDValueFromRegistry(wstr ptr)
|
||||
@ stub I_CryptReleaseLruEntry
|
||||
@ stdcall I_CryptSetTls(long ptr)
|
||||
@ stdcall I_CryptUninstallAsn1Module(ptr)
|
||||
@ stdcall I_CryptUninstallAsn1Module(long)
|
||||
@ stub I_CryptUninstallOssGlobal
|
||||
@ stub PFXExportCertStore
|
||||
@ stub PFXImportCertStore
|
||||
|
|
|
@ -97,7 +97,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_CROSS_CERT_DIST_POINTS "Verteilungspunkte für Kreuzzertifikate"
|
||||
IDS_APPLICATION_POLICIES "Anwendungsrichtlinien"
|
||||
IDS_APPLICATION_POLICY_MAPPINGS "Anwendungsrichtlinienzuordnungen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Anweungsungsrichtlinieneinschränkungen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Anwendungsungsrichtlinieneinschränkungen"
|
||||
IDS_CMC_DATA "CMC Daten"
|
||||
IDS_CMC_RESPONSE "CMC Antwort"
|
||||
IDS_UNSIGNED_CMC_REQUEST "Unsignierte CMC Antwort"
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Lebensdauersignatur"
|
||||
IDS_ANY_CERT_POLICY "Alle ausgegebenen Richtlinien"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Vertrauenswürdige Stammzertifizierungsstellen"
|
||||
IDS_LOCALIZEDNAME_MY "Persönlich"
|
||||
IDS_LOCALIZEDNAME_CA "Zwischenzertifizierungsstellen"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Andere Personen"
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Lifetime Signing"
|
||||
IDS_ANY_CERT_POLICY "All issuance policies"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Trusted Root Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_MY "Personal"
|
||||
IDS_LOCALIZEDNAME_CA "Intermediate Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Other People"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* crypt32 dll French resources
|
||||
*
|
||||
* Copyright 2006 Jonathan Ernst
|
||||
* Copyright 2006-2008 Jonathan Ernst
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -22,13 +22,13 @@ 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_AUTHORITY_KEY_ID "Identifiant de l'authorité de la clé"
|
||||
IDS_KEY_ATTRIBUTES "Attributs de la clé"
|
||||
IDS_KEY_USAGE_RESTRICTION "Restrictions de l'utilisation de la clé"
|
||||
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_KEY_USAGE "Utilisation de la clé"
|
||||
IDS_CERT_POLICIES "Certificate Policies"
|
||||
IDS_SUBJECT_KEY_IDENTIFIER "Subject Key Identifier"
|
||||
IDS_CRL_REASON_CODE "CRL Reason Code"
|
||||
|
@ -49,7 +49,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_SMIME_CAPABILITIES "SMIME Capabilities"
|
||||
IDS_PREFER_SIGNED_DATA "Prefer Signed Data"
|
||||
IDS_CPS "CPS"
|
||||
IDS_USER_NOTICE "User Notice"
|
||||
IDS_USER_NOTICE "Notice utilisateur"
|
||||
IDS_OCSP "On-line Certificate Status Protocol"
|
||||
IDS_CA_ISSUER "Certification Authority Issuer"
|
||||
IDS_CERT_TEMPLATE_NAME "Certification Template Name"
|
||||
|
@ -157,10 +157,18 @@ STRINGTABLE DISCARDABLE
|
|||
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_ROOT_LIST_SIGNER "Signataires de la liste racine"
|
||||
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"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Autorités de certification de confiance"
|
||||
IDS_LOCALIZEDNAME_MY "Personnel"
|
||||
IDS_LOCALIZEDNAME_CA "Autorités intermédiaires"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Autres personnes"
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -165,3 +165,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "평생 서명"
|
||||
IDS_ANY_CERT_POLICY "모든 배포 방침"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "신회 할 수 있는 루트 검사증기관"
|
||||
IDS_LOCALIZEDNAME_MY "개인적"
|
||||
IDS_LOCALIZEDNAME_CA "중간 검증 기관ㄴIntermediate Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "다른 사람"
|
||||
}
|
||||
|
|
174
reactos/dll/win32/crypt32/crypt32_Nl.rc
Normal file
174
reactos/dll/win32/crypt32/crypt32_Nl.rc
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Dutch crypt32 dll resources
|
||||
*
|
||||
* Copyright (C) 2008 Frans Kool
|
||||
*
|
||||
* 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_DUTCH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_AUTHORITY_KEY_ID "Autoriteits Sleutel Identificatie nummer"
|
||||
IDS_KEY_ATTRIBUTES "Sleutel Attributen"
|
||||
IDS_KEY_USAGE_RESTRICTION "Sleutel Gebruiksbeperkingen"
|
||||
IDS_SUBJECT_ALT_NAME "Onderwerp's Alternatieve Naam"
|
||||
IDS_ISSUER_ALT_NAME "Verstrekker's Alternatieve Naam"
|
||||
IDS_BASIC_CONSTRAINTS "Basis Beperkingen"
|
||||
IDS_KEY_USAGE "Sleutel Gebruik"
|
||||
IDS_CERT_POLICIES "Certificaat Beleid"
|
||||
IDS_SUBJECT_KEY_IDENTIFIER "Onderwerp's Sleutel Identificatie nummer"
|
||||
IDS_CRL_REASON_CODE "CRL Reden Code"
|
||||
IDS_CRL_DIST_POINTS "CRL Distributie Locaties"
|
||||
IDS_ENHANCED_KEY_USAGE "Uitgebreid Sleutel Gebruik"
|
||||
IDS_AUTHORITY_INFO_ACCESS "Autoriteits Informatie Toegang"
|
||||
IDS_CERT_EXTENSIONS "Certificaat Extensies"
|
||||
IDS_NEXT_UPDATE_LOCATION "Volgende Update Locatie"
|
||||
IDS_YES_OR_NO_TRUST "Wel of Geen Vertrouwen"
|
||||
IDS_EMAIL_ADDRESS "Email Adres"
|
||||
IDS_UNSTRUCTURED_NAME "Ongestructureerde Naam"
|
||||
IDS_CONTENT_TYPE "Inhoud Type"
|
||||
IDS_MESSAGE_DIGEST "Boodschap Samenvatting"
|
||||
IDS_SIGNING_TIME "Tijd van Ondertekening"
|
||||
IDS_COUNTER_SIGN "Counter Sign"
|
||||
IDS_CHALLENGE_PASSWORD "Geheime Vraag Wachtwoord"
|
||||
IDS_UNSTRUCTURED_ADDRESS "Ongestructureerd Adres"
|
||||
IDS_SMIME_CAPABILITIES "SMIME Mogelijkheden"
|
||||
IDS_PREFER_SIGNED_DATA "Prefereer Getekende Data"
|
||||
IDS_CPS "CPS"
|
||||
IDS_USER_NOTICE "Gebruikers Mededeling"
|
||||
IDS_OCSP "On-line Certificaat Status Protocol"
|
||||
IDS_CA_ISSUER "Certificatie Autoriteits Verstrekker"
|
||||
IDS_CERT_TEMPLATE_NAME "Certificatie Template Naam"
|
||||
IDS_CERT_TYPE "Type Certificaat"
|
||||
IDS_CERT_MANIFOLD "Certificaat Verspreider"
|
||||
IDS_NETSCAPE_CERT_TYPE "Netscape Certificaat Type"
|
||||
IDS_NETSCAPE_BASE_URL "Netscape Basis URL"
|
||||
IDS_NETSCAPE_REVOCATION_URL "Netscape Terugroep URL"
|
||||
IDS_NETSCAPE_CA_REVOCATION_URL "Netscape CA Terugroep URL"
|
||||
IDS_NETSCAPE_CERT_RENEWAL_URL "Netscape Cert Verversings URL"
|
||||
IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Beleids URL"
|
||||
IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL Server Naam"
|
||||
IDS_NETSCAPE_COMMENT "Netscape Commentaar"
|
||||
IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
|
||||
IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
|
||||
IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
|
||||
IDS_COUNTRY "Land/Regio"
|
||||
IDS_ORGANIZATION "Organisatie"
|
||||
IDS_ORGANIZATIONAL_UNIT "Organisatie Onderdeel"
|
||||
IDS_COMMON_NAME "Gemeenschappelijke Naam"
|
||||
IDS_LOCALITY "Localiteit"
|
||||
IDS_STATE_OR_PROVINCE "Staat of Provincie"
|
||||
IDS_TITLE "Titel"
|
||||
IDS_GIVEN_NAME "Voornaam"
|
||||
IDS_INITIALS "Initialen"
|
||||
IDS_SUR_NAME "Achternaam"
|
||||
IDS_DOMAIN_COMPONENT "Domein Component"
|
||||
IDS_STREET_ADDRESS "Straat/Adres"
|
||||
IDS_SERIAL_NUMBER "Registratie Nummer"
|
||||
IDS_CA_VERSION "CA Versie"
|
||||
IDS_CROSS_CA_VERSION "Cross CA Versie"
|
||||
IDS_SERIALIZED_SIG_SERIAL_NUMBER "Geautomatiseerde Handtekening Serienummer"
|
||||
IDS_PRINCIPAL_NAME "Hoofd Naam"
|
||||
IDS_WINDOWS_PRODUCT_UPDATE "Windows Produkt Update"
|
||||
IDS_ENROLLMENT_NAME_VALUE_PAIR "Inschrijvingsnaam Waarde Paar"
|
||||
IDS_OS_VERSION "OS Versie"
|
||||
IDS_ENROLLMENT_CSP "Inschrijving CSP"
|
||||
IDS_CRL_NUMBER "CRL Nummer"
|
||||
IDS_DELTA_CRL_INDICATOR "Delta CRL Indicatie"
|
||||
IDS_ISSUING_DIST_POINT "Verstrekkend Distributie Punt"
|
||||
IDS_FRESHEST_CRL "Nieuwste CRL"
|
||||
IDS_NAME_CONSTRAINTS "Beperkingen op Naam"
|
||||
IDS_POLICY_MAPPINGS "Beleids Mappingen"
|
||||
IDS_POLICY_CONSTRAINTS "Beperkingen op Beleid"
|
||||
IDS_CROSS_CERT_DIST_POINTS "Trans-Certificaat Distributie Punten"
|
||||
IDS_APPLICATION_POLICIES "Applicatie Beleid"
|
||||
IDS_APPLICATION_POLICY_MAPPINGS "Applicatie Beleids Mappingen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Applicatie Beperkingen op Beleid"
|
||||
IDS_CMC_DATA "CMC Data"
|
||||
IDS_CMC_RESPONSE "CMC Antwoord"
|
||||
IDS_UNSIGNED_CMC_REQUEST "Ongetekend CMC Verzoek"
|
||||
IDS_CMC_STATUS_INFO "CMC Status Informatie"
|
||||
IDS_CMC_EXTENSIONS "CMC Extensies"
|
||||
IDS_CMC_ATTRIBUTES "CMC Attributen"
|
||||
IDS_PKCS_7_DATA "PKCS 7 Data"
|
||||
IDS_PKCS_7_SIGNED "PKCS 7 Ondertekend"
|
||||
IDS_PKCS_7_ENVELOPED "PKCS 7 Omsloten"
|
||||
IDS_PKCS_7_SIGNED_ENVELOPED "PKCS 7 Getekend Omsloten"
|
||||
IDS_PKCS_7_DIGESTED "PKCS 7 Samengevat"
|
||||
IDS_PKCS_7_ENCRYPTED "PKCS 7 Gecodeerd"
|
||||
IDS_PREVIOUS_CA_CERT_HASH "Vorige CA Certificaat Hash"
|
||||
IDS_CRL_VIRTUAL_BASE "Virtueel Basis CRL Nummer"
|
||||
IDS_CRL_NEXT_PUBLISH "Volgende CRL Publicatie"
|
||||
IDS_CA_EXCHANGE "CA Coderings Certificaat"
|
||||
IDS_KEY_RECOVERY_AGENT "Sleutel Herstel Agent"
|
||||
IDS_CERTIFICATE_TEMPLATE "Certificaat Template Information"
|
||||
IDS_ENTERPRISE_ROOT_OID "Ondernemings Basis OID"
|
||||
IDS_RDN_DUMMY_SIGNER "Dummie Tekenaar"
|
||||
IDS_ARCHIVED_KEY_ATTR "Gecodeerde Persoonlijke Sleutel"
|
||||
IDS_CRL_SELF_CDP "Gepubliseerde CRL Locaties"
|
||||
IDS_REQUIRE_CERT_CHAIN_POLICY "Afdwingen Certificaat Keten Beleid"
|
||||
IDS_TRANSACTION_ID "Transactie Nummer"
|
||||
IDS_SENDER_NONCE "Zender Nonce"
|
||||
IDS_RECIPIENT_NONCE "Ontvanger Nonce"
|
||||
IDS_REG_INFO "Registratie Informatie"
|
||||
IDS_GET_CERTIFICATE "Haal Certificaat op"
|
||||
IDS_GET_CRL "Haal CRL op"
|
||||
IDS_REVOKE_REQUEST "Trek Verzoek In"
|
||||
IDS_QUERY_PENDING "Verzoek in behandeling"
|
||||
IDS_SORTED_CTL "Certificaat Vertrouwenslijst"
|
||||
IDS_ARCHIVED_KEY_CERT_HASH "Gearchiveerde Sleutel Certificaat Hash"
|
||||
IDS_PRIVATE_KEY_USAGE_PERIOD "Prive Sleutel Gebruik Periode"
|
||||
IDS_CLIENT_INFORMATION "Cliënt Informatie"
|
||||
IDS_SERVER_AUTHENTICATION "Server Authentificatie"
|
||||
IDS_CLIENT_AUTHENTICATION "Cliënt Authentificatie"
|
||||
IDS_CODE_SIGNING "Code Ondertekenen"
|
||||
IDS_SECURE_EMAIL "Beveiligde Email"
|
||||
IDS_TIME_STAMPING "Tijd Stempel Toekennen"
|
||||
IDS_MICROSOFT_TRUST_LIST_SIGNING "Microsoft Trust Lijst Ondertekenen"
|
||||
IDS_MICROSOFT_TIME_STAMPING "Microsoft Tijd Stempel Toekennen"
|
||||
IDS_IPSEC_END_SYSTEM "IP beveiliging eind systeem"
|
||||
IDS_IPSEC_TUNNEL "IP beveiliging tunnel afsluiting"
|
||||
IDS_IPSEC_USER "IP beveiliging gebruiker"
|
||||
IDS_EFS "Versleutelen Bestand Systeem"
|
||||
IDS_WHQL_CRYPTO "Windows Hardware Driver Verificatie"
|
||||
IDS_NT5_CRYPTO "Windows Systeem Component Verificatie"
|
||||
IDS_OEM_WHQL_CRYPTO "OEM Windows Systeem Component Verificatie"
|
||||
IDS_EMBEDDED_NT_CRYPTO "Ingebed Windows Systeem Componenten Verificatie"
|
||||
IDS_KEY_PACK_LICENSES "Sleutel Verzameling Licenties"
|
||||
IDS_LICENSE_SERVER "Licentie Server Verificatie"
|
||||
IDS_SMART_CARD_LOGON "Smart Card Aanmelden"
|
||||
IDS_DIGITAL_RIGHTS "Digitale Rechten"
|
||||
IDS_QUALIFIED_SUBORDINATION "Gekwalificeerde Ondergeschiktheid"
|
||||
IDS_KEY_RECOVERY "Sleutel Herstellen"
|
||||
IDS_DOCUMENT_SIGNING "Document Ondertekenen"
|
||||
IDS_IPSEC_IKE_INTERMEDIATE "IP beveiliging IKE tussenpersoon"
|
||||
IDS_FILE_RECOVERY "Bestand Herstellen"
|
||||
IDS_ROOT_LIST_SIGNER "Basis Lijst Ondertekenaar"
|
||||
IDS_ANY_APPLICATION_POLICIES "Alle applicaties beleid"
|
||||
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replicatie"
|
||||
IDS_ENROLLMENT_AGENT "Certificaat Verzoek Agent"
|
||||
IDS_LIFETIME_SIGNING "Levensduur Ondertekenen"
|
||||
IDS_ANY_CERT_POLICY "Alle uitgifte beleid"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Vertrouwde Basis Certificatie Autoriteiten"
|
||||
IDS_LOCALIZEDNAME_MY "Persoonlijk"
|
||||
IDS_LOCALIZEDNAME_CA "Certificatie Tussen-Autoriteiten"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Overige Personen"
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
|
||||
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Livstidsignering"
|
||||
IDS_ANY_CERT_POLICY "Alle framgangsmåter for utsteding"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Klarerte rotsertifiseringsinstanser"
|
||||
IDS_LOCALIZEDNAME_MY "Personlig"
|
||||
IDS_LOCALIZEDNAME_CA "Mellomliggende sertifiseringsinstanser"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Andre personer"
|
||||
}
|
||||
|
|
169
reactos/dll/win32/crypt32/crypt32_Sv.rc
Normal file
169
reactos/dll/win32/crypt32/crypt32_Sv.rc
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* crypt32 dll resources
|
||||
*
|
||||
* Copyright (C) 2007 Daniel Nylander
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_AUTHORITY_KEY_ID "Authority Key Identifier"
|
||||
IDS_KEY_ATTRIBUTES "Nyckelattribut"
|
||||
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 "Nyckelanvändning"
|
||||
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 "E-postadress"
|
||||
IDS_UNSTRUCTURED_NAME "Unstructured Name"
|
||||
IDS_CONTENT_TYPE "Innehållstyp"
|
||||
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 "Netscape Cert Type"
|
||||
IDS_NETSCAPE_BASE_URL "Netscape Base URL"
|
||||
IDS_NETSCAPE_REVOCATION_URL "Netscape Revocation URL"
|
||||
IDS_NETSCAPE_CA_REVOCATION_URL "Netscape CA Revocation URL"
|
||||
IDS_NETSCAPE_CERT_RENEWAL_URL "Netscape Cert Renewal URL"
|
||||
IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Policy URL"
|
||||
IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL ServerName"
|
||||
IDS_NETSCAPE_COMMENT "Netscape Comment"
|
||||
IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
|
||||
IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
|
||||
IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
|
||||
IDS_COUNTRY "Land/Region"
|
||||
IDS_ORGANIZATION "Organisation"
|
||||
IDS_ORGANIZATIONAL_UNIT "Organizational Unit"
|
||||
IDS_COMMON_NAME "Common Name"
|
||||
IDS_LOCALITY "Plats"
|
||||
IDS_STATE_OR_PROVINCE "Län eller region"
|
||||
IDS_TITLE "Titel"
|
||||
IDS_GIVEN_NAME "Förnamn"
|
||||
IDS_INITIALS "Initialer"
|
||||
IDS_SUR_NAME "Efternamn"
|
||||
IDS_DOMAIN_COMPONENT "Domain Component"
|
||||
IDS_STREET_ADDRESS "Postadress"
|
||||
IDS_SERIAL_NUMBER "Serienummer"
|
||||
IDS_CA_VERSION "CA Version"
|
||||
IDS_CROSS_CA_VERSION "Cross CA Version"
|
||||
IDS_SERIALIZED_SIG_SERIAL_NUMBER "Serialized Signature Serial Number"
|
||||
IDS_PRINCIPAL_NAME "Principal Name"
|
||||
IDS_WINDOWS_PRODUCT_UPDATE "Windows Product Update"
|
||||
IDS_ENROLLMENT_NAME_VALUE_PAIR "Enrollment Name Value Pair"
|
||||
IDS_OS_VERSION "OS Version"
|
||||
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 "Name Constraints"
|
||||
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 "PKCS 7 Data"
|
||||
IDS_PKCS_7_SIGNED "PKCS 7 Signed"
|
||||
IDS_PKCS_7_ENVELOPED "PKCS 7 Enveloped"
|
||||
IDS_PKCS_7_SIGNED_ENVELOPED "PKCS 7 Signed Enveloped"
|
||||
IDS_PKCS_7_DIGESTED "PKCS 7 Digested"
|
||||
IDS_PKCS_7_ENCRYPTED "PKCS 7 Encrypted"
|
||||
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 "CA Encryption Certificate"
|
||||
IDS_KEY_RECOVERY_AGENT "Key Recovery Agent"
|
||||
IDS_CERTIFICATE_TEMPLATE "Certificate Template Information"
|
||||
IDS_ENTERPRISE_ROOT_OID "Enterprise Root OID"
|
||||
IDS_RDN_DUMMY_SIGNER "Dummy Signer"
|
||||
IDS_ARCHIVED_KEY_ATTR "Encrypted Private Key"
|
||||
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 "Säker e-post"
|
||||
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 "Key Recovery"
|
||||
IDS_DOCUMENT_SIGNING "Document Signing"
|
||||
IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate"
|
||||
IDS_FILE_RECOVERY "File Recovery"
|
||||
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"
|
||||
}
|
||||
|
||||
#pragma code_page(default)
|
|
@ -38,6 +38,81 @@
|
|||
#define ASN_UNIVERSALSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1c)
|
||||
#define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
|
||||
|
||||
BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *,
|
||||
DWORD, PCRYPT_ENCODE_PARA, BYTE *, DWORD *);
|
||||
|
||||
struct AsnEncodeSequenceItem
|
||||
{
|
||||
const void *pvStructInfo;
|
||||
CryptEncodeObjectExFunc encodeFunc;
|
||||
DWORD size; /* used during encoding, not for your use */
|
||||
};
|
||||
|
||||
BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
|
||||
struct AsnEncodeSequenceItem items[], DWORD cItem, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
struct AsnConstructedItem
|
||||
{
|
||||
BYTE tag;
|
||||
const void *pvStructInfo;
|
||||
CryptEncodeObjectExFunc encodeFunc;
|
||||
};
|
||||
|
||||
BOOL WINAPI CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
typedef struct _CRYPT_DIGESTED_DATA
|
||||
{
|
||||
DWORD version;
|
||||
CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
|
||||
CRYPT_CONTENT_INFO ContentInfo;
|
||||
CRYPT_HASH_BLOB hash;
|
||||
} CRYPT_DIGESTED_DATA;
|
||||
|
||||
BOOL CRYPT_AsnEncodePKCSDigestedData(CRYPT_DIGESTED_DATA *digestedData,
|
||||
void *pvData, DWORD *pcbData);
|
||||
|
||||
typedef struct _CRYPT_SIGNED_INFO
|
||||
{
|
||||
DWORD version;
|
||||
DWORD cCertEncoded;
|
||||
PCERT_BLOB rgCertEncoded;
|
||||
DWORD cCrlEncoded;
|
||||
PCRL_BLOB rgCrlEncoded;
|
||||
CRYPT_CONTENT_INFO content;
|
||||
DWORD cSignerInfo;
|
||||
PCMSG_SIGNER_INFO rgSignerInfo;
|
||||
} CRYPT_SIGNED_INFO;
|
||||
|
||||
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
|
||||
DWORD *pcbData);
|
||||
|
||||
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
||||
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo);
|
||||
|
||||
/* Helper function to check *pcbEncoded, set it to the required size, and
|
||||
* optionally to allocate memory. Assumes pbEncoded is not NULL.
|
||||
* If CRYPT_ENCODE_ALLOC_FLAG is set in dwFlags, *pbEncoded will be set to a
|
||||
* pointer to the newly allocated memory.
|
||||
*/
|
||||
BOOL CRYPT_EncodeEnsureSpace(DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded);
|
||||
|
||||
BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
||||
CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData);
|
||||
|
||||
/* The following aren't defined in wincrypt.h, as they're "reserved" */
|
||||
#define CERT_CERT_PROP_ID 32
|
||||
#define CERT_CRL_PROP_ID 33
|
||||
|
@ -50,6 +125,9 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void);
|
|||
|
||||
void crypt_oid_init(HINSTANCE hinst);
|
||||
void crypt_oid_free(void);
|
||||
void crypt_sip_free(void);
|
||||
void root_store_free(void);
|
||||
void default_chain_engine_free(void);
|
||||
|
||||
/* Some typedefs that make it easier to abstract which type of context we're
|
||||
* working with.
|
||||
|
@ -95,6 +173,94 @@ extern PCWINE_CONTEXT_INTERFACE pCertInterface;
|
|||
extern PCWINE_CONTEXT_INTERFACE pCRLInterface;
|
||||
extern PCWINE_CONTEXT_INTERFACE pCTLInterface;
|
||||
|
||||
/* (Internal) certificate store types and functions */
|
||||
struct WINE_CRYPTCERTSTORE;
|
||||
|
||||
typedef struct WINE_CRYPTCERTSTORE * (*StoreOpenFunc)(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
/* Called to enumerate the next context in a store. */
|
||||
typedef void * (*EnumFunc)(struct WINE_CRYPTCERTSTORE *store, void *pPrev);
|
||||
|
||||
/* Called to add a context to a store. If toReplace is not NULL,
|
||||
* context replaces toReplace in the store, and access checks should not be
|
||||
* performed. Otherwise context is a new context, and it should only be
|
||||
* added if the store allows it. If ppStoreContext is not NULL, the added
|
||||
* context should be returned in *ppStoreContext.
|
||||
*/
|
||||
typedef BOOL (*AddFunc)(struct WINE_CRYPTCERTSTORE *store, void *context,
|
||||
void *toReplace, const void **ppStoreContext);
|
||||
|
||||
typedef BOOL (*DeleteFunc)(struct WINE_CRYPTCERTSTORE *store, void *context);
|
||||
|
||||
typedef struct _CONTEXT_FUNCS
|
||||
{
|
||||
AddFunc addContext;
|
||||
EnumFunc enumContext;
|
||||
DeleteFunc deleteContext;
|
||||
} CONTEXT_FUNCS, *PCONTEXT_FUNCS;
|
||||
|
||||
typedef enum _CertStoreType {
|
||||
StoreTypeMem,
|
||||
StoreTypeCollection,
|
||||
StoreTypeProvider,
|
||||
} CertStoreType;
|
||||
|
||||
struct _CONTEXT_PROPERTY_LIST;
|
||||
typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
||||
|
||||
#define WINE_CRYPTCERTSTORE_MAGIC 0x74726563
|
||||
|
||||
/* A cert store is polymorphic through the use of function pointers. A type
|
||||
* is still needed to distinguish collection stores from other types.
|
||||
* On the function pointers:
|
||||
* - closeStore is called when the store's ref count becomes 0
|
||||
* - control is optional, but should be implemented by any store that supports
|
||||
* persistence
|
||||
*/
|
||||
typedef struct WINE_CRYPTCERTSTORE
|
||||
{
|
||||
DWORD dwMagic;
|
||||
LONG ref;
|
||||
DWORD dwOpenFlags;
|
||||
CertStoreType type;
|
||||
PFN_CERT_STORE_PROV_CLOSE closeStore;
|
||||
CONTEXT_FUNCS certs;
|
||||
CONTEXT_FUNCS crls;
|
||||
PFN_CERT_STORE_PROV_CONTROL control; /* optional */
|
||||
PCONTEXT_PROPERTY_LIST properties;
|
||||
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
|
||||
|
||||
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
||||
CertStoreType type);
|
||||
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store);
|
||||
BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
||||
DWORD unk1);
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo);
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags);
|
||||
|
||||
/* Allocates and initializes a certificate chain engine, but without creating
|
||||
* the root store. Instead, it uses root, and assumes the caller has done any
|
||||
* checking necessary.
|
||||
*/
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
|
||||
PCERT_CHAIN_ENGINE_CONFIG pConfig);
|
||||
|
||||
/* Helper function for store reading functions and
|
||||
* CertAddSerializedElementToStore. Returns a context of the appropriate type
|
||||
* if it can, or NULL otherwise. Doesn't validate any of the properties in
|
||||
|
@ -104,15 +270,12 @@ 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);
|
||||
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store);
|
||||
|
||||
/* Fixes up the the pointers in info, where info is assumed to be a
|
||||
/* Fixes up the pointers in info, where info is assumed to be a
|
||||
* CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any
|
||||
* provider parameters, in a contiguous buffer, but where info's pointers are
|
||||
* assumed to be invalid. Upon return, info's pointers point to the
|
||||
|
@ -120,8 +283,6 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store);
|
|||
*/
|
||||
void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info);
|
||||
|
||||
DWORD CertStore_GetAccessState(HCERTSTORE hCertStore);
|
||||
|
||||
/**
|
||||
* Context functions
|
||||
*/
|
||||
|
@ -153,13 +314,10 @@ void *Context_GetLinkedContext(void *context, size_t contextSize);
|
|||
void Context_CopyProperties(const void *to, const void *from,
|
||||
size_t contextSize);
|
||||
|
||||
struct _CONTEXT_PROPERTY_LIST;
|
||||
typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
||||
|
||||
/* Returns context's properties, or the linked context's properties if context
|
||||
* is a link context.
|
||||
*/
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(void *context, size_t contextSize);
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize);
|
||||
|
||||
void Context_AddRef(void *context, size_t contextSize);
|
||||
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
Index: crypt32.rc
|
||||
===================================================================
|
||||
--- crypt32.rc (revision 22838)
|
||||
+++ crypt32.rc (working copy)
|
||||
@@ -17,12 +17,18 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
+
|
||||
+#define REACTOS_VERSION_DLL
|
||||
+#define REACTOS_STR_FILE_DESCRIPTION "CryptoAPI Library\0"
|
||||
+#define REACTOS_STR_INTERNAL_NAME "crypt32\0"
|
||||
+#define REACTOS_STR_ORIGINAL_FILENAME "crypt32.dll\0"
|
||||
+
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "cryptres.h"
|
||||
--- D:/Wine-CVS/wine/dlls/crypt32/rootstore.c Sat Feb 16 22:49:56 2008
|
||||
+++ D:/ReactOS-Trunk/reactos/dll/win32/crypt32/rootstore.c Sat May 10 20:30:25 2008
|
||||
@@ -317,7 +317,7 @@
|
||||
DIR *dir;
|
||||
|
||||
-#include "version.rc"
|
||||
+#include <reactos/version.rc>
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), store);
|
||||
-
|
||||
+ /* UNIX functions = bad for reactos
|
||||
dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
@@ -340,6 +340,7 @@
|
||||
CryptMemFree(filebuf);
|
||||
}
|
||||
}
|
||||
+ */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "crypt32_De.rc"
|
||||
#include "crypt32_En.rc"
|
||||
|
|
|
@ -160,4 +160,9 @@
|
|||
#define IDS_LIFETIME_SIGNING 1139
|
||||
#define IDS_ANY_CERT_POLICY 1140
|
||||
|
||||
#define IDS_LOCALIZEDNAME_ROOT 1141
|
||||
#define IDS_LOCALIZEDNAME_MY 1142
|
||||
#define IDS_LOCALIZEDNAME_CA 1143
|
||||
#define IDS_LOCALIZEDNAME_ADDRESSBOOK 1144
|
||||
|
||||
#endif /* ndef __WINE_CRYPTRES_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
389
reactos/dll/win32/crypt32/filestore.c
Normal file
389
reactos/dll/win32/crypt32/filestore.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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 "winnls.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_FILESTOREINFO
|
||||
{
|
||||
DWORD dwOpenFlags;
|
||||
HCERTSTORE memStore;
|
||||
HANDLE file;
|
||||
DWORD type;
|
||||
BOOL dirty;
|
||||
} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
|
||||
|
||||
static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (store->dirty)
|
||||
CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
|
||||
CertCloseStore(store->memStore, dwFlags);
|
||||
CloseHandle(store->file);
|
||||
CryptMemFree(store);
|
||||
}
|
||||
|
||||
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 CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
blob->cbData = GetFileSize(file, NULL);
|
||||
if (blob->cbData)
|
||||
{
|
||||
blob->pbData = CryptMemAlloc(blob->cbData);
|
||||
if (blob->pbData)
|
||||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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:
|
||||
store->dirty = FALSE;
|
||||
if (store->type == CERT_STORE_SAVE_AS_STORE)
|
||||
{
|
||||
HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
/* FIXME: if I could translate a handle to a path, I could use
|
||||
* CryptQueryObject instead, but there's no API to do so yet.
|
||||
*/
|
||||
ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore);
|
||||
if (ret)
|
||||
I_CertUpdateStore(store->memStore, memStore, 0, 0);
|
||||
CertCloseStore(memStore, 0);
|
||||
}
|
||||
else if (store->type == CERT_STORE_SAVE_AS_PKCS7)
|
||||
{
|
||||
CERT_BLOB blob = { 0, NULL };
|
||||
|
||||
ret = CRYPT_ReadBlobFromFile(store->file, &blob);
|
||||
if (ret)
|
||||
{
|
||||
HCERTSTORE messageStore;
|
||||
|
||||
ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
|
||||
&messageStore, NULL, NULL);
|
||||
I_CertUpdateStore(store->memStore, messageStore, 0, 0);
|
||||
CertCloseStore(messageStore, 0);
|
||||
CryptMemFree(blob.pbData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown type %d\n", store->type);
|
||||
ret = FALSE;
|
||||
}
|
||||
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 = CertSaveStore(store->memStore,
|
||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
|
||||
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_CreateFileStore(DWORD dwFlags,
|
||||
HCERTSTORE memStore, HANDLE file, DWORD type)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
|
||||
|
||||
if (info)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
info->dwOpenFlags = dwFlags;
|
||||
info->memStore = memStore;
|
||||
info->file = file;
|
||||
info->type = type;
|
||||
info->dirty = FALSE;
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
|
||||
sizeof(fileProvFuncs[0]);
|
||||
provInfo.rgpvStoreProvFunc = fileProvFuncs;
|
||||
provInfo.hStoreProv = info;
|
||||
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
HCERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
|
||||
{
|
||||
store = CRYPT_CreateFileStore(dwFlags, memStore, file,
|
||||
CERT_STORE_SAVE_AS_STORE);
|
||||
/* File store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv &&
|
||||
!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", store);
|
||||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
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_STORE_READONLY_FLAG) &&
|
||||
(dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
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)
|
||||
{
|
||||
HCERTSTORE memStore = NULL;
|
||||
DWORD size = GetFileSize(file, NULL), type = 0;
|
||||
|
||||
/* If the file isn't empty, try to get the type from the file itself */
|
||||
if (size)
|
||||
{
|
||||
DWORD contentType;
|
||||
BOOL ret;
|
||||
|
||||
/* Close the file so CryptQueryObject can succeed.. */
|
||||
CloseHandle(file);
|
||||
ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
|
||||
CERT_QUERY_CONTENT_FLAG_CERT |
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
|
||||
&memStore, NULL, NULL);
|
||||
if (ret)
|
||||
{
|
||||
if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
|
||||
type = CERT_STORE_SAVE_AS_PKCS7;
|
||||
else
|
||||
type = CERT_STORE_SAVE_AS_STORE;
|
||||
/* and reopen the file. */
|
||||
file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
|
||||
create, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static const WCHAR spc[] = { 's','p','c',0 };
|
||||
static const WCHAR p7c[] = { 'p','7','c',0 };
|
||||
LPCWSTR ext = strrchrW(fileName, '.');
|
||||
|
||||
if (ext)
|
||||
{
|
||||
ext++;
|
||||
if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
|
||||
type = CERT_STORE_SAVE_AS_PKCS7;
|
||||
}
|
||||
if (!type)
|
||||
type = CERT_STORE_SAVE_AS_STORE;
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
}
|
||||
if (memStore)
|
||||
{
|
||||
store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
|
||||
/* File store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
int len;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
||||
debugstr_a((LPCSTR)pvPara));
|
||||
|
||||
if (!pvPara)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
|
||||
if (len)
|
||||
{
|
||||
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
||||
|
||||
if (storeName)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
|
||||
ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
|
||||
CryptMemFree(storeName);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -25,10 +25,8 @@
|
|||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "mssip.h"
|
||||
#include "winuser.h"
|
||||
#include "advpub.h"
|
||||
#include "i_cryptasn1tls.h"
|
||||
#include "crypt32_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -46,7 +44,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
|
|||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
crypt_oid_free();
|
||||
if (hDefProv) CryptReleaseContext(hDefProv, 0);
|
||||
crypt_sip_free();
|
||||
root_store_free();
|
||||
default_chain_engine_free();
|
||||
/* Don't release the default provider on process shutdown, there's
|
||||
* no guarantee the provider dll hasn't already been unloaded.
|
||||
*/
|
||||
if (hDefProv && !pvReserved) CryptReleaseContext(hDefProv, 0);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -55,8 +59,16 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
|
|||
HCRYPTPROV CRYPT_GetDefaultProvider(void)
|
||||
{
|
||||
if (!hDefProv)
|
||||
CryptAcquireContextW(&hDefProv, NULL, MS_ENHANCED_PROV_W,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
|
||||
{
|
||||
HCRYPTPROV prov;
|
||||
|
||||
CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
InterlockedCompareExchangePointer((PVOID *)&hDefProv, (PVOID)prov,
|
||||
NULL);
|
||||
if (hDefProv != prov)
|
||||
CryptReleaseContext(prov, 0);
|
||||
}
|
||||
return hDefProv;
|
||||
}
|
||||
|
||||
|
@ -75,12 +87,24 @@ BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptFindLruEntry(DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%08x, %08x): stub!\n", unk0, unk1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2)
|
||||
{
|
||||
FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptCreateLruEntry(HLRUCACHE h, DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
|
||||
|
@ -188,7 +212,7 @@ BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
||||
DWORD WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
||||
{
|
||||
static int ret = 8;
|
||||
ret++;
|
||||
|
@ -196,18 +220,30 @@ int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(void *x, DWORD y, DWORD z)
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t x, DWORD y, void* z)
|
||||
{
|
||||
FIXME("%p %08x %08x\n", x, y, z);
|
||||
FIXME("(%p %08x %p): stub\n", x, y, z);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(void *x)
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("%p\n", x);
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
|
||||
DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
|
||||
const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
|
||||
|
@ -217,28 +253,3 @@ BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
|
|||
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( "%08x %p %08x %08x %08x %p %p %p %p %p %p\n", dwObjectType,
|
||||
pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
|
||||
dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
|
||||
phCertStore, phMsg, ppvContext);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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, %d, %p, %d, %p, %p, %p\n",
|
||||
pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
|
||||
pbDecoded, pcbDecoded, ppSignerCert);
|
||||
if (ppSignerCert)
|
||||
*ppSignerCert = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
2614
reactos/dll/win32/crypt32/msg.c
Normal file
2614
reactos/dll/win32/crypt32/msg.c
Normal file
File diff suppressed because it is too large
Load diff
522
reactos/dll/win32/crypt32/object.c
Normal file
522
reactos/dll/win32/crypt32/object.c
Normal file
|
@ -0,0 +1,522 @@
|
|||
/*
|
||||
* crypt32 Crypt*Object functions
|
||||
*
|
||||
* Copyright 2007 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 "imagehlp.h"
|
||||
#include "crypt32_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
HANDLE file;
|
||||
|
||||
TRACE("%s\n", debugstr_w(fileName));
|
||||
|
||||
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = TRUE;
|
||||
blob->cbData = GetFileSize(file, NULL);
|
||||
if (blob->cbData)
|
||||
{
|
||||
blob->pbData = CryptMemAlloc(blob->cbData);
|
||||
if (blob->pbData)
|
||||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
|
||||
DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
HCERTSTORE store;
|
||||
DWORD contentType;
|
||||
BOOL ret;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
|
||||
* just read the file directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ret = FALSE;
|
||||
if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
|
||||
{
|
||||
ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CERT;
|
||||
}
|
||||
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
|
||||
{
|
||||
ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CRL;
|
||||
}
|
||||
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
|
||||
{
|
||||
ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CTL;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = contentType;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(store);
|
||||
}
|
||||
CertCloseStore(store, 0);
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD dwExpectedContentTypeFlags,
|
||||
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, const void **ppvContext)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
|
||||
const void *context;
|
||||
DWORD contextType;
|
||||
BOOL ret;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
|
||||
* just read the file directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
context = CRYPT_ReadSerializedElement(blob->pbData, blob->cbData,
|
||||
CERT_STORE_ALL_CONTEXT_FLAG, &contextType);
|
||||
if (context)
|
||||
{
|
||||
DWORD contentType, certStoreOffset;
|
||||
|
||||
ret = TRUE;
|
||||
switch (contextType)
|
||||
{
|
||||
case CERT_STORE_CERTIFICATE_CONTEXT:
|
||||
contextInterface = pCertInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CERT;
|
||||
certStoreOffset = offsetof(CERT_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_CRL_CONTEXT:
|
||||
contextInterface = pCRLInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CRL;
|
||||
certStoreOffset = offsetof(CRL_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_CTL_CONTEXT:
|
||||
contextInterface = pCTLInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CTL;
|
||||
certStoreOffset = offsetof(CTL_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = contentType;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(
|
||||
*(HCERTSTORE *)((const BYTE *)context + certStoreOffset));
|
||||
if (ppvContext)
|
||||
*ppvContext = contextInterface->duplicate(context);
|
||||
}
|
||||
|
||||
end:
|
||||
if (contextInterface && context)
|
||||
contextInterface->free(context);
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
LPCWSTR fileName = (LPCWSTR)pvObject;
|
||||
HANDLE file;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
|
||||
{
|
||||
FIXME("unimplemented for non-file type %d\n", dwObjectType);
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("%s\n", debugstr_w(fileName));
|
||||
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
ret = CRYPT_ReadSerializedStoreFromFile(file, store);
|
||||
if (ret)
|
||||
{
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(store);
|
||||
}
|
||||
CertCloseStore(store, 0);
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Used to decode non-embedded messages */
|
||||
static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
|
||||
DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
BOOL ret;
|
||||
HCRYPTMSG msg = NULL;
|
||||
DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* This isn't an embedded PKCS7 message, so just read the file
|
||||
* directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
ret = FALSE;
|
||||
/* Try it first as a PKCS content info */
|
||||
if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
DWORD type, len = sizeof(type);
|
||||
|
||||
ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
|
||||
if (ret)
|
||||
{
|
||||
if ((dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
|
||||
{
|
||||
if (type != CMSG_SIGNED)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
|
||||
}
|
||||
else if ((dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
if (type != CMSG_DATA)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Failing that, try explicitly typed messages */
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (msg && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (msg && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
|
||||
}
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = encodingType;
|
||||
if (msg)
|
||||
{
|
||||
if (phMsg)
|
||||
*phMsg = msg;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0,
|
||||
0, msg);
|
||||
}
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD dwExpectedContentTypeFlags,
|
||||
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
HANDLE file;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
|
||||
{
|
||||
FIXME("don't know what to do for type %d embedded signed messages\n",
|
||||
dwObjectType);
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
file = CreateFileW((LPCWSTR)pvObject, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD len;
|
||||
|
||||
ret = ImageGetCertificateData(file, 0, NULL, &len);
|
||||
if (ret)
|
||||
{
|
||||
WIN_CERTIFICATE *winCert = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
|
||||
if (winCert)
|
||||
{
|
||||
ret = ImageGetCertificateData(file, 0, winCert, &len);
|
||||
if (ret)
|
||||
{
|
||||
CERT_BLOB blob = { winCert->dwLength,
|
||||
winCert->bCertificate };
|
||||
|
||||
ret = CRYPT_QueryMessageObject(CERT_QUERY_OBJECT_BLOB,
|
||||
&blob, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
pdwMsgAndCertEncodingType, NULL, phCertStore, phMsg);
|
||||
if (ret && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, winCert);
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
static const DWORD unimplementedTypes =
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX |
|
||||
CERT_QUERY_CONTENT_FLAG_CERT_PAIR;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
|
||||
dwObjectType, pvObject, dwExpectedContentTypeFlags,
|
||||
dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType,
|
||||
pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext);
|
||||
|
||||
if (dwExpectedContentTypeFlags & unimplementedTypes)
|
||||
WARN("unimplemented for types %08x\n",
|
||||
dwExpectedContentTypeFlags & unimplementedTypes);
|
||||
if (!(dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY))
|
||||
{
|
||||
FIXME("unimplemented for anything but binary\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
if (pdwFormatType)
|
||||
*pdwFormatType = CERT_QUERY_FORMAT_BINARY;
|
||||
|
||||
if (phCertStore)
|
||||
*phCertStore = NULL;
|
||||
if (phMsg)
|
||||
*phMsg = NULL;
|
||||
if (ppvContext)
|
||||
*ppvContext = NULL;
|
||||
|
||||
ret = FALSE;
|
||||
if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
|
||||
{
|
||||
ret = CRYPT_QueryContextObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, ppvContext);
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE))
|
||||
{
|
||||
ret = CRYPT_QuerySerializedStoreObject(dwObjectType, pvObject,
|
||||
pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
|
||||
}
|
||||
if (!ret &&
|
||||
((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL)))
|
||||
{
|
||||
ret = CRYPT_QuerySerializedContextObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, ppvContext);
|
||||
}
|
||||
if (!ret &&
|
||||
((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
|
||||
{
|
||||
ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, phMsg);
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED))
|
||||
{
|
||||
ret = CRYPT_QueryEmbeddedMessageObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, phMsg);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
|
@ -37,14 +37,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|||
|
||||
static const WCHAR DllW[] = { 'D','l','l',0 };
|
||||
|
||||
static void init_function_sets(void);
|
||||
static void init_oid_info(HINSTANCE hinst);
|
||||
static void free_function_sets(void);
|
||||
static void free_oid_info(void);
|
||||
|
||||
void crypt_oid_init(HINSTANCE hinst)
|
||||
{
|
||||
init_function_sets();
|
||||
init_oid_info(hinst);
|
||||
}
|
||||
|
||||
|
@ -55,7 +53,14 @@ void crypt_oid_free(void)
|
|||
}
|
||||
|
||||
static CRITICAL_SECTION funcSetCS;
|
||||
static struct list funcSets;
|
||||
static CRITICAL_SECTION_DEBUG funcSetCSDebug =
|
||||
{
|
||||
0, 0, &funcSetCS,
|
||||
{ &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": funcSetCS") }
|
||||
};
|
||||
static CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 };
|
||||
static struct list funcSets = { &funcSets, &funcSets };
|
||||
|
||||
struct OIDFunctionSet
|
||||
{
|
||||
|
@ -72,12 +77,12 @@ struct OIDFunction
|
|||
struct list next;
|
||||
};
|
||||
|
||||
static void init_function_sets(void)
|
||||
{
|
||||
InitializeCriticalSection(&funcSetCS);
|
||||
funcSetCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": funcSetCS");
|
||||
list_init(&funcSets);
|
||||
}
|
||||
static const WCHAR ROOT[] = {'R','O','O','T',0};
|
||||
static const WCHAR MY[] = {'M','Y',0};
|
||||
static const WCHAR CA[] = {'C','A',0};
|
||||
static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0};
|
||||
static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK};
|
||||
static WCHAR LocalizedNames[4][256];
|
||||
|
||||
static void free_function_sets(void)
|
||||
{
|
||||
|
@ -100,8 +105,6 @@ static void free_function_sets(void)
|
|||
DeleteCriticalSection(&setCursor->cs);
|
||||
CryptMemFree(setCursor);
|
||||
}
|
||||
funcSetCS.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&funcSetCS);
|
||||
}
|
||||
|
||||
/* There is no free function associated with this; therefore, the sets are
|
||||
|
@ -181,7 +184,8 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
|
||||
szKey = CryptMemAlloc(len);
|
||||
if (szKey)
|
||||
sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
|
||||
sprintf(szKey, szEncodingTypeFmt,
|
||||
GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid);
|
||||
return szKey;
|
||||
}
|
||||
|
||||
|
@ -211,7 +215,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
|||
else
|
||||
{
|
||||
/* No value, return an empty list */
|
||||
if (*pcchDllList)
|
||||
if (pwszDllList && *pcchDllList)
|
||||
*pwszDllList = '\0';
|
||||
*pcchDllList = 1;
|
||||
}
|
||||
|
@ -219,8 +223,10 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
|||
}
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
/* No value, return an empty list */
|
||||
if (pwszDllList && *pcchDllList)
|
||||
*pwszDllList = '\0';
|
||||
*pcchDllList = 1;
|
||||
}
|
||||
CryptMemFree(keyName);
|
||||
|
||||
|
@ -254,7 +260,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
|
|||
func = CryptMemAlloc(sizeof(struct OIDFunction));
|
||||
if (func)
|
||||
{
|
||||
func->encoding = dwEncodingType;
|
||||
func->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType);
|
||||
if (HIWORD(rgFuncEntry[i].pszOID))
|
||||
{
|
||||
LPSTR oid;
|
||||
|
@ -278,6 +284,13 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct FuncAddr
|
||||
{
|
||||
HMODULE lib;
|
||||
LPWSTR dllList;
|
||||
LPWSTR currentDll;
|
||||
};
|
||||
|
||||
static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
||||
LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
|
||||
{
|
||||
|
@ -294,7 +307,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
DWORD type, size = 0;
|
||||
|
||||
rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
|
||||
if (rc == ERROR_MORE_DATA && type == REG_SZ)
|
||||
if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
|
||||
{
|
||||
funcName = CryptMemAlloc(size);
|
||||
rc = RegQueryValueExA(key, "FuncName", NULL, &type,
|
||||
|
@ -303,7 +316,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
else
|
||||
funcName = szFuncName;
|
||||
rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
|
||||
if (rc == ERROR_MORE_DATA && type == REG_SZ)
|
||||
if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
|
||||
{
|
||||
LPWSTR dllName = CryptMemAlloc(size);
|
||||
|
||||
|
@ -322,13 +335,26 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
lib = LoadLibraryW(dllName);
|
||||
if (lib)
|
||||
{
|
||||
*ppvFuncAddr = GetProcAddress(lib, szFuncName);
|
||||
*ppvFuncAddr = GetProcAddress(lib, funcName);
|
||||
if (*ppvFuncAddr)
|
||||
{
|
||||
*phFuncAddr = (HCRYPTOIDFUNCADDR)lib;
|
||||
struct FuncAddr *addr =
|
||||
CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
|
||||
if (addr)
|
||||
{
|
||||
addr->lib = lib;
|
||||
addr->dllList = addr->currentDll = NULL;
|
||||
*phFuncAddr = addr;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*phFuncAddr = NULL;
|
||||
FreeLibrary(lib);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unload the library, the caller doesn't want
|
||||
* to unload it when the return value is NULL.
|
||||
|
@ -372,7 +398,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
|||
EnterCriticalSection(&set->cs);
|
||||
LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
|
||||
{
|
||||
if (function->encoding == dwEncodingType)
|
||||
if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
{
|
||||
if (HIWORD(pszOID))
|
||||
{
|
||||
|
@ -399,6 +425,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
|||
if (!*ppvFuncAddr)
|
||||
ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
|
||||
ppvFuncAddr, phFuncAddr);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -411,17 +438,151 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
|
|||
* and only unload it if it can be unloaded. Also need to implement ref
|
||||
* counting on the functions.
|
||||
*/
|
||||
FreeLibrary((HMODULE)hFuncAddr);
|
||||
if (hFuncAddr)
|
||||
{
|
||||
struct FuncAddr *addr = (struct FuncAddr *)hFuncAddr;
|
||||
|
||||
CryptMemFree(addr->dllList);
|
||||
FreeLibrary(addr->lib);
|
||||
CryptMemFree(addr);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib,
|
||||
void **ppvFuncAddr)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
*lib = LoadLibraryW(dll);
|
||||
if (*lib)
|
||||
{
|
||||
*ppvFuncAddr = GetProcAddress(*lib, func);
|
||||
if (*ppvFuncAddr)
|
||||
ret = TRUE;
|
||||
else
|
||||
{
|
||||
FreeLibrary(*lib);
|
||||
*lib = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
|
||||
HCRYPTOIDFUNCADDR *phFuncAddr)
|
||||
{
|
||||
FIXME("(%p, %d, %s, %08x, %p, %p): stub\n", hFuncSet, dwEncodingType,
|
||||
struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
|
||||
debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
|
||||
return FALSE;
|
||||
|
||||
if (pwszDll)
|
||||
{
|
||||
HMODULE lib;
|
||||
|
||||
*phFuncAddr = NULL;
|
||||
ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
|
||||
if (ret)
|
||||
{
|
||||
struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
|
||||
if (addr)
|
||||
{
|
||||
addr->lib = lib;
|
||||
addr->dllList = addr->currentDll = NULL;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeLibrary(lib);
|
||||
*ppvFuncAddr = NULL;
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct FuncAddr *addr = (struct FuncAddr *)*phFuncAddr;
|
||||
|
||||
if (!addr)
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
|
||||
&size);
|
||||
if (ret)
|
||||
{
|
||||
LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
|
||||
|
||||
if (dllList)
|
||||
{
|
||||
ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
|
||||
dllList, &size);
|
||||
if (ret)
|
||||
{
|
||||
addr = CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
if (addr)
|
||||
{
|
||||
addr->dllList = dllList;
|
||||
addr->currentDll = dllList;
|
||||
addr->lib = NULL;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptMemFree(dllList);
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addr)
|
||||
{
|
||||
if (!*addr->currentDll)
|
||||
{
|
||||
CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
*phFuncAddr = NULL;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: as elsewhere, can't free until DllCanUnloadNow says
|
||||
* it's possible, and should defer unloading for some time to
|
||||
* avoid repeated LoadLibrary/FreeLibrary on the same dll.
|
||||
*/
|
||||
FreeLibrary(addr->lib);
|
||||
ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
|
||||
&addr->lib, ppvFuncAddr);
|
||||
if (ret)
|
||||
{
|
||||
/* Move past the current DLL */
|
||||
addr->currentDll += lstrlenW(addr->currentDll) + 1;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
*phFuncAddr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -454,10 +615,6 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
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))
|
||||
return TRUE;
|
||||
|
||||
/* Native does nothing pwszDll is NULL */
|
||||
if (!pwszDll)
|
||||
return TRUE;
|
||||
|
@ -515,10 +672,8 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
LPSTR szKey;
|
||||
LONG rc;
|
||||
|
||||
TRACE("%x %s %s\n", dwEncodingType, pszFuncName, pszOID);
|
||||
|
||||
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
return TRUE;
|
||||
TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName),
|
||||
debugstr_a(pszOID));
|
||||
|
||||
if (!pszFuncName || !pszOID)
|
||||
{
|
||||
|
@ -783,11 +938,10 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
{
|
||||
HKEY key;
|
||||
LPWSTR dlls;
|
||||
LPCWSTR existing;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%x, %s, %x, %s)\n", dwEncodingType, pszFuncName, dwIndex,
|
||||
debugstr_w(pwszDll));
|
||||
TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
|
||||
dwIndex, debugstr_w(pwszDll));
|
||||
|
||||
if (!pwszDll)
|
||||
{
|
||||
|
@ -799,7 +953,7 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
return FALSE;
|
||||
|
||||
dlls = CRYPT_GetDefaultOIDDlls(key);
|
||||
if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll)))
|
||||
if (CRYPT_FindStringInMultiString(dlls, pwszDll))
|
||||
SetLastError(ERROR_FILE_EXISTS);
|
||||
else
|
||||
{
|
||||
|
@ -839,8 +993,44 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void oid_init_localizednames(HINSTANCE hInstance)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
|
||||
{
|
||||
LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* CryptFindLocalizedName (CRYPT32.@)
|
||||
*/
|
||||
LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
|
||||
{
|
||||
if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
|
||||
{
|
||||
return LocalizedNames[i];
|
||||
}
|
||||
}
|
||||
|
||||
FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CRITICAL_SECTION oidInfoCS;
|
||||
static struct list oidInfo;
|
||||
static CRITICAL_SECTION_DEBUG oidInfoCSDebug =
|
||||
{
|
||||
0, 0, &oidInfoCS,
|
||||
{ &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": oidInfoCS") }
|
||||
};
|
||||
static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 };
|
||||
static struct list oidInfo = { &oidInfo, &oidInfo };
|
||||
|
||||
static const WCHAR tripledes[] = { '3','d','e','s',0 };
|
||||
static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a',
|
||||
|
@ -1181,9 +1371,7 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
{
|
||||
DWORD i;
|
||||
|
||||
InitializeCriticalSection(&oidInfoCS);
|
||||
oidInfoCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": oidInfoCS");
|
||||
list_init(&oidInfo);
|
||||
oid_init_localizednames(hinst);
|
||||
for (i = 0; i < sizeof(oidInfoConstructors) /
|
||||
sizeof(oidInfoConstructors[0]); i++)
|
||||
{
|
||||
|
@ -1213,8 +1401,9 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
}
|
||||
else
|
||||
{
|
||||
LPCWSTR stringresource;
|
||||
int len = LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
|
||||
NULL, 0);
|
||||
(LPWSTR)&stringresource, 0);
|
||||
|
||||
if (len)
|
||||
{
|
||||
|
@ -1226,12 +1415,11 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
memset(info, 0, sizeof(*info));
|
||||
info->info.cbSize = sizeof(CRYPT_OID_INFO);
|
||||
info->info.pszOID = oidInfoConstructors[i].pszOID;
|
||||
info->info.pwszName =
|
||||
(LPWSTR)((LPBYTE)info + sizeof(struct OIDInfo));
|
||||
info->info.pwszName = (LPWSTR)(info + 1);
|
||||
info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
|
||||
info->info.u.Algid = oidInfoConstructors[i].Algid;
|
||||
LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
|
||||
(LPWSTR)info->info.pwszName, len + 1);
|
||||
memcpy(info + 1, stringresource, len*sizeof(WCHAR));
|
||||
((LPWSTR)(info + 1))[len] = 0;
|
||||
if (oidInfoConstructors[i].blob)
|
||||
{
|
||||
info->info.ExtraInfo.cbData =
|
||||
|
@ -1255,8 +1443,6 @@ static void free_oid_info(void)
|
|||
list_remove(&info->entry);
|
||||
CryptMemFree(info);
|
||||
}
|
||||
oidInfoCS.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&oidInfoCS);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -42,14 +42,15 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#define CRYPT32_PROTECTDATA_PROV PROV_RSA_FULL
|
||||
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_MD5
|
||||
#define CRYPT32_PROTECTDATA_KEY_CALG CALG_RC2
|
||||
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_SHA1
|
||||
#define CRYPT32_PROTECTDATA_HASH_LEN 160
|
||||
#define CRYPT32_PROTECTDATA_KEY_CALG CALG_3DES
|
||||
#define CRYPT32_PROTECTDATA_KEY_LEN 168
|
||||
#define CRYPT32_PROTECTDATA_SALT_LEN 16
|
||||
|
||||
static const BYTE crypt32_protectdata_secret[] = {
|
||||
|
@ -62,21 +63,22 @@ static const BYTE crypt32_protectdata_secret[] = {
|
|||
* to be something like this:
|
||||
|
||||
DWORD count0; - how many "info0_*[16]" blocks follow (was always 1)
|
||||
BYTE info0_0[16]; - unknown information
|
||||
...
|
||||
BYTE info0_0[16]; - unknown information - persistent across invocations,
|
||||
... reboots, password changes, and users
|
||||
DWORD count1; - how many "info1_*[16]" blocks follow (was always 1)
|
||||
BYTE info1_0[16]; - unknown information
|
||||
...
|
||||
BYTE info1_0[16]; - unknown information - unique to each user, but
|
||||
... persistent across reboots and password changes
|
||||
DWORD null0; - NULL "end of records"?
|
||||
DWORD str_len; - length of WCHAR string including term
|
||||
WCHAR str[str_len]; - The "dataDescription" value
|
||||
DWORD unknown0; - unknown value (seems large, but only WORD large)
|
||||
DWORD unknown1; - unknown value (seems small, less than a BYTE)
|
||||
DWORD str_len; - byte length of WCHAR string including term
|
||||
BYTE str[str_len]; - The "dataDescription" value as a NULL-terminated
|
||||
little-endian WCHAR string
|
||||
ALG_ID cipher_alg; - cipher algo - was CALG_3DES
|
||||
DWORD cipher_key_len; - cipher key bit length - was 0xa8==168
|
||||
DWORD data_len; - length of data (was 16 in samples)
|
||||
BYTE data[data_len]; - unknown data (fingerprint?)
|
||||
DWORD null1; - NULL ?
|
||||
DWORD unknown2; - unknown value (seems large, but only WORD large)
|
||||
DWORD unknown3; - unknown value (seems small, less than a BYTE)
|
||||
ALG_ID hash_alg; - hash algo - was CALG_SHA1
|
||||
DWORD hash_len; - bit length of hash - was 0xa0==160
|
||||
DWORD salt_len; - length of salt(?) data
|
||||
BYTE salt[salt_len]; - salt(?) for symmetric encryption
|
||||
DWORD cipher_len; - length of cipher(?) data - was close to plain len
|
||||
|
@ -95,12 +97,12 @@ struct protect_data_t
|
|||
DATA_BLOB info1;
|
||||
DWORD null0;
|
||||
WCHAR * szDataDescr; /* serialized differently than the DATA_BLOBs */
|
||||
DWORD unknown0; /* perhaps the HASH alg const should go here? */
|
||||
DWORD unknown1;
|
||||
ALG_ID cipher_alg;
|
||||
DWORD cipher_key_len;
|
||||
DATA_BLOB data0;
|
||||
DWORD null1;
|
||||
DWORD unknown2; /* perhaps the KEY alg const should go here? */
|
||||
DWORD unknown3;
|
||||
ALG_ID hash_alg;
|
||||
DWORD hash_len;
|
||||
DATA_BLOB salt;
|
||||
DATA_BLOB cipher;
|
||||
DATA_BLOB fingerprint;
|
||||
|
@ -288,11 +290,11 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
(dwStrLen+1)*sizeof(WCHAR),sizeof(BYTE),TRUE);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* unknown0 */
|
||||
serialize_dword(pInfo->unknown0,&ptr);
|
||||
/* cipher_alg */
|
||||
serialize_dword(pInfo->cipher_alg,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
/* unknown1 */
|
||||
serialize_dword(pInfo->unknown1,&ptr);
|
||||
/* cipher_key_len */
|
||||
serialize_dword(pInfo->cipher_key_len,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* data0 */
|
||||
|
@ -304,11 +306,11 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
serialize_dword(pInfo->null1,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* unknown2 */
|
||||
serialize_dword(pInfo->unknown2,&ptr);
|
||||
/* hash_alg */
|
||||
serialize_dword(pInfo->hash_alg,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
/* unknown3 */
|
||||
serialize_dword(pInfo->unknown3,&ptr);
|
||||
/* hash_len */
|
||||
serialize_dword(pInfo->hash_len,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* salt */
|
||||
|
@ -329,7 +331,7 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
if (ptr - pSerial->pbData != dwStruct)
|
||||
{
|
||||
ERR("struct size changed!? %u != expected %u\n",
|
||||
ptr - pSerial->pbData, (unsigned int)dwStruct);
|
||||
ptr - pSerial->pbData, dwStruct);
|
||||
LocalFree(pSerial->pbData);
|
||||
pSerial->pbData=NULL;
|
||||
pSerial->cbData=0;
|
||||
|
@ -401,17 +403,17 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown0 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown0))
|
||||
/* cipher_alg */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->cipher_alg))
|
||||
{
|
||||
ERR("reading unknown0 failed!\n");
|
||||
ERR("reading cipher_alg failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown1 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown1))
|
||||
/* cipher_key_len */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->cipher_key_len))
|
||||
{
|
||||
ERR("reading unknown1 failed!\n");
|
||||
ERR("reading cipher_key_len failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -430,17 +432,17 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown2 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown2))
|
||||
/* hash_alg */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->hash_alg))
|
||||
{
|
||||
ERR("reading unknown2 failed!\n");
|
||||
ERR("reading hash_alg failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown3 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown3))
|
||||
/* hash_len */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->hash_len))
|
||||
{
|
||||
ERR("reading unknown3 failed!\n");
|
||||
ERR("reading hash_len failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -474,8 +476,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
{
|
||||
/* this is an impossible-to-reach test, but if the padding
|
||||
* issue is ever understood, this may become more useful */
|
||||
ERR("loaded corrupt structure! (used %u expected %u)\n",
|
||||
(unsigned int)index, (unsigned int)size);
|
||||
ERR("loaded corrupt structure! (used %u expected %u)\n", index, size);
|
||||
status=FALSE;
|
||||
}
|
||||
|
||||
|
@ -596,14 +597,14 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
|
|||
memcpy(pInfo->szDataDescr,szDataDescr,(dwStrLen+1)*sizeof(WCHAR));
|
||||
}
|
||||
|
||||
pInfo->unknown0=0x0000;
|
||||
pInfo->unknown1=0x0000;
|
||||
pInfo->cipher_alg=CRYPT32_PROTECTDATA_KEY_CALG;
|
||||
pInfo->cipher_key_len=CRYPT32_PROTECTDATA_KEY_LEN;
|
||||
|
||||
convert_str_to_blob(crypt_magic_str, &pInfo->data0);
|
||||
|
||||
pInfo->null1=0x0000;
|
||||
pInfo->unknown2=0x0000;
|
||||
pInfo->unknown3=0x0000;
|
||||
pInfo->hash_alg=CRYPT32_PROTECTDATA_HASH_CALG;
|
||||
pInfo->hash_len=CRYPT32_PROTECTDATA_HASH_LEN;
|
||||
|
||||
/* allocate memory to hold a salt */
|
||||
pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN;
|
||||
|
@ -704,7 +705,7 @@ BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two)
|
|||
|
||||
/* create an encryption key from a given salt and optional entropy */
|
||||
static
|
||||
BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
|
||||
BOOL load_encryption_key(HCRYPTPROV hProv, DWORD key_len, const DATA_BLOB *salt,
|
||||
const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
|
@ -753,7 +754,7 @@ BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
|
|||
|
||||
/* produce a symmetric key */
|
||||
if (rc && !CryptDeriveKey(hProv,CRYPT32_PROTECTDATA_KEY_CALG,
|
||||
hSaltHash,CRYPT_EXPORTABLE,phKey))
|
||||
hSaltHash,key_len << 16 | CRYPT_EXPORTABLE,phKey))
|
||||
{
|
||||
ERR("CryptDeriveKey\n");
|
||||
rc = FALSE;
|
||||
|
@ -774,15 +775,15 @@ report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy,
|
|||
TRACE("pPromptStruct: %p\n", pPromptStruct);
|
||||
if (pPromptStruct)
|
||||
{
|
||||
TRACE(" cbSize: 0x%x\n",(unsigned int)pPromptStruct->cbSize);
|
||||
TRACE(" dwPromptFlags: 0x%x\n",(unsigned int)pPromptStruct->dwPromptFlags);
|
||||
TRACE(" cbSize: 0x%x\n", pPromptStruct->cbSize);
|
||||
TRACE(" dwPromptFlags: 0x%x\n", pPromptStruct->dwPromptFlags);
|
||||
TRACE(" hwndApp: %p\n", pPromptStruct->hwndApp);
|
||||
TRACE(" szPrompt: %p %s\n",
|
||||
pPromptStruct->szPrompt,
|
||||
pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt)
|
||||
: "");
|
||||
}
|
||||
TRACE("dwFlags: 0x%04x\n",(unsigned int)dwFlags);
|
||||
TRACE("dwFlags: 0x%04x\n", dwFlags);
|
||||
TRACE_DATA_BLOB(pDataIn);
|
||||
if (pOptionalEntropy)
|
||||
{
|
||||
|
@ -857,7 +858,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
szDataDescr = empty_str;
|
||||
|
||||
/* get crypt context */
|
||||
if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContextW(&hProv,NULL,MS_ENHANCED_PROV_W,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
{
|
||||
ERR("CryptAcquireContextW failed\n");
|
||||
goto finished;
|
||||
|
@ -871,7 +872,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
}
|
||||
|
||||
/* load key */
|
||||
if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
{
|
||||
goto free_protect_data;
|
||||
}
|
||||
|
@ -891,7 +892,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
ERR("CryptEncrypt\n");
|
||||
goto free_hash;
|
||||
}
|
||||
TRACE("required encrypted storage: %u\n",(unsigned int)dwLength);
|
||||
TRACE("required encrypted storage: %u\n", dwLength);
|
||||
|
||||
/* copy plain text into cipher area for CryptEncrypt call */
|
||||
protect_data.cipher.cbData=dwLength;
|
||||
|
@ -908,7 +909,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData,
|
||||
&dwLength, protect_data.cipher.cbData))
|
||||
{
|
||||
ERR("CryptEncrypt %u\n",(unsigned int)GetLastError());
|
||||
ERR("CryptEncrypt %u\n", GetLastError());
|
||||
goto free_hash;
|
||||
}
|
||||
protect_data.cipher.cbData=dwLength;
|
||||
|
@ -1016,6 +1017,11 @@ BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn,
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto finished;
|
||||
}
|
||||
if (!pDataIn->cbData)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
goto finished;
|
||||
}
|
||||
|
||||
/* debug: show our arguments */
|
||||
report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
|
||||
|
@ -1038,14 +1044,14 @@ BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn,
|
|||
}
|
||||
|
||||
/* get a crypt context */
|
||||
if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContextW(&hProv,NULL,MS_ENHANCED_PROV_W,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
{
|
||||
ERR("CryptAcquireContextW failed\n");
|
||||
goto free_protect_data;
|
||||
}
|
||||
|
||||
/* load key */
|
||||
if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
{
|
||||
goto free_context;
|
||||
}
|
||||
|
|
300
reactos/dll/win32/crypt32/provstore.c
Normal file
300
reactos/dll/win32/crypt32/provstore.c
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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 "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_PROVIDERSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
DWORD dwStoreProvFlags;
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
HCERTSTOREPROV hStoreProv;
|
||||
PFN_CERT_STORE_PROV_CLOSE provCloseStore;
|
||||
PFN_CERT_STORE_PROV_WRITE_CERT provWriteCert;
|
||||
PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert;
|
||||
PFN_CERT_STORE_PROV_WRITE_CRL provWriteCrl;
|
||||
PFN_CERT_STORE_PROV_DELETE_CRL provDeleteCrl;
|
||||
PFN_CERT_STORE_PROV_CONTROL provControl;
|
||||
} WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
|
||||
|
||||
static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
|
||||
if (store->provCloseStore)
|
||||
store->provCloseStore(store->hStoreProv, dwFlags);
|
||||
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
|
||||
CertCloseStore(store->memStore, dwFlags);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->certs.addContext(ps->memStore, cert, toReplace,
|
||||
ppStoreContext);
|
||||
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,
|
||||
ppStoreContext);
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ppStoreContext)
|
||||
(*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
|
||||
ret = ps->memStore->certs.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store, void *cert)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, cert);
|
||||
|
||||
if (ps->provDeleteCert)
|
||||
ret = ps->provDeleteCert(ps->hStoreProv, cert, 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->certs.deleteContext(ps->memStore, cert);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, toReplace,
|
||||
ppStoreContext);
|
||||
else
|
||||
{
|
||||
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCrl)
|
||||
ret = ps->provWriteCrl(ps->hStoreProv, (PCCRL_CONTEXT)crl,
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, NULL,
|
||||
ppStoreContext);
|
||||
}
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ppStoreContext)
|
||||
(*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
|
||||
ret = ps->memStore->crls.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store, void *crl)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, crl);
|
||||
|
||||
if (ps->provDeleteCrl)
|
||||
ret = ps->provDeleteCrl(ps->hStoreProv, crl, 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.deleteContext(ps->memStore, crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
if (store->provControl)
|
||||
ret = store->provControl(store->hStoreProv, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider);
|
||||
ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
|
||||
if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
|
||||
{
|
||||
CertCloseStore(memStore, 0);
|
||||
ret->memStore = NULL;
|
||||
}
|
||||
else
|
||||
ret->memStore = memStore;
|
||||
ret->hStoreProv = pProvInfo->hStoreProv;
|
||||
ret->hdr.closeStore = CRYPT_ProvCloseStore;
|
||||
ret->hdr.certs.addContext = CRYPT_ProvAddCert;
|
||||
ret->hdr.certs.enumContext = CRYPT_ProvEnumCert;
|
||||
ret->hdr.certs.deleteContext = CRYPT_ProvDeleteCert;
|
||||
ret->hdr.crls.addContext = CRYPT_ProvAddCRL;
|
||||
ret->hdr.crls.enumContext = CRYPT_ProvEnumCRL;
|
||||
ret->hdr.crls.deleteContext = CRYPT_ProvDeleteCRL;
|
||||
ret->hdr.control = CRYPT_ProvControl;
|
||||
if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
|
||||
ret->provCloseStore =
|
||||
pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
|
||||
else
|
||||
ret->provCloseStore = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_WRITE_CERT_FUNC)
|
||||
ret->provWriteCert = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_WRITE_CERT_FUNC];
|
||||
else
|
||||
ret->provWriteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_DELETE_CERT_FUNC)
|
||||
ret->provDeleteCert = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_DELETE_CERT_FUNC];
|
||||
else
|
||||
ret->provDeleteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_WRITE_CRL_FUNC)
|
||||
ret->provWriteCrl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_WRITE_CRL_FUNC];
|
||||
else
|
||||
ret->provWriteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_DELETE_CRL_FUNC)
|
||||
ret->provDeleteCrl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_DELETE_CRL_FUNC];
|
||||
else
|
||||
ret->provDeleteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_CONTROL_FUNC)
|
||||
ret->provControl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_CONTROL_FUNC];
|
||||
else
|
||||
ret->provControl = NULL;
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
static HCRYPTOIDFUNCSET set = NULL;
|
||||
PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
|
||||
HCRYPTOIDFUNCADDR hFunc;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
|
||||
if (!set)
|
||||
set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
|
||||
CryptGetOIDFunctionAddress(set, dwEncodingType, lpszStoreProvider, 0,
|
||||
(void **)&provOpenFunc, &hFunc);
|
||||
if (provOpenFunc)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
|
||||
dwFlags, pvPara, NULL, &provInfo);
|
||||
else
|
||||
{
|
||||
HCERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
if (provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
|
||||
dwFlags, pvPara, memStore, &provInfo))
|
||||
ret = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
else
|
||||
CertCloseStore(memStore, 0);
|
||||
}
|
||||
}
|
||||
CryptFreeOIDFunctionAddress(hFunc, 0);
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return ret;
|
||||
}
|
550
reactos/dll/win32/crypt32/regstore.c
Normal file
550
reactos/dll/win32/crypt32/regstore.c
Normal file
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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 <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_HASH_TO_DELETE
|
||||
{
|
||||
BYTE hash[20];
|
||||
struct list entry;
|
||||
} WINE_HASH_TO_DELETE, *PWINE_HASH_TO_DELETE;
|
||||
|
||||
typedef struct _WINE_REGSTOREINFO
|
||||
{
|
||||
DWORD dwOpenFlags;
|
||||
HCERTSTORE memStore;
|
||||
HKEY key;
|
||||
BOOL dirty;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list certsToDelete;
|
||||
struct list crlsToDelete;
|
||||
} WINE_REGSTOREINFO, *PWINE_REGSTOREINFO;
|
||||
|
||||
static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash)
|
||||
{
|
||||
static const WCHAR fmt[] = { '%','0','2','X',0 };
|
||||
DWORD i;
|
||||
|
||||
assert(hash);
|
||||
assert(asciiHash);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
wsprintfW(asciiHash + i * 2, fmt, hash[i]);
|
||||
}
|
||||
|
||||
static const WCHAR CertsW[] = { 'C','e','r','t','i','f','i','c','a','t','e','s',
|
||||
0 };
|
||||
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(HKEY key, DWORD contextType,
|
||||
HCERTSTORE store)
|
||||
{
|
||||
LONG rc;
|
||||
DWORD index = 0;
|
||||
WCHAR subKeyName[MAX_PATH];
|
||||
|
||||
do {
|
||||
DWORD size = sizeof(subKeyName) / sizeof(WCHAR);
|
||||
|
||||
rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (!rc)
|
||||
{
|
||||
HKEY subKey;
|
||||
|
||||
rc = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
|
||||
if (!rc)
|
||||
{
|
||||
LPBYTE buf = NULL;
|
||||
|
||||
size = 0;
|
||||
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, NULL, &size);
|
||||
if (!rc)
|
||||
buf = CryptMemAlloc(size);
|
||||
if (buf)
|
||||
{
|
||||
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, buf,
|
||||
&size);
|
||||
if (!rc)
|
||||
{
|
||||
const void *context;
|
||||
DWORD addedType;
|
||||
|
||||
TRACE("Adding cert with hash %s\n",
|
||||
debugstr_w(subKeyName));
|
||||
context = CRYPT_ReadSerializedElement(buf, size,
|
||||
contextType, &addedType);
|
||||
if (context)
|
||||
{
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface;
|
||||
BYTE hash[20];
|
||||
|
||||
switch (addedType)
|
||||
{
|
||||
case CERT_STORE_CERTIFICATE_CONTEXT:
|
||||
contextInterface = pCertInterface;
|
||||
break;
|
||||
case CERT_STORE_CRL_CONTEXT:
|
||||
contextInterface = pCRLInterface;
|
||||
break;
|
||||
case CERT_STORE_CTL_CONTEXT:
|
||||
contextInterface = pCTLInterface;
|
||||
break;
|
||||
default:
|
||||
contextInterface = NULL;
|
||||
}
|
||||
if (contextInterface)
|
||||
{
|
||||
size = sizeof(hash);
|
||||
if (contextInterface->getProp(context,
|
||||
CERT_HASH_PROP_ID, hash, &size))
|
||||
{
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
|
||||
CRYPT_HashToStr(hash, asciiHash);
|
||||
TRACE("comparing %s\n",
|
||||
debugstr_w(asciiHash));
|
||||
TRACE("with %s\n", debugstr_w(subKeyName));
|
||||
if (!lstrcmpW(asciiHash, subKeyName))
|
||||
{
|
||||
TRACE("hash matches, adding\n");
|
||||
contextInterface->addContextToStore(
|
||||
store, context,
|
||||
CERT_STORE_ADD_REPLACE_EXISTING, NULL);
|
||||
}
|
||||
else
|
||||
TRACE("hash doesn't match, ignoring\n");
|
||||
}
|
||||
contextInterface->free(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
RegCloseKey(subKey);
|
||||
}
|
||||
/* Ignore intermediate errors, continue enumerating */
|
||||
rc = ERROR_SUCCESS;
|
||||
}
|
||||
} while (!rc);
|
||||
}
|
||||
|
||||
static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store)
|
||||
{
|
||||
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;
|
||||
|
||||
for (i = 0; i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
|
||||
{
|
||||
HKEY hKey;
|
||||
LONG rc;
|
||||
|
||||
rc = RegCreateKeyExW(key, subKeys[i], 0, NULL, 0, KEY_READ, NULL,
|
||||
&hKey, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
CRYPT_RegReadSerializedFromReg(hKey, contextFlags[i], store);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */
|
||||
static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *buf,
|
||||
DWORD len)
|
||||
{
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
LONG rc;
|
||||
HKEY subKey;
|
||||
BOOL ret;
|
||||
|
||||
CRYPT_HashToStr(hash, asciiHash);
|
||||
rc = RegCreateKeyExW(key, asciiHash, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
|
||||
&subKey, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
rc = RegSetValueExW(subKey, BlobW, 0, REG_BINARY, buf, len);
|
||||
RegCloseKey(subKey);
|
||||
}
|
||||
if (!rc)
|
||||
ret = TRUE;
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToReg(HKEY key,
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE memStore)
|
||||
{
|
||||
const void *context = NULL;
|
||||
BOOL ret;
|
||||
|
||||
do {
|
||||
context = contextInterface->enumContextsInStore(memStore, context);
|
||||
if (context)
|
||||
{
|
||||
BYTE hash[20];
|
||||
DWORD hashSize = sizeof(hash);
|
||||
|
||||
ret = contextInterface->getProp(context, CERT_HASH_PROP_ID, hash,
|
||||
&hashSize);
|
||||
if (ret)
|
||||
{
|
||||
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 = CRYPT_WriteSerializedToReg(key, hash, buf, size);
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
} while (ret && context != NULL);
|
||||
if (context)
|
||||
contextInterface->free(context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
|
||||
{
|
||||
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
|
||||
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
|
||||
pCRLInterface, pCTLInterface };
|
||||
struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete,
|
||||
NULL };
|
||||
BOOL ret = TRUE;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
|
||||
{
|
||||
HKEY key;
|
||||
LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0,
|
||||
KEY_ALL_ACCESS, NULL, &key, NULL);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
if (listToDelete[i])
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete, next;
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(toDelete, next, listToDelete[i],
|
||||
WINE_HASH_TO_DELETE, entry)
|
||||
{
|
||||
LONG rc;
|
||||
|
||||
CRYPT_HashToStr(toDelete->hash, asciiHash);
|
||||
TRACE("Removing %s\n", debugstr_w(asciiHash));
|
||||
rc = RegDeleteKeyW(key, asciiHash);
|
||||
if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
list_remove(&toDelete->entry);
|
||||
CryptMemFree(toDelete);
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
}
|
||||
ret = CRYPT_SerializeContextsToReg(key, interfaces[i],
|
||||
store->memStore);
|
||||
RegCloseKey(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If force is true or the registry store is dirty, writes the contents of the
|
||||
* store to the registry.
|
||||
*/
|
||||
static BOOL CRYPT_RegFlushStore(PWINE_REGSTOREINFO store, BOOL force)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d)\n", store, force);
|
||||
|
||||
if (store->dirty || force)
|
||||
ret = CRYPT_RegWriteToReg(store);
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (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);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
|
||||
const void *context, DWORD dwFlags)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (dwFlags & CERT_STORE_PROV_WRITE_ADD_FLAG)
|
||||
{
|
||||
store->dirty = TRUE;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegDeleteContext(PWINE_REGSTOREINFO store,
|
||||
struct list *deleteList, const void *context,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (store->dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete =
|
||||
CryptMemAlloc(sizeof(WINE_HASH_TO_DELETE));
|
||||
|
||||
if (toDelete)
|
||||
{
|
||||
DWORD size = sizeof(toDelete->hash);
|
||||
|
||||
ret = contextInterface->getProp(context, CERT_HASH_PROP_ID,
|
||||
toDelete->hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
EnterCriticalSection(&store->cs);
|
||||
list_add_tail(deleteList, &toDelete->entry);
|
||||
LeaveCriticalSection(&store->cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptMemFree(toDelete);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
store->dirty = TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
|
||||
|
||||
return CRYPT_RegWriteContext(store, cert, dwFlags);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags);
|
||||
|
||||
return CRYPT_RegDeleteContext(store, &store->certsToDelete, pCertContext,
|
||||
pCertInterface);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
|
||||
|
||||
return CRYPT_RegWriteContext(store, crl, dwFlags);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags);
|
||||
|
||||
return CRYPT_RegDeleteContext(store, &store->crlsToDelete, pCrlContext,
|
||||
pCRLInterface);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
switch (dwCtrlType)
|
||||
{
|
||||
case CERT_STORE_CTRL_RESYNC:
|
||||
{
|
||||
HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
CRYPT_RegFlushStore(store, FALSE);
|
||||
CRYPT_RegReadFromReg(store->key, memStore);
|
||||
I_CertUpdateStore(store->memStore, memStore, 0, 0);
|
||||
CertCloseStore(memStore, 0);
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
case CERT_STORE_CTRL_COMMIT:
|
||||
ret = CRYPT_RegFlushStore(store,
|
||||
dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG);
|
||||
break;
|
||||
default:
|
||||
FIXME("%d: stub\n", dwCtrlType);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *regProvFuncs[] = {
|
||||
CRYPT_RegCloseStore,
|
||||
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
|
||||
CRYPT_RegWriteCert,
|
||||
CRYPT_RegDeleteCert,
|
||||
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
|
||||
CRYPT_RegWriteCRL,
|
||||
CRYPT_RegDeleteCRL,
|
||||
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_RegControl,
|
||||
};
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
DWORD rc = RegDeleteTreeW((HKEY)pvPara, CertsW);
|
||||
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = RegDeleteTreeW((HKEY)pvPara, CRLsW);
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = RegDeleteTreeW((HKEY)pvPara, CTLsW);
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = ERROR_SUCCESS;
|
||||
SetLastError(rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
HKEY key;
|
||||
|
||||
if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
|
||||
GetCurrentProcess(), (LPHANDLE)&key,
|
||||
dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : KEY_ALL_ACCESS,
|
||||
TRUE, 0))
|
||||
{
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, hCryptProv,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
PWINE_REGSTOREINFO regInfo = CryptMemAlloc(
|
||||
sizeof(WINE_REGSTOREINFO));
|
||||
|
||||
if (regInfo)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
regInfo->dwOpenFlags = dwFlags;
|
||||
regInfo->memStore = memStore;
|
||||
regInfo->key = key;
|
||||
InitializeCriticalSection(®Info->cs);
|
||||
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
|
||||
list_init(®Info->certsToDelete);
|
||||
list_init(®Info->crlsToDelete);
|
||||
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
|
||||
regInfo->dirty = FALSE;
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
provInfo.cStoreProvFunc = sizeof(regProvFuncs) /
|
||||
sizeof(regProvFuncs[0]);
|
||||
provInfo.rgpvStoreProvFunc = regProvFuncs;
|
||||
provInfo.hStoreProv = regInfo;
|
||||
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
/* Reg store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv &&
|
||||
!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", store);
|
||||
return store;
|
||||
}
|
514
reactos/dll/win32/crypt32/rootstore.c
Normal file
514
reactos/dll/win32/crypt32/rootstore.c
Normal file
|
@ -0,0 +1,514 @@
|
|||
/*
|
||||
* Copyright 2007 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 "config.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#define INITIAL_CERT_BUFFER 1024
|
||||
|
||||
struct DynamicBuffer
|
||||
{
|
||||
DWORD allocated;
|
||||
DWORD used;
|
||||
BYTE *data;
|
||||
};
|
||||
|
||||
static inline void reset_buffer(struct DynamicBuffer *buffer)
|
||||
{
|
||||
buffer->used = 0;
|
||||
if (buffer->data) buffer->data[0] = 0;
|
||||
}
|
||||
|
||||
static BOOL add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (buffer->used + strlen(line) + 1 > buffer->allocated)
|
||||
{
|
||||
if (!buffer->allocated)
|
||||
{
|
||||
buffer->data = CryptMemAlloc(INITIAL_CERT_BUFFER);
|
||||
if (buffer->data)
|
||||
{
|
||||
buffer->data[0] = 0;
|
||||
buffer->allocated = INITIAL_CERT_BUFFER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD new_size = max(buffer->allocated * 2,
|
||||
buffer->used + strlen(line) + 1);
|
||||
|
||||
buffer->data = CryptMemRealloc(buffer->data, new_size);
|
||||
if (buffer->data)
|
||||
buffer->allocated = new_size;
|
||||
}
|
||||
}
|
||||
if (buffer->data)
|
||||
{
|
||||
strcpy((char *)buffer->data + strlen((char *)buffer->data), line);
|
||||
/* Not strlen + 1, otherwise we'd count the NULL for every line's
|
||||
* addition (but we overwrite the previous NULL character.) Not an
|
||||
* overrun, we allocate strlen + 1 bytes above.
|
||||
*/
|
||||
buffer->used += strlen(line);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reads any base64-encoded certificates present in fp and adds them to store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_base64_certs_from_fp(FILE *fp, HCERTSTORE store)
|
||||
{
|
||||
char line[1024];
|
||||
BOOL in_cert = FALSE;
|
||||
struct DynamicBuffer saved_cert = { 0, 0, NULL };
|
||||
int num_certs = 0;
|
||||
|
||||
TRACE("\n");
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
static const char header[] = "-----BEGIN CERTIFICATE-----";
|
||||
static const char trailer[] = "-----END CERTIFICATE-----";
|
||||
|
||||
if (!strncmp(line, header, strlen(header)))
|
||||
{
|
||||
TRACE("begin new certificate\n");
|
||||
in_cert = TRUE;
|
||||
reset_buffer(&saved_cert);
|
||||
}
|
||||
else if (!strncmp(line, trailer, strlen(trailer)))
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
TRACE("end of certificate, adding cert\n");
|
||||
in_cert = FALSE;
|
||||
if (CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used,
|
||||
CRYPT_STRING_BASE64, NULL, &size, NULL, NULL))
|
||||
{
|
||||
LPBYTE buf = CryptMemAlloc(size);
|
||||
|
||||
if (buf)
|
||||
{
|
||||
CryptStringToBinaryA((char *)saved_cert.data,
|
||||
saved_cert.used, CRYPT_STRING_BASE64, buf, &size, NULL,
|
||||
NULL);
|
||||
if (CertAddEncodedCertificateToStore(store,
|
||||
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_NEW, NULL))
|
||||
num_certs++;
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (in_cert)
|
||||
add_line_to_buffer(&saved_cert, line);
|
||||
}
|
||||
CryptMemFree(saved_cert.data);
|
||||
TRACE("Read %d certs\n", num_certs);
|
||||
return num_certs > 0;
|
||||
}
|
||||
|
||||
static const char *trust_status_to_str(DWORD status)
|
||||
{
|
||||
static char buf[1024];
|
||||
int pos = 0;
|
||||
|
||||
if (status & CERT_TRUST_IS_NOT_TIME_VALID)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\texpired");
|
||||
if (status & CERT_TRUST_IS_NOT_TIME_NESTED)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad time nesting");
|
||||
if (status & CERT_TRUST_IS_REVOKED)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\trevoked");
|
||||
if (status & CERT_TRUST_IS_NOT_SIGNATURE_VALID)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad signature");
|
||||
if (status & CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad usage");
|
||||
if (status & CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tuntrusted root");
|
||||
if (status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunknown revocation status");
|
||||
if (status & CERT_TRUST_IS_CYCLIC)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tcyclic chain");
|
||||
if (status & CERT_TRUST_INVALID_EXTENSION)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunsupported critical extension");
|
||||
if (status & CERT_TRUST_INVALID_POLICY_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad policy");
|
||||
if (status & CERT_TRUST_INVALID_BASIC_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tbad basic constraints");
|
||||
if (status & CERT_TRUST_INVALID_NAME_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tbad name constraints");
|
||||
if (status & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunsuported name constraint");
|
||||
if (status & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tundefined name constraint");
|
||||
if (status & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tdisallowed name constraint");
|
||||
if (status & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\texcluded name constraint");
|
||||
if (status & CERT_TRUST_IS_OFFLINE_REVOCATION)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\trevocation server offline");
|
||||
if (status & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tno issuance policy");
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *get_cert_common_name(PCCERT_CONTEXT cert)
|
||||
{
|
||||
static char buf[1024];
|
||||
const char *name = NULL;
|
||||
CERT_NAME_INFO *nameInfo;
|
||||
DWORD size;
|
||||
BOOL ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME,
|
||||
cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData,
|
||||
CRYPT_DECODE_NOCOPY_FLAG | CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
|
||||
&size);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
PCERT_RDN_ATTR commonName = CertFindRDNAttr(szOID_COMMON_NAME,
|
||||
nameInfo);
|
||||
|
||||
if (commonName)
|
||||
{
|
||||
CertRDNValueToStrA(commonName->dwValueType,
|
||||
&commonName->Value, buf, sizeof(buf));
|
||||
name = buf;
|
||||
}
|
||||
LocalFree(nameInfo);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
|
||||
{
|
||||
DWORD root_count = 0;
|
||||
CERT_CHAIN_ENGINE_CONFIG chainEngineConfig =
|
||||
{ sizeof(chainEngineConfig), 0 };
|
||||
HCERTCHAINENGINE engine;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
CertDuplicateStore(to);
|
||||
engine = CRYPT_CreateChainEngine(to, &chainEngineConfig);
|
||||
if (engine)
|
||||
{
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(from, cert);
|
||||
if (cert)
|
||||
{
|
||||
CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
|
||||
PCCERT_CHAIN_CONTEXT chain;
|
||||
BOOL ret = CertGetCertificateChain(engine, cert, NULL, from,
|
||||
&chainPara, 0, NULL, &chain);
|
||||
|
||||
if (!ret)
|
||||
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
|
||||
"chain creation failed");
|
||||
else
|
||||
{
|
||||
/* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */
|
||||
if (chain->TrustStatus.dwErrorStatus &
|
||||
~CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
|
||||
trust_status_to_str(chain->TrustStatus.dwErrorStatus &
|
||||
~CERT_TRUST_IS_UNTRUSTED_ROOT));
|
||||
else
|
||||
{
|
||||
DWORD i, j;
|
||||
|
||||
for (i = 0; i < chain->cChain; i++)
|
||||
for (j = 0; j < chain->rgpChain[i]->cElement; j++)
|
||||
if (CertAddCertificateContextToStore(to,
|
||||
chain->rgpChain[i]->rgpElement[j]->pCertContext,
|
||||
CERT_STORE_ADD_NEW, NULL))
|
||||
root_count++;
|
||||
}
|
||||
CertFreeCertificateChain(chain);
|
||||
}
|
||||
}
|
||||
} while (cert);
|
||||
CertFreeCertificateChainEngine(engine);
|
||||
}
|
||||
TRACE("Added %d root certificates\n", root_count);
|
||||
}
|
||||
|
||||
/* Reads the file fd, and imports any certificates in it into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_file(int fd, HCERTSTORE store)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
FILE *fp;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp)
|
||||
{
|
||||
ret = import_base64_certs_from_fp(fp, store);
|
||||
fclose(fp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
|
||||
BOOL allow_dir);
|
||||
|
||||
/* Opens path, which must be a directory, and imports certificates from every
|
||||
* file in the directory into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
DIR *dir;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), store);
|
||||
/* UNIX functions = bad for reactos
|
||||
dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
size_t bufsize = strlen(path) + 1 + PATH_MAX + 1;
|
||||
char *filebuf = CryptMemAlloc(bufsize);
|
||||
|
||||
if (filebuf)
|
||||
{
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)))
|
||||
{
|
||||
if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
|
||||
{
|
||||
snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name);
|
||||
if (import_certs_from_path(filebuf, store, FALSE) && !ret)
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
CryptMemFree(filebuf);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Opens path, which may be a file or a directory, and imports any certificates
|
||||
* it finds into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
|
||||
BOOL allow_dir)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
int fd;
|
||||
|
||||
TRACE("(%s, %p, %d)\n", debugstr_a(path), store, allow_dir);
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) == 0)
|
||||
{
|
||||
if (S_ISREG(st.st_mode))
|
||||
ret = import_certs_from_file(fd, store);
|
||||
else if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
if (allow_dir)
|
||||
ret = import_certs_from_dir(path, store);
|
||||
else
|
||||
WARN("%s is a directory and directories are disallowed\n",
|
||||
debugstr_a(path));
|
||||
}
|
||||
else
|
||||
ERR("%s: invalid file type\n", path);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have certs added */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have certs deleted */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can have CRLs added. At worst, a malicious application
|
||||
* can DoS itself, as the changes aren't persisted in any way.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have CRLs deleted */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void *rootProvFuncs[] = {
|
||||
NULL, /* CERT_STORE_PROV_CLOSE_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
|
||||
CRYPT_RootWriteCert,
|
||||
CRYPT_RootDeleteCert,
|
||||
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
|
||||
CRYPT_RootWriteCRL,
|
||||
CRYPT_RootDeleteCRL,
|
||||
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 */
|
||||
NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
|
||||
};
|
||||
|
||||
static const char * const CRYPT_knownLocations[] = {
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
"/etc/ssl/certs",
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
};
|
||||
|
||||
/* Reads certificates from the list of known locations. Stops when any
|
||||
* location contains any certificates, to prevent spending unnecessary time
|
||||
* adding redundant certificates, e.g. when both a certificate bundle and
|
||||
* individual certificates exist in the same directory.
|
||||
*/
|
||||
static PWINECRYPT_CERTSTORE CRYPT_RootOpenStoreFromKnownLocations(void)
|
||||
{
|
||||
HCERTSTORE root = NULL;
|
||||
HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||||
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
HCERTSTORE to = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||||
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
if (from && to)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = {
|
||||
sizeof(CERT_STORE_PROV_INFO),
|
||||
sizeof(rootProvFuncs) / sizeof(rootProvFuncs[0]),
|
||||
rootProvFuncs,
|
||||
NULL,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
DWORD i;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
for (i = 0; !ret &&
|
||||
i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
|
||||
i++)
|
||||
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
|
||||
check_and_store_certs(from, to);
|
||||
root = CRYPT_ProvCreateStore(0, to, &provInfo);
|
||||
}
|
||||
CertCloseStore(from, 0);
|
||||
TRACE("returning %p\n", root);
|
||||
return root;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_rootStore;
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
|
||||
{
|
||||
TRACE("(%ld, %08x)\n", hCryptProv, dwFlags);
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
WARN("root store can't be deleted\n");
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return NULL;
|
||||
}
|
||||
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
||||
{
|
||||
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
||||
case CERT_SYSTEM_STORE_CURRENT_USER:
|
||||
break;
|
||||
default:
|
||||
TRACE("location %08x unsupported\n",
|
||||
dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK);
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
if (!CRYPT_rootStore)
|
||||
{
|
||||
HCERTSTORE root = CRYPT_RootOpenStoreFromKnownLocations();
|
||||
|
||||
InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root,
|
||||
NULL);
|
||||
if (CRYPT_rootStore != root)
|
||||
CertCloseStore(root, 0);
|
||||
}
|
||||
CertDuplicateStore(CRYPT_rootStore);
|
||||
return CRYPT_rootStore;
|
||||
}
|
||||
|
||||
void root_store_free(void)
|
||||
{
|
||||
CertCloseStore(CRYPT_rootStore, 0);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2006 Juan Lang
|
||||
* Copyright 2004-2007 Juan Lang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -15,12 +15,15 @@
|
|||
* 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 <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "wine/debug.h"
|
||||
#include "excpt.h"
|
||||
#include "wine/exception.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
|
@ -422,7 +425,7 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
|
|||
|
||||
static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };
|
||||
|
||||
BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
||||
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
|
||||
{
|
||||
BYTE fileHeaderBuf[sizeof(fileHeader)];
|
||||
DWORD read;
|
||||
|
@ -432,7 +435,11 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
|||
ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL);
|
||||
if (ret)
|
||||
{
|
||||
if (!memcmp(fileHeaderBuf, fileHeader, read))
|
||||
if (!read)
|
||||
; /* an empty file is okay */
|
||||
else if (read != sizeof(fileHeaderBuf))
|
||||
ret = FALSE;
|
||||
else if (!memcmp(fileHeaderBuf, fileHeader, read))
|
||||
{
|
||||
WINE_CERT_PROP_HEADER propHdr;
|
||||
const void *context = NULL;
|
||||
|
@ -504,6 +511,8 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
|||
CryptMemFree(buf);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
|
@ -534,8 +543,11 @@ static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
|
|||
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
||||
typedef BOOL (*SerializedOutputFunc)(void *handle, const void *buffer,
|
||||
DWORD size);
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
||||
void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
||||
{
|
||||
const void *context = NULL;
|
||||
BOOL ret;
|
||||
|
@ -554,7 +566,7 @@ static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
|||
{
|
||||
ret = contextInterface->serialize(context, 0, buf, &size);
|
||||
if (ret)
|
||||
ret = WriteFile(file, buf, size, &size, NULL);
|
||||
ret = output(handle, buf, size);
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
|
@ -566,35 +578,307 @@ static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store)
|
||||
static BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
|
||||
SerializedOutputFunc output, void *handle)
|
||||
{
|
||||
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);
|
||||
ret = output(handle, fileHeader, sizeof(fileHeader));
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCertInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCRLInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCTLInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL);
|
||||
ret = output(handle, fileTrailer, sizeof(fileTrailer));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_FileOutputFunc(void *handle, const void *buffer, DWORD size)
|
||||
{
|
||||
return WriteFile(handle, buffer, size, &size, NULL);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
|
||||
{
|
||||
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||
return CRYPT_WriteSerializedStoreToStream(store, CRYPT_FileOutputFunc,
|
||||
file);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||
CRYPT_SIGNED_INFO signedInfo = { 0 };
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
PCCRL_CONTEXT crl = NULL;
|
||||
DWORD size;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData);
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(store, cert);
|
||||
if (cert)
|
||||
signedInfo.cCertEncoded++;
|
||||
} while (cert);
|
||||
if (signedInfo.cCertEncoded)
|
||||
{
|
||||
signedInfo.rgCertEncoded = CryptMemAlloc(
|
||||
signedInfo.cCertEncoded * sizeof(CERT_BLOB));
|
||||
if (!signedInfo.rgCertEncoded)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD i = 0;
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(store, cert);
|
||||
if (cert)
|
||||
{
|
||||
signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded;
|
||||
signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded;
|
||||
i++;
|
||||
}
|
||||
} while (cert);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
crl = CertEnumCRLsInStore(store, crl);
|
||||
if (crl)
|
||||
signedInfo.cCrlEncoded++;
|
||||
} while (crl);
|
||||
if (signedInfo.cCrlEncoded)
|
||||
{
|
||||
signedInfo.rgCrlEncoded = CryptMemAlloc(
|
||||
signedInfo.cCrlEncoded * sizeof(CERT_BLOB));
|
||||
if (!signedInfo.rgCrlEncoded)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD i = 0;
|
||||
|
||||
do {
|
||||
crl = CertEnumCRLsInStore(store, crl);
|
||||
if (crl)
|
||||
{
|
||||
signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded;
|
||||
signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded;
|
||||
i++;
|
||||
}
|
||||
} while (crl);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
|
||||
if (ret)
|
||||
{
|
||||
if (!blob->pbData)
|
||||
blob->cbData = size;
|
||||
else if (blob->cbData < size)
|
||||
{
|
||||
blob->cbData = size;
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
blob->cbData = size;
|
||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
|
||||
&blob->cbData);
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(signedInfo.rgCertEncoded);
|
||||
CryptMemFree(signedInfo.rgCrlEncoded);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SavePKCSToFile(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB blob = { 0, NULL };
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", handle);
|
||||
|
||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||
if (ret)
|
||||
{
|
||||
blob.pbData = CryptMemAlloc(blob.cbData);
|
||||
if (blob.pbData)
|
||||
{
|
||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||
if (ret)
|
||||
ret = WriteFile(handle, blob.pbData, blob.cbData,
|
||||
&blob.cbData, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SaveSerializedToFile(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
return CRYPT_WriteSerializedStoreToFile(handle, store);
|
||||
}
|
||||
|
||||
struct MemWrittenTracker
|
||||
{
|
||||
DWORD cbData;
|
||||
BYTE *pbData;
|
||||
DWORD written;
|
||||
};
|
||||
|
||||
/* handle is a pointer to a MemWrittenTracker. Assumes its pointer is valid. */
|
||||
static BOOL CRYPT_MemOutputFunc(void *handle, const void *buffer, DWORD size)
|
||||
{
|
||||
struct MemWrittenTracker *tracker = (struct MemWrittenTracker *)handle;
|
||||
BOOL ret;
|
||||
|
||||
if (tracker->written + size > tracker->cbData)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
/* Update written so caller can notify its caller of the required size
|
||||
*/
|
||||
tracker->written += size;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(tracker->pbData + tracker->written, buffer, size);
|
||||
tracker->written += size;
|
||||
ret = TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CountSerializedBytes(void *handle, const void *buffer,
|
||||
DWORD size)
|
||||
{
|
||||
*(DWORD *)handle += size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SaveSerializedToMem(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||
DWORD size;
|
||||
BOOL ret;
|
||||
|
||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_CountSerializedBytes,
|
||||
&size);
|
||||
if (ret)
|
||||
{
|
||||
if (!blob->pbData)
|
||||
blob->cbData = size;
|
||||
else if (blob->cbData < size)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
blob->cbData = size;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct MemWrittenTracker tracker = { blob->cbData, blob->pbData,
|
||||
0 };
|
||||
|
||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_MemOutputFunc,
|
||||
&tracker);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA)
|
||||
blob->cbData = tracker.written;
|
||||
}
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
|
||||
DWORD dwSaveAs, DWORD dwSaveTo, void *pvSaveToPara, DWORD dwFlags)
|
||||
{
|
||||
BOOL (*saveFunc)(HCERTSTORE, DWORD, void *);
|
||||
void *handle;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore,
|
||||
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
|
||||
|
||||
switch (dwSaveAs)
|
||||
{
|
||||
case CERT_STORE_SAVE_AS_STORE:
|
||||
case CERT_STORE_SAVE_AS_PKCS7:
|
||||
break;
|
||||
default:
|
||||
WARN("unimplemented for %d\n", dwSaveAs);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
switch (dwSaveTo)
|
||||
{
|
||||
case CERT_STORE_SAVE_TO_FILE:
|
||||
handle = pvSaveToPara;
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_FILENAME_A:
|
||||
handle = CreateFileA((LPCSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, 0, NULL);
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_FILENAME_W:
|
||||
handle = CreateFileW((LPCWSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, 0, NULL);
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_MEMORY:
|
||||
handle = pvSaveToPara;
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToMem : CRYPT_SavePKCSToMem;
|
||||
break;
|
||||
default:
|
||||
WARN("unimplemented for %d\n", dwSaveTo);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
ret = saveFunc(hCertStore, dwMsgAndCertEncodingType, handle);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "winuser.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
|
@ -324,7 +325,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
|
|||
dos = (IMAGE_DOS_HEADER *)pMapped;
|
||||
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
memcpy(pgSubject, &unknown, sizeof(GUID));
|
||||
*pgSubject = unknown;
|
||||
SetLastError(S_OK);
|
||||
bRet = TRUE;
|
||||
goto cleanup1;
|
||||
|
@ -354,6 +355,165 @@ cleanup3:
|
|||
return bRet;
|
||||
}
|
||||
|
||||
static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function,
|
||||
HKEY *key)
|
||||
{
|
||||
WCHAR szFullKey[ 0x100 ];
|
||||
|
||||
lstrcpyW(szFullKey, szOID);
|
||||
lstrcatW(szFullKey, function);
|
||||
CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]);
|
||||
return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key);
|
||||
}
|
||||
|
||||
/* Loads the function named function for the SIP specified by pgSubject, and
|
||||
* returns it if found. Returns NULL on error. If the function is loaded,
|
||||
* *pLib is set to the library in which it is found.
|
||||
*/
|
||||
static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
|
||||
HMODULE *pLib)
|
||||
{
|
||||
LONG r;
|
||||
HKEY key = NULL;
|
||||
DWORD size;
|
||||
WCHAR dllName[MAX_PATH];
|
||||
char functionName[MAX_PATH];
|
||||
HMODULE lib;
|
||||
void *func = NULL;
|
||||
|
||||
TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));
|
||||
|
||||
r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
|
||||
if (r) goto error;
|
||||
|
||||
/* Read the DLL entry */
|
||||
size = sizeof(dllName);
|
||||
r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
|
||||
if (r) goto error;
|
||||
|
||||
/* Read the Function entry */
|
||||
size = sizeof(functionName);
|
||||
r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
|
||||
&size);
|
||||
if (r) goto error;
|
||||
|
||||
lib = LoadLibraryW(dllName);
|
||||
if (!lib)
|
||||
goto error;
|
||||
func = GetProcAddress(lib, functionName);
|
||||
if (func)
|
||||
*pLib = lib;
|
||||
else
|
||||
FreeLibrary(lib);
|
||||
|
||||
error:
|
||||
RegCloseKey(key);
|
||||
TRACE("returning %p\n", func);
|
||||
return func;
|
||||
}
|
||||
|
||||
typedef struct _WINE_SIP_PROVIDER {
|
||||
GUID subject;
|
||||
SIP_DISPATCH_INFO info;
|
||||
struct list entry;
|
||||
} WINE_SIP_PROVIDER;
|
||||
|
||||
static struct list providers = { &providers, &providers };
|
||||
static CRITICAL_SECTION providers_cs;
|
||||
static CRITICAL_SECTION_DEBUG providers_cs_debug =
|
||||
{
|
||||
0, 0, &providers_cs,
|
||||
{ &providers_cs_debug.ProcessLocksList,
|
||||
&providers_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": providers_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION providers_cs = { &providers_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static void CRYPT_CacheSIP(const GUID *pgSubject, SIP_DISPATCH_INFO *info)
|
||||
{
|
||||
WINE_SIP_PROVIDER *prov = CryptMemAlloc(sizeof(WINE_SIP_PROVIDER));
|
||||
|
||||
if (prov)
|
||||
{
|
||||
prov->subject = *pgSubject;
|
||||
prov->info = *info;
|
||||
EnterCriticalSection(&providers_cs);
|
||||
list_add_tail(&providers, &prov->entry);
|
||||
LeaveCriticalSection(&providers_cs);
|
||||
}
|
||||
}
|
||||
|
||||
static WINE_SIP_PROVIDER *CRYPT_GetCachedSIP(const GUID *pgSubject)
|
||||
{
|
||||
WINE_SIP_PROVIDER *provider = NULL, *ret = NULL;
|
||||
|
||||
EnterCriticalSection(&providers_cs);
|
||||
LIST_FOR_EACH_ENTRY(provider, &providers, WINE_SIP_PROVIDER, entry)
|
||||
{
|
||||
if (IsEqualGUID(pgSubject, &provider->subject))
|
||||
break;
|
||||
}
|
||||
if (provider && IsEqualGUID(pgSubject, &provider->subject))
|
||||
ret = provider;
|
||||
LeaveCriticalSection(&providers_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline BOOL CRYPT_IsSIPCached(const GUID *pgSubject)
|
||||
{
|
||||
return CRYPT_GetCachedSIP(pgSubject) != NULL;
|
||||
}
|
||||
|
||||
void crypt_sip_free(void)
|
||||
{
|
||||
WINE_SIP_PROVIDER *prov, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(prov, next, &providers, WINE_SIP_PROVIDER, entry)
|
||||
{
|
||||
list_remove(&prov->entry);
|
||||
FreeLibrary(prov->info.hSIP);
|
||||
CryptMemFree(prov);
|
||||
}
|
||||
}
|
||||
|
||||
/* Loads the SIP for pgSubject into the global cache. Returns FALSE if the
|
||||
* SIP isn't registered or is invalid.
|
||||
*/
|
||||
static BOOL CRYPT_LoadSIP(const GUID *pgSubject)
|
||||
{
|
||||
SIP_DISPATCH_INFO sip = { 0 };
|
||||
HMODULE lib = NULL, temp = NULL;
|
||||
|
||||
sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib);
|
||||
if (!sip.pfGet)
|
||||
goto error;
|
||||
sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp);
|
||||
if (!sip.pfPut || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp);
|
||||
if (!sip.pfCreate || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp);
|
||||
if (!sip.pfVerify || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp);
|
||||
if (!sip.pfRemove || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.hSIP = lib;
|
||||
CRYPT_CacheSIP(pgSubject, &sip);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
FreeLibrary(lib);
|
||||
FreeLibrary(temp);
|
||||
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CryptSIPLoad (CRYPT32.@)
|
||||
*
|
||||
|
@ -382,15 +542,24 @@ cleanup3:
|
|||
BOOL WINAPI CryptSIPLoad
|
||||
(const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
|
||||
{
|
||||
FIXME("(%s %d %p) stub!\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
|
||||
TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
|
||||
|
||||
if (!pgSubject || dwFlags != 0 || !pSipDispatch)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CRYPT_IsSIPCached(pgSubject) && !CRYPT_LoadSIP(pgSubject))
|
||||
return FALSE;
|
||||
|
||||
pSipDispatch->hSIP = NULL;
|
||||
pSipDispatch->pfGet = CryptSIPGetSignedDataMsg;
|
||||
pSipDispatch->pfPut = CryptSIPPutSignedDataMsg;
|
||||
pSipDispatch->pfCreate = CryptSIPCreateIndirectData;
|
||||
pSipDispatch->pfVerify = CryptSIPVerifyIndirectData;
|
||||
pSipDispatch->pfRemove = CryptSIPRemoveSignedDataMsg;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -399,9 +568,15 @@ BOOL WINAPI CryptSIPLoad
|
|||
BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
|
||||
SIP_INDIRECT_DATA* pIndirectData)
|
||||
{
|
||||
FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %p %p)\n", pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfCreate(pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -410,10 +585,17 @@ BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcb
|
|||
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,
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
|
||||
pcbSignedDataMsg, pbSignedDataMsg);
|
||||
|
||||
return FALSE;
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfGet(pSubjectInfo, pdwEncodingType, dwIndex,
|
||||
pcbSignedDataMsg, pbSignedDataMsg);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -422,10 +604,17 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
|
|||
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,
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
|
||||
cbSignedDataMsg, pbSignedDataMsg);
|
||||
|
||||
return FALSE;
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfPut(pSubjectInfo, pdwEncodingType, pdwIndex,
|
||||
cbSignedDataMsg, pbSignedDataMsg);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -434,9 +623,15 @@ BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEnc
|
|||
BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
|
||||
DWORD dwIndex)
|
||||
{
|
||||
FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %d)\n", pSubjectInfo, dwIndex);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfRemove(pSubjectInfo, dwIndex);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -445,7 +640,13 @@ BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
|
|||
BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
|
||||
SIP_INDIRECT_DATA* pIndirectData)
|
||||
{
|
||||
FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %p)\n", pSubjectInfo, pIndirectData);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfVerify(pSubjectInfo, pIndirectData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,6 +59,17 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CERT_RDN_UTF8_STRING:
|
||||
if (!psz || !csz)
|
||||
ret = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pValue->pbData,
|
||||
pValue->cbData / sizeof(WCHAR) + 1, NULL, 0, NULL, NULL);
|
||||
else
|
||||
{
|
||||
ret = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pValue->pbData,
|
||||
pValue->cbData / sizeof(WCHAR) + 1, psz, csz - 1, NULL, NULL);
|
||||
csz -= ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("string type %d unimplemented\n", dwValueType);
|
||||
}
|
||||
|
@ -110,6 +121,24 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CERT_RDN_UTF8_STRING:
|
||||
if (!psz || !csz)
|
||||
ret = pValue->cbData / sizeof(WCHAR);
|
||||
else
|
||||
{
|
||||
DWORD chars = min(pValue->cbData / sizeof(WCHAR), csz - 1);
|
||||
|
||||
if (chars)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < chars; i++)
|
||||
psz[i] = *((LPWSTR)pValue->pbData + i);
|
||||
ret += chars;
|
||||
csz -= chars;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("string type %d unimplemented\n", dwValueType);
|
||||
}
|
||||
|
@ -426,7 +455,6 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
|
|||
DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
|
||||
LPCSTR *ppszError)
|
||||
{
|
||||
LPWSTR x500, errorStr;
|
||||
BOOL ret;
|
||||
int len;
|
||||
|
||||
|
@ -435,24 +463,44 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
|
|||
ppszError);
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0);
|
||||
x500 = CryptMemAlloc(len * sizeof(WCHAR));
|
||||
if (x500)
|
||||
if (len)
|
||||
{
|
||||
LPWSTR x500, errorStr;
|
||||
|
||||
if ((x500 = CryptMemAlloc(len * sizeof(WCHAR))))
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len);
|
||||
ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved,
|
||||
pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL);
|
||||
ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType,
|
||||
pvReserved, pbEncoded, pcbEncoded,
|
||||
ppszError ? (LPCWSTR *)&errorStr : NULL);
|
||||
if (ppszError)
|
||||
{
|
||||
if (!ret)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
*ppszError = pszX500;
|
||||
for (i = 0; i < errorStr - x500; i++)
|
||||
CharNextA(*ppszError);
|
||||
*ppszError = CharNextA(*ppszError);
|
||||
}
|
||||
else
|
||||
*ppszError = NULL;
|
||||
}
|
||||
CryptMemFree(x500);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
if (ppszError)
|
||||
*ppszError = pszX500;
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -501,10 +549,10 @@ static void CRYPT_KeynameKeeperFromTokenW(struct KeynameKeeper *keeper,
|
|||
TRACE("Keyname is %s\n", debugstr_w(keeper->keyName));
|
||||
}
|
||||
|
||||
static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
||||
static BOOL CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
||||
LPCWSTR *ppszError)
|
||||
{
|
||||
DWORD ret = ERROR_SUCCESS;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
while (*str && isspaceW(*str))
|
||||
str++;
|
||||
|
@ -520,7 +568,8 @@ static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
|||
TRACE("missing equals char at %s\n", debugstr_w(token->start));
|
||||
if (ppszError)
|
||||
*ppszError = token->start;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -529,10 +578,10 @@ static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
|||
}
|
||||
|
||||
/* Assumes separators are characters in the 0-255 range */
|
||||
static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
||||
static BOOL CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
||||
struct X500TokenW *token, LPCWSTR *ppszError)
|
||||
{
|
||||
DWORD ret = ERROR_SUCCESS;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token,
|
||||
ppszError);
|
||||
|
@ -546,7 +595,7 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
{
|
||||
token->end = NULL;
|
||||
str++;
|
||||
while (!token->end && !ret)
|
||||
while (!token->end && ret)
|
||||
{
|
||||
while (*str && *str != '"')
|
||||
str++;
|
||||
|
@ -562,7 +611,8 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
TRACE("unterminated quote at %s\n", debugstr_w(str));
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +622,7 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
|
||||
while (*separators)
|
||||
map[*separators++] = 1;
|
||||
while (*str && (*str >= 0xff || !map[*(const unsigned short *)str]))
|
||||
while (*str && (*str >= 0xff || !map[*str]))
|
||||
str++;
|
||||
token->end = str;
|
||||
}
|
||||
|
@ -582,7 +632,8 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
TRACE("missing value at %s\n", debugstr_w(str));
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -597,11 +648,21 @@ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
|
|||
LPCWSTR *ppszError)
|
||||
{
|
||||
CERT_NAME_VALUE nameValue = { type, { 0, NULL } };
|
||||
BOOL ret = FALSE;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (value->end > value->start)
|
||||
{
|
||||
nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
|
||||
sizeof(WCHAR));
|
||||
if (nameValue.Value.pbData)
|
||||
if (!nameValue.Value.pbData)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
if (value->end > value->start)
|
||||
{
|
||||
DWORD i;
|
||||
LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;
|
||||
|
@ -613,6 +674,7 @@ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
|
|||
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);
|
||||
|
@ -690,9 +752,12 @@ static BOOL CRYPT_ValueToRDN(DWORD dwCertEncodingType, PCERT_NAME_INFO info,
|
|||
ret = CRYPT_EncodeValue(dwCertEncodingType, value,
|
||||
&info->rgRDN[info->cRDN].rgRDNAttr[0].Value, types, ppszError);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
else
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
info->cRDN++;
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -703,7 +768,7 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
CERT_NAME_INFO info = { 0, NULL };
|
||||
LPCWSTR str;
|
||||
struct KeynameKeeper keeper;
|
||||
DWORD i, error = ERROR_SUCCESS;
|
||||
DWORD i;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
|
||||
|
@ -712,12 +777,12 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
|
||||
CRYPT_InitializeKeynameKeeper(&keeper);
|
||||
str = pszX500;
|
||||
while (str && *str && !error && ret)
|
||||
while (str && *str && ret)
|
||||
{
|
||||
struct X500TokenW token;
|
||||
|
||||
error = CRYPT_GetNextKeyW(str, &token, ppszError);
|
||||
if (!error && token.start)
|
||||
ret = CRYPT_GetNextKeyW(str, &token, ppszError);
|
||||
if (ret && token.start)
|
||||
{
|
||||
PCCRYPT_OID_INFO keyOID;
|
||||
|
||||
|
@ -728,7 +793,8 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
{
|
||||
if (ppszError)
|
||||
*ppszError = token.start;
|
||||
error = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -739,7 +805,8 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
{
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
error = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -758,9 +825,9 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
sep = crlfSep;
|
||||
else
|
||||
sep = allSeps;
|
||||
error = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
|
||||
ret = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
|
||||
ppszError);
|
||||
if (!error)
|
||||
if (ret)
|
||||
{
|
||||
str = token.end;
|
||||
ret = CRYPT_ValueToRDN(dwCertEncodingType, &info,
|
||||
|
@ -771,10 +838,13 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
}
|
||||
}
|
||||
CRYPT_FreeKeynameKeeper(&keeper);
|
||||
if (!error)
|
||||
if (ret)
|
||||
{
|
||||
if (ppszError)
|
||||
*ppszError = NULL;
|
||||
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info,
|
||||
0, NULL, pbEncoded, pcbEncoded);
|
||||
}
|
||||
for (i = 0; i < info.cRDN; i++)
|
||||
{
|
||||
DWORD j;
|
||||
|
@ -784,12 +854,6 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
CryptMemFree(info.rgRDN[i].rgRDNAttr);
|
||||
}
|
||||
CryptMemFree(info.rgRDN);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(error);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -876,8 +940,6 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
|||
sizeof(simpleAttributeOIDs[0]); i++)
|
||||
nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
if (!nameAttr)
|
||||
{
|
||||
PCERT_EXTENSION ext = CertFindExtension(altNameOID,
|
||||
|
@ -895,12 +957,14 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
|||
* Failing that, look for the first attribute.
|
||||
*/
|
||||
FIXME("CERT_NAME_SIMPLE_DISPLAY_TYPE: stub\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nameAttr)
|
||||
ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
|
||||
pszNameString, cchNameString);
|
||||
else
|
||||
ret = 0;
|
||||
if (info)
|
||||
LocalFree(info);
|
||||
break;
|
||||
|
|
40
reactos/include/psdk/i_cryptasn1tls.h
Normal file
40
reactos/include/psdk/i_cryptasn1tls.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Francois Gouget
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __WINE_I_CRYPTASN1TLS_H
|
||||
#define __WINE_I_CRYPTASN1TLS_H
|
||||
|
||||
typedef void *ASN1decoding_t;
|
||||
typedef void *ASN1encoding_t;
|
||||
typedef void *ASN1module_t;
|
||||
typedef DWORD HCRYPTASN1MODULE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE);
|
||||
ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE);
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t, DWORD, void*);
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_I_CRYPTASN1TLS_H */
|
|
@ -26,15 +26,17 @@ extern "C" {
|
|||
|
||||
/* some typedefs for function parameters */
|
||||
typedef unsigned int ALG_ID;
|
||||
typedef unsigned long HCRYPTPROV;
|
||||
typedef unsigned long HCRYPTPROV_LEGACY;
|
||||
typedef unsigned long HCRYPTKEY;
|
||||
typedef unsigned long HCRYPTHASH;
|
||||
typedef ULONG_PTR HCRYPTPROV;
|
||||
typedef ULONG_PTR HCRYPTPROV_OR_NCRYPT_KEY_HANDLE;
|
||||
typedef ULONG_PTR HCRYPTPROV_LEGACY;
|
||||
typedef ULONG_PTR HCRYPTKEY;
|
||||
typedef ULONG_PTR HCRYPTHASH;
|
||||
typedef void *HCERTSTORE;
|
||||
typedef void *HCRYPTMSG;
|
||||
typedef void *HCERTSTOREPROV;
|
||||
typedef void *HCRYPTOIDFUNCSET;
|
||||
typedef void *HCRYPTOIDFUNCADDR;
|
||||
typedef void *HCRYPTDEFAULTCONTEXT;
|
||||
|
||||
/* CSP Structs */
|
||||
|
||||
|
@ -628,11 +630,87 @@ typedef struct _CMSG_SIGNER_INFO {
|
|||
CRYPT_ATTRIBUTES UnauthAttrs;
|
||||
} CMSG_SIGNER_INFO, *PCMSG_SIGNER_INFO;
|
||||
|
||||
typedef struct _CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA {
|
||||
DWORD cbSize;
|
||||
HCRYPTPROV hCryptProv;
|
||||
DWORD dwSignerIndex;
|
||||
DWORD dwSignerType;
|
||||
void *pvSigner;
|
||||
} CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA, *PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA;
|
||||
|
||||
#define CMSG_VERIFY_SIGNER_PUBKEY 1
|
||||
#define CMSG_VERIFY_SIGNER_CERT 2
|
||||
#define CMSG_VERIFY_SIGNER_CHAIN 3
|
||||
#define CMSG_VERIFY_SIGNER_NULL 4
|
||||
|
||||
#define CMSG_TYPE_PARAM 1
|
||||
#define CMSG_CONTENT_PARAM 2
|
||||
#define CMSG_BARE_CONTENT_PARAM 3
|
||||
#define CMSG_INNER_CONTENT_TYPE_PARAM 4
|
||||
#define CMSG_SIGNER_COUNT_PARAM 5
|
||||
#define CMSG_SIGNER_INFO_PARAM 6
|
||||
#define CMSG_SIGNER_CERT_INFO_PARAM 7
|
||||
#define CMSG_SIGNER_HASH_ALGORITHM_PARAM 8
|
||||
#define CMSG_SIGNER_AUTH_ATTR_PARAM 9
|
||||
#define CMSG_SIGNER_UNAUTH_ATTR_PARAM 10
|
||||
#define CMSG_CERT_COUNT_PARAM 11
|
||||
#define CMSG_CERT_PARAM 12
|
||||
#define CMSG_CRL_COUNT_PARAM 13
|
||||
#define CMSG_CRL_PARAM 14
|
||||
#define CMSG_ENVELOPE_ALGORITHM_PARAM 15
|
||||
#define CMSG_RECIPIENT_COUNT_PARAM 17
|
||||
#define CMSG_RECIPIENT_INDEX_PARAM 18
|
||||
#define CMSG_RECIPIENT_INFO_PARAM 19
|
||||
#define CMSG_HASH_ALGORITHM_PARAM 20
|
||||
#define CMSG_HASH_DATA_PARAM 21
|
||||
#define CMSG_COMPUTED_HASH_PARAM 22
|
||||
#define CMSG_ENCRYPT_PARAM 26
|
||||
#define CMSG_ENCRYPTED_DIGEST 27
|
||||
#define CMSG_ENCODED_SIGNER 28
|
||||
#define CMSG_ENCODED_MESSAGE 29
|
||||
#define CMSG_VERSION_PARAM 30
|
||||
#define CMSG_ATTR_CERT_COUNT_PARAM 31
|
||||
#define CMSG_ATTR_CERT_PARAM 32
|
||||
#define CMSG_CMS_RECIPIENT_COUNT_PARAM 33
|
||||
#define CMSG_CMS_RECIPIENT_INDEX_PARAM 34
|
||||
#define CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM 35
|
||||
#define CMSG_CMS_RECIPIENT_INFO_PARAM 36
|
||||
#define CMSG_UNPROTECTED_ATTR_PARAM 37
|
||||
#define CMSG_SIGNER_CERT_ID_PARAM 38
|
||||
#define CMSG_CMS_SIGNER_INFO_PARAM 39
|
||||
|
||||
#define CMSG_SIGNED_DATA_V1 1
|
||||
#define CMSG_SIGNED_DATA_V3 3
|
||||
#define CMSG_SIGNED_DATA_PKCS_1_5_VERSION CMSG_SIGNED_DATA_V1
|
||||
#define CMSG_SIGNED_DATA_CMS_VERSION CMSG_SIGNED_DATA_V3
|
||||
|
||||
#define CMSG_SIGNER_INFO_V1 1
|
||||
#define CMSG_SIGNER_INFO_V3 3
|
||||
#define CMSG_SIGNER_INFO_PKCS_1_5_VERSION CMSG_SIGNER_INFO_V1
|
||||
#define CMSG_SIGNER_INFO_CMS_VERSION CMSG_SIGNER_INFO_V3
|
||||
|
||||
#define CMSG_HASHED_DATA_V0 0
|
||||
#define CMSG_HASHED_DATA_V2 2
|
||||
#define CMSG_HASHED_DATA_PKCS_1_5_VERSION CMSG_HASHED_DATA_V0
|
||||
#define CMSG_HASHED_DATA_CMS_VERSION CMSG_HASHED_DATA_V2
|
||||
|
||||
#define CMSG_ENVELOPED_DATA_V0 0
|
||||
#define CMSG_ENVELOPED_DATA_V2 2
|
||||
#define CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION CMSG_ENVELOPED_DATA_V0
|
||||
#define CMSG_ENVELOPED_DATA_CMS_VERSION CMSG_ENVELOPED_DATA_V2
|
||||
|
||||
/* CryptMsgGetAndVerifySigner flags */
|
||||
#define CMSG_TRUSTED_SIGNER_FLAG 0x1
|
||||
#define CMSG_SIGNER_ONLY_FLAG 0x2
|
||||
#define CMSG_USE_SIGNER_INDEX_FLAG 0x4
|
||||
|
||||
/* CryptMsgSignCTL flags */
|
||||
#define CMSG_CMS_ENCAPSULATED_CTL_FLAG 0x00008000
|
||||
|
||||
/* CryptMsgEncodeAndSignCTL flags */
|
||||
#define CMSG_ENCODED_SORTED_CTL_FLAG 0x1
|
||||
#define CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG 0x2
|
||||
|
||||
typedef struct _CERT_REVOCATION_CRL_INFO {
|
||||
DWORD cbSize;
|
||||
PCCRL_CONTEXT pBaseCrlContext;
|
||||
|
@ -2198,6 +2276,16 @@ static const WCHAR CERT_PHYSICAL_STORE_AUTH_ROOT_NAME[] =
|
|||
/* CertFindChainInStore dwFindType types */
|
||||
#define CERT_CHAIN_FIND_BY_ISSUER 1
|
||||
|
||||
/* CertSaveStore dwSaveAs values */
|
||||
#define CERT_STORE_SAVE_AS_STORE 1
|
||||
#define CERT_STORE_SAVE_AS_PKCS7 2
|
||||
/* CertSaveStore dwSaveTo values */
|
||||
#define CERT_STORE_SAVE_TO_FILE 1
|
||||
#define CERT_STORE_SAVE_TO_MEMORY 2
|
||||
#define CERT_STORE_SAVE_TO_FILENAME_A 3
|
||||
#define CERT_STORE_SAVE_TO_FILENAME_W 4
|
||||
#define CERT_STORE_SAVE_TO_FILENAME CERT_STORE_SAVE_TO_FILENAME_W
|
||||
|
||||
/* CERT_INFO versions/flags */
|
||||
#define CERT_V1 0
|
||||
#define CERT_V2 1
|
||||
|
@ -3132,6 +3220,10 @@ typedef struct _CERT_ID
|
|||
} DUMMYUNIONNAME;
|
||||
} CERT_ID, *PCERT_ID;
|
||||
|
||||
#define CERT_ID_ISSUER_SERIAL_NUMBER 1
|
||||
#define CERT_ID_KEY_IDENTIFIER 2
|
||||
#define CERT_ID_SHA1_HASH 3
|
||||
|
||||
#undef CMSG_DATA /* may be defined by sys/socket.h */
|
||||
#define CMSG_DATA 1
|
||||
#define CMSG_SIGNED 2
|
||||
|
@ -3498,7 +3590,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD);
|
|||
BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList);
|
||||
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
|
||||
HCRYPTOIDFUNCADDR *phFuncAddr);
|
||||
BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
|
||||
|
@ -3850,7 +3942,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
|
|||
DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey);
|
||||
|
||||
BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec,
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec,
|
||||
BOOL *pfCallerFreeProv);
|
||||
|
||||
BOOL WINAPI CryptProtectData( DATA_BLOB* pDataIn, LPCWSTR szDataDescr,
|
||||
|
@ -3887,9 +3979,65 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
LPCWSTR *ppszError);
|
||||
#define CertStrToName WINELIB_NAME_AW(CertStrToName)
|
||||
|
||||
DWORD WINAPI CryptMsgCalculateEncodedLength(DWORD dwMsgEncodingType,
|
||||
DWORD dwFlags, DWORD dwMsgType, const void *pvMsgEncodeInfo,
|
||||
LPSTR pszInnerContentObjID, DWORD cbData);
|
||||
|
||||
BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg);
|
||||
|
||||
BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
||||
DWORD dwCtrlType, const void *pvCtrlPara);
|
||||
|
||||
BOOL WINAPI CryptMsgCountersign(HCRYPTMSG hCryptMsg, DWORD dwIndex,
|
||||
DWORD dwCountersigners, PCMSG_SIGNER_ENCODE_INFO rgCountersigners);
|
||||
|
||||
BOOL WINAPI CryptMsgCountersignEncoded(DWORD dwEncodingType, PBYTE pbSignerInfo,
|
||||
DWORD cbSignerInfo, DWORD cCountersigners,
|
||||
PCMSG_SIGNER_ENCODE_INFO rgCountersigners, PBYTE pbCountersignature,
|
||||
PDWORD pcbCountersignature);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg);
|
||||
|
||||
BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType,
|
||||
PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore,
|
||||
HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner,
|
||||
DWORD *pdwSignerIndex);
|
||||
|
||||
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
|
||||
DWORD dwIndex, void *pvData, DWORD *pcbData);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags,
|
||||
DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
|
||||
PCMSG_STREAM_INFO pStreamInfo);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
|
||||
DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
|
||||
PCMSG_STREAM_INFO pStreamInfo);
|
||||
|
||||
BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent,
|
||||
DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
|
||||
DWORD cbData, BOOL fFinal);
|
||||
|
||||
BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
|
||||
PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
|
||||
PCERT_INFO pciCountersigner);
|
||||
|
||||
BOOL WINAPI CryptMsgVerifyCountersignatureEncodedEx(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
|
||||
PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
|
||||
DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved);
|
||||
|
||||
BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
|
||||
BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
|
||||
DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob);
|
||||
|
||||
BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara,
|
||||
const BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE *pbSignedBlob,
|
||||
DWORD *pcbSignedBlob);
|
||||
|
@ -3897,6 +4045,7 @@ BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara,
|
|||
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
|
||||
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert);
|
||||
|
||||
BOOL WINAPI CryptVerifyMessageSignatureWithKey(
|
||||
PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||
PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE *pbSignedBlob,
|
||||
|
@ -3907,6 +4056,7 @@ BOOL WINAPI CryptVerifyDetachedMessageSignature(
|
|||
const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
|
||||
const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
|
||||
PCCERT_CONTEXT *ppSignerCert);
|
||||
|
||||
LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
|
||||
const BYTE *pbSignedBlob, DWORD cbSignedBlob);
|
||||
|
||||
|
@ -3914,6 +4064,7 @@ BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
|
|||
DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[],
|
||||
const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob,
|
||||
DWORD *pcbEncryptedBlob);
|
||||
|
||||
BOOL WINAPI CryptDecryptMessage(PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
|
||||
const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted,
|
||||
DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert);
|
||||
|
@ -3923,6 +4074,7 @@ BOOL WINAPI CryptSignAndEncryptMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
|
|||
PCCERT_CONTEXT rgpRecipientCert[], const BYTE *pbToBeSignedAndEncrypted,
|
||||
DWORD cbToBeSignedAndEncrypted, BYTE *pbSignedAndEncryptedBlob,
|
||||
DWORD *pcbSignedAndEncryptedBlob);
|
||||
|
||||
BOOL WINAPI CryptDecryptAndVerifyMessageSignature(
|
||||
PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
|
||||
PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue