in xsec/enc/WinCAPI/WinCAPICryptoHashHMAC.cpp [140:305]
void WinCAPICryptoHashHMAC::setKey(const XSECCryptoKey *key) {
BOOL fResult;
// Use this to initialise the ipadKeyed/opadKeyed values
if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:HashHMAC - Non HMAC Key passed to HashHMAC");
}
if (m_blockSize > XSEC_MAX_HASH_BLOCK_SIZE) {
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:HashHMAC - Internal error - have got a blocksize bigger than I can handle");
}
// Check to see if this is an internal Windows Key
if (strEquals(key->getProviderName(), DSIGConstants::s_unicodeStrPROVWinCAPI) &&
((WinCAPICryptoKeyHMAC *) key)->getWinKey() != 0) {
// Over-ride the local provider for this
HCRYPTPROV p = ((WinCAPICryptoKeyHMAC *) key)->getWinKeyProv();
HCRYPTKEY k = ((WinCAPICryptoKeyHMAC *) key)->getWinKey();
fResult = CryptCreateHash(
p,
CALG_HMAC,
k,
0,
&m_h);
if (fResult == 0 || m_h == 0) {
DWORD error = GetLastError();
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:Hash::setKey - Error creating internally keyed hash object");
}
// Set the HMAC algorithm
HMAC_INFO hi;
hi.HashAlgid = m_algId;
hi.pbInnerString = NULL; // Use default inner and outer strings
hi.cbInnerString = 0;
hi.pbOuterString = NULL;
hi.cbOuterString = 0;
fResult = CryptSetHashParam(
m_h,
HP_HMAC_INFO,
(BYTE *) &hi,
0);
if (fResult == 0 || m_h == 0) {
DWORD error = GetLastError();
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:Hash::setKey - Error setting HASH_INFO object");
}
return;
}
// Need to load from raw bit string
safeBuffer keyBuf;
unsigned int keyLen = ((XSECCryptoKeyHMAC *) key)->getKey(keyBuf);
if (keyLen > m_blockSize) {
HCRYPTHASH h;
fResult = CryptCreateHash(
m_p,
m_algId,
0,
0,
&h);
if (fResult == 0 || h == 0) {
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:Hash::setKey - Error creating hash object");
}
fResult = CryptHashData(
h,
keyBuf.rawBuffer(),
keyLen,
0);
if (fResult == 0 || h == 0) {
if (h)
CryptDestroyHash(h);
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:Hash::setKey - Error hashing key data");
}
BYTE outData[XSEC_MAX_HASH_SIZE];
DWORD outDataLen = XSEC_MAX_HASH_SIZE;
CryptGetHashParam(
h,
HP_HASHVAL,
outData,
&outDataLen,
0);
if (fResult == 0 || h == 0) {
if (h)
CryptDestroyHash(h);
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:Hash::setKey - Error getting hash result");
}
keyBuf.sbMemcpyIn(outData, outDataLen);
keyLen = outDataLen;
if (h)
CryptDestroyHash(h);
}
// Now create the ipad and opad keyed values
memcpy(m_ipadKeyed, ipad, m_blockSize);
memcpy(m_opadKeyed, opad, m_blockSize);
// XOR with the key
for (unsigned int i = 0; i < keyLen; ++i) {
m_ipadKeyed[i] = keyBuf[i] ^ m_ipadKeyed[i];
m_opadKeyed[i] = keyBuf[i] ^ m_opadKeyed[i];
}
// Now create the hash object, and start with the ipad operation
fResult = CryptCreateHash(
m_p,
m_algId,
0,
0,
&m_h);
if (fResult == 0 || m_h == 0) {
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:HashHMAC - Error creating hash object");
}
fResult = CryptHashData(
m_h,
m_ipadKeyed,
m_blockSize,
0);
if (fResult == 0 || m_h == 0) {
throw XSECCryptoException(XSECCryptoException::MDError,
"WinCAPI:HashHMAC - Error performing initial ipad digest");
}
}