QByteArray ImapPrivate::hmacMd5 (const QString& username, const QString& password, const QString& serverResponse) { QByteArray passwordBytes = password.toLatin1(); QByteArray ipad(64, 0); QByteArray opad(64, 0); for (int i = 0; i < 64; ++i) { if (i < passwordBytes.size()) { ipad[i] = (quint8)(0x36 ^ passwordBytes[i]); opad[i] = (quint8)(0x5c ^ passwordBytes[i]); } else { ipad[i] = 0x36; opad[i] = 0x5c; } } QByteArray serverResponseBytes = serverResponse.toLatin1(); while (serverResponseBytes[0] == '+' || serverResponseBytes[0] == ' ') serverResponseBytes.remove(0, 1); QCryptographicHash md5hash(QCryptographicHash::Md5); md5hash.addData(ipad); md5hash.addData(serverResponseBytes); QByteArray resultIpad = md5hash.result(); md5hash.reset(); md5hash.addData(opad); md5hash.addData(resultIpad); QByteArray resultOpad = md5hash.result(); QByteArray response = username.toLatin1() + ' ' + resultOpad.toHex(); return(response.toBase64()); }
void CAuthenticationHmac::ConstructL(const TLibraryPtr &aLib, TUint anIndex, const TDesC8 &aKey, TInt aBits) { /** * Setup HMAC processing using the specified digest. * * @param aLib The library to use for the digest engine * @param anIndex The digest algorithm number in library * @param aKey The authentication key * @param aBits The number of bits used from the digets. */ iDigest = aLib.iLibrary->MessageDigest(anIndex); iBlockSize = aLib.iAlgs[anIndex].iBlock; iDigestSize = aLib.iAlgs[anIndex].iVector; iBits = aBits; iHmac_ipad = HBufC8::NewMaxL(iBlockSize); iHmac_opad = HBufC8::NewMaxL(iBlockSize); iTemp = HBufC8::NewMaxL(iDigestSize); TPtr8 ipad(iHmac_ipad->Des()); TPtr8 opad(iHmac_opad->Des()); if (aKey.Length() > iBlockSize) { iDigest->Init(); iDigest->Update(aKey); iDigest->Final(ipad); ipad.SetLength(iDigestSize); } else ipad = aKey; opad.SetLength(iBlockSize); int i; for (i = 0; i < ipad.Length(); ++i) { opad[i] = (TUint8)(ipad[i] ^ 0x5c); ipad[i] ^= 0x36; } ipad.SetLength(iBlockSize); for ( ;i < iBlockSize; ++i) { ipad[i] = 0x36; opad[i] = 0x5c; } }