I am trying to decrypt a p7m attachment using CryptQueryObject
/ CryptDecryptMessage
functions. For large files (30Mb) each call can take up to 30 seconds to execute. Outlook itself has no problem opening an encrypted message and showing its contents instantaneously.
I do realize CryptQueryObject
is deprecated (but CryptDecryptMessage
is not). It does not matter what parameters I use and whether the data is in a memory blob or a file. Below is the Delphi code (C++ would be very similar). If I pause the execution while either function is executing, I can see from the call stack that the code is resizing or allocating a new memory block. It is almost as if the code is building a buffer reallocating/copying the previous contents on each iteration.
Here is what the call looks like, nothing extraordinary, no amount of playing with the parameters makes the calls any faster.
if not CryptQueryObject(CERT_QUERY_OBJECT_FILE,//CERT_QUERY_OBJECT_BLOB,
pointer(PWideChar(wFileName)),//@stCryptBlob,
CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED or CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, //CERT_QUERY_CONTENT_FLAG_ALL, //CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_ALL, //CERT_QUERY_FORMAT_FLAG_BINARY,
0,
nil, //@dwEncoding, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
@dwContentType, // a PKCS7 signed message embedded in a file CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED = 10
nil, //@dwFormatType, // the content is in binary format CERT_QUERY_FORMAT_BINARY = 1
@hStore,
nil, //@hMsg, // for dwContentType == CERT_QUERY_CONTENT_PKCS7_SIGNED,
// CERT_QUERY_CONTENT_PKCS7_UNSIGNED
// CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
nil {@pvContext}) then RaiseLastWindowError('CryptQueryObject');
And here is the typical call stack when the function is executing. It is always memory/heap related.
:77dc8913 ntdll.memcpy + 0x33
:77d93526 ;
:77d92867 ;
:77d92763 ntdll.RtlReAllocateHeap + 0x43
:75d3a1f5 ; C:\WINDOWS\SysWOW64\KERNELBASE.dll
:754a869c MSASN1.ASN1EncSetError + 0x5c
:754a5bf9 ; C:\WINDOWS\SysWOW64\MSASN1.dll
:754a1b67 MSASN1.ASN1BERDecOctetString + 0x17
:769b485f ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:769b42e5 ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:754a2e3c ; C:\WINDOWS\SysWOW64\MSASN1.dll
:7690a697 ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:769b3354 ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:7694053a ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:7692d71b ; C:\WINDOWS\SysWOW64\CRYPT32.dll
:7692d373 ; C:\WINDOWS\SysWOW64\CRYPT32.dll
uEncryptedMessage.DecodeP7M($356A3C50)
Anybody knows why this happens?
Did anybody have luck processing large encrypted blobs using these functions?
Would I be better off using the new CNG functions? What would the sequence of calls be like then?