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:
Colin Finck 2008-05-10 18:43:43 +00:00
parent 7e4da4bd18
commit b1c2a48e3b
35 changed files with 12733 additions and 3345 deletions

View file

@ -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

View 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);
}

View file

@ -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;

View file

@ -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)

View file

@ -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>

View file

@ -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"

View file

@ -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

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
@ -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 "다른 사람"
}

View 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"
}

View file

@ -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"
}

View 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)

View file

@ -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);

View file

@ -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"

View file

@ -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

View 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;
}

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View 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;
}

View file

@ -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);
}
/***********************************************************************

View file

@ -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;
}

View 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;
}

View 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(&regInfo->cs);
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
list_init(&regInfo->certsToDelete);
list_init(&regInfo->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;
}

View 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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View 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 */

View file

@ -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,