/* * Copyright (c) 2013-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include #include #include #pragma GCC diagnostic ignored "-Wdeprecated-declarations" using namespace Swift; namespace { class SHA1Hash : public Hash { public: SHA1Hash() : finalized(false) { if (!SHA1_Init(&context)) { assert(false); } } ~SHA1Hash() override { } virtual Hash& update(const ByteArray& data) override { return updateInternal(data); } virtual Hash& update(const SafeByteArray& data) override { return updateInternal(data); } virtual std::vector getHash() override { assert(!finalized); std::vector result(SHA_DIGEST_LENGTH); SHA1_Final(vecptr(result), &context); return result; } private: template Hash& updateInternal(const ContainerType& data) { assert(!finalized); if (!SHA1_Update(&context, vecptr(data), data.size())) { assert(false); } return *this; } private: SHA_CTX context; bool finalized; }; class MD5Hash : public Hash { public: MD5Hash() : finalized(false) { if (!MD5_Init(&context)) { assert(false); } } ~MD5Hash() override { } virtual Hash& update(const ByteArray& data) override { return updateInternal(data); } virtual Hash& update(const SafeByteArray& data) override { return updateInternal(data); } virtual std::vector getHash() override { assert(!finalized); std::vector result(MD5_DIGEST_LENGTH); MD5_Final(vecptr(result), &context); return result; } private: template Hash& updateInternal(const ContainerType& data) { assert(!finalized); if (!MD5_Update(&context, vecptr(data), data.size())) { assert(false); } return *this; } private: MD5_CTX context; bool finalized; }; template ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data) { unsigned int len = SHA_DIGEST_LENGTH; std::vector result(len); try { HMAC(EVP_sha1(), vecptr(key), boost::numeric_cast(key.size()), vecptr(data), boost::numeric_cast(data.size()), vecptr(result), &len); } catch (const boost::numeric::bad_numeric_cast&) { assert(false); } return result; } } OpenSSLCryptoProvider::OpenSSLCryptoProvider() { } OpenSSLCryptoProvider::~OpenSSLCryptoProvider() { } Hash* OpenSSLCryptoProvider::createSHA1() { return new SHA1Hash(); } Hash* OpenSSLCryptoProvider::createMD5() { return new MD5Hash(); } ByteArray OpenSSLCryptoProvider::getHMACSHA1(const SafeByteArray& key, const ByteArray& data) { return getHMACSHA1Internal(key, data); } ByteArray OpenSSLCryptoProvider::getHMACSHA1(const ByteArray& key, const ByteArray& data) { return getHMACSHA1Internal(key, data); } bool OpenSSLCryptoProvider::isMD5AllowedForCrypto() const { return true; }