Module: wine Branch: master Commit: 8b4f53bb269621abb6da253bbec6f88a49c036e2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8b4f53bb269621abb6da253bbe...
Author: Juan Lang juan.lang@gmail.com Date: Fri Nov 14 16:06:13 2008 -0800
crypt32: Implement encoding CERT_POLICIES_INFO.
---
dlls/crypt32/encode.c | 161 +++++++++++++++++++++++++++++++++++++++++++ dlls/crypt32/tests/encode.c | 4 - 2 files changed, 161 insertions(+), 4 deletions(-)
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 3699b5f..9e10298 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -2812,6 +2812,162 @@ static BOOL WINAPI CRYPT_AsnEncodeBasicConstraints2(DWORD dwCertEncodingType, return ret; }
+static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + DWORD cPolicyQualifier = *(DWORD *)pvStructInfo; + const CERT_POLICY_QUALIFIER_INFO *rgPolicyQualifier = + *(const CERT_POLICY_QUALIFIER_INFO **) + ((LPBYTE)pvStructInfo + sizeof(DWORD)); + BOOL ret; + + if (!cPolicyQualifier) + { + *pcbEncoded = 0; + ret = TRUE; + } + else + { + struct AsnEncodeSequenceItem items[2] = { + { NULL, CRYPT_AsnEncodeOid, 0 }, + { NULL, CRYPT_CopyEncodedBlob, 0 }, + }; + DWORD bytesNeeded = 0, lenBytes, size, i; + + ret = TRUE; + for (i = 0; ret && i < cPolicyQualifier; i++) + { + items[0].pvStructInfo = rgPolicyQualifier[i].pszPolicyQualifierId; + items[1].pvStructInfo = &rgPolicyQualifier[i].Qualifier; + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), + dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size); + if (ret) + bytesNeeded += size; + } + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (ret) + { + if (!pbEncoded) + *pcbEncoded = bytesNeeded; + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + *pbEncoded++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < cPolicyQualifier; i++) + { + items[0].pvStructInfo = + rgPolicyQualifier[i].pszPolicyQualifierId; + items[1].pvStructInfo = + &rgPolicyQualifier[i].Qualifier; + size = bytesNeeded; + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), + dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, pbEncoded, + &size); + if (ret) + { + pbEncoded += size; + bytesNeeded -= size; + } + } + } + } + } + } + return ret; +} + +static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType, + const CERT_POLICY_INFO *info, DWORD dwFlags, BYTE *pbEncoded, + DWORD *pcbEncoded) +{ + struct AsnEncodeSequenceItem items[2] = { + { info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 }, + { &info->cPolicyQualifier, CRYPT_AsnEncodeCertPolicyQualifiers, 0 }, + }; + BOOL ret; + + if (!info->pszPolicyIdentifier) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded); + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret = FALSE; + + __TRY + { + const CERT_POLICIES_INFO *info = pvStructInfo; + DWORD bytesNeeded = 0, lenBytes, size, i; + + ret = TRUE; + for (i = 0; ret && i < info->cPolicyInfo; i++) + { + ret = CRYPT_AsnEncodeCertPolicy(dwCertEncodingType, + &info->rgPolicyInfo[i], dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, + &size); + if (ret) + bytesNeeded += size; + } + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (ret) + { + if (!pbEncoded) + *pcbEncoded = bytesNeeded; + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + *pbEncoded++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < info->cPolicyInfo; i++) + { + size = bytesNeeded; + ret = CRYPT_AsnEncodeCertPolicy(dwCertEncodingType, + &info->rgPolicyInfo[i], + dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pbEncoded, &size); + if (ret) + { + pbEncoded += size; + bytesNeeded -= size; + } + } + } + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -4110,6 +4266,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, case LOWORD(X509_BASIC_CONSTRAINTS2): encodeFunc = CRYPT_AsnEncodeBasicConstraints2; break; + case LOWORD(X509_CERT_POLICIES): + encodeFunc = CRYPT_AsnEncodeCertPolicies; + break; case LOWORD(RSA_CSP_PUBLICKEYBLOB): encodeFunc = CRYPT_AsnEncodeRsaPubKey; break; @@ -4223,6 +4382,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, encodeFunc = CRYPT_AsnEncodeAltName; else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS)) encodeFunc = CRYPT_AsnEncodeCRLDistPoints; + else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) + encodeFunc = CRYPT_AsnEncodeCertPolicies; else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage; else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 92bc0b4..b52919a 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -7184,7 +7184,6 @@ static void test_encodeCertPolicies(DWORD dwEncoding) memset(&info, 0, sizeof(info)); ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); if (ret) { @@ -7197,13 +7196,11 @@ static void test_encodeCertPolicies(DWORD dwEncoding) info.rgPolicyInfo = policy; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); policy[0].pszPolicyIdentifier = oid_any_policy; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); if (ret) { @@ -7221,7 +7218,6 @@ static void test_encodeCertPolicies(DWORD dwEncoding) info.cPolicyInfo = 2; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); if (ret) {