diff options
Diffstat (limited to 'Swiften/Crypto')
-rw-r--r-- | Swiften/Crypto/CommonCryptoCryptoProvider.cpp | 213 | ||||
-rw-r--r-- | Swiften/Crypto/CommonCryptoCryptoProvider.h | 26 | ||||
-rw-r--r-- | Swiften/Crypto/CryptoProvider.cpp | 28 | ||||
-rw-r--r-- | Swiften/Crypto/CryptoProvider.h | 38 | ||||
-rw-r--r-- | Swiften/Crypto/Hash.cpp | 24 | ||||
-rw-r--r-- | Swiften/Crypto/Hash.h | 49 | ||||
-rw-r--r-- | Swiften/Crypto/OpenSSLCryptoProvider.cpp | 199 | ||||
-rw-r--r-- | Swiften/Crypto/OpenSSLCryptoProvider.h | 25 | ||||
-rw-r--r-- | Swiften/Crypto/PlatformCryptoProvider.cpp | 64 | ||||
-rw-r--r-- | Swiften/Crypto/PlatformCryptoProvider.h | 34 | ||||
-rw-r--r-- | Swiften/Crypto/SConscript | 24 | ||||
-rw-r--r-- | Swiften/Crypto/UnitTest/CryptoProviderTest.cpp | 312 | ||||
-rw-r--r-- | Swiften/Crypto/WindowsCryptoProvider.cpp | 339 | ||||
-rw-r--r-- | Swiften/Crypto/WindowsCryptoProvider.h | 37 |
14 files changed, 717 insertions, 695 deletions
diff --git a/Swiften/Crypto/CommonCryptoCryptoProvider.cpp b/Swiften/Crypto/CommonCryptoCryptoProvider.cpp index 14f9284..3cc69b0 100644 --- a/Swiften/Crypto/CommonCryptoCryptoProvider.cpp +++ b/Swiften/Crypto/CommonCryptoCryptoProvider.cpp @@ -1,110 +1,127 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2018 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Crypto/CommonCryptoCryptoProvider.h> +#include <cassert> + +#include <boost/numeric/conversion/cast.hpp> + #include <CommonCrypto/CommonDigest.h> #include <CommonCrypto/CommonHMAC.h> -#include <cassert> -#include <Swiften/Crypto/Hash.h> #include <Swiften/Base/ByteArray.h> -#include <boost/numeric/conversion/cast.hpp> +#include <Swiften/Crypto/Hash.h> using namespace Swift; namespace { - class SHA1Hash : public Hash { - public: - SHA1Hash() : finalized(false) { - if (!CC_SHA1_Init(&context)) { - assert(false); - } - } - - ~SHA1Hash() { - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - assert(!finalized); - std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); - CC_SHA1_Final(vecptr(result), &context); - return result; - } - - private: - template<typename ContainerType> - Hash& updateInternal(const ContainerType& data) { - assert(!finalized); - if (!CC_SHA1_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { - assert(false); - } - return *this; - } - - private: - CC_SHA1_CTX context; - bool finalized; - }; - - class MD5Hash : public Hash { - public: - MD5Hash() : finalized(false) { - if (!CC_MD5_Init(&context)) { - assert(false); - } - } - - ~MD5Hash() { - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - assert(!finalized); - std::vector<unsigned char> result(CC_MD5_DIGEST_LENGTH); - CC_MD5_Final(vecptr(result), &context); - return result; - } - - private: - template<typename ContainerType> - Hash& updateInternal(const ContainerType& data) { - assert(!finalized); - if (!CC_MD5_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { - assert(false); - } - return *this; - } - - private: - CC_MD5_CTX context; - bool finalized; - }; - - template<typename T> - ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data) { - std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); - CCHmac(kCCHmacAlgSHA1, vecptr(key), key.size(), vecptr(data), boost::numeric_cast<CC_LONG>(data.size()), vecptr(result)); - return result; - } + class SHA1Hash : public Hash { + public: + SHA1Hash() : finalized(false) { + if (!CC_SHA1_Init(&context)) { + assert(false); + } + } + + virtual ~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<unsigned char> getHash() override { + assert(!finalized); + std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); + CC_SHA1_Final(vecptr(result), &context); + return result; + } + + private: + template<typename ContainerType> + Hash& updateInternal(const ContainerType& data) { + assert(!finalized); + try { + if (!CC_SHA1_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { + assert(false); + } + } + catch (const boost::numeric::bad_numeric_cast&) { + assert(false); + } + return *this; + } + + private: + CC_SHA1_CTX context; + bool finalized; + }; + + class MD5Hash : public Hash { + public: + MD5Hash() : finalized(false) { + if (!CC_MD5_Init(&context)) { + assert(false); + } + } + + virtual ~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<unsigned char> getHash() override { + assert(!finalized); + std::vector<unsigned char> result(CC_MD5_DIGEST_LENGTH); + CC_MD5_Final(vecptr(result), &context); + return result; + } + + private: + template<typename ContainerType> + Hash& updateInternal(const ContainerType& data) { + assert(!finalized); + try { + if (!CC_MD5_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { + assert(false); + } + } + catch (const boost::numeric::bad_numeric_cast&) { + assert(false); + } + return *this; + } + + private: + CC_MD5_CTX context; + bool finalized; + }; + + template<typename T> + ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data) { + std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); + try { + CCHmac(kCCHmacAlgSHA1, vecptr(key), key.size(), vecptr(data), boost::numeric_cast<CC_LONG>(data.size()), vecptr(result)); + } + catch (const boost::numeric::bad_numeric_cast&) { + assert(false); + } + return result; + } } CommonCryptoCryptoProvider::CommonCryptoCryptoProvider() { @@ -114,22 +131,22 @@ CommonCryptoCryptoProvider::~CommonCryptoCryptoProvider() { } Hash* CommonCryptoCryptoProvider::createSHA1() { - return new SHA1Hash(); + return new SHA1Hash(); } Hash* CommonCryptoCryptoProvider::createMD5() { - return new MD5Hash(); + return new MD5Hash(); } ByteArray CommonCryptoCryptoProvider::getHMACSHA1(const SafeByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data); + return getHMACSHA1Internal(key, data); } ByteArray CommonCryptoCryptoProvider::getHMACSHA1(const ByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data); + return getHMACSHA1Internal(key, data); } bool CommonCryptoCryptoProvider::isMD5AllowedForCrypto() const { - return true; + return true; } diff --git a/Swiften/Crypto/CommonCryptoCryptoProvider.h b/Swiften/Crypto/CommonCryptoCryptoProvider.h index f921e17..7d1675f 100644 --- a/Swiften/Crypto/CommonCryptoCryptoProvider.h +++ b/Swiften/Crypto/CommonCryptoCryptoProvider.h @@ -1,24 +1,24 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2017 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <Swiften/Base/API.h> #include <Swiften/Crypto/CryptoProvider.h> -#include <Swiften/Base/Override.h> namespace Swift { - class CommonCryptoCryptoProvider : public CryptoProvider { - public: - CommonCryptoCryptoProvider(); - ~CommonCryptoCryptoProvider(); + class SWIFTEN_API CommonCryptoCryptoProvider : public CryptoProvider { + public: + CommonCryptoCryptoProvider(); + virtual ~CommonCryptoCryptoProvider() override; - virtual Hash* createSHA1() SWIFTEN_OVERRIDE; - virtual Hash* createMD5() SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE; - }; + virtual Hash* createSHA1() override; + virtual Hash* createMD5() override; + virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) override; + virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) override; + virtual bool isMD5AllowedForCrypto() const override; + }; } diff --git a/Swiften/Crypto/CryptoProvider.cpp b/Swiften/Crypto/CryptoProvider.cpp index 0189de4..9c7c637 100644 --- a/Swiften/Crypto/CryptoProvider.cpp +++ b/Swiften/Crypto/CryptoProvider.cpp @@ -1,14 +1,14 @@ -/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#include <Swiften/Crypto/CryptoProvider.h>
-
-#include <boost/shared_ptr.hpp>
-
-using namespace Swift;
-
-CryptoProvider::~CryptoProvider() {
-}
+/* + * Copyright (c) 2013-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Crypto/CryptoProvider.h> + +#include <memory> + +using namespace Swift; + +CryptoProvider::~CryptoProvider() { +} diff --git a/Swiften/Crypto/CryptoProvider.h b/Swiften/Crypto/CryptoProvider.h index c1e1eb9..3eaeeb3 100644 --- a/Swiften/Crypto/CryptoProvider.h +++ b/Swiften/Crypto/CryptoProvider.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2016 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ @@ -12,25 +12,25 @@ #include <Swiften/Crypto/Hash.h> namespace Swift { - class Hash; + class Hash; - class SWIFTEN_API CryptoProvider { - public: - virtual ~CryptoProvider(); + class SWIFTEN_API CryptoProvider { + public: + virtual ~CryptoProvider(); - virtual Hash* createSHA1() = 0; - virtual Hash* createMD5() = 0; - virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) = 0; - virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) = 0; - virtual bool isMD5AllowedForCrypto() const = 0; + virtual Hash* createSHA1() = 0; + virtual Hash* createMD5() = 0; + virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) = 0; + virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) = 0; + virtual bool isMD5AllowedForCrypto() const = 0; - // Convenience - template<typename T> ByteArray getSHA1Hash(const T& data) { - return boost::shared_ptr<Hash>(createSHA1())->update(data).getHash(); - } + // Convenience + template<typename T> ByteArray getSHA1Hash(const T& data) { + return std::shared_ptr<Hash>(createSHA1())->update(data).getHash(); + } - template<typename T> ByteArray getMD5Hash(const T& data) { - return boost::shared_ptr<Hash>(createMD5())->update(data).getHash(); - } - }; + template<typename T> ByteArray getMD5Hash(const T& data) { + return std::shared_ptr<Hash>(createMD5())->update(data).getHash(); + } + }; } diff --git a/Swiften/Crypto/Hash.cpp b/Swiften/Crypto/Hash.cpp index 35c7e70..b945301 100644 --- a/Swiften/Crypto/Hash.cpp +++ b/Swiften/Crypto/Hash.cpp @@ -1,12 +1,12 @@ -/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#include <Swiften/Crypto/Hash.h>
-
-using namespace Swift;
-
-Hash::~Hash() {
-}
+/* + * Copyright (c) 2013 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Crypto/Hash.h> + +using namespace Swift; + +Hash::~Hash() { +} diff --git a/Swiften/Crypto/Hash.h b/Swiften/Crypto/Hash.h index 37c6ec8..a9ed323 100644 --- a/Swiften/Crypto/Hash.h +++ b/Swiften/Crypto/Hash.h @@ -1,24 +1,25 @@ -/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#pragma once
-
-#include <vector>
-
-#include <Swiften/Base/ByteArray.h>
-#include <Swiften/Base/SafeByteArray.h>
-
-namespace Swift {
- class Hash {
- public:
- virtual ~Hash();
-
- virtual Hash& update(const ByteArray& data) = 0;
- virtual Hash& update(const SafeByteArray& data) = 0;
-
- virtual std::vector<unsigned char> getHash() = 0;
- };
-}
+/* + * Copyright (c) 2013-2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Base/API.h> +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> + +namespace Swift { + class SWIFTEN_API Hash { + public: + virtual ~Hash(); + + virtual Hash& update(const ByteArray& data) = 0; + virtual Hash& update(const SafeByteArray& data) = 0; + + virtual std::vector<unsigned char> getHash() = 0; + }; +} diff --git a/Swiften/Crypto/OpenSSLCryptoProvider.cpp b/Swiften/Crypto/OpenSSLCryptoProvider.cpp index 9b1d544..5245bd8 100644 --- a/Swiften/Crypto/OpenSSLCryptoProvider.cpp +++ b/Swiften/Crypto/OpenSSLCryptoProvider.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2018 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ @@ -20,96 +20,101 @@ using namespace Swift; namespace { - class SHA1Hash : public Hash { - public: - SHA1Hash() : finalized(false) { - if (!SHA1_Init(&context)) { - assert(false); - } - } - - ~SHA1Hash() { - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - assert(!finalized); - std::vector<unsigned char> result(SHA_DIGEST_LENGTH); - SHA1_Final(vecptr(result), &context); - return result; - } - - private: - template<typename ContainerType> - 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() { - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - assert(!finalized); - std::vector<unsigned char> result(MD5_DIGEST_LENGTH); - MD5_Final(vecptr(result), &context); - return result; - } - - private: - template<typename ContainerType> - 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<typename T> - ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data) { - unsigned int len = SHA_DIGEST_LENGTH; - std::vector<unsigned char> result(len); - HMAC(EVP_sha1(), vecptr(key), boost::numeric_cast<int>(key.size()), vecptr(data), data.size(), vecptr(result), &len); - return result; - } + 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<unsigned char> getHash() override { + assert(!finalized); + std::vector<unsigned char> result(SHA_DIGEST_LENGTH); + SHA1_Final(vecptr(result), &context); + return result; + } + + private: + template<typename ContainerType> + 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<unsigned char> getHash() override { + assert(!finalized); + std::vector<unsigned char> result(MD5_DIGEST_LENGTH); + MD5_Final(vecptr(result), &context); + return result; + } + + private: + template<typename ContainerType> + 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<typename T> + ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data) { + unsigned int len = SHA_DIGEST_LENGTH; + std::vector<unsigned char> result(len); + try { + HMAC(EVP_sha1(), vecptr(key), boost::numeric_cast<int>(key.size()), vecptr(data), data.size(), vecptr(result), &len); + } + catch (const boost::numeric::bad_numeric_cast&) { + assert(false); + } + return result; + } } OpenSSLCryptoProvider::OpenSSLCryptoProvider() { @@ -119,22 +124,22 @@ OpenSSLCryptoProvider::~OpenSSLCryptoProvider() { } Hash* OpenSSLCryptoProvider::createSHA1() { - return new SHA1Hash(); + return new SHA1Hash(); } Hash* OpenSSLCryptoProvider::createMD5() { - return new MD5Hash(); + return new MD5Hash(); } ByteArray OpenSSLCryptoProvider::getHMACSHA1(const SafeByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data); + return getHMACSHA1Internal(key, data); } ByteArray OpenSSLCryptoProvider::getHMACSHA1(const ByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data); + return getHMACSHA1Internal(key, data); } bool OpenSSLCryptoProvider::isMD5AllowedForCrypto() const { - return true; + return true; } diff --git a/Swiften/Crypto/OpenSSLCryptoProvider.h b/Swiften/Crypto/OpenSSLCryptoProvider.h index 9440aee..e4ee97d 100644 --- a/Swiften/Crypto/OpenSSLCryptoProvider.h +++ b/Swiften/Crypto/OpenSSLCryptoProvider.h @@ -1,24 +1,23 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2017 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <Swiften/Crypto/CryptoProvider.h> -#include <Swiften/Base/Override.h> namespace Swift { - class OpenSSLCryptoProvider : public CryptoProvider { - public: - OpenSSLCryptoProvider(); - ~OpenSSLCryptoProvider(); + class OpenSSLCryptoProvider : public CryptoProvider { + public: + OpenSSLCryptoProvider(); + virtual ~OpenSSLCryptoProvider() override; - virtual Hash* createSHA1() SWIFTEN_OVERRIDE; - virtual Hash* createMD5() SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE; - }; + virtual Hash* createSHA1() override; + virtual Hash* createMD5() override; + virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) override; + virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) override; + virtual bool isMD5AllowedForCrypto() const override; + }; } diff --git a/Swiften/Crypto/PlatformCryptoProvider.cpp b/Swiften/Crypto/PlatformCryptoProvider.cpp index ab0fa7b..a72bf8e 100644 --- a/Swiften/Crypto/PlatformCryptoProvider.cpp +++ b/Swiften/Crypto/PlatformCryptoProvider.cpp @@ -1,32 +1,32 @@ -/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#include <Swiften/Crypto/PlatformCryptoProvider.h>
-
-#include <cassert>
-
-#include <Swiften/Base/Platform.h>
-#if defined(SWIFTEN_PLATFORM_WIN32)
-#include <Swiften/Crypto/WindowsCryptoProvider.h>
-#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER)
-#include <Swiften/Crypto/CommonCryptoCryptoProvider.h>
-#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER)
-#include <Swiften/Crypto/OpenSSLCryptoProvider.h>
-#endif
-
-using namespace Swift;
-
-CryptoProvider* PlatformCryptoProvider::create() {
-#if defined(SWIFTEN_PLATFORM_WIN32)
- return new WindowsCryptoProvider();
-#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER)
- return new CommonCryptoCryptoProvider();
-#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER)
- return new OpenSSLCryptoProvider();
-#endif
- assert(false);
- return NULL;
-}
+/* + * Copyright (c) 2013-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Crypto/PlatformCryptoProvider.h> + +#include <cassert> + +#include <Swiften/Base/Platform.h> +#if defined(SWIFTEN_PLATFORM_WIN32) +#include <Swiften/Crypto/WindowsCryptoProvider.h> +#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER) +#include <Swiften/Crypto/CommonCryptoCryptoProvider.h> +#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER) +#include <Swiften/Crypto/OpenSSLCryptoProvider.h> +#endif + +using namespace Swift; + +CryptoProvider* PlatformCryptoProvider::create() { +#if defined(SWIFTEN_PLATFORM_WIN32) + return new WindowsCryptoProvider(); +#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER) + return new CommonCryptoCryptoProvider(); +#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER) + return new OpenSSLCryptoProvider(); +#endif + assert(false); + return nullptr; +} diff --git a/Swiften/Crypto/PlatformCryptoProvider.h b/Swiften/Crypto/PlatformCryptoProvider.h index 0721887..1133ae5 100644 --- a/Swiften/Crypto/PlatformCryptoProvider.h +++ b/Swiften/Crypto/PlatformCryptoProvider.h @@ -1,17 +1,17 @@ -/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#pragma once
-
-#include <Swiften/Base/API.h>
-
-namespace Swift {
- class CryptoProvider;
-
- namespace PlatformCryptoProvider {
- SWIFTEN_API CryptoProvider* create();
- }
-}
+/* + * Copyright (c) 2013 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/API.h> + +namespace Swift { + class CryptoProvider; + + namespace PlatformCryptoProvider { + SWIFTEN_API CryptoProvider* create(); + } +} diff --git a/Swiften/Crypto/SConscript b/Swiften/Crypto/SConscript index ce4bdae..d5532fd 100644 --- a/Swiften/Crypto/SConscript +++ b/Swiften/Crypto/SConscript @@ -2,27 +2,27 @@ Import("swiften_env", "env") objects = swiften_env.SwiftenObject([
- "CryptoProvider.cpp",
- "Hash.cpp"
+ "CryptoProvider.cpp",
+ "Hash.cpp"
])
myenv = swiften_env.Clone()
if myenv["PLATFORM"] == "win32" :
- objects += myenv.SwiftenObject(["WindowsCryptoProvider.cpp"])
+ objects += myenv.SwiftenObject(["WindowsCryptoProvider.cpp"])
if myenv.get("HAVE_OPENSSL", False) :
- myenv.Append(CPPDEFINES = ["HAVE_OPENSSL_CRYPTO_PROVIDER"])
- objects += myenv.SwiftenObject(["OpenSSLCryptoProvider.cpp"])
+ myenv.Append(CPPDEFINES = ["HAVE_OPENSSL_CRYPTO_PROVIDER"])
+ objects += myenv.SwiftenObject(["OpenSSLCryptoProvider.cpp"])
if myenv["PLATFORM"] == "darwin" and myenv["target"] == "native" :
- myenv.Append(CPPDEFINES = ["HAVE_COMMONCRYPTO_CRYPTO_PROVIDER"])
- objects += myenv.SwiftenObject(["CommonCryptoCryptoProvider.cpp"])
+ myenv.Append(CPPDEFINES = ["HAVE_COMMONCRYPTO_CRYPTO_PROVIDER"])
+ objects += myenv.SwiftenObject(["CommonCryptoCryptoProvider.cpp"])
objects += myenv.SwiftenObject(["PlatformCryptoProvider.cpp"])
swiften_env.Append(SWIFTEN_OBJECTS = [objects])
if env["TEST"] :
- test_env = myenv.Clone()
- test_env.UseFlags(swiften_env["CPPUNIT_FLAGS"])
- env.Append(UNITTEST_OBJECTS = test_env.SwiftenObject([
- File("UnitTest/CryptoProviderTest.cpp"),
- ]))
+ test_env = myenv.Clone()
+ test_env.UseFlags(swiften_env["CPPUNIT_FLAGS"])
+ env.Append(UNITTEST_OBJECTS = test_env.SwiftenObject([
+ File("UnitTest/CryptoProviderTest.cpp"),
+ ]))
diff --git a/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp b/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp index 1e2275a..72eb81d 100644 --- a/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp +++ b/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp @@ -1,156 +1,156 @@ -/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/Base/ByteArray.h>
-#include <Swiften/Base/Platform.h>
-#include <QA/Checker/IO.h>
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-
-#ifdef SWIFTEN_PLATFORM_WIN32
-#include <Swiften/Crypto/WindowsCryptoProvider.h>
-#endif
-#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
-#include <Swiften/Crypto/OpenSSLCryptoProvider.h>
-#endif
-#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
-#include <Swiften/Crypto/CommonCryptoCryptoProvider.h>
-#endif
-#include <Swiften/Crypto/Hash.h>
-
-using namespace Swift;
-
-template <typename CryptoProviderType>
-class CryptoProviderTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(CryptoProviderTest);
-
- CPPUNIT_TEST(testGetSHA1Hash);
- CPPUNIT_TEST(testGetSHA1Hash_TwoUpdates);
- CPPUNIT_TEST(testGetSHA1Hash_NoData);
- CPPUNIT_TEST(testGetSHA1HashStatic);
- CPPUNIT_TEST(testGetSHA1HashStatic_Twice);
- CPPUNIT_TEST(testGetSHA1HashStatic_NoData);
-
- CPPUNIT_TEST(testGetMD5Hash_Empty);
- CPPUNIT_TEST(testGetMD5Hash_Alphabet);
- CPPUNIT_TEST(testMD5Incremental);
-
- CPPUNIT_TEST(testGetHMACSHA1);
- CPPUNIT_TEST(testGetHMACSHA1_KeyLongerThanBlockSize);
-
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- provider = new CryptoProviderType();
- }
-
- void tearDown() {
- delete provider;
- }
-
- ////////////////////////////////////////////////////////////
- // SHA-1
- ////////////////////////////////////////////////////////////
-
- void testGetSHA1Hash() {
- boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
- sha->update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha->getHash());
- }
-
- void testGetSHA1Hash_TwoUpdates() {
- boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
- sha->update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<"));
- sha->update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha->getHash());
- }
-
- void testGetSHA1Hash_NoData() {
- boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
- sha->update(std::vector<unsigned char>());
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), sha->getHash());
- }
-
- void testGetSHA1HashStatic() {
- ByteArray result(provider->getSHA1Hash(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")));
- CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result);
- }
-
-
- void testGetSHA1HashStatic_Twice() {
- ByteArray input(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"));
- provider->getSHA1Hash(input);
- ByteArray result(provider->getSHA1Hash(input));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result);
- }
-
- void testGetSHA1HashStatic_NoData() {
- ByteArray result(provider->getSHA1Hash(ByteArray()));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result);
- }
-
-
- ////////////////////////////////////////////////////////////
- // MD5
- ////////////////////////////////////////////////////////////
-
- void testGetMD5Hash_Empty() {
- ByteArray result(provider->getMD5Hash(createByteArray("")));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result);
- }
-
- void testGetMD5Hash_Alphabet() {
- ByteArray result(provider->getMD5Hash(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")));
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result);
- }
-
- void testMD5Incremental() {
- boost::shared_ptr<Hash> testling = boost::shared_ptr<Hash>(provider->createMD5());
- testling->update(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
- testling->update(createByteArray("abcdefghijklmnopqrstuvwxyz0123456789"));
-
- ByteArray result = testling->getHash();
-
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result);
- }
-
-
- ////////////////////////////////////////////////////////////
- // HMAC-SHA1
- ////////////////////////////////////////////////////////////
-
- void testGetHMACSHA1() {
- ByteArray result(provider->getHMACSHA1(createSafeByteArray("foo"), createByteArray("foobar")));
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result);
- }
-
- void testGetHMACSHA1_KeyLongerThanBlockSize() {
- ByteArray result(provider->getHMACSHA1(createSafeByteArray("---------|---------|---------|---------|---------|----------|---------|"), createByteArray("foobar")));
- CPPUNIT_ASSERT_EQUAL(createByteArray("\xd6""n""\x8f""P|1""\xd3"",""\x6"" ""\xb9\xe3""gg""\x8e\xcf"" ]+""\xa"), result);
- }
-
- private:
- CryptoProviderType* provider;
-};
-
-#ifdef SWIFTEN_PLATFORM_WIN32
-CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<WindowsCryptoProvider>);
-#endif
-#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
-CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<OpenSSLCryptoProvider>);
-#endif
-#ifdef HAVE_COMMONCRYPTO_CRYPTO_PROVIDER
-CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<CommonCryptoCryptoProvider>);
-#endif
+/* + * Copyright (c) 2010-2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Platform.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#ifdef SWIFTEN_PLATFORM_WIN32 +#include <Swiften/Crypto/WindowsCryptoProvider.h> +#endif +#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER +#include <Swiften/Crypto/OpenSSLCryptoProvider.h> +#endif +#ifdef HAVE_COMMONCRYPTO_CRYPTO_PROVIDER +#include <Swiften/Crypto/CommonCryptoCryptoProvider.h> +#endif +#include <Swiften/Crypto/Hash.h> + +using namespace Swift; + +template <typename CryptoProviderType> +class CryptoProviderTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(CryptoProviderTest); + + CPPUNIT_TEST(testGetSHA1Hash); + CPPUNIT_TEST(testGetSHA1Hash_TwoUpdates); + CPPUNIT_TEST(testGetSHA1Hash_NoData); + CPPUNIT_TEST(testGetSHA1HashStatic); + CPPUNIT_TEST(testGetSHA1HashStatic_Twice); + CPPUNIT_TEST(testGetSHA1HashStatic_NoData); + + CPPUNIT_TEST(testGetMD5Hash_Empty); + CPPUNIT_TEST(testGetMD5Hash_Alphabet); + CPPUNIT_TEST(testMD5Incremental); + + CPPUNIT_TEST(testGetHMACSHA1); + CPPUNIT_TEST(testGetHMACSHA1_KeyLongerThanBlockSize); + + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + provider = new CryptoProviderType(); + } + + void tearDown() { + delete provider; + } + + //////////////////////////////////////////////////////////// + // SHA-1 + //////////////////////////////////////////////////////////// + + void testGetSHA1Hash() { + std::shared_ptr<Hash> sha = std::shared_ptr<Hash>(provider->createSHA1()); + sha->update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha->getHash()); + } + + void testGetSHA1Hash_TwoUpdates() { + std::shared_ptr<Hash> sha = std::shared_ptr<Hash>(provider->createSHA1()); + sha->update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<")); + sha->update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha->getHash()); + } + + void testGetSHA1Hash_NoData() { + std::shared_ptr<Hash> sha = std::shared_ptr<Hash>(provider->createSHA1()); + sha->update(std::vector<unsigned char>()); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), sha->getHash()); + } + + void testGetSHA1HashStatic() { + ByteArray result(provider->getSHA1Hash(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); + } + + + void testGetSHA1HashStatic_Twice() { + ByteArray input(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + provider->getSHA1Hash(input); + ByteArray result(provider->getSHA1Hash(input)); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); + } + + void testGetSHA1HashStatic_NoData() { + ByteArray result(provider->getSHA1Hash(ByteArray())); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result); + } + + + //////////////////////////////////////////////////////////// + // MD5 + //////////////////////////////////////////////////////////// + + void testGetMD5Hash_Empty() { + ByteArray result(provider->getMD5Hash(createByteArray(""))); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result); + } + + void testGetMD5Hash_Alphabet() { + ByteArray result(provider->getMD5Hash(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); + } + + void testMD5Incremental() { + std::shared_ptr<Hash> testling = std::shared_ptr<Hash>(provider->createMD5()); + testling->update(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); + testling->update(createByteArray("abcdefghijklmnopqrstuvwxyz0123456789")); + + ByteArray result = testling->getHash(); + + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); + } + + + //////////////////////////////////////////////////////////// + // HMAC-SHA1 + //////////////////////////////////////////////////////////// + + void testGetHMACSHA1() { + ByteArray result(provider->getHMACSHA1(createSafeByteArray("foo"), createByteArray("foobar"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result); + } + + void testGetHMACSHA1_KeyLongerThanBlockSize() { + ByteArray result(provider->getHMACSHA1(createSafeByteArray("---------|---------|---------|---------|---------|----------|---------|"), createByteArray("foobar"))); + CPPUNIT_ASSERT_EQUAL(createByteArray("\xd6""n""\x8f""P|1""\xd3"",""\x6"" ""\xb9\xe3""gg""\x8e\xcf"" ]+""\xa"), result); + } + + private: + CryptoProviderType* provider; +}; + +#ifdef SWIFTEN_PLATFORM_WIN32 +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<WindowsCryptoProvider>); +#endif +#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<OpenSSLCryptoProvider>); +#endif +#ifdef HAVE_COMMONCRYPTO_CRYPTO_PROVIDER +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<CommonCryptoCryptoProvider>); +#endif diff --git a/Swiften/Crypto/WindowsCryptoProvider.cpp b/Swiften/Crypto/WindowsCryptoProvider.cpp index 9ca4c14..c784283 100644 --- a/Swiften/Crypto/WindowsCryptoProvider.cpp +++ b/Swiften/Crypto/WindowsCryptoProvider.cpp @@ -1,12 +1,12 @@ /* - * Copyright (c) 2012 Kevin Smith - * Licensed under the GNU General Public License. + * Copyright (c) 2012-2017 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ @@ -17,7 +17,7 @@ #include <security.h> #include <Wincrypt.h> #include <cassert> -#include <boost/smart_ptr/make_shared.hpp> +#include <memory> #include <Swiften/Crypto/Hash.h> #include <Swiften/Base/ByteArray.h> @@ -27,196 +27,195 @@ using namespace Swift; struct WindowsCryptoProvider::Private { - HCRYPTPROV context; + HCRYPTPROV context; }; namespace { - class WindowsHash : public Hash { - public: - WindowsHash(HCRYPTPROV context, ALG_ID algorithm) : hash(NULL) { - if (!CryptCreateHash(context, algorithm, 0, 0, &hash)) { - assert(false); - } - } - - ~WindowsHash() { - CryptDestroyHash(hash); - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - std::vector<unsigned char> result; - DWORD hashLength = sizeof(DWORD); - DWORD hashSize; - CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0); - result.resize(static_cast<size_t>(hashSize)); - if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) { - assert(false); - } - result.resize(static_cast<size_t>(hashSize)); - return result; - } - - private: - template<typename ContainerType> - Hash& updateInternal(const ContainerType& data) { - if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) { - assert(false); - } - return *this; - } - - private: - HCRYPTHASH hash; - }; + class WindowsHash : public Hash { + public: + WindowsHash(HCRYPTPROV context, ALG_ID algorithm) : hash(NULL) { + if (!CryptCreateHash(context, algorithm, 0, 0, &hash)) { + assert(false); + } + } + + virtual ~WindowsHash() { + CryptDestroyHash(hash); + } + + virtual Hash& update(const ByteArray& data) override { + return updateInternal(data); + } + + virtual Hash& update(const SafeByteArray& data) override { + return updateInternal(data); + } + + virtual std::vector<unsigned char> getHash() { + std::vector<unsigned char> result; + DWORD hashLength = sizeof(DWORD); + DWORD hashSize; + CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0); + result.resize(static_cast<size_t>(hashSize)); + if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) { + assert(false); + } + result.resize(static_cast<size_t>(hashSize)); + return result; + } + + private: + template<typename ContainerType> + Hash& updateInternal(const ContainerType& data) { + if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) { + assert(false); + } + return *this; + } + + private: + HCRYPTHASH hash; + }; #if 0 // NOT YET DONE - // Haven't tested the code below properly yet, but figured out after writing - // it that PLAINTEXTKEYBLOB doesn't work on XP or 2k, and the workaround is a - // bit too ugly to try this now. So, using our own algorithm for now. See - // http://support.microsoft.com/kb/228786/en-us - - // MSDN describes this as PLAINTEXTKEYBLOB, but this struct doesn't exist, - // and seems to even conflict with the PLAINTEXTKEYBLOB constant. Redefining - // here. - struct PlainTextKeyBlob { - BLOBHEADER hdr; - DWORD dwKeySize; - }; - - class HMACHash : public Hash { - public: - template<typename T> - HMACHash(HCRYPTPROV context, const T& rawKey) : hash(NULL) { - // Import raw key - T blobData(sizeof(PlainTextKeyBlob) + rawKey.size()); - PlainTextKeyBlob* blob = reinterpret_cast<PlainTextKeyBlob*>(vecptr(blobData)); - blob->hdr.bType = PLAINTEXTKEYBLOB; - blob->hdr.bVersion = CUR_BLOB_VERSION; - blob->hdr.reserved = 0; - blob->hdr.aiKeyAlg = CALG_RC2; - blob->dwKeySize = rawKey.size(); - std::copy(rawKey.begin(), rawKey.end(), blobData.begin() + sizeof(PlainTextKeyBlob)); - HCRYPTKEY key; - if (!CryptImportKey(context, vecptr(blobData), blobData.size(), 0, CRYPT_IPSEC_HMAC_KEY, &key)) { - assert(false); - return; - } - - // Create hash - if (!CryptCreateHash(context, CALG_HMAC, key, 0, &hash)) { - assert(false); - return; - } - ZeroMemory(&info, sizeof(info)); - info.HashAlgid = CALG_SHA1; - } - - ~HMACHash() { - CryptDestroyHash(hash); - } - - virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { - return updateInternal(data); - } - - virtual std::vector<unsigned char> getHash() { - std::vector<unsigned char> result; - DWORD hashLength = sizeof(DWORD); - DWORD hashSize; - CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0); - result.resize(static_cast<size_t>(hashSize)); - if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) { - assert(false); - } - result.resize(static_cast<size_t>(hashSize)); - return result; - } - - private: - template<typename ContainerType> - Hash& updateInternal(const ContainerType& data) { - if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) { - assert(false); - } - return *this; - } - - private: - HCRYPTHASH hash; - HMAC_INFO info; - }; + // Haven't tested the code below properly yet, but figured out after writing + // it that PLAINTEXTKEYBLOB doesn't work on XP or 2k, and the workaround is a + // bit too ugly to try this now. So, using our own algorithm for now. See + // http://support.microsoft.com/kb/228786/en-us + + // MSDN describes this as PLAINTEXTKEYBLOB, but this struct doesn't exist, + // and seems to even conflict with the PLAINTEXTKEYBLOB constant. Redefining + // here. + struct PlainTextKeyBlob { + BLOBHEADER hdr; + DWORD dwKeySize; + }; + + class HMACHash : public Hash { + public: + template<typename T> + HMACHash(HCRYPTPROV context, const T& rawKey) : hash(NULL) { + // Import raw key + T blobData(sizeof(PlainTextKeyBlob) + rawKey.size()); + PlainTextKeyBlob* blob = reinterpret_cast<PlainTextKeyBlob*>(vecptr(blobData)); + blob->hdr.bType = PLAINTEXTKEYBLOB; + blob->hdr.bVersion = CUR_BLOB_VERSION; + blob->hdr.reserved = 0; + blob->hdr.aiKeyAlg = CALG_RC2; + blob->dwKeySize = rawKey.size(); + std::copy(rawKey.begin(), rawKey.end(), blobData.begin() + sizeof(PlainTextKeyBlob)); + HCRYPTKEY key; + if (!CryptImportKey(context, vecptr(blobData), blobData.size(), 0, CRYPT_IPSEC_HMAC_KEY, &key)) { + assert(false); + return; + } + + // Create hash + if (!CryptCreateHash(context, CALG_HMAC, key, 0, &hash)) { + assert(false); + return; + } + ZeroMemory(&info, sizeof(info)); + info.HashAlgid = CALG_SHA1; + } + + ~HMACHash() { + CryptDestroyHash(hash); + } + + virtual Hash& update(const ByteArray& data) override { + return updateInternal(data); + } + + virtual Hash& update(const SafeByteArray& data) override { + return updateInternal(data); + } + + virtual std::vector<unsigned char> getHash() { + std::vector<unsigned char> result; + DWORD hashLength = sizeof(DWORD); + DWORD hashSize; + CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0); + result.resize(static_cast<size_t>(hashSize)); + if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) { + assert(false); + } + result.resize(static_cast<size_t>(hashSize)); + return result; + } + + private: + template<typename ContainerType> + Hash& updateInternal(const ContainerType& data) { + if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) { + assert(false); + } + return *this; + } + + private: + HCRYPTHASH hash; + HMAC_INFO info; + }; #endif - // Simple implementation. - template<typename T> - ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data, CryptoProvider* crypto) { - static const int BLOCK_SIZE = 64; - - T paddedKey; - if (key.size() <= BLOCK_SIZE) { - paddedKey = key; - } - else { - assign(paddedKey, crypto->getSHA1Hash(key)); - } - paddedKey.resize(BLOCK_SIZE, 0x0); - - // Create the first value - T x(paddedKey); - for (unsigned int i = 0; i < x.size(); ++i) { - x[i] ^= 0x36; - } - append(x, data); - - // Create the second value - T y(paddedKey); - for (unsigned int i = 0; i < y.size(); ++i) { - y[i] ^= 0x5c; - } - append(y, crypto->getSHA1Hash(x)); - return crypto->getSHA1Hash(y); - } + // Simple implementation. + template<typename T> + ByteArray getHMACSHA1Internal(const T& key, const ByteArray& data, CryptoProvider* crypto) { + static const int BLOCK_SIZE = 64; + + T paddedKey; + if (key.size() <= BLOCK_SIZE) { + paddedKey = key; + } + else { + assign(paddedKey, crypto->getSHA1Hash(key)); + } + paddedKey.resize(BLOCK_SIZE, 0x0); + + // Create the first value + T x(paddedKey); + for (unsigned int i = 0; i < x.size(); ++i) { + x[i] ^= 0x36; + } + append(x, data); + + // Create the second value + T y(paddedKey); + for (unsigned int i = 0; i < y.size(); ++i) { + y[i] ^= 0x5c; + } + append(y, crypto->getSHA1Hash(x)); + return crypto->getSHA1Hash(y); + } } -WindowsCryptoProvider::WindowsCryptoProvider() { - p = boost::make_shared<Private>(); - if (!CryptAcquireContext(&p->context, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - assert(false); - } +WindowsCryptoProvider::WindowsCryptoProvider() : p(new Private()){ + if (!CryptAcquireContext(&p->context, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + assert(false); + } } WindowsCryptoProvider::~WindowsCryptoProvider() { - CryptReleaseContext(p->context, 0); + CryptReleaseContext(p->context, 0); } Hash* WindowsCryptoProvider::createSHA1() { - return new WindowsHash(p->context, CALG_SHA1); + return new WindowsHash(p->context, CALG_SHA1); } Hash* WindowsCryptoProvider::createMD5() { - return new WindowsHash(p->context, CALG_MD5); + return new WindowsHash(p->context, CALG_MD5); } bool WindowsCryptoProvider::isMD5AllowedForCrypto() const { - return !WindowsRegistry::isFIPSEnabled(); + return !WindowsRegistry::isFIPSEnabled(); } ByteArray WindowsCryptoProvider::getHMACSHA1(const SafeByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data, this); + return getHMACSHA1Internal(key, data, this); } ByteArray WindowsCryptoProvider::getHMACSHA1(const ByteArray& key, const ByteArray& data) { - return getHMACSHA1Internal(key, data, this); + return getHMACSHA1Internal(key, data, this); } diff --git a/Swiften/Crypto/WindowsCryptoProvider.h b/Swiften/Crypto/WindowsCryptoProvider.h index 9418fc0..d0c982e 100644 --- a/Swiften/Crypto/WindowsCryptoProvider.h +++ b/Swiften/Crypto/WindowsCryptoProvider.h @@ -1,30 +1,31 @@ /* - * Copyright (c) 2013 Remko Tronçon - * Licensed under the GNU General Public License. + * Copyright (c) 2013-2017 Isode Limited. + * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <Swiften/Crypto/CryptoProvider.h> -#include <Swiften/Base/Override.h> +#include <memory> + #include <boost/noncopyable.hpp> -#include <boost/shared_ptr.hpp> + +#include <Swiften/Crypto/CryptoProvider.h> namespace Swift { - class WindowsCryptoProvider : public CryptoProvider, public boost::noncopyable { - public: - WindowsCryptoProvider(); - ~WindowsCryptoProvider(); + class WindowsCryptoProvider : public CryptoProvider, public boost::noncopyable { + public: + WindowsCryptoProvider(); + virtual ~WindowsCryptoProvider(); - virtual Hash* createSHA1() SWIFTEN_OVERRIDE; - virtual Hash* createMD5() SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) SWIFTEN_OVERRIDE; - virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE; + virtual Hash* createSHA1() override; + virtual Hash* createMD5() override; + virtual ByteArray getHMACSHA1(const SafeByteArray& key, const ByteArray& data) override; + virtual ByteArray getHMACSHA1(const ByteArray& key, const ByteArray& data) override; + virtual bool isMD5AllowedForCrypto() const override; - private: - struct Private; - boost::shared_ptr<Private> p; - }; + private: + struct Private; + const std::unique_ptr<Private> p; + }; } |