in xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp [235:347]
bool WinCAPICryptoKeyRSA::verifySHA1PKCS1Base64Signature(const unsigned char * hashBuf,
unsigned int hashLen,
const char * base64Signature,
unsigned int sigLen,
XSECCryptoHash::HashType type) const {
// Use the currently loaded key to validate the Base64 encoded signature
if (m_key == 0) {
// Try to import from the parameters
importKey();
if (m_key == 0) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"WinCAPI:RSA - Attempt to validate signature with empty key");
}
}
/* Is this a hash we support? */
ALG_ID alg;
switch (type) {
case (XSECCryptoHash::HASH_MD5):
alg = CALG_MD5;
break;
case (XSECCryptoHash::HASH_SHA1):
alg=CALG_SHA1;
break;
default:
throw XSECCryptoException(XSECCryptoException::RSAError,
"WinCAPI:RSA Unsupported hash algorithm for RSA sign - only MD5 or SHA1 supported");
}
// Decode the signature
unsigned char * rawSig;
DWORD rawSigLen;
XSECnew(rawSig, BYTE [sigLen]);
ArrayJanitor<BYTE> j_rawSig(rawSig);
// Decode the signature
XSCryptCryptoBase64 b64;
b64.decodeInit();
rawSigLen = b64.decode((unsigned char *) base64Signature, sigLen, rawSig, sigLen);
rawSigLen += b64.decodeFinish(&rawSig[rawSigLen], sigLen - rawSigLen);
BYTE * rawSigFinal;
XSECnew(rawSigFinal, BYTE[rawSigLen]);
ArrayJanitor<BYTE> j_rawSigFinal(rawSigFinal);
BYTE * j, *l;
j = rawSig;
l = rawSigFinal + rawSigLen - 1;
while (l >= rawSigFinal) {
*l-- = *j++;
}
// Have to create a Windows hash object and feed in the hash
BOOL fResult;
HCRYPTHASH h;
fResult = CryptCreateHash(m_p,
alg,
0,
0,
&h);
if (!fResult) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"WinCAPI:RSA - Error creating Windows Hash Object");
}
// Feed the hash value into the newly created hash object
fResult = CryptSetHashParam(
h,
HP_HASHVAL,
(unsigned char *) hashBuf,
0);
if (!fResult) {
throw XSECCryptoException(XSECCryptoException::RSAError,
"WinCAPI:RSA - Error Setting Hash Value in Windows Hash object");
}
// Now validate
fResult = CryptVerifySignature(
h,
rawSigFinal,
rawSigLen,
m_key,
NULL,
0);
if (!fResult) {
DWORD error = GetLastError();
if (error != NTE_BAD_SIGNATURE) {
if (h)
CryptDestroyHash(h);
throw XSECCryptoException(XSECCryptoException::RSAError,
"WinCAPI:RSA - Error occurred in RSA validation");
}
if (h)
CryptDestroyHash(h);
return false;
}
if (h)
CryptDestroyHash(h);
return true;
}