bool WinCAPICryptoKeyRSA::verifySHA1PKCS1Base64Signature()

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;
}