Module: wine Branch: master Commit: 817adc5599d541f2effcdaf403c7a2bd0af012c6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=817adc5599d541f2effcdaf403...
Author: Juan Lang juan.lang@gmail.com Date: Thu Aug 14 12:50:57 2008 -0700
crypt32: Implement CMSG_CMS_SIGNER_INFO encoding.
---
dlls/crypt32/encode.c | 94 ++++++++++++++++++++++++++++++++++++++++++- dlls/crypt32/tests/encode.c | 15 ------- 2 files changed, 93 insertions(+), 16 deletions(-)
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 0d62b02..16b4bb8 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Juan Lang + * Copyright 2005-2008 Juan Lang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -3419,6 +3419,95 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType, return ret; }
+static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret = FALSE; + + if (!(dwCertEncodingType & PKCS_7_ASN_ENCODING)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + __TRY + { + const CMSG_CMS_SIGNER_INFO *info = (const CMSG_CMS_SIGNER_INFO *)pvStructInfo; + + if (info->SignerId.dwIdChoice != CERT_ID_ISSUER_SERIAL_NUMBER && + info->SignerId.dwIdChoice != CERT_ID_KEY_IDENTIFIER) + SetLastError(E_INVALIDARG); + else if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER && + !info->SignerId.u.IssuerSerialNumber.Issuer.cbData) + SetLastError(E_INVALIDARG); + else + { + struct AsnEncodeSequenceItem items[7] = { + { &info->dwVersion, CRYPT_AsnEncodeInt, 0 }, + }; + struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } }; + DWORD cItem = 1, cSwapped = 0; + + if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) + { + items[cItem].pvStructInfo = + &info->SignerId.u.IssuerSerialNumber.Issuer; + items[cItem].encodeFunc = + CRYPT_AsnEncodeIssuerSerialNumber; + cItem++; + } + else + { + swapped[cSwapped].tag = ASN_CONTEXT | 0; + swapped[cSwapped].pvStructInfo = &info->SignerId.u.KeyId; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeOctets; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + items[cItem].pvStructInfo = &info->HashAlgorithm; + items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams; + cItem++; + if (info->AuthAttrs.cAttr) + { + swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0; + swapped[cSwapped].pvStructInfo = &info->AuthAttrs; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + items[cItem].pvStructInfo = &info->HashEncryptionAlgorithm; + items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams; + cItem++; + items[cItem].pvStructInfo = &info->EncryptedHash; + items[cItem].encodeFunc = CRYPT_AsnEncodeOctets; + cItem++; + if (info->UnauthAttrs.cAttr) + { + swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 1; + swapped[cSwapped].pvStructInfo = &info->UnauthAttrs; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, + dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData, DWORD *pcbData) { @@ -3607,6 +3696,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, case LOWORD(PKCS7_SIGNER_INFO): encodeFunc = CRYPT_AsnEncodePKCSSignerInfo; break; + case LOWORD(CMS_SIGNER_INFO): + encodeFunc = CRYPT_AsnEncodeCMSSignerInfo; + break; } } else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS)) diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 027bfe8..10128ad 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -5498,14 +5498,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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 @@ -5519,7 +5517,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5533,13 +5530,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5554,14 +5549,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5576,7 +5569,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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.) @@ -5587,7 +5579,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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 */ @@ -5599,7 +5590,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5615,12 +5605,10 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5636,13 +5624,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) 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()); @@ -5657,7 +5643,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) LocalFree(buf); } } - } }
static void test_decodeCMSSignerInfo(DWORD dwEncoding)