Juan Lang : crypt32: Add chain debugging channel for debugging certificate chaining errors.
Alexandre Julliard
julliard at winehq.org
Thu Feb 12 11:14:42 CST 2009
Module: wine
Branch: master
Commit: e7dd46b8075af3003acf5e3194f79ee7fe9119a2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e7dd46b8075af3003acf5e3194f79ee7fe9119a2
Author: Juan Lang <juan.lang at gmail.com>
Date: Wed Feb 11 10:06:27 2009 -0800
crypt32: Add chain debugging channel for debugging certificate chaining errors.
---
dlls/crypt32/chain.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 6d7bb54..f36d360 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -28,6 +28,7 @@
#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+WINE_DECLARE_DEBUG_CHANNEL(chain);
#define DEFAULT_CYCLE_MODULUS 7
@@ -709,6 +710,101 @@ static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain)
}
}
+static void dump_basic_constraints(PCERT_EXTENSION ext)
+{
+ CERT_BASIC_CONSTRAINTS_INFO *info;
+ DWORD size = 0;
+
+ if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS,
+ ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
+ NULL, &info, &size))
+ {
+ TRACE_(chain)("SubjectType: %02x\n", info->SubjectType.pbData[0]);
+ TRACE_(chain)("%s path length constraint\n",
+ info->fPathLenConstraint ? "has" : "doesn't have");
+ TRACE_(chain)("path length=%d\n", info->dwPathLenConstraint);
+ LocalFree(info);
+ }
+}
+
+static void dump_basic_constraints2(PCERT_EXTENSION ext)
+{
+ CERT_BASIC_CONSTRAINTS2_INFO constraints;
+ DWORD size = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
+
+ if (CryptDecodeObjectEx(X509_ASN_ENCODING,
+ szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
+ 0, NULL, &constraints, &size))
+ {
+ TRACE_(chain)("basic constraints:\n");
+ TRACE_(chain)("can%s be a CA\n", constraints.fCA ? "" : "not");
+ TRACE_(chain)("%s path length constraint\n",
+ constraints.fPathLenConstraint ? "has" : "doesn't have");
+ TRACE_(chain)("path length=%d\n", constraints.dwPathLenConstraint);
+ }
+}
+
+static void dump_extension(PCERT_EXTENSION ext)
+{
+ TRACE_(chain)("%s (%scritical)\n", debugstr_a(ext->pszObjId),
+ ext->fCritical ? "" : "not ");
+ if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS))
+ dump_basic_constraints(ext);
+ else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS2))
+ dump_basic_constraints2(ext);
+}
+
+static LPCWSTR filetime_to_str(const FILETIME *time)
+{
+ static WCHAR date[80];
+ WCHAR dateFmt[80]; /* sufficient for all versions of LOCALE_SSHORTDATE */
+ SYSTEMTIME sysTime;
+
+ if (!time) return NULL;
+
+ GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
+ sizeof(dateFmt) / sizeof(dateFmt[0]));
+ FileTimeToSystemTime(time, &sysTime);
+ GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
+ sizeof(date) / sizeof(date[0]));
+ return date;
+}
+
+static void dump_element(PCCERT_CONTEXT cert)
+{
+ LPWSTR name = NULL;
+ DWORD len, i;
+
+ TRACE_(chain)("%p\n", cert);
+ len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
+ name = CryptMemAlloc(len * sizeof(WCHAR));
+ if (name)
+ {
+ CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, NULL, name, len);
+ TRACE_(chain)("issued by %s\n", debugstr_w(name));
+ CryptMemFree(name);
+ }
+ len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
+ NULL, 0);
+ name = CryptMemAlloc(len * sizeof(WCHAR));
+ if (name)
+ {
+ CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
+ name, len);
+ TRACE_(chain)("issued to %s\n", debugstr_w(name));
+ CryptMemFree(name);
+ }
+ TRACE_(chain)("valid from %s",
+ debugstr_w(filetime_to_str(&cert->pCertInfo->NotBefore)));
+ TRACE_(chain)("to %s\n",
+ debugstr_w(filetime_to_str(&cert->pCertInfo->NotAfter)));
+ TRACE_(chain)("%d extensions\n", cert->pCertInfo->cExtension);
+ for (i = 0; i < cert->pCertInfo->cExtension; i++)
+ dump_extension(&cert->pCertInfo->rgExtension[i]);
+}
+
static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
{
@@ -717,8 +813,12 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
BOOL pathLengthConstraintViolated = FALSE;
CERT_BASIC_CONSTRAINTS2_INFO constraints = { TRUE, FALSE, 0 };
+ TRACE_(chain)("checking chain with %d elements for time %s\n",
+ chain->cElement, debugstr_w(filetime_to_str(time)));
for (i = chain->cElement - 1; i >= 0; i--)
{
+ if (TRACE_ON(chain))
+ dump_element(chain->rgpElement[i]->pCertContext);
if (CertVerifyTimeValidity(time,
chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
More information about the wine-cvs
mailing list