public void DecryptVerify(Mechanism verificationMechanism, ObjectHandle verificationKeyHandle, Mechanism decryptionMechanism, ObjectHandle decryptionKeyHandle, Stream inputStream, Stream outputStream, byte[] signature, out bool isValid, int bufferLength)
{
if (this._disposed)
throw new ObjectDisposedException(this.GetType().FullName);
if (verificationMechanism == null)
throw new ArgumentNullException("verificationMechanism");
if (verificationKeyHandle == null)
throw new ArgumentNullException("verificationKeyHandle");
if (decryptionMechanism == null)
throw new ArgumentNullException("decryptionMechanism");
if (decryptionKeyHandle == null)
throw new ArgumentNullException("decryptionKeyHandle");
if (inputStream == null)
throw new ArgumentNullException("inputStream");
if (outputStream == null)
throw new ArgumentNullException("outputStream");
if (signature == null)
throw new ArgumentNullException("signature");
if (bufferLength < 1)
throw new ArgumentException("Value has to be positive number", "bufferLength");
CK_MECHANISM ckVerificationMechanism = verificationMechanism.CkMechanism;
CKR rv = _p11.C_VerifyInit(_sessionId, ref ckVerificationMechanism, verificationKeyHandle.ObjectId);
if (rv != CKR.CKR_OK)
throw new Pkcs11Exception("C_VerifyInit", rv);
CK_MECHANISM ckDecryptionMechanism = decryptionMechanism.CkMechanism;
rv = _p11.C_DecryptInit(_sessionId, ref ckDecryptionMechanism, decryptionKeyHandle.ObjectId);
if (rv != CKR.CKR_OK)
throw new Pkcs11Exception("C_DecryptInit", rv);
byte[] encryptedPart = new byte[bufferLength];
byte[] part = new byte[bufferLength];
ulong partLen = Convert.ToUInt64(part.Length);
int bytesRead = 0;
while ((bytesRead = inputStream.Read(encryptedPart, 0, encryptedPart.Length)) > 0)
{
partLen = Convert.ToUInt64(part.Length);
rv = _p11.C_DecryptVerifyUpdate(_sessionId, encryptedPart, Convert.ToUInt64(bytesRead), part, ref partLen);
if (rv != CKR.CKR_OK)
throw new Pkcs11Exception("C_DecryptVerifyUpdate", rv);
outputStream.Write(part, 0, Convert.ToInt32(partLen));
}
byte[] lastPart = null;
ulong lastPartLen = 0;
rv = _p11.C_DecryptFinal(_sessionId, null, ref lastPartLen);
if (rv != CKR.CKR_OK)
throw new Pkcs11Exception("C_DecryptFinal", rv);
lastPart = new byte[lastPartLen];
rv = _p11.C_DecryptFinal(_sessionId, lastPart, ref lastPartLen);
if (rv != CKR.CKR_OK)
throw new Pkcs11Exception("C_DecryptFinal", rv);
if (lastPartLen > 0)
outputStream.Write(lastPart, 0, Convert.ToInt32(lastPartLen));
rv = _p11.C_VerifyFinal(_sessionId, signature, Convert.ToUInt64(signature.Length));
if (rv == CKR.CKR_OK)
isValid = true;
else if (rv == CKR.CKR_SIGNATURE_INVALID)
isValid = false;
else
throw new Pkcs11Exception("C_VerifyFinal", rv);
}