[PATCH 0/1] MR1137: crypt32: Parse OCSP responder name.
From: Hans Leidekker <hans(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53813 --- dlls/crypt32/decode.c | 102 +++++++++++++++++++++++++++++++++--- dlls/crypt32/tests/encode.c | 86 +++++++++++++++++++++++++++--- 2 files changed, 174 insertions(+), 14 deletions(-) diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index b834c9828b6..946114dcb4d 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -6521,13 +6521,13 @@ static BOOL CRYPT_AsnDecodeOCSPBasicResponseEntriesArray(const BYTE *pbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); } -static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, +static BOOL CRYPT_AsnDecodeResponderIDByName(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { OCSP_BASIC_RESPONSE_INFO *info = pvStructInfo; - BYTE tag = pbEncoded[0] & ~3, choice = pbEncoded[0] & 3; - DWORD decodedLen, dataLen, lenBytes, bytesNeeded = sizeof(*info), len; + DWORD dataLen, decodedLen, lenBytes, bytesNeeded = sizeof(*info); + BYTE tag = pbEncoded[0] & ~3; CERT_NAME_BLOB *blob; if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR)) @@ -6536,15 +6536,78 @@ static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, SetLastError(CRYPT_E_ASN1_BADTAG); return FALSE; } - if (choice > 2) + + if (!CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)) + return FALSE; + lenBytes = GET_LEN_BYTES(pbEncoded[1]); + cbEncoded -= 1 + lenBytes; + + if (dataLen > cbEncoded) { - WARN("Unexpected choice %02x\n", choice); - SetLastError(CRYPT_E_ASN1_CORRUPT); + SetLastError(CRYPT_E_ASN1_EOD); return FALSE; } + pbEncoded += 1 + lenBytes; + decodedLen = 1 + lenBytes + dataLen; + if (pbEncoded[0] != ASN_SEQUENCE) + { + WARN("Unexpected tag %02x %02x\n", pbEncoded[0], pbEncoded[1]); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) bytesNeeded += dataLen; if (pvStructInfo && *pcbStructInfo >= bytesNeeded) - info->dwResponderIdChoice = choice; + { + info->dwResponderIdChoice = 1; + + blob = &info->u.ByNameResponderId; + blob->cbData = dataLen; + if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) + blob->pbData = (BYTE *)pbEncoded; + else if (blob->cbData) + { + blob->pbData = (BYTE *)(info + 1); + memcpy(blob->pbData, pbEncoded, blob->cbData); + } + } + + if (pcbDecoded) + *pcbDecoded = decodedLen; + + if (!pvStructInfo) + { + *pcbStructInfo = bytesNeeded; + return TRUE; + } + + if (*pcbStructInfo < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + *pcbStructInfo = bytesNeeded; + return FALSE; + } + + *pcbStructInfo = bytesNeeded; + return TRUE; +} + +static BOOL CRYPT_AsnDecodeResponderIDByKey(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + OCSP_BASIC_RESPONSE_INFO *info = pvStructInfo; + DWORD dataLen, decodedLen, lenBytes, bytesNeeded = sizeof(*info), len; + BYTE tag = pbEncoded[0] & ~3; + CRYPT_HASH_BLOB *blob; + + if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + WARN("Unexpected tag %02x\n", tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } if (!CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)) return FALSE; @@ -6581,7 +6644,8 @@ static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) bytesNeeded += len; if (pvStructInfo && *pcbStructInfo >= bytesNeeded) { - blob = &info->u.ByNameResponderId; + info->dwResponderIdChoice = 2; + blob = &info->u.ByKeyResponderId; blob->cbData = len; if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) blob->pbData = (BYTE *)pbEncoded; @@ -6612,6 +6676,28 @@ static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, return TRUE; } +static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BYTE choice = pbEncoded[0] & 3; + + TRACE("choice %02x\n", choice); + switch (choice) + { + case 1: + return CRYPT_AsnDecodeResponderIDByName(pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pcbStructInfo, pcbDecoded); + case 2: + return CRYPT_AsnDecodeResponderIDByKey(pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pcbStructInfo, pcbDecoded); + default: + WARN("Unexpected choice %02x\n", choice); + SetLastError(CRYPT_E_ASN1_CORRUPT); + return FALSE; + } +} + static BOOL WINAPI CRYPT_AsnDecodeOCSPBasicResponse(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 565afb4c9e0..527e663860a 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -8673,6 +8673,26 @@ static const BYTE ocsp_basic_response[] = { 0x33, 0x36, 0x30, 0x31, 0x5a }; +static const BYTE ocsp_basic_response2[] = { + 0x30, 0x81, 0xbe, 0xa1, 0x34, 0x30, 0x32, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x4c, 0x65, 0x74, 0x27, 0x73, + 0x20, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x02, 0x52, 0x33, 0x18, 0x0f, 0x32, + 0x30, 0x32, 0x32, 0x31, 0x30, 0x32, 0x30, 0x30, 0x36, 0x30, 0x31, 0x30, + 0x30, 0x5a, 0x30, 0x75, 0x30, 0x73, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x05, + 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x48, 0xda, 0xc9, + 0xa0, 0xfb, 0x2b, 0xd3, 0x2d, 0x4f, 0xf0, 0xde, 0x68, 0xd2, 0xf5, 0x67, + 0xb7, 0x35, 0xf9, 0xb3, 0xc4, 0x04, 0x14, 0x14, 0x2e, 0xb3, 0x17, 0xb7, + 0x58, 0x56, 0xcb, 0xae, 0x50, 0x09, 0x40, 0xe6, 0x1f, 0xaf, 0x9d, 0x8b, + 0x14, 0xc2, 0xc6, 0x02, 0x12, 0x03, 0x26, 0x1c, 0x82, 0x80, 0xf3, 0x8c, + 0x13, 0xef, 0xae, 0x83, 0x9d, 0x89, 0xb9, 0xcd, 0x59, 0x83, 0x5b, 0x80, + 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x31, 0x30, 0x32, 0x30, 0x30, + 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0xa0, 0x11, 0x18, 0x0f, 0x32, 0x30, + 0x32, 0x32, 0x31, 0x30, 0x32, 0x37, 0x30, 0x35, 0x35, 0x39, 0x35, 0x38, + 0x5a +}; + static const BYTE ocsp_basic_response_revoked[] = { 0x30, 0x81, 0xb1, 0xa2, 0x16, 0x04, 0x14, 0xa4, 0x8d, 0xe5, 0xbe, 0x7c, 0x79, 0xe4, 0x70, 0x23, 0x6d, 0x2e, 0x29, 0x34, 0xad, 0x23, 0x58, 0xdc, @@ -8758,22 +8778,36 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding) static const BYTE resp_id2[] = { 0xa4, 0x8d, 0xe5, 0xbe, 0x7c, 0x79, 0xe4, 0x70, 0x23, 0x6d, 0x2e, 0x29, 0x34, 0xad, 0x23, 0x58, 0xdc, 0xf5, 0x31, 0x7f}; + static const BYTE resp_id3[] = { + 0x30, 0x32, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x4c, 0x65, 0x74, 0x27, 0x73, 0x20, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x02, 0x52, 0x33}; static const BYTE name_hash[] = { 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab, 0xd8}; static const BYTE name_hash2[] = { 0x74, 0xb4, 0xe7, 0x23, 0x19, 0xc7, 0x65, 0x92, 0x15, 0x40, 0x44, 0x7b, 0xc7, 0xce, 0x3e, 0x90, 0xc2, 0x18, 0x76, 0xeb}; + static const BYTE name_hash3[] = { + 0x48, 0xda, 0xc9, 0xa0, 0xfb, 0x2b, 0xd3, 0x2d, 0x4f, 0xf0, 0xde, 0x68, 0xd2, 0xf5, 0x67, 0xb7, + 0x35, 0xf9, 0xb3, 0xc4}; static const BYTE key_hash[] = { 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4}; static const BYTE key_hash2[] = { 0xa4, 0x8d, 0xe5, 0xbe, 0x7c, 0x79, 0xe4, 0x70, 0x23, 0x6d, 0x2e, 0x29, 0x34, 0xad, 0x23, 0x58, 0xdc, 0xf5, 0x31, 0x7f}; + static const BYTE key_hash3[] = { + 0x14, 0x2e, 0xb3, 0x17, 0xb7, 0x58, 0x56, 0xcb, 0xae, 0x50, 0x09, 0x40, 0xe6, 0x1f, 0xaf, 0x9d, + 0x8b, 0x14, 0xc2, 0xc6}; static const BYTE serial[] = { 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08}; static const BYTE serial2[] = { 0x2f, 0x57, 0xa4, 0x85, 0xa2, 0xe3, 0x52, 0x54, 0x9a, 0x3b, 0x85, 0x98, 0xa2, 0x67, 0x2e, 0x0d}; + static const BYTE serial3[] = { + 0x5b, 0x83, 0x59, 0xcd, 0xb9, 0x89, 0x9d, 0x83, 0xae, 0xef, 0x13, 0x8c, 0xf3, 0x80, 0x82, 0x1c, + 0x26, 0x03}; OCSP_BASIC_RESPONSE_INFO *info; OCSP_BASIC_RESPONSE_ENTRY *entry; OCSP_BASIC_REVOKED_INFO *revoked; @@ -8800,11 +8834,11 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding) ok(entry->CertId.HashAlgorithm.Parameters.cbData == 2, "got %lu\n", entry->CertId.HashAlgorithm.Parameters.cbData); ok(entry->CertId.HashAlgorithm.Parameters.pbData[0] == 5, "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[0]); ok(!entry->CertId.HashAlgorithm.Parameters.pbData[1], "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[1]); - ok(entry->CertId.IssuerNameHash.cbData == 20, "got %lu\n", entry->CertId.IssuerNameHash.cbData); + ok(entry->CertId.IssuerNameHash.cbData == sizeof(name_hash), "got %lu\n", entry->CertId.IssuerNameHash.cbData); ok(!memcmp(entry->CertId.IssuerNameHash.pbData, name_hash, sizeof(name_hash)), "wrong data\n"); - ok(entry->CertId.IssuerKeyHash.cbData == 20, "got %lu\n", entry->CertId.IssuerKeyHash.cbData); + ok(entry->CertId.IssuerKeyHash.cbData == sizeof(key_hash), "got %lu\n", entry->CertId.IssuerKeyHash.cbData); ok(!memcmp(entry->CertId.IssuerKeyHash.pbData, key_hash, sizeof(key_hash)), "wrong data\n"); - ok(entry->CertId.SerialNumber.cbData == 16, "got %lu\n", entry->CertId.SerialNumber.cbData); + ok(entry->CertId.SerialNumber.cbData == sizeof(serial), "got %lu\n", entry->CertId.SerialNumber.cbData); ok(!memcmp(entry->CertId.SerialNumber.pbData, serial, sizeof(serial)), "wrong data\n"); ok(entry->dwCertStatus == 0, "got %lu\n", entry->dwCertStatus); ok(entry->pRevokedInfo == NULL, "got %p\n", entry->pRevokedInfo); @@ -8839,11 +8873,11 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding) ok(entry->CertId.HashAlgorithm.Parameters.cbData == 2, "got %lu\n", entry->CertId.HashAlgorithm.Parameters.cbData); ok(entry->CertId.HashAlgorithm.Parameters.pbData[0] == 5, "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[0]); ok(!entry->CertId.HashAlgorithm.Parameters.pbData[1], "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[1]); - ok(entry->CertId.IssuerNameHash.cbData == 20, "got %lu\n", entry->CertId.IssuerNameHash.cbData); + ok(entry->CertId.IssuerNameHash.cbData == sizeof(name_hash2), "got %lu\n", entry->CertId.IssuerNameHash.cbData); ok(!memcmp(entry->CertId.IssuerNameHash.pbData, name_hash2, sizeof(name_hash2)), "wrong data\n"); - ok(entry->CertId.IssuerKeyHash.cbData == 20, "got %lu\n", entry->CertId.IssuerKeyHash.cbData); + ok(entry->CertId.IssuerKeyHash.cbData == sizeof(key_hash2), "got %lu\n", entry->CertId.IssuerKeyHash.cbData); ok(!memcmp(entry->CertId.IssuerKeyHash.pbData, key_hash2, sizeof(key_hash2)), "wrong data\n"); - ok(entry->CertId.SerialNumber.cbData == 16, "got %lu\n", entry->CertId.SerialNumber.cbData); + ok(entry->CertId.SerialNumber.cbData == sizeof(serial2), "got %lu\n", entry->CertId.SerialNumber.cbData); ok(!memcmp(entry->CertId.SerialNumber.pbData, serial2, sizeof(serial2)), "wrong data\n"); ok(entry->dwCertStatus == 1, "got %lu\n", entry->dwCertStatus); ok(entry->pRevokedInfo != NULL, "got NULL\n"); @@ -8863,6 +8897,46 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding) ok(!info->cExtension, "got %lu\n", info->cExtension); ok(info->rgExtension == NULL, "got %p\n", info->rgExtension); LocalFree(info); + + size = 0; + ret = CryptDecodeObjectEx(dwEncoding, OCSP_BASIC_RESPONSE, ocsp_basic_response2, + sizeof(ocsp_basic_response2), CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + ok(ret, "got %08lx\n", GetLastError()); + + ok(!info->dwVersion, "got %lu\n", info->dwVersion); + ok(info->dwResponderIdChoice == 1, "got %lu\n", info->dwResponderIdChoice); + ok(info->ByNameResponderId.cbData == sizeof(resp_id3), "got %lu\n", info->ByNameResponderId.cbData); + ok(!memcmp(info->ByNameResponderId.pbData, resp_id3, sizeof(resp_id3)), "wrong data\n"); + + ok(info->ProducedAt.dwLowDateTime == 1408824832, "got %lu\n", info->ProducedAt.dwLowDateTime); + ok(info->ProducedAt.dwHighDateTime == 30991433, "got %lu\n", info->ProducedAt.dwHighDateTime); + ok(info->cResponseEntry == 1, "got %lu\n", info->cResponseEntry); + ok(info->rgResponseEntry != NULL, "got %p\n", info->rgResponseEntry); + + entry = info->rgResponseEntry; + ok(!strcmp(entry->CertId.HashAlgorithm.pszObjId, szOID_OIWSEC_sha1), "got '%s'\n", entry->CertId.HashAlgorithm.pszObjId); + ok(entry->CertId.HashAlgorithm.Parameters.cbData == 2, "got %lu\n", entry->CertId.HashAlgorithm.Parameters.cbData); + ok(entry->CertId.HashAlgorithm.Parameters.pbData[0] == 5, "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[0]); + ok(!entry->CertId.HashAlgorithm.Parameters.pbData[1], "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[1]); + ok(entry->CertId.IssuerNameHash.cbData == sizeof(name_hash3), "got %lu\n", entry->CertId.IssuerNameHash.cbData); + ok(!memcmp(entry->CertId.IssuerNameHash.pbData, name_hash3, sizeof(name_hash3)), "wrong data\n"); + + ok(entry->CertId.IssuerKeyHash.cbData == sizeof(key_hash3), "got %lu\n", entry->CertId.IssuerKeyHash.cbData); + ok(!memcmp(entry->CertId.IssuerKeyHash.pbData, key_hash3, sizeof(key_hash3)), "wrong data\n"); + ok(entry->CertId.SerialNumber.cbData == sizeof(serial3), "got %lu\n", entry->CertId.SerialNumber.cbData); + ok(!memcmp(entry->CertId.SerialNumber.pbData, serial3, sizeof(serial3)), "wrong data\n"); + ok(entry->dwCertStatus == 0, "got %lu\n", entry->dwCertStatus); + ok(entry->pRevokedInfo == NULL, "got %p\n", entry->pRevokedInfo); + ok(entry->ThisUpdate.dwLowDateTime == 808824832, "got %lu\n", entry->ThisUpdate.dwLowDateTime); + ok(entry->ThisUpdate.dwHighDateTime == 30991433, "got %lu\n", entry->ThisUpdate.dwHighDateTime); + ok(entry->NextUpdate.dwLowDateTime == 1474872064, "got %lu\n", entry->NextUpdate.dwLowDateTime); + ok(entry->NextUpdate.dwHighDateTime == 30992841, "got %lu\n", entry->NextUpdate.dwHighDateTime); + ok(!entry->cExtension, "got %lu\n", entry->cExtension); + ok(entry->rgExtension == NULL, "got %p\n", entry->rgExtension); + + ok(!info->cExtension, "got %lu\n", info->cExtension); + ok(info->rgExtension == NULL, "got %p\n", info->rgExtension); + LocalFree(info); } START_TEST(encode) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1137
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125254 Your paranoid android. === debian11 (build log) === Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
participants (3)
-
Hans Leidekker -
Hans Leidekker (@hans) -
Marvin