From 869db8445762e687050b304e6e1ee596929b99ba Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 3 Jan 2010 11:59:38 +0000 Subject: [PATCH] [crypt32] sync crypt32 to wine 1.1.35 svn path=/trunk/; revision=44909 --- reactos/dll/win32/crypt32/cert.c | 6 +- reactos/dll/win32/crypt32/chain.c | 125 ++++++++++++++++++++++++++++-- reactos/dll/win32/crypt32/crl.c | 21 +++-- reactos/dll/win32/crypt32/ctl.c | 6 ++ reactos/dll/win32/crypt32/store.c | 9 ++- 5 files changed, 149 insertions(+), 18 deletions(-) diff --git a/reactos/dll/win32/crypt32/cert.c b/reactos/dll/win32/crypt32/cert.c index a24757019cb..c25e612574f 100644 --- a/reactos/dll/win32/crypt32/cert.c +++ b/reactos/dll/win32/crypt32/cert.c @@ -2854,7 +2854,7 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, { info.pwszContainerName = CryptMemAlloc(len * sizeof(WCHAR)); - len = MultiByteToWideChar(CP_ACP, 0, szContainer, -1, + MultiByteToWideChar(CP_ACP, 0, szContainer, -1, info.pwszContainerName, len); } } @@ -2878,7 +2878,7 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, { info.pwszProvName = CryptMemAlloc(len * sizeof(WCHAR)); - len = MultiByteToWideChar(CP_ACP, 0, szProvider, -1, + MultiByteToWideChar(CP_ACP, 0, szProvider, -1, info.pwszProvName, len); } } @@ -2898,7 +2898,7 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, pInfo = &info; } - ret = CertSetCertificateContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID, + CertSetCertificateContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID, 0, pInfo); if (pInfo == &info) diff --git a/reactos/dll/win32/crypt32/chain.c b/reactos/dll/win32/crypt32/chain.c index 5cc46b763bc..28a22064440 100644 --- a/reactos/dll/win32/crypt32/chain.c +++ b/reactos/dll/win32/crypt32/chain.c @@ -230,10 +230,118 @@ typedef struct _CertificateChain LONG ref; } CertificateChain, *PCertificateChain; -static inline BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) +static BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) { - return CertCompareCertificateName(cert->dwCertEncodingType, - &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer); + PCERT_EXTENSION ext; + DWORD size; + BOOL ret; + + if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) + { + CERT_AUTHORITY_KEY_ID2_INFO *info; + + ret = CryptDecodeObjectEx(cert->dwCertEncodingType, + X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, + &info, &size); + if (ret) + { + 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) + { + ret = CertCompareCertificateName(cert->dwCertEncodingType, + &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer) + && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, + &cert->pCertInfo->SerialNumber); + } + else + { + FIXME("no supported name type in authority key id2\n"); + ret = FALSE; + } + } + else if (info->KeyId.cbData) + { + ret = CertGetCertificateContextProperty(cert, + CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); + if (ret && size == info->KeyId.cbData) + { + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(cert, + CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); + ret = !memcmp(buf, info->KeyId.pbData, size); + CryptMemFree(buf); + } + } + else + ret = FALSE; + } + LocalFree(info); + } + } + else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) + { + CERT_AUTHORITY_KEY_ID_INFO *info; + + ret = CryptDecodeObjectEx(cert->dwCertEncodingType, + X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, + &info, &size); + if (ret) + { + if (info->CertIssuer.cbData && info->CertSerialNumber.cbData) + { + ret = CertCompareCertificateName(cert->dwCertEncodingType, + &info->CertIssuer, &cert->pCertInfo->Issuer) && + CertCompareIntegerBlob(&info->CertSerialNumber, + &cert->pCertInfo->SerialNumber); + } + else if (info->KeyId.cbData) + { + ret = CertGetCertificateContextProperty(cert, + CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); + if (ret && size == info->KeyId.cbData) + { + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(cert, + CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); + ret = !memcmp(buf, info->KeyId.pbData, size); + CryptMemFree(buf); + } + else + ret = FALSE; + } + else + ret = FALSE; + } + else + ret = FALSE; + LocalFree(info); + } + } + else + ret = CertCompareCertificateName(cert->dwCertEncodingType, + &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer); + return ret; } static void CRYPT_FreeChainElement(PCERT_CHAIN_ELEMENT element) @@ -619,7 +727,7 @@ static BOOL rfc822_name_matches(LPCWSTR constraint, LPCWSTR name, *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS; else if (!name) ; /* no match */ - else if ((at = strchrW(constraint, '@'))) + else if (strchrW(constraint, '@')) match = !lstrcmpiW(constraint, name); else { @@ -2541,10 +2649,11 @@ static void CRYPT_CheckUsages(PCERT_CHAIN_CONTEXT chain, * key usage extension be present and that a particular purpose * be indicated in order for the certificate to be acceptable to * that application." - * For now I'm being more conservative and disallowing it. + * Not all web sites include the extended key usage extension, so + * accept chains without it. */ - WARN_(chain)("requested usage from a certificate with no usages\n"); - validForUsage = FALSE; + TRACE_(chain)("requested usage from certificate with no usages\n"); + validForUsage = TRUE; } if (!validForUsage) { @@ -2641,6 +2750,8 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, if (!pChain->TrustStatus.dwErrorStatus) CRYPT_VerifyChainRevocation(pChain, pTime, pChainPara, dwFlags); CRYPT_CheckUsages(pChain, pChainPara); + TRACE_(chain)("error status: %08x\n", + pChain->TrustStatus.dwErrorStatus); if (ppChainContext) *ppChainContext = pChain; else diff --git a/reactos/dll/win32/crypt32/crl.c b/reactos/dll/win32/crypt32/crl.c index a24e6adf887..72180c52473 100644 --- a/reactos/dll/win32/crypt32/crl.c +++ b/reactos/dll/win32/crypt32/crl.c @@ -167,14 +167,21 @@ static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType, } else if (info->KeyId.cbData) { - if ((ext = CertFindExtension( - szOID_SUBJECT_KEY_IDENTIFIER, - issuer->pCertInfo->cExtension, - issuer->pCertInfo->rgExtension))) + DWORD size; + + ret = CertGetCertificateContextProperty(issuer, + CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); + if (ret && size == info->KeyId.cbData) { - if (info->KeyId.cbData == ext->Value.cbData) - ret = !memcmp(info->KeyId.pbData, - ext->Value.pbData, info->KeyId.cbData); + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(issuer, + CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); + ret = !memcmp(buf, info->KeyId.pbData, size); + CryptMemFree(buf); + } else ret = FALSE; } diff --git a/reactos/dll/win32/crypt32/ctl.c b/reactos/dll/win32/crypt32/ctl.c index 44b517aeff3..40895fa1bdb 100644 --- a/reactos/dll/win32/crypt32/ctl.c +++ b/reactos/dll/win32/crypt32/ctl.c @@ -113,7 +113,13 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, break; case CERT_STORE_ADD_USE_EXISTING: if (existing) + { CtlContext_CopyProperties(existing, pCtlContext); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCTLContext(existing); + } + else + toAdd = CertDuplicateCTLContext(pCtlContext); break; default: FIXME("Unimplemented add disposition %d\n", dwAddDisposition); diff --git a/reactos/dll/win32/crypt32/store.c b/reactos/dll/win32/crypt32/store.c index 3a786b05cf4..153d3aa71ea 100644 --- a/reactos/dll/win32/crypt32/store.c +++ b/reactos/dll/win32/crypt32/store.c @@ -899,7 +899,8 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, if (existing) { CertContext_CopyProperties(existing, pCertContext); - *ppStoreContext = CertDuplicateCertificateContext(existing); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCertificateContext(existing); } else toAdd = CertDuplicateCertificateContext(pCertContext); @@ -1090,7 +1091,13 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, break; case CERT_STORE_ADD_USE_EXISTING: if (existing) + { CrlContext_CopyProperties(existing, pCrlContext); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCRLContext(existing); + } + else + toAdd = CertDuplicateCRLContext(pCrlContext); break; default: FIXME("Unimplemented add disposition %d\n", dwAddDisposition);