Module: wine Branch: master Commit: b82bfa3455a391c9a9c28fa5b2f47fb1d44d33cf URL: http://source.winehq.org/git/wine.git/?a=commit;h=b82bfa3455a391c9a9c28fa5b2...
Author: Juan Lang juan.lang@gmail.com Date: Mon Aug 13 14:29:58 2007 -0700
crypt32: Test authority key identifier with a multi-byte id to show that its byte-order is swapped and fix encoding and decoding it.
---
dlls/crypt32/decode.c | 41 +++++++++++++++++++++++++++++++++++++++-- dlls/crypt32/encode.c | 43 +++++++++++++++++++++++++++++++++++++++++-- dlls/crypt32/tests/encode.c | 20 +++++++++++--------- 3 files changed, 91 insertions(+), 13 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index f1915d4..723873a 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -2213,6 +2213,43 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType, return ret; }
+/* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */ +static BOOL WINAPI CRYPT_AsnDecodeIntegerSwapBytes(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + + TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, *pcbStructInfo); + + /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in- + * place. + */ + ret = CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType, lpszStructType, + pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pDecodePara, + pvStructInfo, pcbStructInfo); + if (ret && pvStructInfo) + { + CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo; + + if (blob->cbData) + { + DWORD i; + BYTE temp; + + for (i = 0; i < blob->cbData / 2; i++) + { + temp = blob->pbData[i]; + blob->pbData[i] = blob->pbData[blob->cbData - i - 1]; + blob->pbData[blob->cbData - i - 1] = temp; + } + } + } + TRACE("returning %d (%08x)\n", ret, GetLastError()); + return ret; +} + static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) @@ -2223,7 +2260,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType, { struct AsnDecodeSequenceItem items[] = { { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId), - CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_DATA_BLOB), + CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB), TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR| 1, offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer), @@ -2258,7 +2295,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType, { struct AsnDecodeSequenceItem items[] = { { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId), - CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_DATA_BLOB), + CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB), TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR| 1, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer), diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index be724d0..96e94f4 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -2003,6 +2003,45 @@ static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry, return ret; }
+static BOOL WINAPI CRYPT_AsnEncodeIntegerSwapBytes(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvStructInfo; + CRYPT_DATA_BLOB newBlob = { blob->cbData, NULL }; + + ret = TRUE; + if (newBlob.cbData) + { + newBlob.pbData = CryptMemAlloc(newBlob.cbData); + if (newBlob.pbData) + { + DWORD i; + + for (i = 0; i < newBlob.cbData; i++) + newBlob.pbData[newBlob.cbData - i - 1] = blob->pbData[i]; + } + else + ret = FALSE; + } + if (ret) + ret = CRYPT_AsnEncodeInteger(dwCertEncodingType, lpszStructType, + &newBlob, dwFlags, pEncodePara, pbEncoded, pcbEncoded); + CryptMemFree(newBlob.pbData); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -2022,7 +2061,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType, { swapped[cSwapped].tag = ASN_CONTEXT | 0; swapped[cSwapped].pvStructInfo = &info->KeyId; - swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeIntegerSwapBytes; items[cItem].pvStructInfo = &swapped[cSwapped]; items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; cSwapped++; @@ -2155,7 +2194,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId2(DWORD dwCertEncodingType, { swapped[cSwapped].tag = ASN_CONTEXT | 0; swapped[cSwapped].pvStructInfo = &info->KeyId; - swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeIntegerSwapBytes; items[cItem].pvStructInfo = &swapped[cSwapped]; items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; cSwapped++; diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 50c458d..7b3e562 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -4423,7 +4423,9 @@ static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) } }
-static const BYTE authorityKeyIdWithId[] = { 0x30,0x03,0x80,0x01,0x01 }; +static BYTE keyId[] = { 1,2,3,4 }; +static const BYTE authorityKeyIdWithId[] = { + 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 }; static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15, 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 0x20,0x4c,0x61,0x6e,0x67,0x00 }; @@ -4447,8 +4449,8 @@ static void test_encodeAuthorityKeyId(DWORD dwEncoding) LocalFree(buf); } /* With just a key id */ - info.KeyId.cbData = sizeof(serialNum); - info.KeyId.pbData = (BYTE *)serialNum; + info.KeyId.cbData = sizeof(keyId); + info.KeyId.pbData = keyId; ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); @@ -4519,8 +4521,8 @@ static void test_decodeAuthorityKeyId(DWORD dwEncoding)
ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", size); - ok(info->KeyId.cbData == sizeof(serialNum), "Unexpected key id len\n"); - ok(!memcmp(info->KeyId.pbData, serialNum, sizeof(serialNum)), + ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); + ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), "Unexpected key id\n"); ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); @@ -4587,8 +4589,8 @@ static void test_encodeAuthorityKeyId2(DWORD dwEncoding) LocalFree(buf); } /* With just a key id */ - info.KeyId.cbData = sizeof(serialNum); - info.KeyId.pbData = (BYTE *)serialNum; + info.KeyId.cbData = sizeof(keyId); + info.KeyId.pbData = keyId; ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); @@ -4670,8 +4672,8 @@ static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", size); - ok(info->KeyId.cbData == sizeof(serialNum), "Unexpected key id len\n"); - ok(!memcmp(info->KeyId.pbData, serialNum, sizeof(serialNum)), + ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); + ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), "Unexpected key id\n"); ok(info->AuthorityCertIssuer.cAltEntry == 0, "Expected no issuer name entries\n");