00001
00002
00003
00004
00005
00006
00007 #pragma once
00008
00009 #include <Swiften/Base/SafeByteArray.h>
00010 #include <Swiften/Base/ByteArray.h>
00011 #include <Swiften/Base/Algorithm.h>
00012 #include <cassert>
00013
00014 namespace Swift {
00015 namespace HMAC_Detail {
00016 template<typename KeyType> struct KeyWrapper;
00017 template<> struct KeyWrapper<ByteArray> {
00018 ByteArray wrap(const ByteArray& hash) const {
00019 return hash;
00020 }
00021 };
00022 template<> struct KeyWrapper<SafeByteArray> {
00023 SafeByteArray wrap(const ByteArray& hash) const {
00024 return createSafeByteArray(hash);
00025 }
00026 };
00027
00028 template<typename Hash, typename KeyType, int BlockSize>
00029 static ByteArray getHMAC(const KeyType& key, const ByteArray& data) {
00030 Hash hash;
00031
00032
00033 KeyType paddedKey(key.size() <= BlockSize ? key : KeyWrapper<KeyType>().wrap(hash(key)));
00034 paddedKey.resize(BlockSize, 0x0);
00035
00036
00037 KeyType x(paddedKey);
00038 for (unsigned int i = 0; i < x.size(); ++i) {
00039 x[i] ^= 0x36;
00040 }
00041 append(x, data);
00042
00043
00044 KeyType y(paddedKey);
00045 for (unsigned int i = 0; i < y.size(); ++i) {
00046 y[i] ^= 0x5c;
00047 }
00048 append(y, hash(x));
00049
00050 return hash(y);
00051 }
00052 };
00053
00054 template<typename Hash, int BlockSize>
00055 class HMAC {
00056 private:
00057
00058 public:
00059 ByteArray operator()(const ByteArray& key, const ByteArray& data) const {
00060 return HMAC_Detail::getHMAC<Hash,ByteArray,BlockSize>(key, data);
00061 }
00062
00063 ByteArray operator()(const SafeByteArray& key, const ByteArray& data) const {
00064 return HMAC_Detail::getHMAC<Hash,SafeByteArray,BlockSize>(key, data);
00065 }
00066 };
00067 }