From d71e6e96dd7091b6b1a2fe5fb23f28352ee35479 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Thu, 14 Aug 2008 12:50:18 -0700 Subject: [PATCH] crypt32: Add tests for encoding/decoding CMSG_CMS_SIGNER_INFO. --- dlls/crypt32/tests/encode.c | 339 ++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 49e495592f2..027bfe8b0e7 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -5483,6 +5483,343 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) } } +static const BYTE CMSSignerWithKeyId[] = { +0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30, +0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; + +static void test_encodeCMSSignerInfo(DWORD dwEncoding) +{ + BOOL ret; + LPBYTE buf = NULL; + DWORD size = 0; + CMSG_CMS_SIGNER_INFO info = { 0 }; + static char oid1[] = "1.2.3", oid2[] = "1.5.6"; + + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + /* To be encoded, a signer must have a valid cert ID, where a valid ID may + * be a key id or a issuer serial number with at least the issuer set, and + * the encoding must include PKCS_7_ASN_ENCODING. + * (That isn't enough to be decoded, see decoding tests.) + */ + info.SignerId.IssuerSerialNumber.Issuer.cbData = + sizeof(encodedCommonNameNoNull); + info.SignerId.IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); + ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); + LocalFree(buf); + } + } + } + info.SignerId.IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum); + info.SignerId.IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", + size); + ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n"); + LocalFree(buf); + } + } + } + info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; + info.SignerId.KeyId.cbData = sizeof(serialNum); + info.SignerId.KeyId.pbData = (BYTE *)serialNum; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n", + size); + ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n"); + LocalFree(buf); + } + } + } + /* While a CERT_ID can have a hash type, that's not allowed in CMS, where + * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed + * (see RFC 3852, section 5.3.) + */ + info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH; + info.SignerId.HashId.cbData = sizeof(hash); + info.SignerId.HashId.pbData = (BYTE *)hash; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + /* Now with a hash algo */ + info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; + info.SignerId.IssuerSerialNumber.Issuer.cbData = + sizeof(encodedCommonNameNoNull); + info.SignerId.IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; + info.HashAlgorithm.pszObjId = oid1; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", + size); + ok(!memcmp(buf, PKCSSignerWithHashAlgo, size), + "Unexpected value\n"); + LocalFree(buf); + } + } + } + info.HashEncryptionAlgorithm.pszObjId = oid2; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), + "Unexpected size %d\n", size); + ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size), + "Unexpected value\n"); + LocalFree(buf); + } + } + } + info.EncryptedHash.cbData = sizeof(hash); + info.EncryptedHash.pbData = (BYTE *)hash; + SetLastError(0xdeadbeef); + ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine { + if (!(dwEncoding & PKCS_7_ASN_ENCODING)) + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + else + { + ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", + size); + ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n"); + LocalFree(buf); + } + } + } +} + +static void test_decodeCMSSignerInfo(DWORD dwEncoding) +{ + BOOL ret; + LPBYTE buf = NULL; + DWORD size = 0; + CMSG_CMS_SIGNER_INFO *info; + static char oid1[] = "1.2.3", oid2[] = "1.5.6"; + + /* A CMS signer can't be decoded without a serial number. */ + SetLastError(0xdeadbeef); + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + minimalPKCSSigner, sizeof(minimalPKCSSigner), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT, + "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError()); + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + info = (CMSG_CMS_SIGNER_INFO *)buf; + ok(info->dwVersion == 0, "Expected version 0, got %d\n", + info->dwVersion); + ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, + "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", + info->SignerId.dwIdChoice); + ok(info->SignerId.IssuerSerialNumber.Issuer.cbData == + sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.Issuer.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData, + encodedCommonNameNoNull, + info->SignerId.IssuerSerialNumber.Issuer.cbData), + "Unexpected value\n"); + ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData == + sizeof(serialNum), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.SerialNumber.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData, + serialNum, sizeof(serialNum)), "Unexpected value\n"); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + info = (CMSG_CMS_SIGNER_INFO *)buf; + ok(info->dwVersion == 0, "Expected version 0, got %d\n", + info->dwVersion); + ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, + "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", + info->SignerId.dwIdChoice); + ok(info->SignerId.IssuerSerialNumber.Issuer.cbData == + sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.Issuer.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData, + encodedCommonNameNoNull, + info->SignerId.IssuerSerialNumber.Issuer.cbData), + "Unexpected value\n"); + ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData == + sizeof(serialNum), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.SerialNumber.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData, + serialNum, sizeof(serialNum)), "Unexpected value\n"); + ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), + "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + PKCSSignerWithHashAndEncryptionAlgo, + sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, + NULL, (BYTE *)&buf, &size); + todo_wine + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + info = (CMSG_CMS_SIGNER_INFO *)buf; + ok(info->dwVersion == 0, "Expected version 0, got %d\n", + info->dwVersion); + ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, + "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", + info->SignerId.dwIdChoice); + ok(info->SignerId.IssuerSerialNumber.Issuer.cbData == + sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.Issuer.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData, + encodedCommonNameNoNull, + info->SignerId.IssuerSerialNumber.Issuer.cbData), + "Unexpected value\n"); + ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData == + sizeof(serialNum), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.SerialNumber.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData, + serialNum, sizeof(serialNum)), "Unexpected value\n"); + ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), + "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); + ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), + "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + PKCSSignerWithHash, sizeof(PKCSSignerWithHash), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + info = (CMSG_CMS_SIGNER_INFO *)buf; + ok(info->dwVersion == 0, "Expected version 0, got %d\n", + info->dwVersion); + ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, + "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", + info->SignerId.dwIdChoice); + ok(info->SignerId.IssuerSerialNumber.Issuer.cbData == + sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.Issuer.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData, + encodedCommonNameNoNull, + info->SignerId.IssuerSerialNumber.Issuer.cbData), + "Unexpected value\n"); + ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData == + sizeof(serialNum), "Unexpected size %d\n", + info->SignerId.IssuerSerialNumber.SerialNumber.cbData); + ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData, + serialNum, sizeof(serialNum)), "Unexpected value\n"); + ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), + "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); + ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), + "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); + ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n", + info->EncryptedHash.cbData); + ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)), + "Unexpected value\n"); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, + CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + todo_wine + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + if (buf) + { + info = (CMSG_CMS_SIGNER_INFO *)buf; + ok(info->dwVersion == 0, "Expected version 0, got %d\n", + info->dwVersion); + ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER, + "Expected CERT_ID_KEY_IDENTIFIER, got %d\n", + info->SignerId.dwIdChoice); + ok(info->SignerId.KeyId.cbData == sizeof(serialNum), + "Unexpected size %d\n", info->SignerId.KeyId.cbData); + ok(!memcmp(info->SignerId.KeyId.pbData, serialNum, sizeof(serialNum)), + "Unexpected value\n"); + LocalFree(buf); + } +} + static BYTE emptyDNSPermittedConstraints[] = { 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 }; static BYTE emptyDNSExcludedConstraints[] = { @@ -5969,6 +6306,8 @@ START_TEST(encode) test_decodePKCSAttributes(encodings[i]); test_encodePKCSSignerInfo(encodings[i]); test_decodePKCSSignerInfo(encodings[i]); + test_encodeCMSSignerInfo(encodings[i]); + test_decodeCMSSignerInfo(encodings[i]); test_encodeNameConstraints(encodings[i]); test_decodeNameConstraints(encodings[i]); }