update crypt headers

sync crypt32 with wine 1.1.4
sync wintrust with wine 1.1.4

svn path=/trunk/; revision=36232
This commit is contained in:
Christoph von Wittich 2008-09-14 11:32:55 +00:00
parent 7b048be57f
commit 0ff89a79a9
35 changed files with 8225 additions and 1106 deletions

View file

@ -239,8 +239,15 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId,
pvData, pcbData);
break;
case CERT_SIGNATURE_HASH_PROP_ID:
FIXME("CERT_SIGNATURE_HASH_PROP_ID unimplemented\n");
SetLastError(CRYPT_E_NOT_FOUND);
ret = CryptHashToBeSigned(0, pCertContext->dwCertEncodingType,
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, pvData,
pcbData);
if (ret && pvData)
{
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
ret = CertContext_SetProperty(context, dwPropId, 0, &blob);
}
break;
case CERT_KEY_IDENTIFIER_PROP_ID:
{
@ -788,17 +795,62 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
{
if (pPublicKey2->PublicKey.cbData)
ret = !memcmp(pPublicKey1->PublicKey.pbData,
pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
case 0: /* Seems to mean "raw binary bits" */
if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData &&
pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits)
{
if (pPublicKey2->PublicKey.cbData)
ret = !memcmp(pPublicKey1->PublicKey.pbData,
pPublicKey2->PublicKey.pbData, pPublicKey1->PublicKey.cbData);
else
ret = TRUE;
}
else
ret = TRUE;
}
else
ret = FALSE;
break;
default:
WARN("Unknown encoding type %08x\n", dwCertEncodingType);
/* FALLTHROUGH */
case X509_ASN_ENCODING:
{
BLOBHEADER *pblob1, *pblob2;
DWORD length;
ret = FALSE;
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
0, NULL, &length))
{
pblob1 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
0, pblob1, &length))
{
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
0, NULL, &length))
{
pblob2 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
0, pblob2, &length))
{
/* The RSAPUBKEY structure directly follows the BLOBHEADER */
RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
*pk2 = (LPVOID)(pblob2 + 1);
ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
&& !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
}
CryptMemFree(pblob2);
}
}
CryptMemFree(pblob1);
}
break;
}
}
return ret;
}
@ -809,7 +861,7 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
TRACE("(%08x, %p)\n", dwCertEncodingType, pPublicKey);
if (dwCertEncodingType != X509_ASN_ENCODING)
if (GET_CERT_ENCODING_TYPE(dwCertEncodingType) != X509_ASN_ENCODING)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
@ -1091,6 +1143,32 @@ static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType,
pCertContext->pCertInfo, toCompare->pCertInfo);
}
static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
const CRYPT_HASH_BLOB *hash = (const CRYPT_HASH_BLOB *)pvPara;
DWORD size = 0;
BOOL ret;
ret = CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
if (ret && size == hash->cbData)
{
LPBYTE buf = CryptMemAlloc(size);
if (buf)
{
CertGetCertificateContextProperty(pCertContext,
CERT_SIGNATURE_HASH_PROP_ID, buf, &size);
ret = !memcmp(buf, hash->pbData, size);
CryptMemFree(buf);
}
}
else
ret = FALSE;
return ret;
}
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara,
PCCERT_CONTEXT pPrevCertContext)
@ -1127,6 +1205,9 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore,
case CERT_COMPARE_EXISTING:
compare = compare_existing_cert;
break;
case CERT_COMPARE_SIGNATURE_HASH:
compare = compare_cert_by_signature_hash;
break;
default:
FIXME("find type %08x unimplemented\n", dwType);
compare = NULL;
@ -1485,6 +1566,51 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
return ret;
}
BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
BOOL ret;
CERT_SIGNED_CONTENT_INFO *info;
DWORD size;
TRACE("(%08lx, %08x, %p, %d, %p, %d)\n", hCryptProv, dwCertEncodingType,
pbEncoded, cbEncoded, pbComputedHash, *pcbComputedHash);
ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT,
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, (void *)&info, &size);
if (ret)
{
PCCRYPT_OID_INFO oidInfo;
HCRYPTHASH hHash;
if (!hCryptProv)
hCryptProv = CRYPT_GetDefaultProvider();
oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
info->SignatureAlgorithm.pszObjId, 0);
if (!oidInfo)
{
SetLastError(NTE_BAD_ALGID);
ret = FALSE;
}
else
{
ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, info->ToBeSigned.pbData,
info->ToBeSigned.cbData, 0);
if (ret)
ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash,
pcbComputedHash, 0);
CryptDestroyHash(hHash);
}
}
LocalFree(info);
}
return ret;
}
BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned,
DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,

View file

@ -1578,12 +1578,6 @@ static BYTE msTestPubKey1[] = {
0x42,0xb6,0x9d,0x23,0x36,0x0b,0xde,0x54,0x0f,0xcd,0xbd,0x1f,0x99,0x2a,0x10,
0x58,0x11,0xcb,0x40,0xcb,0xb5,0xa7,0x41,0x02,0x03,0x01,0x00,0x01 };
static BYTE msTestPubKey2[] = {
0x30,0x48,0x02,0x41,0x00,0x81,0x55,0x22,0xb9,0x8a,0xa4,0x6f,0xed,0xd6,0xe7,
0xd9,0x66,0x0f,0x55,0xbc,0xd7,0xcd,0xd5,0xbc,0x4e,0x40,0x02,0x21,0xa2,0xb1,
0xf7,0x87,0x30,0x85,0x5e,0xd2,0xf2,0x44,0xb9,0xdc,0x9b,0x75,0xb6,0xfb,0x46,
0x5f,0x42,0xb6,0x9d,0x23,0x36,0x0b,0xde,0x54,0x0f,0xcd,0xbd,0x1f,0x99,0x2a,
0x10,0x58,0x11,0xcb,0x40,0xcb,0xb5,0xa7,0x41,0x02,0x03,0x01,0x00,0x01 };
static BYTE msTestPubKey3[] = {
0x30,0x47,0x02,0x40,0x9c,0x50,0x05,0x1d,0xe2,0x0e,0x4c,0x53,0xd8,0xd9,0xb5,
0xe5,0xfd,0xe9,0xe3,0xad,0x83,0x4b,0x80,0x08,0xd9,0xdc,0xe8,0xe8,0x35,0xf8,
0x11,0xf1,0xe9,0x9b,0x03,0x7a,0x65,0x64,0x76,0x35,0xce,0x38,0x2c,0xf2,0xb6,
@ -1608,7 +1602,6 @@ static BOOL WINAPI verify_authenticode_policy(LPCSTR szPolicyOID,
CRYPT_DATA_BLOB keyBlobs[] = {
{ sizeof(msTestPubKey1), msTestPubKey1 },
{ sizeof(msTestPubKey2), msTestPubKey2 },
{ sizeof(msTestPubKey3), msTestPubKey3 },
};
/* Check whether the root is an MS test root */

View file

@ -341,6 +341,84 @@ static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
return ret;
}
static BOOL CRYPT_CollectionAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
void *toReplace, const void **ppStoreContext)
{
BOOL ret;
void *childContext = NULL;
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, ctls),
ctl, toReplace, sizeof(CTL_CONTEXT), &childContext);
if (ppStoreContext && childContext)
{
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
Context_GetExtra(childContext, sizeof(CTL_CONTEXT));
PCTL_CONTEXT context =
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
sizeof(CTL_CONTEXT), TRUE);
if (context)
context->hCertStore = store;
*ppStoreContext = context;
}
CertFreeCTLContext((PCCTL_CONTEXT)childContext);
return ret;
}
static void *CRYPT_CollectionEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
void *ret;
TRACE("(%p, %p)\n", store, pPrev);
EnterCriticalSection(&cs->cs);
if (pPrev)
{
PWINE_STORE_LIST_ENTRY storeEntry =
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
sizeof(CTL_CONTEXT));
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
&storeEntry->store->ctls, pCTLInterface, pPrev, sizeof(CTL_CONTEXT));
}
else
{
if (!list_empty(&cs->stores))
{
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
WINE_STORE_LIST_ENTRY, entry);
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
&storeEntry->store->ctls, pCTLInterface, NULL,
sizeof(CTL_CONTEXT));
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
}
LeaveCriticalSection(&cs->cs);
if (ret)
((PCTL_CONTEXT)ret)->hCertStore = store;
TRACE("returning %p\n", ret);
return ret;
}
static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
void *pCtlContext)
{
BOOL ret;
TRACE("(%p, %p)\n", store, pCtlContext);
ret = CertDeleteCTLFromStore((PCCTL_CONTEXT)
Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT)));
return ret;
}
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
@ -365,6 +443,9 @@ PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
store->hdr.ctls.addContext = CRYPT_CollectionAddCTL;
store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL;
store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL;
InitializeCriticalSection(&store->cs);
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
list_init(&store->stores);

View file

@ -386,7 +386,7 @@ static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
DWORD dwFlags, const void *pvData)
{
PCONTEXT_PROPERTY_LIST properties =
Context_GetProperties(context, sizeof(CERT_CONTEXT));
Context_GetProperties(context, sizeof(CRL_CONTEXT));
BOOL ret;
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);

View file

@ -35,6 +35,8 @@
<file>sip.c</file>
<file>store.c</file>
<file>str.c</file>
<file>ctl.c</file>
<file>message.c</file>
<file>crypt32.rc</file>
<file>crypt32.spec</file>
</module>

View file

@ -38,7 +38,7 @@
@ stdcall CertEnumSystemStore(long ptr ptr ptr)
@ stdcall CertFindAttribute(str long ptr)
@ stdcall CertFindCRLInStore(long long long long ptr ptr)
@ stub CertFindCTLInStore
@ stdcall CertFindCTLInStore(long long long long ptr ptr)
@ stdcall CertFindCertificateInStore(long long long long ptr ptr)
@ stdcall CertFindCertificateInCRL(ptr ptr long ptr ptr)
@ stdcall CertFindExtension(str long ptr)
@ -129,9 +129,9 @@
@ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr)
@ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr)
@ stdcall CryptHashCertificate(long long long ptr long ptr ptr)
@ stub CryptHashMessage
@ stdcall CryptHashMessage(ptr long long ptr ptr ptr ptr ptr ptr)
@ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr)
@ stub CryptHashToBeSigned
@ stdcall CryptHashToBeSigned(ptr long ptr long ptr ptr)
@ stub CryptImportPKCS8
@ stdcall CryptImportPublicKeyInfo(long long ptr ptr)
@ stdcall CryptImportPublicKeyInfoEx(long long ptr long long ptr ptr)
@ -148,13 +148,14 @@
@ stub CryptMsgCountersignEncoded
@ stdcall CryptMsgDuplicate(ptr)
@ stub CryptMsgEncodeAndSignCTL
@ stub CryptMsgGetAndVerifySigner
@ stdcall CryptMsgGetAndVerifySigner(ptr long ptr long ptr ptr)
@ stdcall CryptMsgGetParam(ptr long long ptr ptr)
@ stdcall CryptMsgOpenToDecode(long long long long ptr ptr)
@ stdcall CryptMsgOpenToEncode(long long long ptr str ptr)
@ stub CryptMsgSignCTL
@ stdcall CryptMsgUpdate(ptr ptr long long)
@ stub CryptMsgVerifyCountersignatureEncoded
@ stdcall CryptMsgVerifyCountersignatureEncodedEx(ptr long ptr long ptr long long ptr long ptr)
@ stdcall CryptProtectData(ptr wstr ptr ptr ptr long ptr)
@ stdcall CryptQueryObject(long ptr long long long ptr ptr ptr ptr ptr ptr)
@ stdcall CryptRegisterDefaultOIDFunction(long str long wstr)
@ -184,7 +185,7 @@
@ stub CryptUnregisterOIDInfo
@ stdcall CryptVerifyCertificateSignature(long long ptr long ptr)
@ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr)
@ stub CryptVerifyDetachedMessageHash
@ stdcall CryptVerifyDetachedMessageHash(ptr ptr long long ptr ptr ptr ptr)
@ stub CryptVerifyDetachedMessageSignature
@ stub CryptVerifyMessageHash
@ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr)

View file

@ -19,7 +19,7 @@
*/
#pragma code_page(65001)
LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
@ -159,11 +159,6 @@ STRINGTABLE DISCARDABLE
IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate"
IDS_FILE_RECOVERY "File Recovery"
IDS_ROOT_LIST_SIGNER "Root List Signer"
IDS_ANY_APPLICATION_POLICIES "All application policies"
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replication"
IDS_ENROLLMENT_AGENT "Certificate Request Agent"
IDS_LIFETIME_SIGNING "Lifetime Signing"
IDS_ANY_CERT_POLICY "All issuance policies"
}
#pragma code_page(default)

View file

@ -84,20 +84,20 @@ BOOL CRYPT_AsnEncodePKCSDigestedData(CRYPT_DIGESTED_DATA *digestedData,
typedef struct _CRYPT_SIGNED_INFO
{
DWORD version;
DWORD cCertEncoded;
PCERT_BLOB rgCertEncoded;
DWORD cCrlEncoded;
PCRL_BLOB rgCrlEncoded;
CRYPT_CONTENT_INFO content;
DWORD cSignerInfo;
PCMSG_SIGNER_INFO rgSignerInfo;
DWORD version;
DWORD cCertEncoded;
PCERT_BLOB rgCertEncoded;
DWORD cCrlEncoded;
PCRL_BLOB rgCrlEncoded;
CRYPT_CONTENT_INFO content;
DWORD cSignerInfo;
PCMSG_CMS_SIGNER_INFO rgSignerInfo;
} CRYPT_SIGNED_INFO;
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
DWORD *pcbData);
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo);
@ -227,6 +227,7 @@ typedef struct WINE_CRYPTCERTSTORE
PFN_CERT_STORE_PROV_CLOSE closeStore;
CONTEXT_FUNCS certs;
CONTEXT_FUNCS crls;
CONTEXT_FUNCS ctls;
PFN_CERT_STORE_PROV_CONTROL control; /* optional */
PCONTEXT_PROPERTY_LIST properties;
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;

View file

@ -0,0 +1,673 @@
/*
* Copyright 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <assert.h>
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
#define CtlContext_CopyProperties(to, from) \
Context_CopyProperties((to), (from), sizeof(CTL_CONTEXT))
BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
PCCTL_CONTEXT* ppStoreContext)
{
PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
BOOL ret = TRUE;
PCCTL_CONTEXT toAdd = NULL, existing = NULL;
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCtlContext, dwAddDisposition,
ppStoreContext);
if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
{
existing = CertFindCTLInStore(hCertStore, 0, 0, CTL_FIND_EXISTING,
pCtlContext, NULL);
}
switch (dwAddDisposition)
{
case CERT_STORE_ADD_ALWAYS:
toAdd = CertDuplicateCTLContext(pCtlContext);
break;
case CERT_STORE_ADD_NEW:
if (existing)
{
TRACE("found matching CTL, not adding\n");
SetLastError(CRYPT_E_EXISTS);
ret = FALSE;
}
else
toAdd = CertDuplicateCTLContext(pCtlContext);
break;
case CERT_STORE_ADD_NEWER:
if (existing)
{
LONG newer = CompareFileTime(&existing->pCtlInfo->ThisUpdate,
&pCtlContext->pCtlInfo->ThisUpdate);
if (newer < 0)
toAdd = CertDuplicateCTLContext(pCtlContext);
else
{
TRACE("existing CTL is newer, not adding\n");
SetLastError(CRYPT_E_EXISTS);
ret = FALSE;
}
}
else
toAdd = CertDuplicateCTLContext(pCtlContext);
break;
case CERT_STORE_ADD_REPLACE_EXISTING:
toAdd = CertDuplicateCTLContext(pCtlContext);
break;
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
toAdd = CertDuplicateCTLContext(pCtlContext);
if (existing)
CtlContext_CopyProperties(toAdd, existing);
break;
case CERT_STORE_ADD_USE_EXISTING:
if (existing)
CtlContext_CopyProperties(existing, pCtlContext);
break;
default:
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
ret = FALSE;
}
if (toAdd)
{
if (store)
ret = store->ctls.addContext(store, (void *)toAdd,
(void *)existing, (const void **)ppStoreContext);
else if (ppStoreContext)
*ppStoreContext = CertDuplicateCTLContext(toAdd);
CertFreeCTLContext(toAdd);
}
CertFreeCTLContext(existing);
TRACE("returning %d\n", ret);
return ret;
}
BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
{
PCCTL_CONTEXT ctl = CertCreateCTLContext(dwMsgAndCertEncodingType,
pbCtlEncoded, cbCtlEncoded);
BOOL ret;
TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore,
dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
ppCtlContext);
if (ctl)
{
ret = CertAddCTLContextToStore(hCertStore, ctl, dwAddDisposition,
ppCtlContext);
CertFreeCTLContext(ctl);
}
else
ret = FALSE;
return ret;
}
PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT pPrev)
{
WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
PCCTL_CONTEXT ret;
TRACE("(%p, %p)\n", hCertStore, pPrev);
if (!hCertStore)
ret = NULL;
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
ret = NULL;
else
ret = (PCCTL_CONTEXT)hcs->ctls.enumContext(hcs, (void *)pPrev);
return ret;
}
typedef BOOL (*CtlCompareFunc)(PCCTL_CONTEXT pCtlContext, DWORD dwType,
DWORD dwFlags, const void *pvPara);
static BOOL compare_ctl_any(PCCTL_CONTEXT pCtlContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
return TRUE;
}
static BOOL compare_ctl_by_md5_hash(PCCTL_CONTEXT pCtlContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
BOOL ret;
BYTE hash[16];
DWORD size = sizeof(hash);
ret = CertGetCTLContextProperty(pCtlContext, CERT_MD5_HASH_PROP_ID, hash,
&size);
if (ret)
{
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
if (size == pHash->cbData)
ret = !memcmp(pHash->pbData, hash, size);
else
ret = FALSE;
}
return ret;
}
static BOOL compare_ctl_by_sha1_hash(PCCTL_CONTEXT pCtlContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
BOOL ret;
BYTE hash[20];
DWORD size = sizeof(hash);
ret = CertGetCTLContextProperty(pCtlContext, CERT_SHA1_HASH_PROP_ID, hash,
&size);
if (ret)
{
const CRYPT_HASH_BLOB *pHash = (const CRYPT_HASH_BLOB *)pvPara;
if (size == pHash->cbData)
ret = !memcmp(pHash->pbData, hash, size);
else
ret = FALSE;
}
return ret;
}
static BOOL compare_ctl_existing(PCCTL_CONTEXT pCtlContext, DWORD dwType,
DWORD dwFlags, const void *pvPara)
{
BOOL ret;
if (pvPara)
{
PCCTL_CONTEXT ctl = (PCCTL_CONTEXT)pvPara;
if (pCtlContext->cbCtlContext == ctl->cbCtlContext)
{
if (ctl->cbCtlContext)
ret = !memcmp(pCtlContext->pbCtlContext, ctl->pbCtlContext,
ctl->cbCtlContext);
else
ret = TRUE;
}
else
ret = FALSE;
}
else
ret = FALSE;
return ret;
}
PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore,
DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType,
const void *pvFindPara, PCCTL_CONTEXT pPrevCtlContext)
{
PCCTL_CONTEXT ret;
CtlCompareFunc compare;
TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType,
dwFindFlags, dwFindType, pvFindPara, pPrevCtlContext);
switch (dwFindType)
{
case CTL_FIND_ANY:
compare = compare_ctl_any;
break;
case CTL_FIND_SHA1_HASH:
compare = compare_ctl_by_sha1_hash;
break;
case CTL_FIND_MD5_HASH:
compare = compare_ctl_by_md5_hash;
break;
case CTL_FIND_EXISTING:
compare = compare_ctl_existing;
break;
default:
FIXME("find type %08x unimplemented\n", dwFindType);
compare = NULL;
}
if (compare)
{
BOOL matches = FALSE;
ret = pPrevCtlContext;
do {
ret = CertEnumCTLsInStore(hCertStore, ret);
if (ret)
matches = compare(ret, dwFindType, dwFindFlags, pvFindPara);
} while (ret != NULL && !matches);
if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
return ret;
}
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
{
BOOL ret;
TRACE("(%p)\n", pCtlContext);
if (!pCtlContext)
ret = TRUE;
else if (!pCtlContext->hCertStore)
{
ret = TRUE;
CertFreeCTLContext(pCtlContext);
}
else
{
PWINECRYPT_CERTSTORE hcs =
(PWINECRYPT_CERTSTORE)pCtlContext->hCertStore;
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
ret = FALSE;
else
ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext);
CertFreeCTLContext(pCtlContext);
}
return ret;
}
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
{
PCTL_CONTEXT ctl = NULL;
HCRYPTMSG msg;
BOOL ret;
BYTE *content = NULL;
DWORD contentSize = 0, size;
PCTL_INFO ctlInfo = NULL;
TRACE("(%08x, %p, %d)\n", dwMsgAndCertEncodingType, pbCtlEncoded,
cbCtlEncoded);
if (GET_CERT_ENCODING_TYPE(dwMsgAndCertEncodingType) != X509_ASN_ENCODING)
{
SetLastError(E_INVALIDARG);
return NULL;
}
if (!pbCtlEncoded || !cbCtlEncoded)
{
SetLastError(ERROR_INVALID_DATA);
return NULL;
}
msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0,
0, NULL, NULL);
if (!msg)
return NULL;
ret = CryptMsgUpdate(msg, pbCtlEncoded, cbCtlEncoded, TRUE);
if (!ret)
{
SetLastError(ERROR_INVALID_DATA);
goto end;
}
/* Check that it's really a CTL */
ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size);
if (ret)
{
char *innerContent = CryptMemAlloc(size);
if (innerContent)
{
ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0,
innerContent, &size);
if (ret)
{
if (strcmp(innerContent, szOID_CTL))
{
SetLastError(ERROR_INVALID_DATA);
ret = FALSE;
}
}
CryptMemFree(innerContent);
}
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
}
if (!ret)
goto end;
ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &contentSize);
if (!ret)
goto end;
content = CryptMemAlloc(contentSize);
if (content)
{
ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, content,
&contentSize);
if (ret)
{
ret = CryptDecodeObjectEx(dwMsgAndCertEncodingType, PKCS_CTL,
content, contentSize, CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&ctlInfo, &size);
if (ret)
{
ctl = (PCTL_CONTEXT)Context_CreateDataContext(
sizeof(CTL_CONTEXT));
if (ctl)
{
BYTE *data = CryptMemAlloc(cbCtlEncoded);
if (data)
{
memcpy(data, pbCtlEncoded, cbCtlEncoded);
ctl->dwMsgAndCertEncodingType =
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
ctl->pbCtlEncoded = data;
ctl->cbCtlEncoded = cbCtlEncoded;
ctl->pCtlInfo = ctlInfo;
ctl->hCertStore = NULL;
ctl->hCryptMsg = msg;
ctl->pbCtlContext = content;
ctl->cbCtlContext = contentSize;
}
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
}
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
}
}
}
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
end:
if (!ret)
{
CryptMemFree(ctl);
ctl = NULL;
LocalFree(ctlInfo);
CryptMemFree(content);
CryptMsgClose(msg);
}
return (PCCTL_CONTEXT)ctl;
}
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
{
TRACE("(%p)\n", pCtlContext);
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
return pCtlContext;
}
static void CTLDataContext_Free(void *context)
{
PCTL_CONTEXT ctlContext = (PCTL_CONTEXT)context;
CryptMsgClose(ctlContext->hCryptMsg);
CryptMemFree(ctlContext->pbCtlEncoded);
CryptMemFree(ctlContext->pbCtlContext);
LocalFree(ctlContext->pCtlInfo);
}
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
{
TRACE("(%p)\n", pCTLContext);
if (pCTLContext)
Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
CTLDataContext_Free);
return TRUE;
}
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId)
{
PCONTEXT_PROPERTY_LIST properties = Context_GetProperties(
(void *)pCTLContext, sizeof(CTL_CONTEXT));
DWORD ret;
TRACE("(%p, %d)\n", pCTLContext, dwPropId);
if (properties)
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
else
ret = 0;
return ret;
}
static BOOL CTLContext_SetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
DWORD dwFlags, const void *pvData);
static BOOL CTLContext_GetHashProp(PCCTL_CONTEXT context, DWORD dwPropId,
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
DWORD *pcbData)
{
BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
pcbData);
if (ret)
{
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
ret = CTLContext_SetProperty(context, dwPropId, 0, &blob);
}
return ret;
}
static BOOL CTLContext_GetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
void *pvData, DWORD *pcbData)
{
PCONTEXT_PROPERTY_LIST properties =
Context_GetProperties(context, sizeof(CTL_CONTEXT));
BOOL ret;
CRYPT_DATA_BLOB blob;
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
if (properties)
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
else
ret = FALSE;
if (ret)
{
if (!pvData)
*pcbData = blob.cbData;
else if (*pcbData < blob.cbData)
{
SetLastError(ERROR_MORE_DATA);
*pcbData = blob.cbData;
ret = FALSE;
}
else
{
memcpy(pvData, blob.pbData, blob.cbData);
*pcbData = blob.cbData;
}
}
else
{
/* Implicit properties */
switch (dwPropId)
{
case CERT_SHA1_HASH_PROP_ID:
ret = CTLContext_GetHashProp(context, dwPropId, CALG_SHA1,
context->pbCtlEncoded, context->cbCtlEncoded, pvData, pcbData);
break;
case CERT_MD5_HASH_PROP_ID:
ret = CTLContext_GetHashProp(context, dwPropId, CALG_MD5,
context->pbCtlEncoded, context->cbCtlEncoded, pvData, pcbData);
break;
default:
SetLastError(CRYPT_E_NOT_FOUND);
}
}
TRACE("returning %d\n", ret);
return ret;
}
BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, void *pvData, DWORD *pcbData)
{
BOOL ret;
TRACE("(%p, %d, %p, %p)\n", pCTLContext, dwPropId, pvData, pcbData);
switch (dwPropId)
{
case 0:
case CERT_CERT_PROP_ID:
case CERT_CRL_PROP_ID:
case CERT_CTL_PROP_ID:
SetLastError(E_INVALIDARG);
ret = FALSE;
break;
case CERT_ACCESS_STATE_PROP_ID:
if (!pvData)
{
*pcbData = sizeof(DWORD);
ret = TRUE;
}
else if (*pcbData < sizeof(DWORD))
{
SetLastError(ERROR_MORE_DATA);
*pcbData = sizeof(DWORD);
ret = FALSE;
}
else
{
if (pCTLContext->hCertStore)
ret = CertGetStoreProperty(pCTLContext->hCertStore, dwPropId,
pvData, pcbData);
else
*(DWORD *)pvData = 0;
ret = TRUE;
}
break;
default:
ret = CTLContext_GetProperty(pCTLContext, dwPropId, pvData,
pcbData);
}
return ret;
}
static BOOL CTLContext_SetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
DWORD dwFlags, const void *pvData)
{
PCONTEXT_PROPERTY_LIST properties =
Context_GetProperties(context, sizeof(CTL_CONTEXT));
BOOL ret;
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
if (!properties)
ret = FALSE;
else if (!pvData)
{
ContextPropertyList_RemoveProperty(properties, dwPropId);
ret = TRUE;
}
else
{
switch (dwPropId)
{
case CERT_AUTO_ENROLL_PROP_ID:
case CERT_CTL_USAGE_PROP_ID: /* same as CERT_ENHKEY_USAGE_PROP_ID */
case CERT_DESCRIPTION_PROP_ID:
case CERT_FRIENDLY_NAME_PROP_ID:
case CERT_HASH_PROP_ID:
case CERT_KEY_IDENTIFIER_PROP_ID:
case CERT_MD5_HASH_PROP_ID:
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
case CERT_PUBKEY_ALG_PARA_PROP_ID:
case CERT_PVK_FILE_PROP_ID:
case CERT_SIGNATURE_HASH_PROP_ID:
case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_ENROLLMENT_PROP_ID:
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
case CERT_RENEWAL_PROP_ID:
{
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
ret = ContextPropertyList_SetProperty(properties, dwPropId,
blob->pbData, blob->cbData);
break;
}
case CERT_DATE_STAMP_PROP_ID:
ret = ContextPropertyList_SetProperty(properties, dwPropId,
(const BYTE *)pvData, sizeof(FILETIME));
break;
default:
FIXME("%d: stub\n", dwPropId);
ret = FALSE;
}
}
TRACE("returning %d\n", ret);
return ret;
}
BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, DWORD dwFlags, const void *pvData)
{
BOOL ret;
TRACE("(%p, %d, %08x, %p)\n", pCTLContext, dwPropId, dwFlags, pvData);
/* Handle special cases for "read-only"/invalid prop IDs. Windows just
* crashes on most of these, I'll be safer.
*/
switch (dwPropId)
{
case 0:
case CERT_ACCESS_STATE_PROP_ID:
case CERT_CERT_PROP_ID:
case CERT_CRL_PROP_ID:
case CERT_CTL_PROP_ID:
SetLastError(E_INVALIDARG);
return FALSE;
}
ret = CTLContext_SetProperty(pCTLContext, dwPropId, dwFlags, pvData);
TRACE("returning %d\n", ret);
return ret;
}

View file

@ -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
@ -112,6 +112,9 @@ static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
/* Gets the number of length bytes from the given (leading) length byte */
#define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
@ -231,6 +234,8 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
*pcbStructInfo = bytesNeeded;
return ret;
}
@ -1995,13 +2000,18 @@ static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
*pcbStructInfo = bytesNeeded;
blob->cbData = encodedLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
blob->pbData = (LPBYTE)pbEncoded;
else
if (encodedLen)
{
assert(blob->pbData);
memcpy(blob->pbData, pbEncoded, blob->cbData);
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
blob->pbData = (LPBYTE)pbEncoded;
else
{
assert(blob->pbData);
memcpy(blob->pbData, pbEncoded, blob->cbData);
}
}
else
blob->pbData = NULL;
}
if (pcbDecoded)
*pcbDecoded = encodedLen;
@ -2026,6 +2036,207 @@ static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo;
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
usage ? usage->rgpszUsageIdentifier : NULL);
return ret;
}
static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
struct AsnDecodeSequenceItem items[] = {
{ ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
};
BOOL ret = TRUE;
CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
return ret;
}
static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
entries ? entries->rgItems : NULL);
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = FALSE;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
__TRY
{
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
{ ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
{ ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
{ ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
{ 0, offsetof(CTL_INFO, ThisUpdate),
CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
0 },
{ 0, offsetof(CTL_INFO, NextUpdate),
CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
0 },
{ ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
{ ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
offsetof(CTL_INFO, rgExtension), 0 },
};
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
BOOL ret;
struct AsnDecodeSequenceItem items[] = {
{ ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
{ 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
};
PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, capability ? capability->pszObjId : NULL);
TRACE("returning %d\n", ret);
return ret;
}
static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
struct AsnArrayDescriptor arrayDesc = { 0,
CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
PCRYPT_SMIME_CAPABILITIES capabilities =
(PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
BOOL ret;
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
capabilities ? capabilities->rgCapability : NULL);
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = FALSE;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
__TRY
{
DWORD bytesNeeded;
if (!cbEncoded)
SetLastError(CRYPT_E_ASN1_EOD);
else if (pbEncoded[0] != ASN_SEQUENCEOF)
SetLastError(CRYPT_E_ASN1_CORRUPT);
else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
NULL)))
{
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo, bytesNeeded)))
{
PCRYPT_SMIME_CAPABILITIES capabilities;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
capabilities->rgCapability =
(PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
sizeof(CRYPT_SMIME_CAPABILITIES));
ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
&bytesNeeded, NULL);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
TRACE("returning %d\n", ret);
return ret;
}
static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
@ -2285,6 +2496,7 @@ static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
}
else
{
*pcbStructInfo = sizeof(BOOL);
*(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
ret = TRUE;
}
@ -2541,6 +2753,52 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
return ret;
}
static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
struct AsnDecodeSequenceItem items[] = {
{ 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
{ 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
};
CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, descr ? descr->pszAccessMethod : NULL);
}
static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
@ -2761,6 +3019,7 @@ static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
struct PATH_LEN_CONSTRAINT *constraint =
(struct PATH_LEN_CONSTRAINT *)pvStructInfo;
*pcbStructInfo = bytesNeeded;
size = sizeof(constraint->dwPathLenConstraint);
ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
&constraint->dwPathLenConstraint, &size, pcbDecoded);
@ -2962,6 +3221,7 @@ static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
{
CRYPT_DATA_BLOB *blob;
*pcbStructInfo = bytesNeeded;
blob = (CRYPT_DATA_BLOB *)pvStructInfo;
blob->cbData = dataLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
@ -3063,6 +3323,7 @@ static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
{
CRYPT_BIT_BLOB *blob;
*pcbStructInfo = bytesNeeded;
blob = (CRYPT_BIT_BLOB *)pvStructInfo;
blob->cbData = dataLen - 1;
blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
@ -3147,7 +3408,7 @@ static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD size = sizeof(buf);
blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, &buf,
ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
&size, pcbDecoded);
if (ret)
{
@ -3250,6 +3511,7 @@ static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
{
CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = dataLen;
assert(blob->pbData);
if (blob->cbData)
@ -3343,6 +3605,7 @@ static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
{
CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = dataLen;
assert(blob->pbData);
/* remove leading zero byte if it exists */
@ -3838,7 +4101,9 @@ static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
BYTE *nextPtr;
DWORD i;
if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo, bytesNeeded)))
{
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
@ -3913,15 +4178,19 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
sizeof(CERT_ALT_NAME_ENTRY), TRUE,
offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
DWORD nameLen;
if (dataLen)
{
DWORD nameLen;
ret = CRYPT_AsnDecodeArray(&arrayDesc,
pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
0, NULL, NULL, &nameLen, NULL, NULL);
bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen;
/* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
* as the sizeof(struct GenericArray), so don't include it in the
* total bytes needed.
*/
bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
sizeof(CERT_ALT_NAME_INFO);
}
else
bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
@ -3939,12 +4208,13 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
{
CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
*pcbStructInfo = bytesNeeded;
if (dataLen)
{
name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
ret = CRYPT_AsnDecodeArray(&arrayDesc,
pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
0, NULL, &name->u.FullName, pcbStructInfo, NULL,
0, NULL, &name->u.FullName, &nameLen, NULL,
name->u.FullName.rgAltEntry);
}
else
@ -4310,13 +4580,137 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
return ret;
}
static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
CERT_ID *id = (CERT_ID *)pvStructInfo;
BOOL ret = FALSE;
if (*pbEncoded == ASN_SEQUENCEOF)
{
ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
if (ret)
{
if (id)
id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
*pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
sizeof(CERT_ISSUER_SERIAL_NUMBER);
else
*pcbStructInfo = sizeof(CERT_ID);
}
}
else if (*pbEncoded == (ASN_CONTEXT | 0))
{
ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
if (ret)
{
if (id)
id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
*pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
sizeof(CRYPT_DATA_BLOB);
else
*pcbStructInfo = sizeof(CERT_ID);
}
}
else
SetLastError(CRYPT_E_ASN1_BADTAG);
return ret;
}
static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
{ 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
{ ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
{ ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
HashEncryptionAlgorithm.pszObjId), 0 },
{ ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
};
BOOL ret;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = FALSE;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
__TRY
{
ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
if (ret && pvStructInfo)
{
ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, *pcbStructInfo);
if (ret)
{
CMSG_CMS_SIGNER_INFO *info;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
info->SignerId.u.KeyId.pbData = ((BYTE *)info +
sizeof(CMSG_CMS_SIGNER_INFO));
ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
pcbStructInfo, NULL);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
TRACE("returning %d\n", ret);
return ret;
}
static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
struct GenericArray *array = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
@ -4328,7 +4722,7 @@ static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
{
@ -4451,6 +4845,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(X509_AUTHORITY_KEY_ID2):
decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
break;
case LOWORD(X509_AUTHORITY_INFO_ACCESS):
decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
break;
case LOWORD(PKCS_CONTENT_INFO):
decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
break;
@ -4466,6 +4863,12 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(X509_ENHANCED_KEY_USAGE):
decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
break;
case LOWORD(PKCS_CTL):
decodeFunc = CRYPT_AsnDecodeCTL;
break;
case LOWORD(PKCS_SMIME_CAPABILITIES):
decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
break;
case LOWORD(PKCS_ATTRIBUTES):
decodeFunc = CRYPT_AsnDecodePKCSAttributes;
break;
@ -4478,12 +4881,17 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(PKCS7_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
break;
case LOWORD(CMS_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
decodeFunc = CRYPT_AsnDecodeExtensions;
else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
decodeFunc = CRYPT_AsnDecodeUtcTime;
else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
@ -4516,6 +4924,10 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
decodeFunc = CRYPT_AsnDecodeNameConstraints;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
return decodeFunc;
}

View file

@ -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
@ -93,6 +93,12 @@ static BOOL WINAPI CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType,
static BOOL WINAPI CRYPT_AsnEncodeChoiceOfTime(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeEnhancedKeyUsage(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodePKCSAttributes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
BOOL CRYPT_EncodeEnsureSpace(DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded)
@ -346,8 +352,8 @@ static BOOL WINAPI CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType,
/* This has two filetimes in a row, a NotBefore and a NotAfter */
const FILETIME *timePtr = (const FILETIME *)pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ timePtr++, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ timePtr, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ timePtr, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ timePtr + 1, CRYPT_AsnEncodeChoiceOfTime, 0 },
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
@ -578,27 +584,31 @@ static BOOL WINAPI CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType,
if (ret)
dataLen += size;
}
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
if (ret)
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < cCRLEntry; i++)
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
DWORD size = dataLen;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < cCRLEntry; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], pbEncoded,
&size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
@ -731,28 +741,31 @@ static BOOL WINAPI CRYPT_AsnEncodeExtensions(DWORD dwCertEncodingType,
if (ret)
dataLen += size;
}
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
if (ret)
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < exts->cExtension; i++)
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
DWORD size = dataLen;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < exts->cExtension; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeExtension(&exts->rgExtension[i],
pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
ret = CRYPT_AsnEncodeExtension(&exts->rgExtension[i],
pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
@ -1404,6 +1417,286 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTLVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
const DWORD *ver = (const DWORD *)pvStructInfo;
BOOL ret;
/* CTL_V1 is not encoded */
if (*ver == CTL_V1)
{
*pcbEncoded = 0;
ret = TRUE;
}
else
ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER, ver,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
/* Like CRYPT_AsnEncodeAlgorithmId, but encodes parameters as an asn.1 NULL
* if they are empty and the OID is not empty (otherwise omits them.)
*/
static BOOL WINAPI CRYPT_AsnEncodeCTLSubjectAlgorithm(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
const CRYPT_ALGORITHM_IDENTIFIER *algo =
(const CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
BOOL ret;
struct AsnEncodeSequenceItem items[2] = {
{ algo->pszObjId, CRYPT_AsnEncodeOid, 0 },
};
DWORD cItem = 1;
if (algo->pszObjId)
{
static const BYTE asn1Null[] = { ASN_NULL, 0 };
static const CRYPT_DATA_BLOB nullBlob = { sizeof(asn1Null),
(LPBYTE)asn1Null };
if (algo->Parameters.cbData)
items[cItem].pvStructInfo = &algo->Parameters;
else
items[cItem].pvStructInfo = &nullBlob;
items[cItem].encodeFunc = CRYPT_CopyEncodedBlob;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
struct AsnEncodeSequenceItem items[2] = {
{ &entry->SubjectIdentifier, CRYPT_AsnEncodeOctets, 0 },
{ &entry->cAttribute, CRYPT_AsnEncodePKCSAttributes, 0 },
};
BOOL ret;
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
return ret;
}
struct CTLEntries
{
DWORD cEntry;
CTL_ENTRY *rgEntry;
};
static BOOL WINAPI CRYPT_AsnEncodeCTLEntries(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
DWORD bytesNeeded, dataLen, lenBytes, i;
const struct CTLEntries *entries = (const struct CTLEntries *)pvStructInfo;
ret = TRUE;
for (i = 0, dataLen = 0; ret && i < entries->cEntry; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeCTLEntry(&entries->rgEntry[i], NULL, &size);
if (ret)
dataLen += size;
}
if (ret)
{
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < entries->cEntry; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeCTLEntry(&entries->rgEntry[i],
pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTL(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CTL_INFO *info = (const CTL_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[9] = {
{ &info->dwVersion, CRYPT_AsnEncodeCTLVersion, 0 },
{ &info->SubjectUsage, CRYPT_AsnEncodeEnhancedKeyUsage, 0 },
};
struct AsnConstructedItem constructed = { 0 };
DWORD cItem = 2;
if (info->ListIdentifier.cbData)
{
items[cItem].pvStructInfo = &info->ListIdentifier;
items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
cItem++;
}
if (info->SequenceNumber.cbData)
{
items[cItem].pvStructInfo = &info->SequenceNumber;
items[cItem].encodeFunc = CRYPT_AsnEncodeInteger;
cItem++;
}
items[cItem].pvStructInfo = &info->ThisUpdate;
items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
cItem++;
if (info->NextUpdate.dwLowDateTime || info->NextUpdate.dwHighDateTime)
{
items[cItem].pvStructInfo = &info->NextUpdate;
items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
cItem++;
}
items[cItem].pvStructInfo = &info->SubjectAlgorithm;
items[cItem].encodeFunc = CRYPT_AsnEncodeCTLSubjectAlgorithm;
cItem++;
if (info->cCTLEntry)
{
items[cItem].pvStructInfo = &info->cCTLEntry;
items[cItem].encodeFunc = CRYPT_AsnEncodeCTLEntries;
cItem++;
}
if (info->cExtension)
{
constructed.tag = 0;
constructed.pvStructInfo = &info->cExtension;
constructed.encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CRYPT_SMIME_CAPABILITY *capability =
(const CRYPT_SMIME_CAPABILITY *)pvStructInfo;
if (!capability->pszObjId)
SetLastError(E_INVALIDARG);
else
{
struct AsnEncodeSequenceItem items[] = {
{ capability->pszObjId, CRYPT_AsnEncodeOid, 0 },
{ &capability->Parameters, CRYPT_CopyEncodedBlob, 0 },
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeSMIMECapabilities(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
DWORD bytesNeeded, dataLen, lenBytes, i;
const CRYPT_SMIME_CAPABILITIES *capabilities =
(const CRYPT_SMIME_CAPABILITIES *)pvStructInfo;
ret = TRUE;
for (i = 0, dataLen = 0; ret && i < capabilities->cCapability; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeSMIMECapability(dwCertEncodingType, NULL,
&capabilities->rgCapability[i], 0, NULL, NULL, &size);
if (ret)
dataLen += size;
}
if (ret)
{
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < capabilities->cCapability; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeSMIMECapability(dwCertEncodingType,
NULL, &capabilities->rgCapability[i], 0, NULL,
pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodePKCSAttribute(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@ -1561,6 +1854,14 @@ static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value,
return ret;
}
static void CRYPT_FreeSpace(PCRYPT_ENCODE_PARA pEncodePara, LPVOID pv)
{
if (pEncodePara && pEncodePara->pfnFree)
pEncodePara->pfnFree(pv);
else
LocalFree(pv);
}
static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
@ -1602,7 +1903,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value,
}
}
if (!ret && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG))
CryptMemFree(*(BYTE **)pbEncoded);
CRYPT_FreeSpace(pEncodePara, *(BYTE **)pbEncoded);
}
}
return ret;
@ -1656,7 +1957,7 @@ static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value,
}
}
if (!ret && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG))
CryptMemFree(*(BYTE **)pbEncoded);
CRYPT_FreeSpace(pEncodePara, *(BYTE **)pbEncoded);
}
}
return ret;
@ -1703,7 +2004,7 @@ static BOOL CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE *value,
}
}
if (!ret && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG))
CryptMemFree(*(BYTE **)pbEncoded);
CRYPT_FreeSpace(pEncodePara, *(BYTE **)pbEncoded);
}
}
return ret;
@ -2249,6 +2550,83 @@ static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId2(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeAccessDescription(
const CERT_ACCESS_DESCRIPTION *descr, BYTE *pbEncoded, DWORD *pcbEncoded)
{
struct AsnEncodeSequenceItem items[] = {
{ descr->pszAccessMethod, CRYPT_AsnEncodeOid, 0 },
{ &descr->AccessLocation, CRYPT_AsnEncodeAltNameEntry, 0 },
};
if (!descr->pszAccessMethod)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeAuthorityInfoAccess(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
DWORD bytesNeeded, dataLen, lenBytes, i;
const CERT_AUTHORITY_INFO_ACCESS *info =
(const CERT_AUTHORITY_INFO_ACCESS *)pvStructInfo;
ret = TRUE;
for (i = 0, dataLen = 0; ret && i < info->cAccDescr; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeAccessDescription(&info->rgAccDescr[i], NULL,
&size);
if (ret)
dataLen += size;
}
if (ret)
{
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < info->cAccDescr; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeAccessDescription(
&info->rgAccDescr[i], pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeBasicConstraints(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@ -2540,8 +2918,8 @@ static BOOL WINAPI CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType,
__TRY
{
DWORD significantBytes, lenBytes;
BYTE padByte = 0, bytesNeeded;
DWORD significantBytes, lenBytes, bytesNeeded;
BYTE padByte = 0;
BOOL pad = FALSE;
const CRYPT_INTEGER_BLOB *blob =
(const CRYPT_INTEGER_BLOB *)pvStructInfo;
@ -2629,8 +3007,7 @@ static BOOL WINAPI CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType,
__TRY
{
DWORD significantBytes, lenBytes;
BYTE bytesNeeded;
DWORD significantBytes, lenBytes, bytesNeeded;
BOOL pad = FALSE;
const CRYPT_INTEGER_BLOB *blob =
(const CRYPT_INTEGER_BLOB *)pvStructInfo;
@ -3412,7 +3789,96 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType,
return ret;
}
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
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_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
DWORD *pcbData)
{
struct AsnEncodeSequenceItem items[7] = {
@ -3428,9 +3894,9 @@ BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
{
digestAlgorithmsSet.cItems = signedInfo->cSignerInfo;
digestAlgorithmsSet.items = signedInfo->rgSignerInfo;
digestAlgorithmsSet.itemSize = sizeof(CMSG_SIGNER_INFO);
digestAlgorithmsSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
digestAlgorithmsSet.itemOffset =
offsetof(CMSG_SIGNER_INFO, HashAlgorithm);
offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm);
digestAlgorithmsSet.encode = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
items[cItem].pvStructInfo = &digestAlgorithmsSet;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
@ -3473,9 +3939,9 @@ BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
{
signerSet.cItems = signedInfo->cSignerInfo;
signerSet.items = signedInfo->rgSignerInfo;
signerSet.itemSize = sizeof(CMSG_SIGNER_INFO);
signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
signerSet.itemOffset = 0;
signerSet.encode = CRYPT_AsnEncodePKCSSignerInfo;
signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo;
items[cItem].pvStructInfo = &signerSet;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
cItem++;
@ -3576,6 +4042,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(X509_AUTHORITY_KEY_ID2):
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId2;
break;
case LOWORD(X509_AUTHORITY_INFO_ACCESS):
encodeFunc = CRYPT_AsnEncodeAuthorityInfoAccess;
break;
case LOWORD(X509_SEQUENCE_OF_ANY):
encodeFunc = CRYPT_AsnEncodeSequenceOfAny;
break;
@ -3588,6 +4057,12 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(X509_ENHANCED_KEY_USAGE):
encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage;
break;
case LOWORD(PKCS_CTL):
encodeFunc = CRYPT_AsnEncodeCTL;
break;
case LOWORD(PKCS_SMIME_CAPABILITIES):
encodeFunc = CRYPT_AsnEncodeSMIMECapabilities;
break;
case LOWORD(PKCS_ATTRIBUTES):
encodeFunc = CRYPT_AsnEncodePKCSAttributes;
break;
@ -3600,12 +4075,17 @@ 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))
encodeFunc = CRYPT_AsnEncodeExtensions;
else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
encodeFunc = CRYPT_AsnEncodeUtcTime;
else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
encodeFunc = CRYPT_AsnEncodeUtcTime;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
encodeFunc = CRYPT_AsnEncodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
@ -3638,6 +4118,10 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeIssuingDistPoint;
else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
encodeFunc = CRYPT_AsnEncodeNameConstraints;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
encodeFunc = CRYPT_AsnEncodeAuthorityInfoAccess;
else if (!strcmp(lpszStructType, szOID_CTL))
encodeFunc = CRYPT_AsnEncodeCTL;
return encodeFunc;
}
@ -3919,8 +4403,12 @@ static BOOL WINAPI CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv,
pInfo->PublicKey.pbData, pInfo->PublicKey.cbData, 0, pubKey,
&pubKeySize);
if (ret)
{
if(aiKeyAlg)
((BLOBHEADER*)pubKey)->aiKeyAlg = aiKeyAlg;
ret = CryptImportKey(hCryptProv, pubKey, pubKeySize, 0, 0,
phKey);
}
CryptMemFree(pubKey);
}
else

View file

@ -88,6 +88,26 @@ static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
return TRUE;
}
static BOOL WINAPI CRYPT_FileWriteCTL(HCERTSTORE hCertStore,
PCCTL_CONTEXT ctl, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL WINAPI CRYPT_FileDeleteCTL(HCERTSTORE hCertStore,
PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
{
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
TRACE("(%p, %p, %08x)\n", hCertStore, pCtlContext, dwFlags);
store->dirty = TRUE;
return TRUE;
}
static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
{
BOOL ret = TRUE;
@ -187,8 +207,8 @@ static void *fileProvFuncs[] = {
CRYPT_FileDeleteCRL,
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
CRYPT_FileWriteCTL,
CRYPT_FileDeleteCTL,
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
CRYPT_FileControl,
};

View file

@ -0,0 +1,320 @@
/*
* Copyright 2007 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType,
HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE* pbSignedBlob,
DWORD cbSignedBlob)
{
CRYPT_DATA_BLOB blob = { cbSignedBlob, (LPBYTE)pbSignedBlob };
TRACE("(%08x, %ld, %d08x %p, %d)\n", dwMsgAndCertEncodingType, hCryptProv,
dwFlags, pbSignedBlob, cbSignedBlob);
return CertOpenStore(CERT_STORE_PROV_PKCS7, dwMsgAndCertEncodingType,
hCryptProv, dwFlags, &blob);
}
LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
const BYTE *pbSignedBlob, DWORD cbSignedBlob)
{
HCRYPTMSG msg;
LONG count = -1;
TRACE("(%08x, %p, %d)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob);
msg = CryptMsgOpenToDecode(dwMsgEncodingType, 0, 0, 0, NULL, NULL);
if (msg)
{
if (CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE))
{
DWORD size = sizeof(count);
CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &count, &size);
}
CryptMsgClose(msg);
}
return count;
}
static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src,
DWORD len)
{
BOOL ret = TRUE;
if (!pvData)
*pcbData = len;
else if (*pcbData < len)
{
*pcbData = len;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
*pcbData = len;
memcpy(pvData, src, len);
}
return ret;
}
static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
DWORD dwSignerIndex)
{
CERT_INFO *certInfo = NULL;
DWORD size;
if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL,
&size))
{
certInfo = CryptMemAlloc(size);
if (certInfo)
{
if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM,
dwSignerIndex, certInfo, &size))
{
CryptMemFree(certInfo);
certInfo = NULL;
}
}
}
return certInfo;
}
static PCCERT_CONTEXT WINAPI CRYPT_DefaultGetSignerCertificate(void *pvGetArg,
DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore)
{
return CertFindCertificateInStore(hMsgCertStore, dwCertEncodingType, 0,
CERT_FIND_SUBJECT_CERT, pSignerId, NULL);
}
static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_INFO certInfo, HCERTSTORE store)
{
PFN_CRYPT_GET_SIGNER_CERTIFICATE getCert;
if (pVerifyPara->pfnGetSignerCertificate)
getCert = pVerifyPara->pfnGetSignerCertificate;
else
getCert = CRYPT_DefaultGetSignerCertificate;
return getCert(pVerifyPara->pvGetArg,
pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
}
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
{
BOOL ret = FALSE;
DWORD size;
CRYPT_CONTENT_INFO *contentInfo;
HCRYPTMSG msg;
TRACE("(%p, %d, %p, %d, %p, %p, %p)\n",
pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
pbDecoded, pcbDecoded, ppSignerCert);
if (ppSignerCert)
*ppSignerCert = NULL;
if (pcbDecoded)
*pcbDecoded = 0;
if (!pVerifyPara ||
pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
PKCS_7_ASN_ENCODING)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (!CryptDecodeObjectEx(pVerifyPara->dwMsgAndCertEncodingType,
PKCS_CONTENT_INFO, pbSignedBlob, cbSignedBlob,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
(LPBYTE)&contentInfo, &size))
return FALSE;
if (strcmp(contentInfo->pszObjId, szOID_RSA_signedData))
{
LocalFree(contentInfo);
SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE);
return FALSE;
}
msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0,
CMSG_SIGNED, pVerifyPara->hCryptProv, NULL, NULL);
if (msg)
{
ret = CryptMsgUpdate(msg, contentInfo->Content.pbData,
contentInfo->Content.cbData, TRUE);
if (ret && pcbDecoded)
ret = CRYPT_CopyParam(pbDecoded, pcbDecoded,
contentInfo->Content.pbData, contentInfo->Content.cbData);
if (ret)
{
CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
dwSignerIndex);
ret = FALSE;
if (certInfo)
{
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
pVerifyPara->dwMsgAndCertEncodingType,
pVerifyPara->hCryptProv, 0, msg);
if (store)
{
PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
msg, pVerifyPara, certInfo, store);
if (cert)
{
ret = CryptMsgControl(msg, 0,
CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
if (ret && ppSignerCert)
*ppSignerCert = cert;
else
CertFreeCertificateContext(cert);
}
CertCloseStore(store, 0);
}
}
CryptMemFree(certInfo);
}
CryptMsgClose(msg);
}
LocalFree(contentInfo);
TRACE("returning %d\n", ret);
return ret;
}
BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara,
BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[],
DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
DWORD i, flags;
BOOL ret = FALSE;
HCRYPTMSG msg;
CMSG_HASHED_ENCODE_INFO info;
TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash,
cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob,
pbComputedHash, pcbComputedHash);
if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
{
SetLastError(E_INVALIDARG);
return FALSE;
}
/* Native seems to ignore any encoding type other than the expected
* PKCS_7_ASN_ENCODING
*/
if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
PKCS_7_ASN_ENCODING)
return TRUE;
/* Native also seems to do nothing if the output parameter isn't given */
if (!pcbHashedBlob)
return TRUE;
flags = fDetachedHash ? CMSG_DETACHED_FLAG : 0;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.hCryptProv = pHashPara->hCryptProv;
memcpy(&info.HashAlgorithm, &pHashPara->HashAlgorithm,
sizeof(info.HashAlgorithm));
info.pvHashAuxInfo = pHashPara->pvHashAuxInfo;
msg = CryptMsgOpenToEncode(pHashPara->dwMsgEncodingType, flags, CMSG_HASHED,
&info, NULL, NULL);
if (msg)
{
for (i = 0, ret = TRUE; ret && i < cToBeHashed; i++)
ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i],
i == cToBeHashed - 1 ? TRUE : FALSE);
if (ret)
{
ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbHashedBlob,
pcbHashedBlob);
if (ret && pcbComputedHash)
ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
pbComputedHash, pcbComputedHash);
}
CryptMsgClose(msg);
}
return ret;
}
BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed,
const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash,
DWORD *pcbComputedHash)
{
HCRYPTMSG msg;
BOOL ret = FALSE;
TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob,
cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed,
pbComputedHash, pcbComputedHash);
if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
{
SetLastError(E_INVALIDARG);
return FALSE;
}
if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
PKCS_7_ASN_ENCODING)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, CMSG_DETACHED_FLAG,
0, pHashPara->hCryptProv, NULL, NULL);
if (msg)
{
DWORD i;
ret = CryptMsgUpdate(msg, pbDetachedHashBlob, cbDetachedHashBlob, TRUE);
if (ret)
{
if (cToBeHashed)
{
for (i = 0; ret && i < cToBeHashed; i++)
{
ret = CryptMsgUpdate(msg, rgpbToBeHashed[i],
rgcbToBeHashed[i], i == cToBeHashed - 1 ? TRUE : FALSE);
}
}
else
ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
}
if (ret)
{
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
if (ret && pcbComputedHash)
ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
pbComputedHash, pcbComputedHash);
}
CryptMsgClose(msg);
}
return ret;
}

File diff suppressed because it is too large Load diff

View file

@ -21,7 +21,7 @@
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "imagehlp.h"
#include "mssip.h"
#include "crypt32_private.h"
#include "wine/debug.h"
@ -400,8 +400,11 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
HANDLE file;
GUID subject;
BOOL ret = FALSE;
TRACE("%s\n", debugstr_w((LPCWSTR)pvObject));
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
{
FIXME("don't know what to do for type %d embedded signed messages\n",
@ -413,28 +416,53 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file != INVALID_HANDLE_VALUE)
{
DWORD len;
ret = ImageGetCertificateData(file, 0, NULL, &len);
ret = CryptSIPRetrieveSubjectGuid((LPCWSTR)pvObject, file, &subject);
if (ret)
{
WIN_CERTIFICATE *winCert = HeapAlloc(GetProcessHeap(), 0, len);
SIP_DISPATCH_INFO sip;
if (winCert)
memset(&sip, 0, sizeof(sip));
sip.cbSize = sizeof(sip);
ret = CryptSIPLoad(&subject, 0, &sip);
if (ret)
{
ret = ImageGetCertificateData(file, 0, winCert, &len);
SIP_SUBJECTINFO subjectInfo;
CERT_BLOB blob;
DWORD encodingType;
memset(&subjectInfo, 0, sizeof(subjectInfo));
subjectInfo.cbSize = sizeof(subjectInfo);
subjectInfo.pgSubjectType = &subject;
subjectInfo.hFile = file;
subjectInfo.pwsFileName = (LPCWSTR)pvObject;
ret = sip.pfGet(&subjectInfo, &encodingType, 0, &blob.cbData,
NULL);
if (ret)
{
CERT_BLOB blob = { winCert->dwLength,
winCert->bCertificate };
ret = CRYPT_QueryMessageObject(CERT_QUERY_OBJECT_BLOB,
&blob, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
pdwMsgAndCertEncodingType, NULL, phCertStore, phMsg);
if (ret && pdwContentType)
*pdwContentType = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
blob.pbData = CryptMemAlloc(blob.cbData);
if (blob.pbData)
{
ret = sip.pfGet(&subjectInfo, &encodingType, 0,
&blob.cbData, blob.pbData);
if (ret)
{
ret = CRYPT_QueryMessageObject(
CERT_QUERY_OBJECT_BLOB, &blob,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
pdwMsgAndCertEncodingType, NULL, phCertStore,
phMsg);
if (ret && pdwContentType)
*pdwContentType =
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
}
CryptMemFree(blob.pbData);
}
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
}
HeapFree(GetProcessHeap(), 0, winCert);
}
}
CloseHandle(file);

View file

@ -36,6 +36,8 @@ typedef struct _WINE_PROVIDERSTORE
PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert;
PFN_CERT_STORE_PROV_WRITE_CRL provWriteCrl;
PFN_CERT_STORE_PROV_DELETE_CRL provDeleteCrl;
PFN_CERT_STORE_PROV_WRITE_CTL provWriteCtl;
PFN_CERT_STORE_PROV_DELETE_CTL provDeleteCtl;
PFN_CERT_STORE_PROV_CONTROL provControl;
} WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
@ -178,6 +180,73 @@ static BOOL CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store, void *crl)
return ret;
}
static BOOL CRYPT_ProvAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
void *toReplace, const void **ppStoreContext)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret;
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
if (toReplace)
ret = ps->memStore->ctls.addContext(ps->memStore, ctl, toReplace,
ppStoreContext);
else
{
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
{
SetLastError(ERROR_ACCESS_DENIED);
ret = FALSE;
}
else
{
ret = TRUE;
if (ps->provWriteCtl)
ret = ps->provWriteCtl(ps->hStoreProv, (PCCTL_CONTEXT)ctl,
CERT_STORE_PROV_WRITE_ADD_FLAG);
if (ret)
ret = ps->memStore->ctls.addContext(ps->memStore, ctl, NULL,
ppStoreContext);
}
}
/* dirty trick: replace the returned context's hCertStore with
* store.
*/
if (ppStoreContext)
(*(PCTL_CONTEXT *)ppStoreContext)->hCertStore = store;
return ret;
}
static void *CRYPT_ProvEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
void *ret;
ret = ps->memStore->ctls.enumContext(ps->memStore, pPrev);
if (ret)
{
/* same dirty trick: replace the returned context's hCertStore with
* store.
*/
((PCTL_CONTEXT)ret)->hCertStore = store;
}
return ret;
}
static BOOL CRYPT_ProvDeleteCTL(PWINECRYPT_CERTSTORE store, void *ctl)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret = TRUE;
TRACE("(%p, %p)\n", store, ctl);
if (ps->provDeleteCtl)
ret = ps->provDeleteCtl(ps->hStoreProv, ctl, 0);
if (ret)
ret = ps->memStore->ctls.deleteContext(ps->memStore, ctl);
return ret;
}
static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
@ -217,6 +286,9 @@ PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
ret->hdr.crls.addContext = CRYPT_ProvAddCRL;
ret->hdr.crls.enumContext = CRYPT_ProvEnumCRL;
ret->hdr.crls.deleteContext = CRYPT_ProvDeleteCRL;
ret->hdr.ctls.addContext = CRYPT_ProvAddCTL;
ret->hdr.ctls.enumContext = CRYPT_ProvEnumCTL;
ret->hdr.ctls.deleteContext = CRYPT_ProvDeleteCTL;
ret->hdr.control = CRYPT_ProvControl;
if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
ret->provCloseStore =
@ -240,13 +312,25 @@ PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
ret->provWriteCrl = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_WRITE_CRL_FUNC];
else
ret->provWriteCert = NULL;
ret->provWriteCrl = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_DELETE_CRL_FUNC)
ret->provDeleteCrl = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_DELETE_CRL_FUNC];
else
ret->provDeleteCert = NULL;
ret->provDeleteCrl = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_WRITE_CTL_FUNC)
ret->provWriteCtl = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_WRITE_CTL_FUNC];
else
ret->provWriteCtl = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_DELETE_CTL_FUNC)
ret->provDeleteCtl = pProvInfo->rgpvStoreProvFunc[
CERT_STORE_PROV_DELETE_CTL_FUNC];
else
ret->provDeleteCtl = NULL;
if (pProvInfo->cStoreProvFunc >
CERT_STORE_PROV_CONTROL_FUNC)
ret->provControl = pProvInfo->rgpvStoreProvFunc[

View file

@ -43,6 +43,7 @@ typedef struct _WINE_REGSTOREINFO
CRITICAL_SECTION cs;
struct list certsToDelete;
struct list crlsToDelete;
struct list ctlsToDelete;
} WINE_REGSTOREINFO, *PWINE_REGSTOREINFO;
static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash)
@ -251,7 +252,7 @@ static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
pCRLInterface, pCTLInterface };
struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete,
NULL };
&store->ctlsToDelete };
BOOL ret = TRUE;
DWORD i;
@ -430,6 +431,27 @@ static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
pCRLInterface);
}
static BOOL WINAPI CRYPT_RegWriteCTL(HCERTSTORE hCertStore,
PCCTL_CONTEXT ctl, DWORD dwFlags)
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags);
return CRYPT_RegWriteContext(store, ctl, dwFlags);
}
static BOOL WINAPI CRYPT_RegDeleteCTL(HCERTSTORE hCertStore,
PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
{
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
TRACE("(%p, %p, %08x)\n", store, pCtlContext, dwFlags);
return CRYPT_RegDeleteContext(store, &store->ctlsToDelete, pCtlContext,
pCTLInterface);
}
static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
DWORD dwCtrlType, void const *pvCtrlPara)
{
@ -475,8 +497,8 @@ static void *regProvFuncs[] = {
CRYPT_RegDeleteCRL,
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
CRYPT_RegWriteCTL,
CRYPT_RegDeleteCTL,
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
CRYPT_RegControl,
};
@ -529,6 +551,7 @@ PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
list_init(&regInfo->certsToDelete);
list_init(&regInfo->crlsToDelete);
list_init(&regInfo->ctlsToDelete);
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
regInfo->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);

View file

@ -434,20 +434,279 @@ static const char * const CRYPT_knownLocations[] = {
"/etc/pki/tls/certs/ca-bundle.crt",
};
/* Reads certificates from the list of known locations. Stops when any
* location contains any certificates, to prevent spending unnecessary time
static const BYTE authenticode[] = {
0x30,0x82,0x03,0xd6,0x30,0x82,0x02,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,
0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0d,
0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,0x32,0x30,
0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,0x74,
0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
0x79,0x30,0x1e,0x17,0x0d,0x39,0x35,0x30,0x31,0x30,0x31,0x30,0x38,0x30,0x30,0x30,
0x31,0x5a,0x17,0x0d,0x39,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,
0x5a,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
0x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
0x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,
0x82,0x01,0x01,0x00,0xdf,0x08,0xba,0xe3,0x3f,0x6e,0x64,0x9b,0xf5,0x89,0xaf,0x28,
0x96,0x4a,0x07,0x8f,0x1b,0x2e,0x8b,0x3e,0x1d,0xfc,0xb8,0x80,0x69,0xa3,0xa1,0xce,
0xdb,0xdf,0xb0,0x8e,0x6c,0x89,0x76,0x29,0x4f,0xca,0x60,0x35,0x39,0xad,0x72,0x32,
0xe0,0x0b,0xae,0x29,0x3d,0x4c,0x16,0xd9,0x4b,0x3c,0x9d,0xda,0xc5,0xd3,0xd1,0x09,
0xc9,0x2c,0x6f,0xa6,0xc2,0x60,0x53,0x45,0xdd,0x4b,0xd1,0x55,0xcd,0x03,0x1c,0xd2,
0x59,0x56,0x24,0xf3,0xe5,0x78,0xd8,0x07,0xcc,0xd8,0xb3,0x1f,0x90,0x3f,0xc0,0x1a,
0x71,0x50,0x1d,0x2d,0xa7,0x12,0x08,0x6d,0x7c,0xb0,0x86,0x6c,0xc7,0xba,0x85,0x32,
0x07,0xe1,0x61,0x6f,0xaf,0x03,0xc5,0x6d,0xe5,0xd6,0xa1,0x8f,0x36,0xf6,0xc1,0x0b,
0xd1,0x3e,0x69,0x97,0x48,0x72,0xc9,0x7f,0xa4,0xc8,0xc2,0x4a,0x4c,0x7e,0xa1,0xd1,
0x94,0xa6,0xd7,0xdc,0xeb,0x05,0x46,0x2e,0xb8,0x18,0xb4,0x57,0x1d,0x86,0x49,0xdb,
0x69,0x4a,0x2c,0x21,0xf5,0x5e,0x0f,0x54,0x2d,0x5a,0x43,0xa9,0x7a,0x7e,0x6a,0x8e,
0x50,0x4d,0x25,0x57,0xa1,0xbf,0x1b,0x15,0x05,0x43,0x7b,0x2c,0x05,0x8d,0xbd,0x3d,
0x03,0x8c,0x93,0x22,0x7d,0x63,0xea,0x0a,0x57,0x05,0x06,0x0a,0xdb,0x61,0x98,0x65,
0x2d,0x47,0x49,0xa8,0xe7,0xe6,0x56,0x75,0x5c,0xb8,0x64,0x08,0x63,0xa9,0x30,0x40,
0x66,0xb2,0xf9,0xb6,0xe3,0x34,0xe8,0x67,0x30,0xe1,0x43,0x0b,0x87,0xff,0xc9,0xbe,
0x72,0x10,0x5e,0x23,0xf0,0x9b,0xa7,0x48,0x65,0xbf,0x09,0x88,0x7b,0xcd,0x72,0xbc,
0x2e,0x79,0x9b,0x7b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xba,0x30,0x81,0xb7,0x30,
0x0d,0x06,0x03,0x55,0x1d,0x0a,0x04,0x06,0x30,0x04,0x03,0x02,0x07,0x80,0x30,0x32,
0x06,0x03,0x55,0x04,0x03,0x04,0x2b,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,
0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,
0x74,0x79,0x30,0x72,0x06,0x03,0x55,0x1d,0x01,0x04,0x6b,0x30,0x69,0x80,0x10,0x1a,
0x1b,0xe7,0x5b,0x9f,0xfd,0x8c,0x2a,0xc3,0x39,0xae,0x0c,0x62,0x2e,0x53,0x32,0xa1,
0x52,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
0x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
0x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
0x69,0x74,0x79,0x82,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2d,0xc9,0xe2,0xf6,0x12,0x9e,
0x5d,0x56,0x67,0xfa,0xfa,0x4b,0x9a,0x7e,0xdc,0x29,0x56,0x5c,0x80,0x14,0x02,0x28,
0x85,0x6e,0x26,0xf3,0xcd,0x58,0xda,0x50,0x80,0xc5,0xf8,0x19,0xb3,0xa6,0x7c,0xe2,
0x9d,0x6b,0x5f,0x3b,0x8f,0x22,0x74,0xe6,0x18,0x04,0xfc,0x47,0x40,0xd8,0x7a,0x3f,
0x30,0x66,0xf0,0x12,0xa4,0xd1,0xeb,0x1d,0xe7,0xb6,0xf4,0x98,0xab,0x53,0x22,0x86,
0x51,0x58,0xee,0x23,0x09,0x76,0xe4,0x1d,0x45,0x5c,0x4b,0xff,0x4c,0xe3,0x02,0x50,
0x01,0x13,0xcc,0x41,0xa4,0x52,0x97,0xd4,0x86,0xd5,0xc4,0xfe,0x83,0x83,0x65,0x7d,
0xea,0xbe,0xa2,0x68,0x3b,0xc1,0xb1,0x29,0x98,0xbf,0xa2,0xa5,0xfc,0x9d,0xd3,0x84,
0xee,0x70,0x17,0x50,0xf3,0x0b,0xfa,0x3c,0xef,0xa9,0x27,0x8b,0x91,0xb4,0x48,0xc8,
0x45,0xa0,0xe1,0x01,0x42,0x4b,0x44,0x76,0x04,0x1c,0xc2,0x19,0xa2,0x8e,0x6b,0x20,
0x98,0xc4,0xdd,0x02,0xac,0xb4,0xd2,0xa2,0x0e,0x8d,0x5d,0xb9,0x36,0x8e,0x4a,0x1b,
0x5d,0x6c,0x1a,0xe2,0xcb,0x00,0x7f,0x10,0xf4,0xb2,0x95,0xef,0xe3,0xe8,0xff,0xa1,
0x73,0x58,0xa9,0x75,0x2c,0xa2,0x49,0x95,0x85,0xfe,0xcc,0xda,0x44,0x8a,0xc2,0x12,
0x44,0xd2,0x44,0xc8,0xa5,0xa2,0x1f,0xa9,0x5a,0x8e,0x56,0xc2,0xc3,0x7b,0xcf,0x42,
0x60,0xdc,0x82,0x1f,0xfb,0xce,0x74,0x06,0x7e,0xd6,0xf1,0xac,0x19,0x6a,0x4f,0x74,
0x5c,0xc5,0x15,0x66,0x31,0x6c,0xc1,0x62,0x71,0x91,0x0f,0x59,0x5b,0x7d,0x2a,0x82,
0x1a,0xdf,0xb1,0xb4,0xd8,0x1d,0x37,0xde,0x0d,0x0f };
static const BYTE rootauthority[] = {
0x30,0x82,0x04,0x12,0x30,0x82,0x02,0xfa,0xa0,0x03,0x02,0x01,0x02,0x02,0x0f,0x00,
0xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,0xdf,0x40,0x30,0x0d,
0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x70,0x31,
0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,0x72,0x69,
0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,0x69,0x63,
0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,0x30,0x1c,
0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,0x30,0x1f,
0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
0x1e,0x17,0x0d,0x39,0x37,0x30,0x31,0x31,0x30,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,
0x17,0x0d,0x32,0x30,0x31,0x32,0x33,0x31,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,0x30,
0x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
0x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
0x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,
0x01,0x00,0xa9,0x02,0xbd,0xc1,0x70,0xe6,0x3b,0xf2,0x4e,0x1b,0x28,0x9f,0x97,0x78,
0x5e,0x30,0xea,0xa2,0xa9,0x8d,0x25,0x5f,0xf8,0xfe,0x95,0x4c,0xa3,0xb7,0xfe,0x9d,
0xa2,0x20,0x3e,0x7c,0x51,0xa2,0x9b,0xa2,0x8f,0x60,0x32,0x6b,0xd1,0x42,0x64,0x79,
0xee,0xac,0x76,0xc9,0x54,0xda,0xf2,0xeb,0x9c,0x86,0x1c,0x8f,0x9f,0x84,0x66,0xb3,
0xc5,0x6b,0x7a,0x62,0x23,0xd6,0x1d,0x3c,0xde,0x0f,0x01,0x92,0xe8,0x96,0xc4,0xbf,
0x2d,0x66,0x9a,0x9a,0x68,0x26,0x99,0xd0,0x3a,0x2c,0xbf,0x0c,0xb5,0x58,0x26,0xc1,
0x46,0xe7,0x0a,0x3e,0x38,0x96,0x2c,0xa9,0x28,0x39,0xa8,0xec,0x49,0x83,0x42,0xe3,
0x84,0x0f,0xbb,0x9a,0x6c,0x55,0x61,0xac,0x82,0x7c,0xa1,0x60,0x2d,0x77,0x4c,0xe9,
0x99,0xb4,0x64,0x3b,0x9a,0x50,0x1c,0x31,0x08,0x24,0x14,0x9f,0xa9,0xe7,0x91,0x2b,
0x18,0xe6,0x3d,0x98,0x63,0x14,0x60,0x58,0x05,0x65,0x9f,0x1d,0x37,0x52,0x87,0xf7,
0xa7,0xef,0x94,0x02,0xc6,0x1b,0xd3,0xbf,0x55,0x45,0xb3,0x89,0x80,0xbf,0x3a,0xec,
0x54,0x94,0x4e,0xae,0xfd,0xa7,0x7a,0x6d,0x74,0x4e,0xaf,0x18,0xcc,0x96,0x09,0x28,
0x21,0x00,0x57,0x90,0x60,0x69,0x37,0xbb,0x4b,0x12,0x07,0x3c,0x56,0xff,0x5b,0xfb,
0xa4,0x66,0x0a,0x08,0xa6,0xd2,0x81,0x56,0x57,0xef,0xb6,0x3b,0x5e,0x16,0x81,0x77,
0x04,0xda,0xf6,0xbe,0xae,0x80,0x95,0xfe,0xb0,0xcd,0x7f,0xd6,0xa7,0x1a,0x72,0x5c,
0x3c,0xca,0xbc,0xf0,0x08,0xa3,0x22,0x30,0xb3,0x06,0x85,0xc9,0xb3,0x20,0x77,0x13,
0x85,0xdf,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xa8,0x30,0x81,0xa5,0x30,0x81,0xa2,
0x06,0x03,0x55,0x1d,0x01,0x04,0x81,0x9a,0x30,0x81,0x97,0x80,0x10,0x5b,0xd0,0x70,
0xef,0x69,0x72,0x9e,0x23,0x51,0x7e,0x14,0xb2,0x4d,0x8e,0xff,0xcb,0xa1,0x72,0x30,
0x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
0x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
0x79,0x82,0x0f,0x00,0xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,
0xdf,0x40,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,
0x00,0x03,0x82,0x01,0x01,0x00,0x95,0xe8,0x0b,0xc0,0x8d,0xf3,0x97,0x18,0x35,0xed,
0xb8,0x01,0x24,0xd8,0x77,0x11,0xf3,0x5c,0x60,0x32,0x9f,0x9e,0x0b,0xcb,0x3e,0x05,
0x91,0x88,0x8f,0xc9,0x3a,0xe6,0x21,0xf2,0xf0,0x57,0x93,0x2c,0xb5,0xa0,0x47,0xc8,
0x62,0xef,0xfc,0xd7,0xcc,0x3b,0x3b,0x5a,0xa9,0x36,0x54,0x69,0xfe,0x24,0x6d,0x3f,
0xc9,0xcc,0xaa,0xde,0x05,0x7c,0xdd,0x31,0x8d,0x3d,0x9f,0x10,0x70,0x6a,0xbb,0xfe,
0x12,0x4f,0x18,0x69,0xc0,0xfc,0xd0,0x43,0xe3,0x11,0x5a,0x20,0x4f,0xea,0x62,0x7b,
0xaf,0xaa,0x19,0xc8,0x2b,0x37,0x25,0x2d,0xbe,0x65,0xa1,0x12,0x8a,0x25,0x0f,0x63,
0xa3,0xf7,0x54,0x1c,0xf9,0x21,0xc9,0xd6,0x15,0xf3,0x52,0xac,0x6e,0x43,0x32,0x07,
0xfd,0x82,0x17,0xf8,0xe5,0x67,0x6c,0x0d,0x51,0xf6,0xbd,0xf1,0x52,0xc7,0xbd,0xe7,
0xc4,0x30,0xfc,0x20,0x31,0x09,0x88,0x1d,0x95,0x29,0x1a,0x4d,0xd5,0x1d,0x02,0xa5,
0xf1,0x80,0xe0,0x03,0xb4,0x5b,0xf4,0xb1,0xdd,0xc8,0x57,0xee,0x65,0x49,0xc7,0x52,
0x54,0xb6,0xb4,0x03,0x28,0x12,0xff,0x90,0xd6,0xf0,0x08,0x8f,0x7e,0xb8,0x97,0xc5,
0xab,0x37,0x2c,0xe4,0x7a,0xe4,0xa8,0x77,0xe3,0x76,0xa0,0x00,0xd0,0x6a,0x3f,0xc1,
0xd2,0x36,0x8a,0xe0,0x41,0x12,0xa8,0x35,0x6a,0x1b,0x6a,0xdb,0x35,0xe1,0xd4,0x1c,
0x04,0xe4,0xa8,0x45,0x04,0xc8,0x5a,0x33,0x38,0x6e,0x4d,0x1c,0x0d,0x62,0xb7,0x0a,
0xa2,0x8c,0xd3,0xd5,0x54,0x3f,0x46,0xcd,0x1c,0x55,0xa6,0x70,0xdb,0x12,0x3a,0x87,
0x93,0x75,0x9f,0xa7,0xd2,0xa0 };
static const BYTE rootcertauthority[] = {
0x30,0x82,0x05,0x99,0x30,0x82,0x03,0x81,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x79,
0xad,0x16,0xa1,0x4a,0xa0,0xa5,0xad,0x4c,0x73,0x58,0xf4,0x07,0x13,0x2e,0x65,0x30,
0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x5f,
0x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,0x19,
0x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,
0xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,0x6f,
0x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,
0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
0x1e,0x17,0x0d,0x30,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x31,0x39,0x32,0x32,0x5a,
0x17,0x0d,0x32,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x32,0x38,0x31,0x33,0x5a,0x30,
0x5f,0x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,
0x19,0x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,
0x93,0xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
0x74,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,
0x6f,0x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,
0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,
0x30,0x82,0x02,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
0x01,0x05,0x00,0x03,0x82,0x02,0x0f,0x00,0x30,0x82,0x02,0x0a,0x02,0x82,0x02,0x01,
0x00,0xf3,0x5d,0xfa,0x80,0x67,0xd4,0x5a,0xa7,0xa9,0x0c,0x2c,0x90,0x20,0xd0,0x35,
0x08,0x3c,0x75,0x84,0xcd,0xb7,0x07,0x89,0x9c,0x89,0xda,0xde,0xce,0xc3,0x60,0xfa,
0x91,0x68,0x5a,0x9e,0x94,0x71,0x29,0x18,0x76,0x7c,0xc2,0xe0,0xc8,0x25,0x76,0x94,
0x0e,0x58,0xfa,0x04,0x34,0x36,0xe6,0xdf,0xaf,0xf7,0x80,0xba,0xe9,0x58,0x0b,0x2b,
0x93,0xe5,0x9d,0x05,0xe3,0x77,0x22,0x91,0xf7,0x34,0x64,0x3c,0x22,0x91,0x1d,0x5e,
0xe1,0x09,0x90,0xbc,0x14,0xfe,0xfc,0x75,0x58,0x19,0xe1,0x79,0xb7,0x07,0x92,0xa3,
0xae,0x88,0x59,0x08,0xd8,0x9f,0x07,0xca,0x03,0x58,0xfc,0x68,0x29,0x6d,0x32,0xd7,
0xd2,0xa8,0xcb,0x4b,0xfc,0xe1,0x0b,0x48,0x32,0x4f,0xe6,0xeb,0xb8,0xad,0x4f,0xe4,
0x5c,0x6f,0x13,0x94,0x99,0xdb,0x95,0xd5,0x75,0xdb,0xa8,0x1a,0xb7,0x94,0x91,0xb4,
0x77,0x5b,0xf5,0x48,0x0c,0x8f,0x6a,0x79,0x7d,0x14,0x70,0x04,0x7d,0x6d,0xaf,0x90,
0xf5,0xda,0x70,0xd8,0x47,0xb7,0xbf,0x9b,0x2f,0x6c,0xe7,0x05,0xb7,0xe1,0x11,0x60,
0xac,0x79,0x91,0x14,0x7c,0xc5,0xd6,0xa6,0xe4,0xe1,0x7e,0xd5,0xc3,0x7e,0xe5,0x92,
0xd2,0x3c,0x00,0xb5,0x36,0x82,0xde,0x79,0xe1,0x6d,0xf3,0xb5,0x6e,0xf8,0x9f,0x33,
0xc9,0xcb,0x52,0x7d,0x73,0x98,0x36,0xdb,0x8b,0xa1,0x6b,0xa2,0x95,0x97,0x9b,0xa3,
0xde,0xc2,0x4d,0x26,0xff,0x06,0x96,0x67,0x25,0x06,0xc8,0xe7,0xac,0xe4,0xee,0x12,
0x33,0x95,0x31,0x99,0xc8,0x35,0x08,0x4e,0x34,0xca,0x79,0x53,0xd5,0xb5,0xbe,0x63,
0x32,0x59,0x40,0x36,0xc0,0xa5,0x4e,0x04,0x4d,0x3d,0xdb,0x5b,0x07,0x33,0xe4,0x58,
0xbf,0xef,0x3f,0x53,0x64,0xd8,0x42,0x59,0x35,0x57,0xfd,0x0f,0x45,0x7c,0x24,0x04,
0x4d,0x9e,0xd6,0x38,0x74,0x11,0x97,0x22,0x90,0xce,0x68,0x44,0x74,0x92,0x6f,0xd5,
0x4b,0x6f,0xb0,0x86,0xe3,0xc7,0x36,0x42,0xa0,0xd0,0xfc,0xc1,0xc0,0x5a,0xf9,0xa3,
0x61,0xb9,0x30,0x47,0x71,0x96,0x0a,0x16,0xb0,0x91,0xc0,0x42,0x95,0xef,0x10,0x7f,
0x28,0x6a,0xe3,0x2a,0x1f,0xb1,0xe4,0xcd,0x03,0x3f,0x77,0x71,0x04,0xc7,0x20,0xfc,
0x49,0x0f,0x1d,0x45,0x88,0xa4,0xd7,0xcb,0x7e,0x88,0xad,0x8e,0x2d,0xec,0x45,0xdb,
0xc4,0x51,0x04,0xc9,0x2a,0xfc,0xec,0x86,0x9e,0x9a,0x11,0x97,0x5b,0xde,0xce,0x53,
0x88,0xe6,0xe2,0xb7,0xfd,0xac,0x95,0xc2,0x28,0x40,0xdb,0xef,0x04,0x90,0xdf,0x81,
0x33,0x39,0xd9,0xb2,0x45,0xa5,0x23,0x87,0x06,0xa5,0x55,0x89,0x31,0xbb,0x06,0x2d,
0x60,0x0e,0x41,0x18,0x7d,0x1f,0x2e,0xb5,0x97,0xcb,0x11,0xeb,0x15,0xd5,0x24,0xa5,
0x94,0xef,0x15,0x14,0x89,0xfd,0x4b,0x73,0xfa,0x32,0x5b,0xfc,0xd1,0x33,0x00,0xf9,
0x59,0x62,0x70,0x07,0x32,0xea,0x2e,0xab,0x40,0x2d,0x7b,0xca,0xdd,0x21,0x67,0x1b,
0x30,0x99,0x8f,0x16,0xaa,0x23,0xa8,0x41,0xd1,0xb0,0x6e,0x11,0x9b,0x36,0xc4,0xde,
0x40,0x74,0x9c,0xe1,0x58,0x65,0xc1,0x60,0x1e,0x7a,0x5b,0x38,0xc8,0x8f,0xbb,0x04,
0x26,0x7c,0xd4,0x16,0x40,0xe5,0xb6,0x6b,0x6c,0xaa,0x86,0xfd,0x00,0xbf,0xce,0xc1,
0x35,0x02,0x03,0x01,0x00,0x01,0xa3,0x51,0x30,0x4f,0x30,0x0b,0x06,0x03,0x55,0x1d,
0x0f,0x04,0x04,0x03,0x02,0x01,0xc6,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,
0x16,0x04,0x14,0x0e,0xac,0x82,0x60,0x40,0x56,0x27,0x97,0xe5,0x25,0x13,0xfc,0x2a,
0xe1,0x0a,0x53,0x95,0x59,0xe4,0xa4,0x30,0x10,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,
0x82,0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0xc5,0x11,0x4d,
0x03,0x3a,0x60,0xdd,0x5d,0x52,0x11,0x77,0x8f,0xb2,0xbb,0x36,0xc8,0xb2,0x05,0xbf,
0xb4,0xb7,0xa8,0xd8,0x20,0x9d,0x5c,0x13,0x03,0xb6,0x1c,0x22,0xfa,0x06,0x13,0x35,
0xb6,0xc8,0x63,0xd4,0x9a,0x47,0x6f,0x26,0x57,0xd2,0x55,0xf1,0x04,0xb1,0x26,0x5f,
0xd6,0xa9,0x50,0x68,0xa0,0xbc,0xd2,0xb8,0x6e,0xcc,0xc3,0xe9,0xac,0xdf,0x19,0xcd,
0x78,0xac,0x59,0x74,0xac,0x66,0x34,0x36,0xc4,0x1b,0x3e,0x6c,0x38,0x4c,0x33,0x0e,
0x30,0x12,0x0d,0xa3,0x26,0xfe,0x51,0x53,0x00,0xff,0xaf,0x5a,0x4e,0x84,0x0d,0x0f,
0x1f,0xe4,0x6d,0x05,0x2e,0x4e,0x85,0x4b,0x8d,0x6c,0x33,0x6f,0x54,0xd2,0x64,0xab,
0xbf,0x50,0xaf,0x7d,0x7a,0x39,0xa0,0x37,0xed,0x63,0x03,0x0f,0xfc,0x13,0x06,0xce,
0x16,0x36,0xd4,0x54,0x3b,0x95,0x1b,0x51,0x62,0x3a,0xe5,0x4d,0x17,0xd4,0x05,0x39,
0x92,0x9a,0x27,0xa8,0x5b,0xaa,0xbd,0xec,0xbb,0xbe,0xe3,0x20,0x89,0x60,0x71,0x6c,
0x56,0xb3,0xa5,0x13,0xd0,0x6d,0x0e,0x23,0x7e,0x95,0x03,0xed,0x68,0x3d,0xf2,0xd8,
0x63,0xb8,0x6b,0x4d,0xb6,0xe8,0x30,0xb5,0xe1,0xca,0x94,0x4b,0xf7,0xa2,0xaa,0x5d,
0x99,0x30,0xb2,0x3d,0xa7,0xc2,0x51,0x6c,0x28,0x20,0x01,0x24,0x27,0x2b,0x4b,0x00,
0xb7,0x9d,0x11,0x6b,0x70,0xbe,0xb2,0x10,0x82,0xbc,0x0c,0x9b,0x68,0xd0,0x8d,0x3b,
0x24,0x87,0xaa,0x99,0x28,0x72,0x9d,0x33,0x5f,0x59,0x90,0xbd,0xf5,0xde,0x93,0x9e,
0x3a,0x62,0x5a,0x34,0x39,0xe2,0x88,0x55,0x1d,0xb9,0x06,0xb0,0xc1,0x89,0x6b,0x2d,
0xd7,0x69,0xc3,0x19,0x12,0x36,0x84,0xd0,0xc9,0xa0,0xda,0xff,0x2f,0x69,0x78,0xb2,
0xe5,0x7a,0xda,0xeb,0xd7,0x0c,0xc0,0xf7,0xbd,0x63,0x17,0xb8,0x39,0x13,0x38,0xa2,
0x36,0x5b,0x7b,0xf2,0x85,0x56,0x6a,0x1d,0x64,0x62,0xc1,0x38,0xe2,0xaa,0xbf,0x51,
0x66,0xa2,0x94,0xf5,0x12,0x9c,0x66,0x22,0x10,0x6b,0xf2,0xb7,0x30,0x92,0x2d,0xf2,
0x29,0xf0,0x3d,0x3b,0x14,0x43,0x68,0xa2,0xf1,0x9c,0x29,0x37,0xcb,0xce,0x38,0x20,
0x25,0x6d,0x7c,0x67,0xf3,0x7e,0x24,0x12,0x24,0x03,0x08,0x81,0x47,0xec,0xa5,0x9e,
0x97,0xf5,0x18,0xd7,0xcf,0xbb,0xd5,0xef,0x76,0x96,0xef,0xfd,0xce,0xdb,0x56,0x9d,
0x95,0xa0,0x42,0xf9,0x97,0x58,0xe1,0xd7,0x31,0x22,0xd3,0x5f,0x59,0xe6,0x3e,0x6e,
0x22,0x00,0xea,0x43,0x84,0xb6,0x25,0xdb,0xd9,0xf3,0x08,0x56,0x68,0xc0,0x64,0x6b,
0x1d,0x7c,0xec,0xb6,0x93,0xa2,0x62,0x57,0x6e,0x2e,0xd8,0xe7,0x58,0x8f,0xc4,0x31,
0x49,0x26,0xdd,0xde,0x29,0x35,0x87,0xf5,0x30,0x71,0x70,0x5b,0x14,0x3c,0x69,0xbd,
0x89,0x12,0x7d,0xeb,0x2e,0xa3,0xfe,0xd8,0x7f,0x9e,0x82,0x5a,0x52,0x0a,0x2b,0xc1,
0x43,0x2b,0xd9,0x30,0x88,0x9f,0xc8,0x10,0xfb,0x89,0x8d,0xe6,0xa1,0x85,0x75,0x33,
0x7e,0x6c,0x9e,0xdb,0x73,0x13,0x64,0x62,0x69,0xa5,0x2f,0x7d,0xca,0x96,0x6d,0x9f,
0xf8,0x04,0x4d,0x30,0x92,0x3d,0x6e,0x21,0x14,0x21,0xc9,0x3d,0xe0,0xc3,0xfd,0x8a,
0x6b,0x9d,0x4a,0xfd,0xd1,0xa1,0x9d,0x99,0x43,0x77,0x3f,0xb0,0xda };
struct CONST_BLOB {
const BYTE *pb;
DWORD cb;
} msRootCerts[] = {
{ authenticode, sizeof(authenticode) },
{ rootauthority, sizeof(rootauthority) },
{ rootcertauthority, sizeof(rootcertauthority) },
};
static void add_ms_root_certs(HCERTSTORE to)
{
DWORD i;
TRACE("\n");
for (i = 0; i < sizeof(msRootCerts) / sizeof(msRootCerts[0]); i++)
if (!CertAddEncodedCertificateToStore(to, X509_ASN_ENCODING,
msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, NULL))
WARN("adding root cert %d failed: %08x\n", i, GetLastError());
}
/* Reads certificates from the list of known locations into store. Stops when
* any location contains any certificates, to prevent spending unnecessary time
* adding redundant certificates, e.g. when both a certificate bundle and
* individual certificates exist in the same directory.
*/
static PWINECRYPT_CERTSTORE CRYPT_RootOpenStoreFromKnownLocations(void)
static void read_trusted_roots_from_known_locations(HCERTSTORE store)
{
HCERTSTORE root = NULL;
HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
HCERTSTORE to = CertOpenStore(CERT_STORE_PROV_MEMORY,
if (from)
{
DWORD i;
BOOL ret = FALSE;
for (i = 0; !ret &&
i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
i++)
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, store);
}
}
static HCERTSTORE create_root_store(void)
{
HCERTSTORE root = NULL;
HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
if (from && to)
if (memStore)
{
CERT_STORE_PROV_INFO provInfo = {
sizeof(CERT_STORE_PROV_INFO),
@ -457,17 +716,11 @@ static PWINECRYPT_CERTSTORE CRYPT_RootOpenStoreFromKnownLocations(void)
0,
NULL
};
DWORD i;
BOOL ret = FALSE;
for (i = 0; !ret &&
i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
i++)
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, to);
root = CRYPT_ProvCreateStore(0, to, &provInfo);
read_trusted_roots_from_known_locations(memStore);
add_ms_root_certs(memStore);
root = CRYPT_ProvCreateStore(0, memStore, &provInfo);
}
CertCloseStore(from, 0);
TRACE("returning %p\n", root);
return root;
}
@ -497,7 +750,7 @@ PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
}
if (!CRYPT_rootStore)
{
HCERTSTORE root = CRYPT_RootOpenStoreFromKnownLocations();
HCERTSTORE root = create_root_store();
InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root,
NULL);

View file

@ -697,7 +697,7 @@ static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
}
if (ret)
{
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, NULL, &size);
if (ret)
{
if (!blob->pbData)
@ -711,7 +711,7 @@ static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
else
{
blob->cbData = size;
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, blob->pbData,
&blob->cbData);
}
}
@ -798,7 +798,7 @@ static BOOL CRYPT_SaveSerializedToMem(HCERTSTORE store,
DWORD dwMsgAndCertEncodingType, void *handle)
{
CERT_BLOB *blob = (CERT_BLOB *)handle;
DWORD size;
DWORD size = 0;
BOOL ret;
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_CountSerializedBytes,

View file

@ -1,6 +1,6 @@
/*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2005 Juan Lang
* Copyright 2005-2008 Juan Lang
* Copyright 2006 Paul Vriens
*
* This library is free software; you can redistribute it and/or
@ -254,6 +254,39 @@ end_function:
return TRUE;
}
static void *CRYPT_LoadSIPFuncFromKey(HKEY key, HMODULE *pLib)
{
LONG r;
DWORD size;
WCHAR dllName[MAX_PATH];
char functionName[MAX_PATH];
HMODULE lib;
void *func = NULL;
/* Read the DLL entry */
size = sizeof(dllName);
r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
if (r) goto end;
/* Read the Function entry */
size = sizeof(functionName);
r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
&size);
if (r) goto end;
lib = LoadLibraryW(dllName);
if (!lib)
goto end;
func = GetProcAddress(lib, functionName);
if (func)
*pLib = lib;
else
FreeLibrary(lib);
end:
return func;
}
/***********************************************************************
* CryptSIPRetrieveSubjectGuid (CRYPT32.@)
*
@ -276,13 +309,18 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
(LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
{
HANDLE hFile;
HANDLE hFilemapped;
LPVOID pMapped;
BOOL bRet = FALSE;
DWORD fileSize;
IMAGE_DOS_HEADER *dos;
DWORD count;
LARGE_INTEGER zero, oldPos;
/* FIXME, find out if there is a name for this GUID */
static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }};
static const WORD dosHdr = IMAGE_DOS_SIGNATURE;
static const BYTE cabHdr[] = { 'M','S','C','F' };
BYTE hdr[SIP_MAX_MAGIC_NUMBER];
WCHAR szFullKey[ 0x100 ];
LONG r = ERROR_SUCCESS;
HKEY key;
TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject);
@ -305,52 +343,122 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
}
hFilemapped = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
/* Last error is set by CreateFileMapping */
if (!hFilemapped) goto cleanup3;
zero.QuadPart = 0;
SetFilePointerEx(hFile, zero, &oldPos, FILE_CURRENT);
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
if (!ReadFile(hFile, hdr, sizeof(hdr), &count, NULL))
goto cleanup;
pMapped = MapViewOfFile(hFilemapped, FILE_MAP_READ, 0, 0, 0);
/* Last error is set by MapViewOfFile */
if (!pMapped) goto cleanup2;
/* Native checks it right here */
fileSize = GetFileSize(hFile, NULL);
if (fileSize < 4)
if (count < SIP_MAX_MAGIC_NUMBER)
{
SetLastError(ERROR_INVALID_PARAMETER);
goto cleanup1;
goto cleanup;
}
/* As everything is in place now we start looking at the file header */
dos = (IMAGE_DOS_HEADER *)pMapped;
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
if (!memcmp(hdr, &dosHdr, sizeof(dosHdr)))
{
*pgSubject = unknown;
SetLastError(S_OK);
bRet = TRUE;
goto cleanup1;
goto cleanup;
}
/* Quick-n-dirty check for a cab file. */
if (!memcmp(hdr, cabHdr, sizeof(cabHdr)))
{
*pgSubject = cabGUID;
SetLastError(S_OK);
bRet = TRUE;
goto cleanup;
}
/* FIXME
* There is a lot more to be checked:
* - Check for MSFC in the header
* - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2
* under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are
* functions listed that need check if a SIP Provider can deal with the
* given file.
/* Check for supported functions using CryptSIPDllIsMyFileType */
/* max length of szFullKey depends on our code only, so we won't overrun */
lstrcpyW(szFullKey, szOID);
lstrcatW(szFullKey, szIsMyFile);
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
if (r == ERROR_SUCCESS)
{
DWORD index = 0, size;
WCHAR subKeyName[MAX_PATH];
do {
size = sizeof(subKeyName) / sizeof(subKeyName[0]);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
{
HKEY subKey;
r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
if (r == ERROR_SUCCESS)
{
HMODULE lib;
pfnIsFileSupported isMy = CRYPT_LoadSIPFuncFromKey(subKey,
&lib);
if (isMy)
{
bRet = isMy(hFile, pgSubject);
FreeLibrary(lib);
}
RegCloseKey(subKey);
}
}
} while (!bRet && r == ERROR_SUCCESS);
RegCloseKey(key);
}
/* Check for supported functions using CryptSIPDllIsMyFileType2 */
if (!bRet)
{
lstrcpyW(szFullKey, szOID);
lstrcatW(szFullKey, szIsMyFile2);
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
if (r == ERROR_SUCCESS)
{
DWORD index = 0, size;
WCHAR subKeyName[MAX_PATH];
do {
size = sizeof(subKeyName) / sizeof(subKeyName[0]);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
{
HKEY subKey;
r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
if (r == ERROR_SUCCESS)
{
HMODULE lib;
pfnIsFileSupportedName isMy2 =
CRYPT_LoadSIPFuncFromKey(subKey, &lib);
if (isMy2)
{
bRet = isMy2((LPWSTR)FileName, pgSubject);
FreeLibrary(lib);
}
RegCloseKey(subKey);
}
}
} while (!bRet && r == ERROR_SUCCESS);
RegCloseKey(key);
}
}
if (!bRet)
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
cleanup:
/* If we didn't open this one we shouldn't close it (hFile is a copy),
* but we should reset the file pointer to its original position.
*/
/* Let's set the most common error for now */
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
/* The 3 different cleanups are here because we shouldn't overwrite the last error */
cleanup1:
UnmapViewOfFile(pMapped);
cleanup2:
CloseHandle(hFilemapped);
cleanup3:
/* If we didn't open this one we shouldn't close it (hFile is a copy) */
if (!hFileIn) CloseHandle(hFile);
if (!hFileIn)
CloseHandle(hFile);
else
SetFilePointerEx(hFile, oldPos, NULL, FILE_BEGIN);
return bRet;
}
@ -374,40 +482,17 @@ static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
HMODULE *pLib)
{
LONG r;
HKEY key = NULL;
DWORD size;
WCHAR dllName[MAX_PATH];
char functionName[MAX_PATH];
HMODULE lib;
HKEY key;
void *func = NULL;
TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));
r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
if (r) goto error;
/* Read the DLL entry */
size = sizeof(dllName);
r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
if (r) goto error;
/* Read the Function entry */
size = sizeof(functionName);
r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
&size);
if (r) goto error;
lib = LoadLibraryW(dllName);
if (!lib)
goto error;
func = GetProcAddress(lib, functionName);
if (func)
*pLib = lib;
else
FreeLibrary(lib);
error:
RegCloseKey(key);
if (!r)
{
func = CRYPT_LoadSIPFuncFromKey(key, pLib);
RegCloseKey(key);
}
TRACE("returning %p\n", func);
return func;
}

View file

@ -91,6 +91,7 @@ typedef struct _WINE_MEMSTORE
WINECRYPT_CERTSTORE hdr;
struct ContextList *certs;
struct ContextList *crls;
struct ContextList *ctls;
} WINE_MEMSTORE, *PWINE_MEMSTORE;
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
@ -229,6 +230,47 @@ static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
return TRUE;
}
static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
void *toReplace, const void **ppStoreContext)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
PCTL_CONTEXT context;
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
context = (PCTL_CONTEXT)ContextList_Add(ms->ctls, ctl, toReplace);
if (context)
{
context->hCertStore = store;
if (ppStoreContext)
*ppStoreContext = CertDuplicateCTLContext(context);
}
return context ? TRUE : FALSE;
}
static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
void *ret;
TRACE("(%p, %p)\n", store, pPrev);
ret = ContextList_Enum(ms->ctls, pPrev);
if (!ret)
SetLastError(CRYPT_E_NOT_FOUND);
TRACE("returning %p\n", ret);
return ret;
}
static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
ContextList_Delete(ms->ctls, pCtlContext);
return TRUE;
}
static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
@ -239,6 +281,7 @@ static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
ContextList_Free(store->certs);
ContextList_Free(store->crls);
ContextList_Free(store->ctls);
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
}
@ -268,11 +311,16 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
store->hdr.crls.addContext = CRYPT_MemAddCrl;
store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
store->hdr.ctls.addContext = CRYPT_MemAddCtl;
store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
store->hdr.control = NULL;
store->certs = ContextList_Create(pCertInterface,
sizeof(CERT_CONTEXT));
store->crls = ContextList_Create(pCRLInterface,
sizeof(CRL_CONTEXT));
store->ctls = ContextList_Create(pCTLInterface,
sizeof(CTL_CONTEXT));
/* Mem store doesn't need crypto provider, so close it */
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
CryptReleaseContext(hCryptProv, 0);
@ -1043,58 +1091,6 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
return ret;
}
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
{
FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
cbCtlEncoded);
return NULL;
}
BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
{
FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
ppCtlContext);
return FALSE;
}
BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
PCCTL_CONTEXT* ppStoreContext)
{
FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
dwAddDisposition, ppStoreContext);
return TRUE;
}
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
{
FIXME("(%p): stub\n", pCtlContext );
return pCtlContext;
}
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
{
FIXME("(%p): stub\n", pCtlContext );
return TRUE;
}
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
{
FIXME("(%p): stub\n", pCtlContext);
return TRUE;
}
PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
PCCTL_CONTEXT pPrev)
{
FIXME("(%p, %p): stub\n", hCertStore, pPrev);
return NULL;
}
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
{
WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
@ -1248,28 +1244,6 @@ BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
return ret;
}
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId)
{
FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
return 0;
}
BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, void *pvData, DWORD *pcbData)
{
FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
return FALSE;
}
BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId, DWORD dwFlags, const void *pvData)
{
FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
pvData);
return FALSE;
}
static LONG CRYPT_OpenParentStore(DWORD dwFlags,
void *pvSystemStoreLocationPara, HKEY *key)
{

View file

@ -169,10 +169,8 @@ static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
{
chars = min(lstrlenA(prefix), csz);
memcpy(psz, prefix, chars);
csz -= chars;
*(psz + chars) = '=';
chars++;
csz--;
}
else
chars = lstrlenA(prefix) + 1;
@ -183,7 +181,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
DWORD dwStrType, LPSTR psz, DWORD csz)
{
static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
static const char commaSep[] = ", ";
static const char semiSep[] = "; ";
static const char crlfSep[] = "\r\n";
@ -204,6 +202,10 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
{
DWORD i, j, sepLen, rdnSepLen;
LPCSTR sep, rdnSep;
BOOL reverse = dwStrType & CERT_NAME_STR_REVERSE_FLAG;
const CERT_RDN *rdn = info->rgRDN;
if(reverse && info->cRDN > 1) rdn += (info->cRDN - 1);
if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
sep = semiSep;
@ -219,19 +221,19 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
rdnSepLen = strlen(rdnSep);
for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
{
for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++)
{
DWORD chars;
char prefixBuf[10]; /* big enough for GivenName */
LPCSTR prefix = NULL;
if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
prefix = rdn->rgRDNAttr[j].pszObjId;
else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
{
PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
CRYPT_OID_INFO_OID_KEY,
info->rgRDN[i].rgRDNAttr[j].pszObjId,
rdn->rgRDNAttr[j].pszObjId,
CRYPT_RDN_ATTR_OID_GROUP_ID);
if (oidInfo)
@ -241,7 +243,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
prefix = prefixBuf;
}
else
prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
prefix = rdn->rgRDNAttr[j].pszObjId;
}
if (prefix)
{
@ -249,16 +251,15 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
chars = CRYPT_AddPrefixA(prefix,
psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars;
csz -= chars;
}
/* FIXME: handle quoting */
chars = CertRDNValueToStrA(
info->rgRDN[i].rgRDNAttr[j].dwValueType,
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
rdn->rgRDNAttr[j].dwValueType,
&rdn->rgRDNAttr[j].Value, psz ? psz + ret : NULL,
psz ? csz - ret : 0);
if (chars)
ret += chars - 1;
if (j < info->rgRDN[i].cRDNAttr - 1)
if (j < rdn->cRDNAttr - 1)
{
if (psz && ret < csz - rdnSepLen - 1)
memcpy(psz + ret, rdnSep, rdnSepLen);
@ -271,13 +272,14 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
memcpy(psz + ret, sep, sepLen);
ret += sepLen;
}
if(reverse) rdn--;
else rdn++;
}
LocalFree(info);
}
if (psz && csz)
{
*(psz + ret) = '\0';
csz--;
ret++;
}
else
@ -305,10 +307,8 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
chars = min(lstrlenA(prefix), csz);
for (i = 0; i < chars; i++)
*(psz + i) = prefix[i];
csz -= chars;
*(psz + chars) = '=';
chars++;
csz--;
}
else
chars = lstrlenA(prefix) + 1;
@ -330,10 +330,8 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
{
chars = min(lstrlenW(prefix), csz);
memcpy(psz, prefix, chars * sizeof(WCHAR));
csz -= chars;
*(psz + chars) = '=';
chars++;
csz--;
}
else
chars = lstrlenW(prefix) + 1;
@ -344,7 +342,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
DWORD dwStrType, LPWSTR psz, DWORD csz)
{
static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
static const WCHAR commaSep[] = { ',',' ',0 };
static const WCHAR semiSep[] = { ';',' ',0 };
static const WCHAR crlfSep[] = { '\r','\n',0 };
@ -365,6 +363,10 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
{
DWORD i, j, sepLen, rdnSepLen;
LPCWSTR sep, rdnSep;
BOOL reverse = dwStrType & CERT_NAME_STR_REVERSE_FLAG;
const CERT_RDN *rdn = info->rgRDN;
if(reverse && info->cRDN > 1) rdn += (info->cRDN - 1);
if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
sep = semiSep;
@ -380,25 +382,25 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
rdnSepLen = lstrlenW(rdnSep);
for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
{
for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++)
{
DWORD chars;
LPCSTR prefixA = NULL;
LPCWSTR prefixW = NULL;
if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
prefixA = rdn->rgRDNAttr[j].pszObjId;
else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
{
PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
CRYPT_OID_INFO_OID_KEY,
info->rgRDN[i].rgRDNAttr[j].pszObjId,
rdn->rgRDNAttr[j].pszObjId,
CRYPT_RDN_ATTR_OID_GROUP_ID);
if (oidInfo)
prefixW = oidInfo->pwszName;
else
prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
prefixA = rdn->rgRDNAttr[j].pszObjId;
}
if (prefixW)
{
@ -406,7 +408,6 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
chars = CRYPT_AddPrefixW(prefixW,
psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars;
csz -= chars;
}
else if (prefixA)
{
@ -414,16 +415,15 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
chars = CRYPT_AddPrefixAToW(prefixA,
psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
ret += chars;
csz -= chars;
}
/* FIXME: handle quoting */
chars = CertRDNValueToStrW(
info->rgRDN[i].rgRDNAttr[j].dwValueType,
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
rdn->rgRDNAttr[j].dwValueType,
&rdn->rgRDNAttr[j].Value, psz ? psz + ret : NULL,
psz ? csz - ret : 0);
if (chars)
ret += chars - 1;
if (j < info->rgRDN[i].cRDNAttr - 1)
if (j < rdn->cRDNAttr - 1)
{
if (psz && ret < csz - rdnSepLen - 1)
memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR));
@ -436,13 +436,14 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
memcpy(psz + ret, sep, sepLen * sizeof(WCHAR));
ret += sepLen;
}
if(reverse) rdn--;
else rdn++;
}
LocalFree(info);
}
if (psz && csz)
{
*(psz + ret) = '\0';
csz--;
ret++;
}
else

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,10 @@
* WinTrust Cryptography functions
*
* Copyright 2006 James Hawkins
* Copyright 2000-2002 Stuart Caie
* Copyright 2002 Patrik Stridvall
* Copyright 2003 Greg Turner
* Copyright 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
@ -19,12 +23,13 @@
*/
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "wintrust.h"
#include "mscat.h"
#include "mssip.h"
#include "imagehlp.h"
#include "wine/debug.h"
@ -50,7 +55,25 @@ BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN* catAdmin,
{
FIXME("%p %s %x\n", catAdmin, debugstr_guid(sysSystem), dwFlags);
if (catAdmin) *catAdmin = (HCATADMIN)0xdeadbeef;
if (!catAdmin)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
*catAdmin = (HCATADMIN)0xdeadbeef;
return TRUE;
}
/***********************************************************************
* CryptCATAdminAddCatalog (WINTRUST.@)
*/
BOOL WINAPI CryptCATAdminAddCatalog(HCATADMIN catAdmin, PWSTR catalogFile,
PWSTR selectBaseName, DWORD flags)
{
FIXME("%p %s %s %d\n", catAdmin, debugstr_w(catalogFile),
debugstr_w(selectBaseName), flags);
return TRUE;
}
@ -79,6 +102,29 @@ HCATINFO WINAPI CryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin,
return NULL;
}
/***********************************************************************
* CryptCATAdminReleaseCatalogContext (WINTRUST.@)
*
* Release a catalog context handle.
*
* PARAMS
* hCatAdmin [I] Context handle.
* hCatInfo [I] Catalog handle.
* dwFlags [I] Reserved.
*
* RETURNS
* Success: TRUE.
* Failure: FAIL.
*
*/
BOOL WINAPI CryptCATAdminReleaseCatalogContext(HCATADMIN hCatAdmin,
HCATINFO hCatInfo,
DWORD dwFlags)
{
FIXME("%p %p %x\n", hCatAdmin, hCatInfo, dwFlags);
return TRUE;
}
/***********************************************************************
* CryptCATAdminReleaseContext (WINTRUST.@)
*
@ -156,20 +202,306 @@ BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcb
SIP_INDIRECT_DATA* pIndirectData)
{
FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData);
return FALSE;
}
static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg,
BYTE *pbSignedDataMsg)
{
BOOL ret;
WIN_CERTIFICATE *pCert = NULL;
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
pcbSignedDataMsg, pbSignedDataMsg);
if (!pbSignedDataMsg)
{
WIN_CERTIFICATE cert;
/* app hasn't passed buffer, just get the length */
ret = ImageGetCertificateHeader(pSubjectInfo->hFile, dwIndex, &cert);
if (ret)
*pcbSignedDataMsg = cert.dwLength;
}
else
{
DWORD len = 0;
ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, NULL, &len);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto error;
pCert = HeapAlloc(GetProcessHeap(), 0, len);
if (!pCert)
{
ret = FALSE;
goto error;
}
ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, pCert,
&len);
if (!ret)
goto error;
if (*pcbSignedDataMsg < pCert->dwLength)
{
*pcbSignedDataMsg = pCert->dwLength;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
ret = FALSE;
}
else
{
memcpy(pbSignedDataMsg, pCert->bCertificate, pCert->dwLength);
switch (pCert->wCertificateType)
{
case WIN_CERT_TYPE_X509:
*pdwEncodingType = X509_ASN_ENCODING;
break;
case WIN_CERT_TYPE_PKCS_SIGNED_DATA:
*pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
break;
default:
FIXME("don't know what to do for encoding type %d\n",
pCert->wCertificateType);
*pdwEncodingType = 0;
}
}
}
error:
HeapFree(GetProcessHeap(), 0, pCert);
return ret;
}
/* structure offsets */
#define cfhead_Signature (0x00)
#define cfhead_CabinetSize (0x08)
#define cfhead_MinorVersion (0x18)
#define cfhead_MajorVersion (0x19)
#define cfhead_Flags (0x1E)
#define cfhead_SIZEOF (0x24)
#define cfheadext_HeaderReserved (0x00)
#define cfheadext_SIZEOF (0x04)
#define cfsigninfo_CertOffset (0x04)
#define cfsigninfo_CertSize (0x08)
#define cfsigninfo_SIZEOF (0x0C)
/* flags */
#define cfheadRESERVE_PRESENT (0x0004)
/* endian-neutral reading of little-endian data */
#define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))
#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
/* For documentation purposes only: this is the structure in the reserved
* area of a signed cabinet file. The cert offset indicates where in the
* cabinet file the signature resides, and the count indicates its size.
*/
typedef struct _CAB_SIGNINFO
{
WORD unk0; /* always 0? */
WORD unk1; /* always 0x0010? */
DWORD dwCertOffset;
DWORD cbCertBlock;
} CAB_SIGNINFO, *PCAB_SIGNINFO;
static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg,
BYTE *pbSignedDataMsg)
{
int header_resv;
LONG base_offset, cabsize;
USHORT flags;
BYTE buf[64];
DWORD cert_offset, cert_size, dwRead;
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
pcbSignedDataMsg, pbSignedDataMsg);
/*
* FIXME: I just noticed that I am memorizing the initial file pointer
* offset and restoring it before reading in the rest of the header
* information in the cabinet. Perhaps that's correct -- that is, perhaps
* this API is supposed to support "streaming" cabinets which are embedded
* in other files, or cabinets which begin at file offsets other than zero.
* Otherwise, I should instead go to the absolute beginning of the file.
* (Either way, the semantics of wine's FDICopy require me to leave the
* file pointer where it is afterwards -- If Windows does not do so, we
* ought to duplicate the native behavior in the FDIIsCabinet API, not here.
*
* So, the answer lies in Windows; will native cabinet.dll recognize a
* cabinet "file" embedded in another file? Note that cabextract.c does
* support this, which implies that Microsoft's might. I haven't tried it
* yet so I don't know. ATM, most of wine's FDI cabinet routines (except
* this one) would not work in this way. To fix it, we could just make the
* various references to absolute file positions in the code relative to an
* initial "beginning" offset. Because the FDICopy API doesn't take a
* file-handle like this one, we would therein need to search through the
* file for the beginning of the cabinet (as we also do in cabextract.c).
* Note that this limits us to a maximum of one cabinet per. file: the first.
*
* So, in summary: either the code below is wrong, or the rest of fdi.c is
* wrong... I cannot imagine that both are correct ;) One of these flaws
* should be fixed after determining the behavior on Windows. We ought
* to check both FDIIsCabinet and FDICopy for the right behavior.
*
* -gmt
*/
/* get basic offset & size info */
base_offset = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == -1)
{
TRACE("seek error\n");
return FALSE;
}
cabsize = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
if ((cabsize == -1) || (base_offset == -1) ||
(SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET) == -1))
{
TRACE("seek error\n");
return FALSE;
}
/* read in the CFHEADER */
if (!ReadFile(pSubjectInfo->hFile, buf, cfhead_SIZEOF, &dwRead, NULL) ||
dwRead != cfhead_SIZEOF)
{
TRACE("reading header failed\n");
return FALSE;
}
/* check basic MSCF signature */
if (EndGetI32(buf+cfhead_Signature) != 0x4643534d)
{
WARN("cabinet signature not present\n");
return FALSE;
}
/* Ignore the number of folders and files and the set and cabinet IDs */
/* check the header revision */
if ((buf[cfhead_MajorVersion] > 1) ||
(buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
{
WARN("cabinet format version > 1.3\n");
return FALSE;
}
/* pull the flags out */
flags = EndGetI16(buf+cfhead_Flags);
if (!(flags & cfheadRESERVE_PRESENT))
{
TRACE("no header present, not signed\n");
return FALSE;
}
if (!ReadFile(pSubjectInfo->hFile, buf, cfheadext_SIZEOF, &dwRead, NULL) ||
dwRead != cfheadext_SIZEOF)
{
ERR("bunk reserve-sizes?\n");
return FALSE;
}
header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
if (!header_resv)
{
TRACE("no header_resv, not signed\n");
return FALSE;
}
else if (header_resv < cfsigninfo_SIZEOF)
{
TRACE("header_resv too small, not signed\n");
return FALSE;
}
if (header_resv > 60000)
{
WARN("WARNING; header reserved space > 60000\n");
}
if (!ReadFile(pSubjectInfo->hFile, buf, cfsigninfo_SIZEOF, &dwRead, NULL) ||
dwRead != cfsigninfo_SIZEOF)
{
ERR("couldn't read reserve\n");
return FALSE;
}
cert_offset = EndGetI32(buf+cfsigninfo_CertOffset);
TRACE("cert_offset: %d\n", cert_offset);
cert_size = EndGetI32(buf+cfsigninfo_CertSize);
TRACE("cert_size: %d\n", cert_size);
/* The redundant checks are to avoid wraparound */
if (cert_offset > cabsize || cert_size > cabsize ||
cert_offset + cert_size > cabsize)
{
WARN("offset beyond file, not attempting to read\n");
return FALSE;
}
SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET);
if (!pbSignedDataMsg)
{
*pcbSignedDataMsg = cert_size;
return TRUE;
}
if (*pcbSignedDataMsg < cert_size)
{
*pcbSignedDataMsg = cert_size;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == -1)
{
ERR("couldn't seek to cert location\n");
return FALSE;
}
if (!ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, cert_size, &dwRead,
NULL) || dwRead != cert_size)
{
ERR("couldn't read cert\n");
return FALSE;
}
/* The encoding of the files I've seen appears to be in ASN.1
* format, and there isn't a field indicating the type, so assume it
* always is.
*/
*pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
return TRUE;
}
/***********************************************************************
* CryptSIPGetSignedDataMsg (WINTRUST.@)
*/
BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
{
FIXME("(%p %p %d %p %p) stub\n", pSubjectInfo, pdwEncodingType, dwIndex,
static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,
0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
BOOL ret;
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
pcbSignedDataMsg, pbSignedDataMsg);
return FALSE;
if (!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown)))
ret = WINTRUST_GetSignedMsgFromPEFile(pSubjectInfo, pdwEncodingType,
dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
else if (!memcmp(pSubjectInfo->pgSubjectType, &cabGUID, sizeof(cabGUID)))
ret = WINTRUST_GetSignedMsgFromCabFile(pSubjectInfo, pdwEncodingType,
dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
else
{
FIXME("unimplemented for subject type %s\n",
debugstr_guid(pSubjectInfo->pgSubjectType));
ret = FALSE;
}
TRACE("returning %d\n", ret);
return ret;
}
/***********************************************************************
@ -180,7 +512,7 @@ BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEnc
{
FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex,
cbSignedDataMsg, pbSignedDataMsg);
return FALSE;
}
@ -191,7 +523,7 @@ BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
DWORD dwIndex)
{
FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex);
return FALSE;
}
@ -202,6 +534,6 @@ BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
SIP_INDIRECT_DATA* pIndirectData)
{
FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData);
return FALSE;
}

View file

@ -26,12 +26,13 @@
#include "winuser.h"
#include "winreg.h"
#include "winnls.h"
#include "objbase.h"
#include "guiddef.h"
#include "wintrust.h"
#include "softpub.h"
#include "mssip.h"
#include "wintrust_priv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
@ -61,6 +62,8 @@ static CRYPT_TRUST_REG_ENTRY DriverCleanupPolicy;
static CRYPT_TRUST_REG_ENTRY GenericChainCertificateTrust;
static CRYPT_TRUST_REG_ENTRY GenericChainFinalProv;
static const CRYPT_TRUST_REG_ENTRY NullCTRE = { 0, NULL, NULL };
static const WCHAR Trust[] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'C','r','y','p','t','o','g','r','a','p','h','y','\\',
@ -89,9 +92,9 @@ static void WINTRUST_InitRegStructs(void)
{
#define WINTRUST_INITREGENTRY( action, dllname, functionname ) \
action.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY); \
action.pwszDLLName = HeapAlloc(GetProcessHeap(), 0, sizeof(dllname)); \
action.pwszDLLName = WINTRUST_Alloc(sizeof(dllname)); \
lstrcpyW(action.pwszDLLName, dllname); \
action.pwszFunctionName = HeapAlloc(GetProcessHeap(), 0, sizeof(functionname)); \
action.pwszFunctionName = WINTRUST_Alloc(sizeof(functionname)); \
lstrcpyW(action.pwszFunctionName, functionname);
WINTRUST_INITREGENTRY(SoftpubInitialization, SP_POLICY_PROVIDER_DLL_NAME, SP_INIT_FUNCTION)
@ -125,8 +128,8 @@ static void WINTRUST_InitRegStructs(void)
static void WINTRUST_FreeRegStructs(void)
{
#define WINTRUST_FREEREGENTRY( action ) \
HeapFree(GetProcessHeap(), 0, action.pwszDLLName); \
HeapFree(GetProcessHeap(), 0, action.pwszFunctionName);
WINTRUST_Free(action.pwszDLLName); \
WINTRUST_Free(action.pwszFunctionName);
WINTRUST_FREEREGENTRY(SoftpubInitialization);
WINTRUST_FREEREGENTRY(SoftpubMessage);
@ -157,7 +160,7 @@ static void WINTRUST_FreeRegStructs(void)
*
*/
static void WINTRUST_Guid2Wstr(const GUID* pgActionID, WCHAR* GuidString)
{
{
static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
'%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
'X','%','0','2','X','%','0','2','X','}', 0};
@ -336,7 +339,7 @@ BOOL WINAPI WintrustRemoveActionID( GUID* pgActionID )
WCHAR GuidString[39];
TRACE("(%s)\n", debugstr_guid(pgActionID));
if (!pgActionID)
{
SetLastError(ERROR_INVALID_PARAMETER);
@ -380,11 +383,11 @@ static LONG WINTRUST_WriteSingleUsageEntry(LPCSTR OID,
/* Turn OID into a wide-character string */
Len = MultiByteToWideChar( CP_ACP, 0, OID, -1, NULL, 0 );
OIDW = HeapAlloc( GetProcessHeap(), 0, Len * sizeof(WCHAR) );
OIDW = WINTRUST_Alloc( Len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, OID, -1, OIDW, Len );
/* Allocate the needed space for UsageKey */
UsageKey = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(Trust) + lstrlenW(Usages) + Len) * sizeof(WCHAR));
UsageKey = WINTRUST_Alloc((lstrlenW(Trust) + lstrlenW(Usages) + Len) * sizeof(WCHAR));
/* Create the key string */
lstrcpyW(UsageKey, Trust);
lstrcatW(UsageKey, Usages);
@ -399,8 +402,8 @@ static LONG WINTRUST_WriteSingleUsageEntry(LPCSTR OID,
}
RegCloseKey(Key);
HeapFree(GetProcessHeap(), 0, OIDW);
HeapFree(GetProcessHeap(), 0, UsageKey);
WINTRUST_Free(OIDW);
WINTRUST_Free(UsageKey);
return Res;
}
@ -418,21 +421,23 @@ static BOOL WINTRUST_RegisterGenVerifyV2(void)
{
BOOL RegisteredOK = TRUE;
static GUID ProvGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
CRYPT_PROVIDER_REGDEFUSAGE DefUsage = { sizeof(CRYPT_PROVIDER_REGDEFUSAGE),
&ProvGUID,
NULL, /* No Dll provided */
NULL, /* No load callback function */
NULL }; /* No free callback function */
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddDefaultForUsage(szOID_PKIX_KP_CODE_SIGNING, &DefUsage))
RegisteredOK = FALSE;
@ -454,15 +459,17 @@ static BOOL WINTRUST_RegisterGenVerifyV2(void)
static BOOL WINTRUST_RegisterPublishedSoftware(void)
{
static GUID ProvGUID = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -484,15 +491,17 @@ static BOOL WINTRUST_RegisterPublishedSoftware(void)
static BOOL WINTRUST_RegisterPublishedSoftwareNoBadUi(void)
{
static GUID ProvGUID = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -512,15 +521,17 @@ static BOOL WINTRUST_RegisterPublishedSoftwareNoBadUi(void)
static BOOL WINTRUST_RegisterGenCertVerify(void)
{
static GUID ProvGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubDefCertInit,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubDefCertInit;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -540,15 +551,17 @@ static BOOL WINTRUST_RegisterGenCertVerify(void)
static BOOL WINTRUST_RegisterTrustProviderTest(void)
{
static GUID ProvGUID = WINTRUST_ACTION_TRUSTPROVIDER_TEST;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
SoftpubDumpStructure,
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = SoftpubDumpStructure;
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -571,22 +584,24 @@ static BOOL WINTRUST_RegisterHttpsProv(void)
static CHAR SoftpubLoadUsage[] = "SoftpubLoadDefUsageCallData";
static CHAR SoftpubFreeUsage[] = "SoftpubFreeDefUsageCallData";
static GUID ProvGUID = HTTPSPROV_ACTION;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
HTTPSCertificateTrust,
SoftpubCertCheck,
HTTPSFinalProv,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
CRYPT_PROVIDER_REGDEFUSAGE DefUsage = { sizeof(CRYPT_PROVIDER_REGDEFUSAGE),
&ProvGUID,
NULL, /* Will be filled later */
SoftpubLoadUsage,
SoftpubFreeUsage };
DefUsage.pwszDllName = HeapAlloc(GetProcessHeap(), 0, sizeof(SP_POLICY_PROVIDER_DLL_NAME));
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = HTTPSCertificateTrust;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = HTTPSFinalProv;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
DefUsage.pwszDllName = WINTRUST_Alloc(sizeof(SP_POLICY_PROVIDER_DLL_NAME));
lstrcpyW(DefUsage.pwszDllName, SP_POLICY_PROVIDER_DLL_NAME);
if (!WintrustAddDefaultForUsage(szOID_PKIX_KP_SERVER_AUTH, &DefUsage))
@ -598,7 +613,7 @@ static BOOL WINTRUST_RegisterHttpsProv(void)
if (!WintrustAddDefaultForUsage(szOID_SGC_NETSCAPE, &DefUsage))
RegisteredOK = FALSE;
HeapFree(GetProcessHeap(), 0, DefUsage.pwszDllName);
WINTRUST_Free(DefUsage.pwszDllName);
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
RegisteredOK = FALSE;
@ -618,15 +633,18 @@ static BOOL WINTRUST_RegisterHttpsProv(void)
static BOOL WINTRUST_RegisterOfficeSignVerify(void)
{
static GUID ProvGUID = OFFICESIGN_ACTION_VERIFY;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
OfficeInitializePolicy,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
SoftpubFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
OfficeCleanupPolicy };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = OfficeInitializePolicy;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = SoftpubFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = OfficeCleanupPolicy;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -646,15 +664,18 @@ static BOOL WINTRUST_RegisterOfficeSignVerify(void)
static BOOL WINTRUST_RegisterDriverVerify(void)
{
static GUID ProvGUID = DRIVER_ACTION_VERIFY;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
DriverInitializePolicy,
SoftpubMessage,
SoftpubSignature,
SoftpubCertficate,
SoftpubCertCheck,
DriverFinalPolicy,
{ 0, NULL, NULL }, /* No diagnostic policy */
DriverCleanupPolicy };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = DriverInitializePolicy;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = SoftpubCertficate;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = DriverFinalPolicy;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = DriverCleanupPolicy;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -674,15 +695,17 @@ static BOOL WINTRUST_RegisterDriverVerify(void)
static BOOL WINTRUST_RegisterGenChainVerify(void)
{
static GUID ProvGUID = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
CRYPT_REGISTER_ACTIONID ProvInfo = { sizeof(CRYPT_REGISTER_ACTIONID),
SoftpubInitialization,
SoftpubMessage,
SoftpubSignature,
GenericChainCertificateTrust,
SoftpubCertCheck,
GenericChainFinalProv,
{ 0, NULL, NULL }, /* No diagnostic policy */
SoftpubCleanup };
CRYPT_REGISTER_ACTIONID ProvInfo;
ProvInfo.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ProvInfo.sInitProvider = SoftpubInitialization;
ProvInfo.sObjectProvider = SoftpubMessage;
ProvInfo.sSignatureProvider = SoftpubSignature;
ProvInfo.sCertificateProvider = GenericChainCertificateTrust;
ProvInfo.sCertificatePolicyProvider = SoftpubCertCheck;
ProvInfo.sFinalPolicyProvider = GenericChainFinalProv;
ProvInfo.sTestPolicyProvider = NullCTRE; /* No diagnostic policy */
ProvInfo.sCleanupProvider = SoftpubCleanup;
if (!WintrustAddActionID(&ProvGUID, 0, &ProvInfo))
return FALSE;
@ -704,7 +727,7 @@ static BOOL WINTRUST_RegisterGenChainVerify(void)
* Failure: FALSE.
*
* NOTES
* WintrustAddDefaultForUsage will only return TRUE or FALSE, no last
* WintrustAddDefaultForUsage will only return TRUE or FALSE, no last
* error is set, not even when the registry cannot be written to.
*/
BOOL WINAPI WintrustAddDefaultForUsage(const char *pszUsageOID,
@ -739,26 +762,26 @@ BOOL WINAPI WintrustAddDefaultForUsage(const char *pszUsageOID,
WCHAR* CallbackW;
Len = MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszLoadCallbackDataFunctionName, -1, NULL, 0 );
CallbackW = HeapAlloc( GetProcessHeap(), 0, Len * sizeof(WCHAR) );
CallbackW = WINTRUST_Alloc( Len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszLoadCallbackDataFunctionName, -1, CallbackW, Len );
Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, CBAlloc, CallbackW);
if (Res != ERROR_SUCCESS) WriteUsageError = Res;
HeapFree(GetProcessHeap(), 0, CallbackW);
WINTRUST_Free(CallbackW);
}
if (psDefUsage->pwszFreeCallbackDataFunctionName)
{
WCHAR* CallbackW;
Len = MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszFreeCallbackDataFunctionName, -1, NULL, 0 );
CallbackW = HeapAlloc( GetProcessHeap(), 0, Len * sizeof(WCHAR) );
CallbackW = WINTRUST_Alloc( Len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, psDefUsage->pwszFreeCallbackDataFunctionName, -1, CallbackW, Len );
Res = WINTRUST_WriteSingleUsageEntry(pszUsageOID, CBFree, CallbackW);
if (Res != ERROR_SUCCESS) WriteUsageError = Res;
HeapFree(GetProcessHeap(), 0, CallbackW);
WINTRUST_Free(CallbackW);
}
WINTRUST_Guid2Wstr(psDefUsage->pgActionID, GuidString);
@ -771,6 +794,88 @@ BOOL WINAPI WintrustAddDefaultForUsage(const char *pszUsageOID,
return TRUE;
}
static FARPROC WINTRUST_ReadProviderFromReg(WCHAR *GuidString, const WCHAR *FunctionType)
{
WCHAR ProvKey[MAX_PATH], DllName[MAX_PATH];
char FunctionName[MAX_PATH];
HKEY Key;
LONG Res = ERROR_SUCCESS;
DWORD Size;
HMODULE Lib;
FARPROC Func = NULL;
/* Create the needed key string */
ProvKey[0]='\0';
lstrcatW(ProvKey, Trust);
lstrcatW(ProvKey, FunctionType);
lstrcatW(ProvKey, GuidString);
Res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ProvKey, 0, KEY_READ, &Key);
if (Res != ERROR_SUCCESS) goto error_close_key;
/* Read the $DLL entry */
Size = sizeof(DllName);
Res = RegQueryValueExW(Key, Dll, NULL, NULL, (LPBYTE)DllName, &Size);
if (Res != ERROR_SUCCESS) goto error_close_key;
/* Read the $Function entry */
Size = sizeof(FunctionName);
Res = RegQueryValueExA(Key, "$Function", NULL, NULL, (LPBYTE)FunctionName, &Size);
if (Res != ERROR_SUCCESS) goto error_close_key;
/* Load the library - there appears to be no way to close a provider, so
* just leak the module handle.
*/
Lib = LoadLibraryW(DllName);
Func = GetProcAddress(Lib, FunctionName);
error_close_key:
RegCloseKey(Key);
return Func;
}
/***********************************************************************
* WintrustLoadFunctionPointers (WINTRUST.@)
*/
BOOL WINAPI WintrustLoadFunctionPointers( GUID* pgActionID,
CRYPT_PROVIDER_FUNCTIONS* pPfns )
{
WCHAR GuidString[39];
TRACE("(%s %p)\n", debugstr_guid(pgActionID), pPfns);
if (!pPfns) return FALSE;
if (!pgActionID)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (pPfns->cbStruct != sizeof(CRYPT_PROVIDER_FUNCTIONS)) return FALSE;
/* Create this string only once, instead of in the helper function */
WINTRUST_Guid2Wstr( pgActionID, GuidString);
/* Get the function pointers from the registry, where applicable */
pPfns->pfnAlloc = WINTRUST_Alloc;
pPfns->pfnFree = WINTRUST_Free;
pPfns->pfnAddStore2Chain = WINTRUST_AddStore;
pPfns->pfnAddSgnr2Chain = WINTRUST_AddSgnr;
pPfns->pfnAddCert2Chain = WINTRUST_AddCert;
pPfns->pfnAddPrivData2Chain = WINTRUST_AddPrivData;
pPfns->psUIpfns = NULL;
pPfns->pfnInitialize = (PFN_PROVIDER_INIT_CALL)WINTRUST_ReadProviderFromReg(GuidString, Initialization);
pPfns->pfnObjectTrust = (PFN_PROVIDER_OBJTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Message);
pPfns->pfnSignatureTrust = (PFN_PROVIDER_SIGTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Signature);
pPfns->pfnCertificateTrust = (PFN_PROVIDER_CERTTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Certificate);
pPfns->pfnCertCheckPolicy = (PFN_PROVIDER_CERTCHKPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, CertCheck);
pPfns->pfnFinalPolicy = (PFN_PROVIDER_FINALPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, FinalPolicy);
pPfns->pfnTestFinalPolicy = (PFN_PROVIDER_TESTFINALPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, DiagnosticPolicy);
pPfns->pfnCleanupPolicy = (PFN_PROVIDER_CLEANUP_CALL)WINTRUST_ReadProviderFromReg(GuidString, Cleanup);
return TRUE;
}
/***********************************************************************
* WINTRUST_SIPPAddProvider
*
@ -794,7 +899,7 @@ static BOOL WINTRUST_SIPPAddProvider(GUID* Subject, WCHAR* MagicNumber)
/* Clear and initialize the structure */
memset(&NewProv, 0, sizeof(SIP_ADD_NEWPROVIDER));
NewProv.cbStruct = sizeof(SIP_ADD_NEWPROVIDER);
NewProv.pwszDLLFileName = HeapAlloc(GetProcessHeap(), 0, sizeof(SP_POLICY_PROVIDER_DLL_NAME));
NewProv.pwszDLLFileName = WINTRUST_Alloc(sizeof(SP_POLICY_PROVIDER_DLL_NAME));
/* Fill the structure */
NewProv.pgSubject = Subject;
lstrcpyW(NewProv.pwszDLLFileName, SP_POLICY_PROVIDER_DLL_NAME);
@ -809,8 +914,8 @@ static BOOL WINTRUST_SIPPAddProvider(GUID* Subject, WCHAR* MagicNumber)
Ret = CryptSIPAddProvider(&NewProv);
HeapFree(GetProcessHeap(), 0, NewProv.pwszDLLFileName);
WINTRUST_Free(NewProv.pwszDLLFileName);
return Ret;
}
@ -976,7 +1081,7 @@ add_trust_providers:
return CryptRegisterRes;
else if (SIPAddProviderRes == S_OK)
return TrustProviderRes;
else
else
return SIPAddProviderRes;
}

View file

@ -0,0 +1,897 @@
/*
* Copyright 2007 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wintrust.h"
#include "mssip.h"
#include "softpub.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
HRESULT WINAPI SoftpubDefCertInit(CRYPT_PROVIDER_DATA *data)
{
HRESULT ret = S_FALSE;
TRACE("(%p)\n", data);
if (data->padwTrustStepErrors &&
!data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT])
ret = S_OK;
TRACE("returning %08x\n", ret);
return ret;
}
HRESULT WINAPI SoftpubInitialize(CRYPT_PROVIDER_DATA *data)
{
HRESULT ret = S_FALSE;
TRACE("(%p)\n", data);
if (data->padwTrustStepErrors &&
!data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT])
ret = S_OK;
TRACE("returning %08x\n", ret);
return ret;
}
/* Assumes data->pWintrustData->u.pFile exists. Makes sure a file handle is
* open for the file.
*/
static BOOL SOFTPUB_OpenFile(CRYPT_PROVIDER_DATA *data)
{
BOOL ret = TRUE;
/* PSDK implies that all values should be initialized to NULL, so callers
* typically have hFile as NULL rather than INVALID_HANDLE_VALUE. Check
* for both.
*/
if (!data->pWintrustData->u.pFile->hFile ||
data->pWintrustData->u.pFile->hFile == INVALID_HANDLE_VALUE)
{
data->pWintrustData->u.pFile->hFile =
CreateFileW(data->pWintrustData->u.pFile->pcwszFilePath, GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (data->pWintrustData->u.pFile->hFile != INVALID_HANDLE_VALUE)
data->fOpenedFile = TRUE;
else
ret = FALSE;
}
if (ret)
GetFileTime(data->pWintrustData->u.pFile->hFile, &data->sftSystemTime,
NULL, NULL);
TRACE("returning %d\n", ret);
return ret;
}
/* Assumes data->pWintrustData->u.pFile exists. Sets data->pPDSip->gSubject to
* the file's subject GUID.
*/
static BOOL SOFTPUB_GetFileSubject(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
if (!data->pWintrustData->u.pFile->pgKnownSubject)
{
ret = CryptSIPRetrieveSubjectGuid(
data->pWintrustData->u.pFile->pcwszFilePath,
data->pWintrustData->u.pFile->hFile,
&data->u.pPDSip->gSubject);
}
else
{
data->u.pPDSip->gSubject = *data->pWintrustData->u.pFile->pgKnownSubject;
ret = TRUE;
}
TRACE("returning %d\n", ret);
return ret;
}
/* Assumes data->u.pPDSip exists, and its gSubject member set.
* Allocates data->u.pPDSip->pSip and loads it, if possible.
*/
static BOOL SOFTPUB_GetSIP(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
data->u.pPDSip->pSip = data->psPfns->pfnAlloc(sizeof(SIP_DISPATCH_INFO));
if (data->u.pPDSip->pSip)
ret = CryptSIPLoad(&data->u.pPDSip->gSubject, 0, data->u.pPDSip->pSip);
else
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
}
TRACE("returning %d\n", ret);
return ret;
}
/* Assumes data->u.pPDSip has been loaded, and data->u.pPDSip->pSip allocated.
* Calls data->u.pPDSip->pSip->pfGet to construct data->hMsg.
*/
static BOOL SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
LPBYTE buf = NULL;
DWORD size = 0;
data->u.pPDSip->psSipSubjectInfo =
data->psPfns->pfnAlloc(sizeof(SIP_SUBJECTINFO));
if (!data->u.pPDSip->psSipSubjectInfo)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
data->u.pPDSip->psSipSubjectInfo->cbSize = sizeof(SIP_SUBJECTINFO);
data->u.pPDSip->psSipSubjectInfo->pgSubjectType = &data->u.pPDSip->gSubject;
data->u.pPDSip->psSipSubjectInfo->hFile = data->pWintrustData->u.pFile->hFile;
data->u.pPDSip->psSipSubjectInfo->pwsFileName =
data->pWintrustData->u.pFile->pcwszFilePath;
data->u.pPDSip->psSipSubjectInfo->hProv = data->hProv;
ret = data->u.pPDSip->pSip->pfGet(data->u.pPDSip->psSipSubjectInfo,
&data->dwEncoding, 0, &size, 0);
if (!ret)
{
SetLastError(TRUST_E_NOSIGNATURE);
return FALSE;
}
buf = data->psPfns->pfnAlloc(size);
if (!buf)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
ret = data->u.pPDSip->pSip->pfGet(data->u.pPDSip->psSipSubjectInfo,
&data->dwEncoding, 0, &size, buf);
if (ret)
{
data->hMsg = CryptMsgOpenToDecode(data->dwEncoding, 0, 0, data->hProv,
NULL, NULL);
if (data->hMsg)
ret = CryptMsgUpdate(data->hMsg, buf, size, TRUE);
}
data->psPfns->pfnFree(buf);
TRACE("returning %d\n", ret);
return ret;
}
static BOOL SOFTPUB_CreateStoreFromMessage(CRYPT_PROVIDER_DATA *data)
{
BOOL ret = FALSE;
HCERTSTORE store;
store = CertOpenStore(CERT_STORE_PROV_MSG, data->dwEncoding,
data->hProv, CERT_STORE_NO_CRYPT_RELEASE_FLAG, data->hMsg);
if (store)
{
ret = data->psPfns->pfnAddStore2Chain(data, store);
CertCloseStore(store, 0);
}
TRACE("returning %d\n", ret);
return ret;
}
static DWORD SOFTPUB_DecodeInnerContent(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
DWORD size;
LPBYTE buf = NULL;
ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL,
&size);
if (!ret)
goto error;
buf = data->psPfns->pfnAlloc(size);
if (!buf)
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
goto error;
}
ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, buf,
&size);
if (!ret)
goto error;
if (!strcmp((LPCSTR)buf, SPC_INDIRECT_DATA_OBJID))
{
data->psPfns->pfnFree(buf);
buf = NULL;
ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &size);
if (!ret)
goto error;
buf = data->psPfns->pfnAlloc(size);
if (!buf)
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
goto error;
}
ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, buf, &size);
if (!ret)
goto error;
ret = CryptDecodeObject(data->dwEncoding,
SPC_INDIRECT_DATA_CONTENT_STRUCT, buf, size, 0, NULL, &size);
if (!ret)
goto error;
data->u.pPDSip->psIndirectData = data->psPfns->pfnAlloc(size);
if (!data->u.pPDSip->psIndirectData)
{
SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
goto error;
}
ret = CryptDecodeObject(data->dwEncoding,
SPC_INDIRECT_DATA_CONTENT_STRUCT, buf, size, 0,
data->u.pPDSip->psIndirectData, &size);
}
else
{
FIXME("unimplemented for OID %s\n", (LPCSTR)buf);
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
ret = FALSE;
}
error:
TRACE("returning %d\n", ret);
return ret;
}
HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
TRACE("(%p)\n", data);
if (!data->padwTrustStepErrors)
return S_FALSE;
switch (data->pWintrustData->dwUnionChoice)
{
case WTD_CHOICE_CERT:
if (data->pWintrustData->u.pCert &&
data->pWintrustData->u.pCert->cbStruct == sizeof(WINTRUST_CERT_INFO))
{
if (data->psPfns)
{
CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
DWORD i;
/* Add a signer with nothing but the time to verify, so we can
* add a cert to it
*/
if (data->pWintrustData->u.pCert->psftVerifyAsOf)
data->sftSystemTime = signer.sftVerifyAsOf;
else
{
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
}
ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
if (!ret)
goto error;
ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
data->pWintrustData->u.pCert->psCertContext);
if (!ret)
goto error;
for (i = 0; ret && i < data->pWintrustData->u.pCert->chStores;
i++)
ret = data->psPfns->pfnAddStore2Chain(data,
data->pWintrustData->u.pCert->pahStores[i]);
}
else
{
/* Do nothing!? See the tests */
ret = TRUE;
}
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
ret = FALSE;
}
break;
case WTD_CHOICE_FILE:
if (!data->pWintrustData->u.pFile)
{
SetLastError(ERROR_INVALID_PARAMETER);
ret = FALSE;
goto error;
}
ret = SOFTPUB_OpenFile(data);
if (!ret)
goto error;
ret = SOFTPUB_GetFileSubject(data);
if (!ret)
goto error;
ret = SOFTPUB_GetSIP(data);
if (!ret)
goto error;
ret = SOFTPUB_GetMessageFromFile(data);
if (!ret)
goto error;
ret = SOFTPUB_CreateStoreFromMessage(data);
if (!ret)
goto error;
ret = SOFTPUB_DecodeInnerContent(data);
break;
default:
FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
SetLastError(ERROR_INVALID_PARAMETER);
ret = FALSE;
}
error:
if (!ret)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] =
GetLastError();
TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
return ret ? S_OK : S_FALSE;
}
static CMSG_SIGNER_INFO *WINTRUST_GetSigner(CRYPT_PROVIDER_DATA *data,
DWORD signerIdx)
{
BOOL ret;
CMSG_SIGNER_INFO *signerInfo = NULL;
DWORD size;
ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_INFO_PARAM, signerIdx,
NULL, &size);
if (ret)
{
signerInfo = data->psPfns->pfnAlloc(size);
if (signerInfo)
{
ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_INFO_PARAM,
signerIdx, signerInfo, &size);
if (!ret)
{
data->psPfns->pfnFree(signerInfo);
signerInfo = NULL;
}
}
else
SetLastError(ERROR_OUTOFMEMORY);
}
return signerInfo;
}
static BOOL WINTRUST_SaveSigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
{
BOOL ret;
CMSG_SIGNER_INFO *signerInfo = WINTRUST_GetSigner(data, signerIdx);
if (signerInfo)
{
CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } };
sgnr.psSigner = signerInfo;
sgnr.sftVerifyAsOf = data->sftSystemTime;
ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, signerIdx, &sgnr);
}
else
ret = FALSE;
return ret;
}
static CERT_INFO *WINTRUST_GetSignerCertInfo(CRYPT_PROVIDER_DATA *data,
DWORD signerIdx)
{
BOOL ret;
CERT_INFO *certInfo = NULL;
DWORD size;
ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_CERT_INFO_PARAM, signerIdx,
NULL, &size);
if (ret)
{
certInfo = data->psPfns->pfnAlloc(size);
if (certInfo)
{
ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_CERT_INFO_PARAM,
signerIdx, certInfo, &size);
if (!ret)
{
data->psPfns->pfnFree(certInfo);
certInfo = NULL;
}
}
else
SetLastError(ERROR_OUTOFMEMORY);
}
return certInfo;
}
static BOOL WINTRUST_VerifySigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
{
BOOL ret;
CERT_INFO *certInfo = WINTRUST_GetSignerCertInfo(data, signerIdx);
if (certInfo)
{
PCCERT_CONTEXT subject = CertGetSubjectCertificateFromStore(
data->pahStores[0], data->dwEncoding, certInfo);
if (subject)
{
CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA para = { sizeof(para), 0,
signerIdx, CMSG_VERIFY_SIGNER_CERT, (LPVOID)subject };
ret = CryptMsgControl(data->hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE_EX,
&para);
if (!ret)
SetLastError(TRUST_E_CERT_SIGNATURE);
else
data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0,
subject);
CertFreeCertificateContext(subject);
}
else
{
SetLastError(TRUST_E_NO_SIGNER_CERT);
ret = FALSE;
}
data->psPfns->pfnFree(certInfo);
}
else
ret = FALSE;
return ret;
}
HRESULT WINAPI SoftpubLoadSignature(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
TRACE("(%p)\n", data);
if (!data->padwTrustStepErrors)
return S_FALSE;
if (data->hMsg)
{
DWORD signerCount, size;
size = sizeof(signerCount);
ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_COUNT_PARAM, 0,
&signerCount, &size);
if (ret)
{
DWORD i;
for (i = 0; ret && i < signerCount; i++)
{
if ((ret = WINTRUST_SaveSigner(data, i)))
ret = WINTRUST_VerifySigner(data, i);
}
}
else
SetLastError(TRUST_E_NOSIGNATURE);
}
else
ret = TRUE;
if (!ret)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] =
GetLastError();
return ret ? S_OK : S_FALSE;
}
BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
BOOL fCounterSignerChain, DWORD idxCounterSigner)
{
BOOL ret;
TRACE("(%p, %d, %d, %d)\n", data, idxSigner, fCounterSignerChain,
idxCounterSigner);
if (fCounterSignerChain)
{
FIXME("unimplemented for counter signers\n");
ret = FALSE;
}
else
{
PCERT_SIMPLE_CHAIN simpleChain =
data->pasSigners[idxSigner].pChainContext->rgpChain[0];
DWORD i;
ret = TRUE;
for (i = 0; i < simpleChain->cElement; i++)
{
/* Set confidence */
data->pasSigners[idxSigner].pasCertChain[i].dwConfidence = 0;
if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_TIME_VALID))
data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
|= CERT_CONFIDENCE_TIME;
if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_TIME_NESTED))
data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
|= CERT_CONFIDENCE_TIMENEST;
if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_SIGNATURE_VALID))
data->pasSigners[idxSigner].pasCertChain[i].dwConfidence
|= CERT_CONFIDENCE_SIG;
/* Set additional flags */
if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_UNTRUSTED_ROOT))
data->pasSigners[idxSigner].pasCertChain[i].fTrustedRoot = TRUE;
if (simpleChain->rgpElement[i]->TrustStatus.dwInfoStatus &
CERT_TRUST_IS_SELF_SIGNED)
data->pasSigners[idxSigner].pasCertChain[i].fSelfSigned = TRUE;
if (simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_CYCLIC)
data->pasSigners[idxSigner].pasCertChain[i].fIsCyclic = TRUE;
}
}
return ret;
}
static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
{
BOOL ret;
PCERT_SIMPLE_CHAIN simpleChain =
data->pasSigners[signerIdx].pChainContext->rgpChain[0];
DWORD i;
data->pasSigners[signerIdx].pasCertChain[0].pChainElement =
simpleChain->rgpElement[0];
ret = TRUE;
for (i = 1; ret && i < simpleChain->cElement; i++)
{
ret = data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0,
simpleChain->rgpElement[i]->pCertContext);
if (ret)
data->pasSigners[signerIdx].pasCertChain[i].pChainElement =
simpleChain->rgpElement[i];
}
return ret;
}
static void WINTRUST_CreateChainPolicyCreateInfo(
const CRYPT_PROVIDER_DATA *data, PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO info,
PCERT_CHAIN_PARA chainPara)
{
chainPara->cbSize = sizeof(CERT_CHAIN_PARA);
if (data->pRequestUsage)
chainPara->RequestedUsage = *data->pRequestUsage;
info->u.cbSize = sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO);
info->hChainEngine = NULL;
info->pChainPara = chainPara;
if (data->dwProvFlags & CPD_REVOCATION_CHECK_END_CERT)
info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_END_CERT;
else if (data->dwProvFlags & CPD_REVOCATION_CHECK_CHAIN)
info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN;
else if (data->dwProvFlags & CPD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)
info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
else
info->dwFlags = 0;
info->pvReserved = NULL;
}
static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data,
DWORD signer, PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo,
PCERT_CHAIN_PARA chainPara)
{
BOOL ret = TRUE;
/* Expect the end certificate for each signer to be the only cert in the
* chain:
*/
if (data->pasSigners[signer].csCertChain)
{
/* Create a certificate chain for each signer */
ret = CertGetCertificateChain(createInfo->hChainEngine,
data->pasSigners[signer].pasCertChain[0].pCert,
&data->pasSigners[signer].sftVerifyAsOf,
data->chStores ? data->pahStores[0] : NULL,
chainPara, createInfo->dwFlags, createInfo->pvReserved,
&data->pasSigners[signer].pChainContext);
if (ret)
{
if (data->pasSigners[signer].pChainContext->cChain != 1)
{
FIXME("unimplemented for more than 1 simple chain\n");
ret = FALSE;
}
else
{
if ((ret = WINTRUST_CopyChain(data, signer)))
ret = data->psPfns->pfnCertCheckPolicy(data, signer, FALSE,
0);
}
}
}
return ret;
}
HRESULT WINAPI WintrustCertificateTrust(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
TRACE("(%p)\n", data);
if (!data->csSigners)
{
ret = FALSE;
SetLastError(TRUST_E_NOSIGNATURE);
}
else
{
DWORD i;
WTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo;
CERT_CHAIN_PARA chainPara;
WINTRUST_CreateChainPolicyCreateInfo(data, &createInfo, &chainPara);
ret = TRUE;
for (i = 0; i < data->csSigners; i++)
ret = WINTRUST_CreateChainForSigner(data, i, &createInfo,
&chainPara);
}
if (!ret)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
GetLastError();
TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
return ret ? S_OK : S_FALSE;
}
HRESULT WINAPI GenericChainCertificateTrust(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
WTD_GENERIC_CHAIN_POLICY_DATA *policyData =
(WTD_GENERIC_CHAIN_POLICY_DATA *)data->pWintrustData->pPolicyCallbackData;
TRACE("(%p)\n", data);
if (policyData && policyData->u.cbSize !=
sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO))
{
SetLastError(ERROR_INVALID_PARAMETER);
ret = FALSE;
goto end;
}
if (!data->csSigners)
{
ret = FALSE;
SetLastError(TRUST_E_NOSIGNATURE);
}
else
{
DWORD i;
WTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo, *pCreateInfo;
CERT_CHAIN_PARA chainPara, *pChainPara;
if (policyData)
{
pCreateInfo = policyData->pSignerChainInfo;
pChainPara = pCreateInfo->pChainPara;
}
else
{
WINTRUST_CreateChainPolicyCreateInfo(data, &createInfo, &chainPara);
pChainPara = &chainPara;
pCreateInfo = &createInfo;
}
ret = TRUE;
for (i = 0; i < data->csSigners; i++)
ret = WINTRUST_CreateChainForSigner(data, i, pCreateInfo,
pChainPara);
}
end:
if (!ret)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
GetLastError();
TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
return ret ? S_OK : S_FALSE;
}
HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data)
{
BOOL ret;
CERT_CHAIN_POLICY_STATUS policyStatus = { sizeof(policyStatus), 0 };
TRACE("(%p)\n", data);
if (data->pWintrustData->dwUIChoice != WTD_UI_NONE)
FIXME("unimplemented for UI choice %d\n",
data->pWintrustData->dwUIChoice);
if (!data->csSigners)
{
ret = FALSE;
policyStatus.dwError = TRUST_E_NOSIGNATURE;
}
else
{
DWORD i;
ret = TRUE;
for (i = 0; ret && i < data->csSigners; i++)
{
CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
if (data->dwRegPolicySettings & WTPF_TRUSTTEST)
policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID)
policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG;
if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
policyPara.dwFlags |=
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION)
policyPara.dwFlags |=
CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE,
data->pasSigners[i].pChainContext, &policyPara, &policyStatus);
if (policyStatus.dwError != NO_ERROR)
ret = FALSE;
}
}
if (!ret)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] =
policyStatus.dwError;
TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
return ret ? S_OK : S_FALSE;
}
static HRESULT WINAPI WINTRUST_DefaultPolicy(CRYPT_PROVIDER_DATA *pProvData,
DWORD dwStepError, DWORD dwRegPolicySettings, DWORD cSigner,
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO rgpSigner, void *pvPolicyArg)
{
DWORD i;
CERT_CHAIN_POLICY_STATUS policyStatus = { sizeof(policyStatus), 0 };
for (i = 0; !policyStatus.dwError && i < cSigner; i++)
{
CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
if (dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
policyPara.dwFlags |=
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
if (dwRegPolicySettings & WTPF_IGNOREREVOKATION)
policyPara.dwFlags |=
CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE,
rgpSigner[i].pChainContext, &policyPara, &policyStatus);
}
return policyStatus.dwError;
}
HRESULT WINAPI GenericChainFinalProv(CRYPT_PROVIDER_DATA *data)
{
HRESULT err = NO_ERROR; /* not a typo, MS confused the types */
WTD_GENERIC_CHAIN_POLICY_DATA *policyData =
(WTD_GENERIC_CHAIN_POLICY_DATA *)data->pWintrustData->pPolicyCallbackData;
TRACE("(%p)\n", data);
if (data->pWintrustData->dwUIChoice != WTD_UI_NONE)
FIXME("unimplemented for UI choice %d\n",
data->pWintrustData->dwUIChoice);
if (!data->csSigners)
err = TRUST_E_NOSIGNATURE;
else
{
PFN_WTD_GENERIC_CHAIN_POLICY_CALLBACK policyCallback;
void *policyArg;
WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *signers = NULL;
if (policyData)
{
policyCallback = policyData->pfnPolicyCallback;
policyArg = policyData->pvPolicyArg;
}
else
{
policyCallback = WINTRUST_DefaultPolicy;
policyArg = NULL;
}
if (data->csSigners)
{
DWORD i;
signers = data->psPfns->pfnAlloc(
data->csSigners * sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO));
if (signers)
{
for (i = 0; i < data->csSigners; i++)
{
signers[i].u.cbSize =
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO);
signers[i].pChainContext =
data->pasSigners[i].pChainContext;
signers[i].dwSignerType = data->pasSigners[i].dwSignerType;
signers[i].pMsgSignerInfo = data->pasSigners[i].psSigner;
signers[i].dwError = data->pasSigners[i].dwError;
if (data->pasSigners[i].csCounterSigners)
FIXME("unimplemented for counter signers\n");
signers[i].cCounterSigner = 0;
signers[i].rgpCounterSigner = NULL;
}
}
else
err = ERROR_OUTOFMEMORY;
}
if (!err)
err = policyCallback(data, TRUSTERROR_STEP_FINAL_POLICYPROV,
data->dwRegPolicySettings, data->csSigners, signers, policyArg);
data->psPfns->pfnFree(signers);
}
if (err)
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = err;
TRACE("returning %d (%08x)\n", !err ? S_OK : S_FALSE,
data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
return err == NO_ERROR ? S_OK : S_FALSE;
}
HRESULT WINAPI SoftpubCleanup(CRYPT_PROVIDER_DATA *data)
{
DWORD i, j;
for (i = 0; i < data->csSigners; i++)
{
for (j = 0; j < data->pasSigners[i].csCertChain; j++)
CertFreeCertificateContext(data->pasSigners[i].pasCertChain[j].pCert);
data->psPfns->pfnFree(data->pasSigners[i].pasCertChain);
data->psPfns->pfnFree(data->pasSigners[i].psSigner);
CertFreeCertificateChain(data->pasSigners[i].pChainContext);
}
data->psPfns->pfnFree(data->pasSigners);
for (i = 0; i < data->chStores; i++)
CertCloseStore(data->pahStores[i], 0);
data->psPfns->pfnFree(data->pahStores);
if (data->u.pPDSip)
{
data->psPfns->pfnFree(data->u.pPDSip->pSip);
data->psPfns->pfnFree(data->u.pPDSip->pCATSip);
data->psPfns->pfnFree(data->u.pPDSip->psSipSubjectInfo);
data->psPfns->pfnFree(data->u.pPDSip->psSipCATSubjectInfo);
data->psPfns->pfnFree(data->u.pPDSip->psIndirectData);
}
CryptMsgClose(data->hMsg);
if (data->fOpenedFile)
CloseHandle(data->pWintrustData->u.pFile->hFile);
return S_OK;
}

View file

@ -12,10 +12,13 @@
<library>user32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>imagehlp</library>
<library>ntdll</library>
<file>crypt.c</file>
<file>register.c</file>
<file>wintrust_main.c</file>
<file>asn.c</file>
<file>softpub.c</file>
<file>version.rc</file>
<file>wintrust.spec</file>
</module>

View file

@ -1,11 +1,11 @@
@ stub AddPersonalTrustDBPages
@ stub CatalogCompactHashDatabase
@ stdcall CryptCATAdminAcquireContext(long ptr long)
@ stub CryptCATAdminAddCatalog
@ stdcall CryptCATAdminAddCatalog(long wstr wstr long)
@ stdcall CryptCATAdminCalcHashFromFileHandle(long ptr ptr long)
@ stdcall CryptCATAdminEnumCatalogFromHash(long ptr long long ptr)
@ stub CryptCATAdminPauseServiceForBackup
@ stub CryptCATAdminReleaseCatalogContext
@ stdcall CryptCATAdminReleaseCatalogContext(long long long)
@ stdcall CryptCATAdminReleaseContext(long long)
@ stdcall CryptCATAdminRemoveCatalog(ptr wstr long)
@ stub CryptCATAdminResolveCatalogPath
@ -46,8 +46,8 @@
@ stub DriverFinalPolicy
@ stub DriverInitializePolicy
@ stub FindCertsByIssuer
@ stub GenericChainCertificateTrust
@ stub GenericChainFinalProv
@ stdcall GenericChainCertificateTrust(ptr)
@ stdcall GenericChainFinalProv(ptr)
@ stub HTTPSCertificateTrust
@ stub HTTPSFinalProv
@ stub IsCatalogFile
@ -56,18 +56,18 @@
@ stub OfficeCleanupPolicy
@ stub OfficeInitializePolicy
@ stub OpenPersonalTrustDBDialog
@ stub SoftpubAuthenticode
@ stub SoftpubCheckCert
@ stub SoftpubCleanup
@ stub SoftpubDefCertInit
@ stdcall SoftpubAuthenticode(ptr)
@ stdcall SoftpubCheckCert(ptr long long long)
@ stdcall SoftpubCleanup(ptr)
@ stdcall SoftpubDefCertInit(ptr)
@ stdcall SoftpubDllRegisterServer()
@ stdcall SoftpubDllUnregisterServer()
@ stub SoftpubDumpStructure
@ stub SoftpubFreeDefUsageCallData
@ stub SoftpubInitialize
@ stdcall SoftpubInitialize(ptr)
@ stub SoftpubLoadDefUsageCallData
@ stub SoftpubLoadMessage
@ stub SoftpubLoadSignature
@ stdcall SoftpubLoadMessage(ptr)
@ stdcall SoftpubLoadSignature(ptr)
@ stub TrustDecode
@ stub TrustFindIssuerCertificate
@ stub TrustFreeDecode
@ -77,11 +77,11 @@
@ stub WTHelperCertIsSelfSigned
@ stub WTHelperCheckCertUsage
@ stub WTHelperGetAgencyInfo
@ stub WTHelperGetFileHandle
@ stub WTHelperGetFileName
@ stdcall WTHelperGetFileHandle(ptr)
@ stdcall WTHelperGetFileName(ptr)
@ stub WTHelperGetKnownUsages
@ stub WTHelperGetProvCertFromChain
@ stub WTHelperGetProvPrivateDataFromChain
@ stdcall WTHelperGetProvCertFromChain(ptr long)
@ stdcall WTHelperGetProvPrivateDataFromChain(ptr ptr)
@ stdcall WTHelperGetProvSignerFromChain(ptr long long long)
@ stub WTHelperIsInRootStore
@ stub WTHelperOpenKnownStores
@ -92,19 +92,19 @@
@ stub WVTAsn1CatNameValueEncode
@ stub WVTAsn1SpcFinancialCriteriaInfoDecode
@ stub WVTAsn1SpcFinancialCriteriaInfoEncode
@ stub WVTAsn1SpcIndirectDataContentDecode
@ stub WVTAsn1SpcIndirectDataContentEncode
@ stub WVTAsn1SpcLinkDecode
@ stub WVTAsn1SpcLinkEncode
@ stdcall WVTAsn1SpcIndirectDataContentDecode(long str ptr long long ptr ptr)
@ stdcall WVTAsn1SpcIndirectDataContentEncode(long str ptr ptr ptr)
@ stdcall WVTAsn1SpcLinkDecode(long str ptr long long ptr ptr)
@ stdcall WVTAsn1SpcLinkEncode(long str ptr ptr ptr)
@ stub WVTAsn1SpcMinimalCriteriaInfoDecode
@ stub WVTAsn1SpcMinimalCriteriaInfoEncode
@ stub WVTAsn1SpcPeImageDataDecode
@ stub WVTAsn1SpcPeImageDataEncode
@ stdcall WVTAsn1SpcPeImageDataDecode(long str ptr long long ptr ptr)
@ stdcall WVTAsn1SpcPeImageDataEncode(long str ptr ptr ptr)
@ stub WVTAsn1SpcSigInfoDecode
@ stub WVTAsn1SpcSigInfoEncode
@ stub WVTAsn1SpcSpAgencyInfoDecode
@ stub WVTAsn1SpcSpAgencyInfoEncode
@ stub WVTAsn1SpcSpOpusInfoDecode
@ stdcall WVTAsn1SpcSpOpusInfoDecode(long str ptr long long ptr ptr)
@ stub WVTAsn1SpcSpOpusInfoEncode
@ stub WVTAsn1SpcStatementTypeDecode
@ stub WVTAsn1SpcStatementTypeEncode
@ -112,7 +112,7 @@
@ stdcall WinVerifyTrustEx(long ptr ptr)
@ stdcall WintrustAddActionID(ptr long ptr)
@ stdcall WintrustAddDefaultForUsage(ptr ptr)
@ stub WintrustCertificateTrust
@ stdcall WintrustCertificateTrust(ptr)
@ stub WintrustGetDefaultForUsage
@ stdcall WintrustGetRegPolicyFlags(ptr)
@ stdcall WintrustLoadFunctionPointers(ptr ptr)

View file

@ -1,5 +1,6 @@
/*
* Copyright 2001 Rein Klazes
* Copyright 2007 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,15 +21,19 @@
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "guiddef.h"
#include "wintrust.h"
#include "softpub.h"
#include "mscat.h"
#include "objbase.h"
#include "winuser.h"
#include "wintrust_priv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
@ -41,8 +46,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
{
switch(reason)
{
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( inst );
break;
@ -63,6 +66,284 @@ BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
return ret;
}
typedef HRESULT (WINAPI *wintrust_step_func)(CRYPT_PROVIDER_DATA *data);
struct wintrust_step
{
wintrust_step_func func;
DWORD error_index;
};
static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps,
DWORD numSteps, CRYPT_PROVIDER_DATA *provData)
{
DWORD i, err = ERROR_SUCCESS;
for (i = 0; !err && i < numSteps; i++)
{
err = steps[i].func(provData);
if (err)
err = provData->padwTrustStepErrors[steps[i].error_index];
}
return err;
}
static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID,
WINTRUST_DATA *data)
{
DWORD err = ERROR_SUCCESS, numSteps = 0;
CRYPT_PROVIDER_DATA *provData;
BOOL ret;
struct wintrust_step verifySteps[5];
TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA));
if (!provData)
goto oom;
provData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
provData->padwTrustStepErrors =
WINTRUST_Alloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
if (!provData->padwTrustStepErrors)
goto oom;
provData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
provData->u.pPDSip = WINTRUST_Alloc(sizeof(PROVDATA_SIP));
if (!provData->u.pPDSip)
goto oom;
provData->u.pPDSip->cbStruct = sizeof(PROVDATA_SIP);
provData->psPfns = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_FUNCTIONS));
if (!provData->psPfns)
goto oom;
provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
ret = WintrustLoadFunctionPointers(actionID, provData->psPfns);
if (!ret)
{
err = GetLastError();
goto error;
}
data->hWVTStateData = (HANDLE)provData;
provData->pWintrustData = data;
if (hwnd == INVALID_HANDLE_VALUE)
provData->hWndParent = GetDesktopWindow();
else
provData->hWndParent = hwnd;
provData->pgActionID = actionID;
WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings);
if (provData->psPfns->pfnInitialize)
{
verifySteps[numSteps].func = provData->psPfns->pfnInitialize;
verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT;
}
if (provData->psPfns->pfnObjectTrust)
{
verifySteps[numSteps].func = provData->psPfns->pfnObjectTrust;
verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV;
}
if (provData->psPfns->pfnSignatureTrust)
{
verifySteps[numSteps].func = provData->psPfns->pfnSignatureTrust;
verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV;
}
if (provData->psPfns->pfnCertificateTrust)
{
verifySteps[numSteps].func = provData->psPfns->pfnCertificateTrust;
verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV;
}
if (provData->psPfns->pfnFinalPolicy)
{
verifySteps[numSteps].func = provData->psPfns->pfnFinalPolicy;
verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV;
}
err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData);
goto done;
oom:
err = ERROR_OUTOFMEMORY;
error:
if (provData)
{
WINTRUST_Free(provData->padwTrustStepErrors);
WINTRUST_Free(provData->u.pPDSip);
WINTRUST_Free(provData->psPfns);
WINTRUST_Free(provData);
}
done:
TRACE("returning %08x\n", err);
return err;
}
static LONG WINTRUST_DefaultClose(HWND hwnd, GUID *actionID,
WINTRUST_DATA *data)
{
DWORD err = ERROR_SUCCESS;
CRYPT_PROVIDER_DATA *provData = (CRYPT_PROVIDER_DATA *)data->hWVTStateData;
TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
if (provData)
{
if (provData->psPfns->pfnCleanupPolicy)
err = provData->psPfns->pfnCleanupPolicy(provData);
WINTRUST_Free(provData->padwTrustStepErrors);
WINTRUST_Free(provData->u.pPDSip);
WINTRUST_Free(provData->psPfns);
WINTRUST_Free(provData);
data->hWVTStateData = NULL;
}
TRACE("returning %08x\n", err);
return err;
}
static LONG WINTRUST_DefaultVerifyAndClose(HWND hwnd, GUID *actionID,
WINTRUST_DATA *data)
{
LONG err;
TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data);
err = WINTRUST_DefaultVerify(hwnd, actionID, data);
WINTRUST_DefaultClose(hwnd, actionID, data);
TRACE("returning %08x\n", err);
return err;
}
static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID,
WINTRUST_DATA *data)
{
WINTRUST_DATA wintrust_data = { sizeof(wintrust_data), 0 };
/* Undocumented: the published software action is passed a path,
* and pSIPClientData points to a WIN_TRUST_SUBJECT_FILE.
*/
LPWIN_TRUST_SUBJECT_FILE subjectFile =
(LPWIN_TRUST_SUBJECT_FILE)data->pSIPClientData;
WINTRUST_FILE_INFO fileInfo = { sizeof(fileInfo), 0 };
TRACE("subjectFile->hFile: %p\n", subjectFile->hFile);
TRACE("subjectFile->lpPath: %s\n", debugstr_w(subjectFile->lpPath));
fileInfo.pcwszFilePath = subjectFile->lpPath;
fileInfo.hFile = subjectFile->hFile;
wintrust_data.u.pFile = &fileInfo;
wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
wintrust_data.dwUIChoice = WTD_UI_NONE;
return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data);
}
static void dump_file_info(WINTRUST_FILE_INFO *pFile)
{
TRACE("%p\n", pFile);
if (pFile)
{
TRACE("cbStruct: %d\n", pFile->cbStruct);
TRACE("pcwszFilePath: %s\n", debugstr_w(pFile->pcwszFilePath));
TRACE("hFile: %p\n", pFile->hFile);
TRACE("pgKnownSubject: %s\n", debugstr_guid(pFile->pgKnownSubject));
}
}
static void dump_catalog_info(WINTRUST_CATALOG_INFO *catalog)
{
TRACE("%p\n", catalog);
if (catalog)
{
TRACE("cbStruct: %d\n", catalog->cbStruct);
TRACE("dwCatalogVersion: %d\n", catalog->dwCatalogVersion);
TRACE("pcwszCatalogFilePath: %s\n",
debugstr_w(catalog->pcwszCatalogFilePath));
TRACE("pcwszMemberTag: %s\n", debugstr_w(catalog->pcwszMemberTag));
TRACE("pcwszMemberFilePath: %s\n",
debugstr_w(catalog->pcwszMemberFilePath));
TRACE("hMemberFile: %p\n", catalog->hMemberFile);
TRACE("pbCalculatedFileHash: %p\n", catalog->pbCalculatedFileHash);
TRACE("cbCalculatedFileHash: %d\n", catalog->cbCalculatedFileHash);
TRACE("pcCatalogContext: %p\n", catalog->pcCatalogContext);
}
}
static void dump_blob_info(WINTRUST_BLOB_INFO *blob)
{
TRACE("%p\n", blob);
if (blob)
{
TRACE("cbStruct: %d\n", blob->cbStruct);
TRACE("gSubject: %s\n", debugstr_guid(&blob->gSubject));
TRACE("pcwszDisplayName: %s\n", debugstr_w(blob->pcwszDisplayName));
TRACE("cbMemObject: %d\n", blob->cbMemObject);
TRACE("pbMemObject: %p\n", blob->pbMemObject);
TRACE("cbMemSignedMsg: %d\n", blob->cbMemSignedMsg);
TRACE("pbMemSignedMsg: %p\n", blob->pbMemSignedMsg);
}
}
static void dump_sgnr_info(WINTRUST_SGNR_INFO *sgnr)
{
TRACE("%p\n", sgnr);
if (sgnr)
{
TRACE("cbStruct: %d\n", sgnr->cbStruct);
TRACE("pcwszDisplayName: %s\n", debugstr_w(sgnr->pcwszDisplayName));
TRACE("psSignerInfo: %p\n", sgnr->psSignerInfo);
TRACE("chStores: %d\n", sgnr->chStores);
}
}
static void dump_cert_info(WINTRUST_CERT_INFO *cert)
{
TRACE("%p\n", cert);
if (cert)
{
TRACE("cbStruct: %d\n", cert->cbStruct);
TRACE("pcwszDisplayName: %s\n", debugstr_w(cert->pcwszDisplayName));
TRACE("psCertContext: %p\n", cert->psCertContext);
TRACE("chStores: %d\n", cert->chStores);
TRACE("dwFlags: %08x\n", cert->dwFlags);
TRACE("psftVerifyAsOf: %p\n", cert->psftVerifyAsOf);
}
}
static void dump_wintrust_data(WINTRUST_DATA *data)
{
TRACE("%p\n", data);
if (data)
{
TRACE("cbStruct: %d\n", data->cbStruct);
TRACE("pPolicyCallbackData: %p\n", data->pPolicyCallbackData);
TRACE("pSIPClientData: %p\n", data->pSIPClientData);
TRACE("dwUIChoice: %d\n", data->dwUIChoice);
TRACE("fdwRevocationChecks: %08x\n", data->fdwRevocationChecks);
TRACE("dwUnionChoice: %d\n", data->dwUnionChoice);
switch (data->dwUnionChoice)
{
case WTD_CHOICE_FILE:
dump_file_info(data->u.pFile);
break;
case WTD_CHOICE_CATALOG:
dump_catalog_info(data->u.pCatalog);
break;
case WTD_CHOICE_BLOB:
dump_blob_info(data->u.pBlob);
break;
case WTD_CHOICE_SIGNER:
dump_sgnr_info(data->u.pSgnr);
break;
case WTD_CHOICE_CERT:
dump_cert_info(data->u.pCert);
break;
}
TRACE("dwStateAction: %d\n", data->dwStateAction);
TRACE("hWVTStateData: %p\n", data->hWVTStateData);
TRACE("pwszURLReference: %s\n", debugstr_w(data->pwszURLReference));
TRACE("dwProvFlags: %08x\n", data->dwProvFlags);
TRACE("dwUIContext: %d\n", data->dwUIContext);
}
}
/***********************************************************************
* WinVerifyTrust (WINTRUST.@)
*
@ -83,27 +364,48 @@ BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
*/
LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
{
static const GUID gen_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
static const GUID published_software = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
LONG err = ERROR_SUCCESS;
WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData;
FIXME("%p %s %p\n", hwnd, debugstr_guid(ActionID), ActionData);
TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(ActionID), ActionData);
dump_wintrust_data(ActionData);
/* Trust providers can be found at:
* HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\CertCheck\
*
* Process Explorer expects a correct implementation, so we
* return TRUST_E_PROVIDER_UNKNOWN.
*
* Girotel needs ERROR_SUCCESS.
*
* For now return TRUST_E_PROVIDER_UNKNOWN only when
* ActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2.
*
*/
/* Support for known old-style callers: */
if (IsEqualGUID(ActionID, &published_software))
err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData);
else
{
/* Check known actions to warn of possible problems */
if (!IsEqualGUID(ActionID, &unknown) &&
!IsEqualGUID(ActionID, &generic_verify_v2) &&
!IsEqualGUID(ActionID, &generic_cert_verify) &&
!IsEqualGUID(ActionID, &generic_chain_verify))
WARN("unknown action %s, default behavior may not be right\n",
debugstr_guid(ActionID));
switch (actionData->dwStateAction)
{
case WTD_STATEACTION_IGNORE:
err = WINTRUST_DefaultVerifyAndClose(hwnd, ActionID, ActionData);
break;
case WTD_STATEACTION_VERIFY:
err = WINTRUST_DefaultVerify(hwnd, ActionID, ActionData);
break;
case WTD_STATEACTION_CLOSE:
err = WINTRUST_DefaultClose(hwnd, ActionID, ActionData);
break;
default:
FIXME("unimplemented for %d\n", actionData->dwStateAction);
}
}
if (IsEqualCLSID(ActionID, &gen_verify_v2))
return TRUST_E_PROVIDER_UNKNOWN;
return ERROR_SUCCESS;
TRACE("returning %08x\n", err);
return err;
}
/***********************************************************************
@ -112,8 +414,7 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData )
HRESULT WINAPI WinVerifyTrustEx( HWND hwnd, GUID *ActionID,
WINTRUST_DATA* ActionData )
{
FIXME("%p %s %p\n", hwnd, debugstr_guid(ActionID), ActionData);
return S_OK;
return WinVerifyTrust(hwnd, ActionID, ActionData);
}
/***********************************************************************
@ -123,9 +424,59 @@ CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
DWORD idxCounterSigner)
{
FIXME("%p %d %d %d\n", pProvData, idxSigner, fCounterSigner,
CRYPT_PROVIDER_SGNR *sgnr;
TRACE("(%p %d %d %d)\n", pProvData, idxSigner, fCounterSigner,
idxCounterSigner);
return NULL;
if (idxSigner >= pProvData->csSigners || !pProvData->pasSigners)
return NULL;
sgnr = &pProvData->pasSigners[idxSigner];
if (fCounterSigner)
{
if (idxCounterSigner >= sgnr->csCounterSigners ||
!sgnr->pasCounterSigners)
return NULL;
sgnr = &sgnr->pasCounterSigners[idxCounterSigner];
}
TRACE("returning %p\n", sgnr);
return sgnr;
}
/***********************************************************************
* WTHelperGetProvCertFromChain (WINTRUST.@)
*/
CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert)
{
CRYPT_PROVIDER_CERT *cert;
TRACE("(%p %d)\n", pSgnr, idxCert);
if (idxCert >= pSgnr->csCertChain || !pSgnr->pasCertChain)
return NULL;
cert = &pSgnr->pasCertChain[idxCert];
TRACE("returning %p\n", cert);
return cert;
}
CRYPT_PROVIDER_PRIVDATA *WINAPI WTHelperGetProvPrivateDataFromChain(
CRYPT_PROVIDER_DATA* pProvData,
GUID* pgProviderID)
{
CRYPT_PROVIDER_PRIVDATA *privdata = NULL;
DWORD i;
TRACE("(%p, %s)\n", pProvData, debugstr_guid(pgProviderID));
for (i = 0; i < pProvData->csProvPrivData; i++)
if (IsEqualGUID(pgProviderID, &pProvData->pasProvPrivData[i].gProviderID))
{
privdata = &pProvData->pasProvPrivData[i];
break;
}
return privdata;
}
/***********************************************************************
@ -133,28 +484,76 @@ CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
*/
CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData)
{
FIXME("%p\n", hStateData);
return NULL;
TRACE("%p\n", hStateData);
return (CRYPT_PROVIDER_DATA *)hStateData;
}
/***********************************************************************
* WintrustLoadFunctionPointers (WINTRUST.@)
* WTHelperGetFileName(WINTRUST.@)
*/
BOOL WINAPI WintrustLoadFunctionPointers( GUID* pgActionID,
CRYPT_PROVIDER_FUNCTIONS* pPfns )
LPCWSTR WINAPI WTHelperGetFileName(WINTRUST_DATA *data)
{
FIXME("%s %p\n", debugstr_guid(pgActionID), pPfns);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
TRACE("%p\n",data);
if (data->dwUnionChoice == WTD_CHOICE_FILE)
return data->u.pFile->pcwszFilePath;
else
return NULL;
}
/***********************************************************************
* WTHelperGetFileHandle(WINTRUST.@)
*/
HANDLE WINAPI WTHelperGetFileHandle(WINTRUST_DATA *data)
{
TRACE("%p\n",data);
if (data->dwUnionChoice == WTD_CHOICE_FILE)
return data->u.pFile->hFile;
else
return INVALID_HANDLE_VALUE;
}
static const WCHAR Software_Publishing[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'W','i','n','t','r','u','s','t','\\',
'T','r','u','s','t',' ','P','r','o','v','i','d','e','r','s','\\',
'S','o','f','t','w','a','r','e',' ',
'P','u','b','l','i','s','h','i','n','g',0 };
static const WCHAR State[] = { 'S','t','a','t','e',0 };
/***********************************************************************
* WintrustGetRegPolicyFlags (WINTRUST.@)
*/
void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
{
FIXME("%p\n", pdwPolicyFlags);
HKEY key;
LONG r;
TRACE("%p\n", pdwPolicyFlags);
*pdwPolicyFlags = 0;
r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0, NULL, 0,
KEY_READ, NULL, &key, NULL);
if (!r)
{
DWORD size = sizeof(DWORD);
r = RegQueryValueExW(key, State, NULL, NULL, (LPBYTE)pdwPolicyFlags,
&size);
RegCloseKey(key);
if (r)
{
/* Failed to query, create and return default value */
*pdwPolicyFlags = WTPF_IGNOREREVOCATIONONTS |
WTPF_OFFLINEOKNBU_COM |
WTPF_OFFLINEOKNBU_IND |
WTPF_OFFLINEOK_COM |
WTPF_OFFLINEOK_IND;
WintrustSetRegPolicyFlags(*pdwPolicyFlags);
}
}
}
/***********************************************************************
@ -162,6 +561,183 @@ void WINAPI WintrustGetRegPolicyFlags( DWORD* pdwPolicyFlags )
*/
BOOL WINAPI WintrustSetRegPolicyFlags( DWORD dwPolicyFlags)
{
FIXME("stub: %x\n", dwPolicyFlags);
return TRUE;
HKEY key;
LONG r;
TRACE("%x\n", dwPolicyFlags);
r = RegCreateKeyExW(HKEY_CURRENT_USER, Software_Publishing, 0,
NULL, 0, KEY_WRITE, NULL, &key, NULL);
if (!r)
{
r = RegSetValueExW(key, State, 0, REG_DWORD, (LPBYTE)&dwPolicyFlags,
sizeof(DWORD));
RegCloseKey(key);
}
if (r) SetLastError(r);
return r == ERROR_SUCCESS;
}
/* Utility functions */
void * WINAPI WINTRUST_Alloc(DWORD cb)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
}
void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb)
{
return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, cb);
}
void WINAPI WINTRUST_Free(void *p)
{
HeapFree(GetProcessHeap(), 0, p);
}
BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store)
{
BOOL ret = FALSE;
if (data->chStores)
data->pahStores = WINTRUST_ReAlloc(data->pahStores,
(data->chStores + 1) * sizeof(HCERTSTORE));
else
{
data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE));
data->chStores = 0;
}
if (data->pahStores)
{
data->pahStores[data->chStores++] = CertDuplicateStore(store);
ret = TRUE;
}
else
SetLastError(ERROR_OUTOFMEMORY);
return ret;
}
BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr)
{
BOOL ret = FALSE;
if (sgnr->cbStruct > sizeof(CRYPT_PROVIDER_SGNR))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (fCounterSigner)
{
FIXME("unimplemented for counter signers\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (data->csSigners)
data->pasSigners = WINTRUST_ReAlloc(data->pasSigners,
(data->csSigners + 1) * sizeof(CRYPT_PROVIDER_SGNR));
else
{
data->pasSigners = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
data->csSigners = 0;
}
if (data->pasSigners)
{
if (idxSigner < data->csSigners)
memmove(&data->pasSigners[idxSigner],
&data->pasSigners[idxSigner + 1],
(data->csSigners - idxSigner) * sizeof(CRYPT_PROVIDER_SGNR));
ret = TRUE;
if (sgnr->cbStruct == sizeof(CRYPT_PROVIDER_SGNR))
{
/* The PSDK says psSigner should be allocated using pfnAlloc, but
* it doesn't say anything about ownership. Since callers are
* internal, assume ownership is passed, and just store the
* pointer.
*/
memcpy(&data->pasSigners[idxSigner], sgnr,
sizeof(CRYPT_PROVIDER_SGNR));
}
else
memset(&data->pasSigners[idxSigner], 0,
sizeof(CRYPT_PROVIDER_SGNR));
data->csSigners++;
}
else
SetLastError(ERROR_OUTOFMEMORY);
return ret;
}
BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add)
{
BOOL ret = FALSE;
if (fCounterSigner)
{
FIXME("unimplemented for counter signers\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (data->pasSigners[idxSigner].csCertChain)
data->pasSigners[idxSigner].pasCertChain =
WINTRUST_ReAlloc(data->pasSigners[idxSigner].pasCertChain,
(data->pasSigners[idxSigner].csCertChain + 1) *
sizeof(CRYPT_PROVIDER_CERT));
else
{
data->pasSigners[idxSigner].pasCertChain =
WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_CERT));
data->pasSigners[idxSigner].csCertChain = 0;
}
if (data->pasSigners[idxSigner].pasCertChain)
{
CRYPT_PROVIDER_CERT *cert = &data->pasSigners[idxSigner].pasCertChain[
data->pasSigners[idxSigner].csCertChain];
cert->cbStruct = sizeof(CRYPT_PROVIDER_CERT);
cert->pCert = CertDuplicateCertificateContext(pCert2Add);
data->pasSigners[idxSigner].csCertChain++;
ret = TRUE;
}
else
SetLastError(ERROR_OUTOFMEMORY);
return ret;
}
BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
CRYPT_PROVIDER_PRIVDATA *pPrivData2Add)
{
BOOL ret = FALSE;
TRACE("(%p, %p)\n", data, pPrivData2Add);
if (pPrivData2Add->cbStruct > sizeof(CRYPT_PROVIDER_PRIVDATA))
{
SetLastError(ERROR_INVALID_PARAMETER);
WARN("invalid struct size\n");
return FALSE;
}
if (data->csProvPrivData)
data->pasProvPrivData = WINTRUST_ReAlloc(data->pasProvPrivData,
(data->csProvPrivData + 1) * sizeof(CRYPT_PROVIDER_SGNR));
else
{
data->pasProvPrivData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_SGNR));
data->csProvPrivData = 0;
}
if (data->pasProvPrivData)
{
DWORD i;
for (i = 0; i < data->csProvPrivData; i++)
if (IsEqualGUID(&pPrivData2Add->gProviderID, &data->pasProvPrivData[i]))
break;
data->pasProvPrivData[i] = *pPrivData2Add;
if (i == data->csProvPrivData)
data->csProvPrivData++;
}
else
SetLastError(ERROR_OUTOFMEMORY);
return ret;
}

View file

@ -0,0 +1,32 @@
/*
* Copyright 2007 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINTRUST_PRIV_H__
#define __WINTRUST_PRIV_H__
void * WINAPI WINTRUST_Alloc(DWORD cb);
void * WINAPI WINTRUST_ReAlloc(void *ptr, DWORD cb);
void WINAPI WINTRUST_Free(void *p);
BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store);
BOOL WINAPI WINTRUST_AddSgnr(CRYPT_PROVIDER_DATA *data,
BOOL fCounterSigner, DWORD idxSigner, CRYPT_PROVIDER_SGNR *sgnr);
BOOL WINAPI WINTRUST_AddCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
BOOL fCounterSigner, DWORD idxCounterSigner, PCCERT_CONTEXT pCert2Add);
BOOL WINAPI WINTRUST_AddPrivData(CRYPT_PROVIDER_DATA *data,
CRYPT_PROVIDER_PRIVDATA *pPrivData2Add);
#endif /* ndef __WINTRUST_PRIV_H__ */

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2007 Francois Gouget
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_BCRYPT_H
#define __WINE_BCRYPT_H
#ifndef WINAPI
#define WINAPI __stdcall
#endif
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif
#endif /* __WINE_BCRYPT_H */

View file

@ -52,6 +52,49 @@ static const WCHAR GENERIC_CHAIN_CERTTRUST_FUNCTION[] =
{'G','e','n','e','r','i','c','C','h','a','i','n','C','e','r','t','i','f','i','c','a','t','e','T','r','u','s','t', 0};
#endif
typedef struct _WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO
{
union {
DWORD cbStruct;
DWORD cbSize;
} DUMMYUNIONNAME;
PCCERT_CHAIN_CONTEXT pChainContext;
DWORD dwSignerType;
PCMSG_SIGNER_INFO pMsgSignerInfo;
DWORD dwError;
DWORD cCounterSigner;
struct _WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *rgpCounterSigner;
} WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO, *PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO;
typedef HRESULT (WINAPI *PFN_WTD_GENERIC_CHAIN_POLICY_CALLBACK)(
PCRYPT_PROVIDER_DATA pProvData, DWORD dwStepError, DWORD dwRegPolicySettings,
DWORD cSigner, PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO rgpSigner,
void *pvPolicyArg);
typedef struct _WTD_GENERIC_CHAIN_POLICY_CREATE_INFO
{
union {
DWORD cbStruct;
DWORD cbSize;
} DUMMYUNIONNAME;
HCERTCHAINENGINE hChainEngine;
PCERT_CHAIN_PARA pChainPara;
DWORD dwFlags;
void *pvReserved;
} WTD_GENERIC_CHAIN_POLICY_CREATE_INFO, *PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO;
typedef struct _WTD_GENERIC_CHAIN_POLICY_DATA
{
union {
DWORD cbStruct;
DWORD cbSize;
} DUMMYUNIONNAME;
PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO pSignerChainInfo;
PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO pCounterSignerChainInfo;
PFN_WTD_GENERIC_CHAIN_POLICY_CALLBACK pfnPolicyCallback;
void *pvPolicyArg;
} WTD_GENERIC_CHAIN_POLICY_DATA, *PWTD_GENERIC_CHAIN_POLICY_DATA;
#if defined(__GNUC__)
#define SP_POLICY_PROVIDER_DLL_NAME (const WCHAR []) \
{'W','I','N','T','R','U','S','T','.','D','L','L' ,0}
@ -177,4 +220,26 @@ static const WCHAR DRIVER_CLEANUPPOLICY_FUNCTION[] =
{'D','r','i','v','e','r','C','l','e','a','n','u','p','P','o','l','i','c','y', 0};
#endif
typedef struct DRIVER_VER_MAJORMINOR_
{
DWORD dwMajor;
DWORD dwMinor;
} DRIVER_VER_MAJORMINOR;
typedef struct DRIVER_VER_INFO_
{
DWORD cbStruct;
ULONG_PTR dwReserved1;
ULONG_PTR dwReserved2;
DWORD dwPlatform;
DWORD dwVersion;
WCHAR wszVersion[MAX_PATH];
WCHAR wszSignedBy[MAX_PATH];
PCCERT_CONTEXT pcSignerCertContext;
DRIVER_VER_MAJORMINOR sOSVersionLow;
DRIVER_VER_MAJORMINOR sOSVersionHigh;
DWORD dwBuildNumberLow;
DWORD dwBuildNumberHigh;
} DRIVER_VER_INFO, *PDRIVER_VER_INFO;
#endif /* __WINE_SOFTPUB_H */

View file

@ -1011,12 +1011,6 @@ typedef struct _OFSTRUCT {
WORD Reserved2;
CHAR szPathName[OFS_MAXPATHNAME];
} OFSTRUCT,*LPOFSTRUCT,*POFSTRUCT;
typedef struct _WIN_CERTIFICATE {
DWORD dwLength;
WORD wRevision;
WORD wCertificateType;
BYTE bCertificate[1];
} WIN_CERTIFICATE, *LPWIN_CERTIFICATE;
#if (_WIN32_WINNT >= 0x0501)
typedef struct tagACTCTXA {
ULONG cbSize;

File diff suppressed because it is too large Load diff

View file

@ -136,6 +136,7 @@ typedef struct _WINTRUST_DATA
#define WTD_HASH_ONLY_FLAG 0x00000200
#define WTD_USE_DEFAULT_OSVER_CHECK 0x00000400
#define WTD_LIFETIME_SIGNING_FLAG 0x00000800
#define WTD_CACHE_ONLY_URL_RETRIEVAL 0x00001000
#define WTD_UICONTEXT_EXECUTE 0
#define WTD_UICONTEXT_INSTALL 1
@ -199,6 +200,13 @@ typedef struct _CRYPT_PROVIDER_CERT {
PCERT_CHAIN_ELEMENT pChainElement;
} CRYPT_PROVIDER_CERT, *PCRYPT_PROVIDER_CERT;
#define CERT_CONFIDENCE_SIG 0x10000000
#define CERT_CONFIDENCE_TIME 0x01000000
#define CERT_CONFIDENCE_TIMENEST 0x00100000
#define CERT_CONFIDENCE_AUTHIDEXT 0x00010000
#define CERT_CONFIDENCE_HYGIENE 0x00001000
#define CERT_CONFIDENCE_HIGHEST 0x11111000
typedef struct _CRYPT_PROVIDER_SGNR {
DWORD cbStruct;
FILETIME sftVerifyAsOf;
@ -212,6 +220,8 @@ typedef struct _CRYPT_PROVIDER_SGNR {
PCCERT_CHAIN_CONTEXT pChainContext;
} CRYPT_PROVIDER_SGNR, *PCRYPT_PROVIDER_SGNR;
#define SGNR_TYPE_TIMESTAMP 0x00000010
typedef struct _CRYPT_PROVIDER_PRIVDATA {
DWORD cbStruct;
GUID gProviderID;
@ -221,32 +231,61 @@ typedef struct _CRYPT_PROVIDER_PRIVDATA {
struct _CRYPT_PROVIDER_DATA;
typedef void * (*PFN_CPD_MEM_ALLOC)(DWORD cbSize);
typedef void (*PFN_CPD_MEM_FREE)(void *pvMem2Free);
typedef BOOL (*PFN_CPD_ADD_STORE)(struct _CRYPT_PROVIDER_DATA *pProvData,
#define TRUSTERROR_STEP_WVTPARAMS 0
#define TRUSTERROR_STEP_FILEIO 2
#define TRUSTERROR_STEP_SIP 3
#define TRUSTERROR_STEP_SIPSUBJINFO 5
#define TRUSTERROR_STEP_CATALOGFILE 6
#define TRUSTERROR_STEP_CERTSTORE 7
#define TRUSTERROR_STEP_MESSAGE 8
#define TRUSTERROR_STEP_MSG_SIGNERCOUNT 9
#define TRUSTERROR_STEP_MSG_INNERCNTTYPE 10
#define TRUSTERROR_STEP_MSG_INNERCNT 11
#define TRUSTERROR_STEP_MSG_STORE 12
#define TRUSTERROR_STEP_MSG_SIGNERINFO 13
#define TRUSTERROR_STEP_MSG_SIGNERCERT 14
#define TRUSTERROR_STEP_MSG_CERTCHAIN 15
#define TRUSTERROR_STEP_MSG_COUNTERSIGINFO 16
#define TRUSTERROR_STEP_MSG_COUNTERSIGCERT 17
#define TRUSTERROR_STEP_VERIFY_MSGHASH 18
#define TRUSTERROR_STEP_VERIFY_MSGINDIRECTDATA 19
#define TRUSTERROR_STEP_FINAL_WVTINIT 30
#define TRUSTERROR_STEP_FINAL_INITPROV 31
#define TRUSTERROR_STEP_FINAL_OBJPROV 32
#define TRUSTERROR_STEP_FINAL_SIGPROV 33
#define TRUSTERROR_STEP_FINAL_CERTPROV 34
#define TRUSTERROR_STEP_FINAL_CERTCHKPROV 35
#define TRUSTERROR_STEP_FINAL_POLICYPROV 36
#define TRUSTERROR_STEP_FINAL_UIPROV 37
#define TRUSTERROR_MAX_STEPS 38
typedef void * (WINAPI *PFN_CPD_MEM_ALLOC)(DWORD cbSize);
typedef void (WINAPI *PFN_CPD_MEM_FREE)(void *pvMem2Free);
typedef BOOL (WINAPI *PFN_CPD_ADD_STORE)(struct _CRYPT_PROVIDER_DATA *pProvData,
HCERTSTORE hStore2Add);
typedef BOOL (*PFN_CPD_ADD_SGNR)(struct _CRYPT_PROVIDER_DATA *pProvData,
typedef BOOL (WINAPI *PFN_CPD_ADD_SGNR)(struct _CRYPT_PROVIDER_DATA *pProvData,
BOOL fCounterSigner, DWORD idxSigner, struct _CRYPT_PROVIDER_SGNR *pSgnr2Add);
typedef BOOL (*PFN_CPD_ADD_CERT)(struct _CRYPT_PROVIDER_DATA *pProvData,
typedef BOOL (WINAPI *PFN_CPD_ADD_CERT)(struct _CRYPT_PROVIDER_DATA *pProvData,
DWORD idxSigner, BOOL fCounterSigner, DWORD idxCounterSigner,
PCCERT_CONTEXT pCert2Add);
typedef BOOL (*PFN_CPD_ADD_PRIVDATA)(struct _CRYPT_PROVIDER_DATA *pProvData,
typedef BOOL (WINAPI *PFN_CPD_ADD_PRIVDATA)(struct _CRYPT_PROVIDER_DATA *pProvData,
struct _CRYPT_PROVIDER_PRIVDATA *pPrivData2Add);
typedef HRESULT (*PFN_PROVIDER_INIT_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_INIT_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_OBJTRUST_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_OBJTRUST_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_SIGTRUST_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_SIGTRUST_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_CERTTTRUST_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_CERTTRUST_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_FINALPOLICY_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_FINALPOLICY_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_TESTFINALPOLICY_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_TESTFINALPOLICY_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef HRESULT (*PFN_PROVIDER_CLEANUP_CALL)(
typedef HRESULT (WINAPI *PFN_PROVIDER_CLEANUP_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData);
typedef BOOL (*PFN_PROVIDER_CERTCHKPOLICY_CALL)(
typedef BOOL (WINAPI *PFN_PROVIDER_CERTCHKPOLICY_CALL)(
struct _CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner,
BOOL fCounterSignerChain, DWORD idxCounterSigner);
@ -261,7 +300,7 @@ typedef struct _CRYPT_PROVIDER_FUNCTIONS {
PFN_PROVIDER_INIT_CALL pfnInitialize;
PFN_PROVIDER_OBJTRUST_CALL pfnObjectTrust;
PFN_PROVIDER_SIGTRUST_CALL pfnSignatureTrust;
PFN_PROVIDER_CERTTTRUST_CALL pfnCertificateTrust;
PFN_PROVIDER_CERTTRUST_CALL pfnCertificateTrust;
PFN_PROVIDER_FINALPOLICY_CALL pfnFinalPolicy;
PFN_PROVIDER_CERTCHKPOLICY_CALL pfnCertCheckPolicy;
PFN_PROVIDER_TESTFINALPOLICY_CALL pfnTestFinalPolicy;
@ -302,6 +341,8 @@ typedef struct _CRYPT_PROVIDER_DATA {
HCRYPTMSG hMsg;
DWORD csSigners;
CRYPT_PROVIDER_SGNR *pasSigners;
DWORD csProvPrivData;
CRYPT_PROVIDER_PRIVDATA *pasProvPrivData;
DWORD dwSubjectChoice;
union {
struct _PROVDATA_SIP *pPDSip;
@ -317,6 +358,19 @@ typedef struct _CRYPT_PROVIDER_DATA {
DWORD dwUIStateFlags;
} CRYPT_PROVIDER_DATA, *PCRYPT_PROVIDER_DATA;
#define CPD_CHOICE_SIP 1
#define CPD_USE_NT5_CHAIN_FLAG 0x80000000
#define CPD_REVOCATION_CHECK_NONE 0x00010000
#define CPD_REVOCATION_CHECK_END_CERT 0x00020000
#define CPD_REVOCATION_CHECK_CHAIN 0x00040000
#define CPD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x00080000
#define CPD_UISTATE_MODE_PROMPT 0x00000000
#define CPD_UISTATE_MODE_BLOCK 0x00000001
#define CPD_UISTATE_MODE_ALLOW 0x00000002
#define CPD_UISTATE_MODE_MASK 0x00000003
typedef BOOL (*PFN_PROVUI_CALL)(HWND hWndSecurityDialog,
struct _CRYPT_PROVIDER_DATA *pProvData);
@ -364,21 +418,31 @@ BOOL WINAPI WintrustRemoveActionID(GUID*);
BOOL WINAPI WintrustLoadFunctionPointers(GUID*,CRYPT_PROVIDER_FUNCTIONS*);
BOOL WINAPI WintrustAddDefaultForUsage(const char*,CRYPT_PROVIDER_REGDEFUSAGE*);
void WINAPI WintrustGetRegPolicyFlags(DWORD*);
BOOL WINAPI WintrustSetRegPolicyFlags(DWORD);
LONG WINAPI WinVerifyTrust(HWND,GUID*,LPVOID);
HRESULT WINAPI WinVerifyTrustEx(HWND,GUID*,WINTRUST_DATA*);
CRYPT_PROVIDER_CERT * WINAPI WTHelperGetProvCertFromChain(
CRYPT_PROVIDER_SGNR *pSgnr, DWORD idxCert);
CRYPT_PROVIDER_SGNR * WINAPI WTHelperGetProvSignerFromChain(
CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner,
DWORD idxCounterSigner);
CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData);
CRYPT_PROVIDER_PRIVDATA * WINAPI WTHelperGetProvPrivateDataFromChain(CRYPT_PROVIDER_DATA *,GUID *);
#define SPC_INDIRECT_DATA_OBJID "1.3.6.1.4.1.311.2.1.4"
#define SPC_SP_AGENCY_INFO_OBJID "1.3.6.1.4.1.311.2.1.10"
#define SPC_STATEMENT_TYPE_OBJID "1.3.6.1.4.1.311.2.1.11"
#define SPC_SP_OPUS_INFO_OBJID "1.3.6.1.4.1.311.2.1.12"
#define SPC_CERT_EXTENSIONS_OBJID "1.3.6.1.4.1.311.2.1.14"
#define SPC_PE_IMAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.15"
#define SPC_RAW_FILE_DATA_OBJID "1.3.6.1.4.1.311.2.1.18"
#define SPC_STRUCTURED_STORAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.19"
#define SPC_JAVA_CLASS_DATA_OBJID "1.3.6.1.4.1.311.2.1.20"
#define SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID "1.3.6.1.4.1.311.2.1.21"
#define SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID "1.3.6.1.4.1.311.2.1.22"
#define SPC_CAB_DATA_OBJID "1.3.6.1.4.1.311.2.1.25"
#define SPC_GLUE_RDN_OBJID "1.3.6.1.4.1.311.2.1.25"
#define SPC_MINIMAL_CRITERIA_OBJID "1.3.6.1.4.1.311.2.1.26"
#define SPC_FINANCIAL_CRITERIA_OBJID "1.3.6.1.4.1.311.2.1.27"
#define SPC_LINK_OBJID "1.3.6.1.4.1.311.2.1.28"
@ -400,6 +464,152 @@ CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData);
#define CAT_NAMEVALUE_STRUCT ((LPCSTR) 2221)
#define CAT_MEMBERINFO_STRUCT ((LPCSTR) 2222)
#define SPC_UUID_LENGTH 16
typedef BYTE SPC_UUID[SPC_UUID_LENGTH];
typedef struct _SPC_SERIALIZED_OBJECT
{
SPC_UUID ClassId;
CRYPT_DATA_BLOB SerializedData;
} SPC_SERIALIZED_OBJECT, *PSPC_SERIALIZED_OBJECT;
typedef struct SPC_SIGINFO_
{
DWORD dwSipVersion;
GUID gSIPGuid;
DWORD dwReserved1;
DWORD dwReserved2;
DWORD dwReserved3;
DWORD dwReserved4;
DWORD dwReserved5;
} SPC_SIGINFO, *PSPC_SIGINFO;
#define SPC_URL_LINK_CHOICE 1
#define SPC_MONIKER_LINK_CHOICE 2
#define SPC_FILE_LINK_CHOICE 3
typedef struct SPC_LINK_
{
DWORD dwLinkChoice;
union
{
LPWSTR pwszUrl;
SPC_SERIALIZED_OBJECT Moniker;
LPWSTR pwszFile;
} DUMMYUNIONNAME;
} SPC_LINK, *PSPC_LINK;
typedef struct _SPC_PE_IMAGE_DATA
{
CRYPT_BIT_BLOB Flags;
PSPC_LINK pFile;
} SPC_PE_IMAGE_DATA, *PSPC_PE_IMAGE_DATA;
typedef struct _SPC_INDIRECT_DATA_CONTENT
{
CRYPT_ATTRIBUTE_TYPE_VALUE Data;
CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
CRYPT_HASH_BLOB Digest;
} SPC_INDIRECT_DATA_CONTENT, *PSPC_INDIRECT_DATA_CONTENT;
typedef struct _SPC_FINANCIAL_CRITERIA
{
BOOL fFinancialInfoAvailable;
BOOL fMeetsCriteria;
} SPC_FINANCIAL_CRITERIA, *PSPC_FINANCIAL_CRITERIA;
typedef struct _SPC_IMAGE
{
struct SPC_LINK_ *pImageLink;
CRYPT_DATA_BLOB Bitmap;
CRYPT_DATA_BLOB Metafile;
CRYPT_DATA_BLOB EnhancedMetafile;
CRYPT_DATA_BLOB GifFile;
} SPC_IMAGE, *PSPC_IMAGE;
typedef struct _SPC_SP_AGENCY_INFO
{
struct SPC_LINK_ *pPolicyInformation;
LPWSTR pwszPolicyDisplayText;
PSPC_IMAGE pLogoImage;
struct SPC_LINK_ *pLogoLink;
} SPC_SP_AGENCY_INFO, *PSPC_SP_AGENCY_INFO;
typedef struct _SPC_STATEMENT_TYPE
{
DWORD cKeyPurposeId;
LPSTR *rgpszKeyPurposeId;
} SPC_STATEMENT_TYPE, *PSPC_STATEMENT_TYPE;
typedef struct _SPC_SP_OPUS_INFO
{
LPCWSTR pwszProgramName;
struct SPC_LINK_ *pMoreInfo;
struct SPC_LINK_ *pPublisherInfo;
} SPC_SP_OPUS_INFO, *PSPC_SP_OPUS_INFO;
typedef struct _CAT_NAMEVALUE
{
LPWSTR pwszTag;
DWORD fdwFlags;
CRYPT_DATA_BLOB Value;
} CAT_NAMEVALUE, *PCAT_NAMEVALUE;
typedef struct _CAT_MEMBERINFO
{
LPWSTR pwszSubjGuid;
DWORD dwCertVersion;
} CAT_MEMBERINFO, *PCAT_MEMBERINFO;
/* PSDK protects the remaining defines with WT_DEFINE_ALL_APIS, but it's
* defined by default. No need to protect against bad headers from old PSDKs.
*/
typedef struct _WIN_CERTIFICATE {
DWORD dwLength;
WORD wRevision; /* WIN_CERT_REVISION_xxx */
WORD wCertificateType; /* WIN_CERT_TYPE_xxx */
BYTE bCertificate[ANYSIZE_ARRAY];
} WIN_CERTIFICATE, *LPWIN_CERTIFICATE;
#define WIN_CERT_REVISION_1_0 0x0100
#define WIN_CERT_REVISION_2_0 0x0200
#define WIN_CERT_TYPE_X509 0x0001 /* X.509 Certificate */
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 /* PKCS SignedData */
#define WIN_CERT_TYPE_RESERVED_1 0x0003 /* Reserved */
#define WIN_CERT_TYPE_TS_STACK_SIGNED 0x0004
typedef LPVOID WIN_TRUST_SUBJECT;
typedef struct _WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT
{
HANDLE hClientToken;
GUID *SubjectType;
WIN_TRUST_SUBJECT Subject;
} WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT,
*LPWIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT;
typedef struct _WIN_TRUST_ACTDATA_CONTEXT_SUBJECT_ONLY
{
GUID *SubjectType;
WIN_TRUST_SUBJECT Subject;
} WIN_TRUST_ACTDATA_CONTEXT_SUBJECT_ONLY,
*LPWIN_TRUST_ACTDATA_CONTEXT_SUBJECT_ONLY;
typedef struct _WIN_TRUST_SUBJECT_FILE
{
HANDLE hFile;
LPCWSTR lpPath;
} WIN_TRUST_SUBJECT_FILE, *LPWIN_TRUST_SUBJECT_FILE;
typedef struct _WIN_TRUST_SUBJECT_FILE_AND_DISPLAY
{
HANDLE hFile;
LPCWSTR lpPath;
LPCWSTR lpDisplayName;
} WIN_TRUST_SUBJECT_FILE_AND_DISPLAY, *LPWIN_TRUST_SUBJECT_FILE_AND_DISPLAY;
#define WIN_SPUB_ACTION_PUBLISHED_SOFTWARE \
{ 0x64b9d180, 0x8da2, 0x11cf, { 0x87,0x36,0x00,0xaa,0x00,0xa4,0x85,0xeb }}