CryptVerifyMessageSignature and CryptDecryptMessage functions allow me to check if an S/MIME signature is valid (or decrypt encrypted data in CryptDecryptMessage case) and also return the certificate which was used for signing (or encryption). However, there is no information about which algorithms were actually used for signing and encryption. How can I get this info?
I'm using C# but any C/C++ sample or hint is also welcome.
Edit: signature verification code snippet (the entire code is very big to include it here) added upon request
IntPtr pbDetachedSignBlob = IntPtr.Zero;
uint cbDetachedSignBlob = (uint)signatureBytes.Length;
IntPtr pbContent = IntPtr.Zero;
uint cbContent = (uint)data.Length;
pbDetachedSignBlob = Marshal.AllocHGlobal((int)cbDetachedSignBlob);
Marshal.Copy(signatureBytes, 0, pbDetachedSignBlob, (int)cbDetachedSignBlob);
pbContent = Marshal.AllocHGlobal((int)cbContent);
Marshal.Copy(data, 0, pbContent, (int)cbContent);
IntPtr[] messageArray = { pbContent };
uint[] messageSizeArray = { cbContent };
GCHandle messageArrayHandle = GCHandle.Alloc(messageArray, GCHandleType.Pinned);
IntPtr messageArrayPtr = (IntPtr)messageArrayHandle.AddrOfPinnedObject();
int ret = CryptoApiFuncs.MessageFuncs.CryptVerifyDetachedMessageSignature(pVerifyPara, 0, pbDetachedSignBlob, cbDetachedSignBlob, 1, messageArrayPtr, ref messageSizeArray[0], ref pSignerCert);
The api you are using, carry out checks validity of digital signature which goes with documents and so on.. this check is done against a certificate, the info of whom are contained in the
CERT_CONTEXT
structure (pSignerCert
) into which in turn it is contained a CERT_INFO structure (pCertInfo CERT_CONTEXT
structure field).Into
CERT_CONTEXT
you can find infos about standard certicate type of encoding used (X509_ASN_ENCODING
orPKCS_7_ASN_ENCODING
).Into
CERT_INFO
you can findCRYPT_ALGORITHM_IDENTIFIER
and other more detailed infos.For a documentation about
CryptVerifyDetachedMessageSignature
apis and related structures:CryptVerifyDetachedMessageSignature
CERT_CONTEXT
CERT_INFO
EDIT:
Digital signature system generally works creating an hash of the data to sign (SHA1 minimum level older certificates standard, now newer certicates start from a level of SHA256..), then this hash get encrypted with a private key using an algorithm of asymmetric cryptography (RSA).
When the message is received, it get decrypted with the public key contained in the certificate released publicly, and then the date get hashed with the right algorithm, declared in the certificate (from programmatically point of view, see the struct fields upon) and if the two hashes (one in the same certificate that goes with the data, and the other calculated on the client who verify the digital signature) correspond, then it is verified that the data are not corrupted or changed by someone other than the author, and if the certificate it is released by a valid certification authority, then the author is also identified in a sure manner.