The CryptVerifyDetachedMessageSignature function verifies a signed message's signature.
[DllImport("Crypt32.dll", SetLastError = true)]
static internal extern bool CryptVerifyDetachedMessageSignature(
ref CRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
int dwSignerIndex,
byte[] pbDetachedSignBlob,
int cbDetachedSignBlob,
int cToBeSigned,
IntPtr[] rgpbToBeSigned,
int[] rgcbToBeSigned,
IntPtr ppSignerCert);
Declare Function CryptVerifyDetachedMessageSignature Lib "crypt32.dll" (TODO) As TODO
None.
None.
Please add some!
public void VerifyDetachedMessageSignature2(byte[] messageData, byte[] signatureData, out byte[] p_x509)
{
CRYPT_VERIFY_MESSAGE_PARA verifyParams;
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(byte)) * messageData.Length);
Marshal.Copy(messageData, 0, buffer, messageData.Length);
IntPtr[] rgpbToBeSigned = new IntPtr[1] { buffer };
int[] rgcbToBeSigned = new int[1] { messageData.Length };
p_x509 = null;
GCHandle pCertContext;
verifyParams = new CRYPT_VERIFY_MESSAGE_PARA();
verifyParams.cbSize = (int)Marshal.SizeOf(verifyParams);
verifyParams.dwMsgAndCertEncodingType = CryptoConstants.X509_ASN_ENCODING | CryptoConstants.PKCS_7_ASN_ENCODING;
verifyParams.hCryptProv = 0;
verifyParams.pfnGetSignerCertificate = IntPtr.Zero;
verifyParams.pvGetArg = IntPtr.Zero;
pCertContext = GCHandle.Alloc(IntPtr.Zero, GCHandleType.Pinned);
try
{
bool res = CryptoApiProvider.CryptVerifyDetachedMessageSignature(
ref verifyParams, // Verify parameters.
0, // Signer index.
signatureData, // Buffer for decoded message.
signatureData.Length, // Size of buffer.
1,
rgpbToBeSigned, // Pointer to signed BLOB.
rgcbToBeSigned, // Size of signed BLOB.
pCertContext.AddrOfPinnedObject());
if (!res)
{
throw new Exception("Error while encrypting data [" + Marshal.GetLastWin32Error() + "].");
}
try
{
X509Certificate x509 = new X509Certificate( ( IntPtr )pCertContext.Target );
}
finally
{
Crypt32.CertFreeCertificateContext( ( IntPtr )pCertContext.Target );
}
}
finally
{
pCertContext.Free();
}
}
Do you know one? Please contribute it!