Juan Lang : crypt32: Implement CMSG_CMS_SIGNER_INFO encoding.
Alexandre Julliard
julliard at winehq.org
Wed Aug 20 08:13:39 CDT 2008
Module: wine
Branch: master
Commit: 817adc5599d541f2effcdaf403c7a2bd0af012c6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=817adc5599d541f2effcdaf403c7a2bd0af012c6
Author: Juan Lang <juan.lang at 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)
More information about the wine-cvs
mailing list