mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
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:
parent
7b048be57f
commit
0ff89a79a9
35 changed files with 8225 additions and 1106 deletions
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
673
reactos/dll/win32/crypt32/ctl.c
Normal file
673
reactos/dll/win32/crypt32/ctl.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
320
reactos/dll/win32/crypt32/message.c
Normal file
320
reactos/dll/win32/crypt32/message.c
Normal 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
|
@ -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);
|
||||
|
|
|
@ -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[
|
||||
|
|
|
@ -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(®Info->certsToDelete);
|
||||
list_init(®Info->crlsToDelete);
|
||||
list_init(®Info->ctlsToDelete);
|
||||
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
|
||||
regInfo->dirty = FALSE;
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
1735
reactos/dll/win32/wintrust/asn.c
Normal file
1735
reactos/dll/win32/wintrust/asn.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
897
reactos/dll/win32/wintrust/softpub.c
Normal file
897
reactos/dll/win32/wintrust/softpub.c
Normal 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,
|
||||
¶);
|
||||
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;
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
32
reactos/dll/win32/wintrust/wintrust_priv.h
Normal file
32
reactos/dll/win32/wintrust/wintrust_priv.h
Normal 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__ */
|
38
reactos/include/psdk/bcrypt.h
Normal file
38
reactos/include/psdk/bcrypt.h
Normal 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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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 }}
|
||||
|
||||
|
|
Loading…
Reference in a new issue