Juan Lang : crypt32: Implement CertGetValidUsages.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Mar 8 06:08:36 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 89b3191c7c5173f09898ba80ba760507a1eda03e
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=89b3191c7c5173f09898ba80ba760507a1eda03e
Author: Juan Lang <juan_lang at yahoo.com>
Date: Tue Mar 7 18:29:18 2006 -0800
crypt32: Implement CertGetValidUsages.
---
dlls/crypt32/cert.c | 141 +++++++++++++++++++++++++++++++++++++++++++++
dlls/crypt32/crypt32.spec | 1
2 files changed, 142 insertions(+), 0 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index 1b38c40..52b8ce1 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -572,3 +572,144 @@ BOOL WINAPI CertRemoveEnhancedKeyUsageId
}
return ret;
}
+
+BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts,
+ int *cNumOIDSs, LPSTR *rghOIDs, DWORD *pcbOIDs)
+{
+ BOOL ret = TRUE;
+ DWORD i, cbOIDs = 0;
+ BOOL allUsagesValid = TRUE;
+ CERT_ENHKEY_USAGE validUsages = { 0, NULL };
+
+ TRACE("(%ld, %p, %p, %p, %ld)\n", cCerts, *rghCerts, cNumOIDSs,
+ rghOIDs, *pcbOIDs);
+
+ for (i = 0; ret && i < cCerts; i++)
+ {
+ CERT_ENHKEY_USAGE usage;
+ DWORD size = sizeof(usage);
+
+ ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, &usage, &size);
+ /* Success is deliberately ignored: it implies all usages are valid */
+ if (!ret && GetLastError() == ERROR_MORE_DATA)
+ {
+ PCERT_ENHKEY_USAGE pUsage = CryptMemAlloc(size);
+
+ allUsagesValid = FALSE;
+ if (pUsage)
+ {
+ ret = CertGetEnhancedKeyUsage(rghCerts[i], 0, pUsage, &size);
+ if (ret)
+ {
+ if (!validUsages.cUsageIdentifier)
+ {
+ DWORD j;
+
+ cbOIDs = pUsage->cUsageIdentifier * sizeof(LPSTR);
+ validUsages.cUsageIdentifier = pUsage->cUsageIdentifier;
+ for (j = 0; j < validUsages.cUsageIdentifier; j++)
+ cbOIDs += lstrlenA(pUsage->rgpszUsageIdentifier[j])
+ + 1;
+ validUsages.rgpszUsageIdentifier =
+ CryptMemAlloc(cbOIDs);
+ if (validUsages.rgpszUsageIdentifier)
+ {
+ LPSTR nextOID = (LPSTR)
+ ((LPBYTE)validUsages.rgpszUsageIdentifier +
+ validUsages.cUsageIdentifier * sizeof(LPSTR));
+
+ for (j = 0; j < validUsages.cUsageIdentifier; j++)
+ {
+ validUsages.rgpszUsageIdentifier[j] = nextOID;
+ lstrcpyA(validUsages.rgpszUsageIdentifier[j],
+ pUsage->rgpszUsageIdentifier[j]);
+ nextOID += lstrlenA(nextOID) + 1;
+ }
+ }
+ else
+ ret = FALSE;
+ }
+ else
+ {
+ DWORD j, k, validIndexes = 0, numRemoved = 0;
+
+ /* Merge: build a bitmap of all the indexes of
+ * validUsages.rgpszUsageIdentifier that are in pUsage.
+ */
+ for (j = 0; j < pUsage->cUsageIdentifier; j++)
+ {
+ for (k = 0; k < validUsages.cUsageIdentifier; k++)
+ {
+ if (!strcmp(pUsage->rgpszUsageIdentifier[j],
+ validUsages.rgpszUsageIdentifier[k]))
+ {
+ validIndexes |= (1 << k);
+ break;
+ }
+ }
+ }
+ /* Merge by removing from validUsages those that are
+ * not in the bitmap.
+ */
+ for (j = 0; j < validUsages.cUsageIdentifier; j++)
+ {
+ if (!(validIndexes & (1 << j)))
+ {
+ if (j < validUsages.cUsageIdentifier - 1)
+ {
+ memcpy(&validUsages.rgpszUsageIdentifier[j],
+ &validUsages.rgpszUsageIdentifier[j +
+ numRemoved + 1],
+ (validUsages.cUsageIdentifier - numRemoved
+ - j - 1) * sizeof(LPSTR));
+ cbOIDs -= lstrlenA(
+ validUsages.rgpszUsageIdentifier[j]) + 1 +
+ sizeof(LPSTR);
+ numRemoved++;
+ }
+ else
+ validUsages.cUsageIdentifier--;
+ }
+ }
+ }
+ }
+ CryptMemFree(pUsage);
+ }
+ else
+ ret = FALSE;
+ }
+ }
+ if (ret)
+ {
+ if (allUsagesValid)
+ {
+ *cNumOIDSs = -1;
+ *pcbOIDs = 0;
+ }
+ else
+ {
+ if (!rghOIDs || *pcbOIDs < cbOIDs)
+ {
+ *pcbOIDs = cbOIDs;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ LPSTR nextOID = (LPSTR)((LPBYTE)rghOIDs +
+ validUsages.cUsageIdentifier * sizeof(LPSTR));
+
+ *pcbOIDs = cbOIDs;
+ *cNumOIDSs = validUsages.cUsageIdentifier;
+ for (i = 0; i < validUsages.cUsageIdentifier; i++)
+ {
+ rghOIDs[i] = nextOID;
+ lstrcpyA(nextOID, validUsages.rgpszUsageIdentifier[i]);
+ nextOID += lstrlenA(nextOID) + 1;
+ }
+ }
+ }
+ }
+ CryptMemFree(validUsages.rgpszUsageIdentifier);
+ return ret;
+}
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index 7d40394..4fc11b3 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -56,6 +56,7 @@
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
@ stub CertGetPublicKeyLength
@ stub CertGetSubjectCertificateFromStore
+@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
@ stub CertIsRDNAttrsInCertificateName
@ stdcall CertNameToStrA(long ptr long ptr long)
@ stdcall CertNameToStrW(long ptr long ptr long)
More information about the wine-cvs
mailing list