You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- added new (experimental) Crypto::CCryptoManager() (#255)
- supports session based data encryption/decryption
- support secure memory handling
- corrections related to new (experimental) Crypto::CSecureString() class (#255)
- rewrote the implementation to use Crypto::CCryptoManager's session data encryption feature (which makes the CSecureString() class compatible with Linux and OSX)
- changed AddChar() to return the number of written characters (useful for UTF-8-mode)
- added missing integer overflow check
- fixed off-by-one checks (incl. off-by-one checks in AddChar() in UTF-8 mode)
- several compile error/warning fixes
- added documentation
- whitespaces
- updated changelog entries (mainly for 0.1.3) (facebookarchive#130, #220, #223, #249, #225, #226, #227, #228, #236, #238, #242, #258, #259, #261, #262, #263, #264, #265, #269)
* Copyright (c) 2019, SLikeSoft UG (haftungsbeschränkt)
3
+
*
4
+
* This source code is licensed under the MIT-style license found in the license.txt
5
+
* file in the root directory of this source tree.
6
+
*/
7
+
#include"slikenet/crypto/cryptomanager.h"
8
+
9
+
#include"slikenet/assert.h"// used for RakAssert
10
+
#include<limits>// used for std::numeric_limits<>
11
+
12
+
// prevent max/min macros getting defined (breaking numeric_limits<>::max() / ::min() usage) through the indirect windows.h include in the OpenSSL includes
13
+
#ifdef _WIN32
14
+
#defineNOMINMAX
15
+
#endif
16
+
17
+
#include<openssl/err.h>// used for ERR_xxxx
18
+
#include<openssl/evp.h>// used for EVP_xxxx, OpenSSL_add_all_algorithms()
19
+
#include<openssl/rand.h>// used for RAND_xxxx
20
+
21
+
namespaceSLNet
22
+
{
23
+
namespaceExperimental
24
+
{
25
+
namespaceCrypto
26
+
{
27
+
boolCCryptoManager::Initialize()
28
+
{
29
+
if (m_Initialized) {
30
+
returntrue; // already initialized
31
+
}
32
+
33
+
ERR_load_crypto_strings();
34
+
OpenSSL_add_all_algorithms();
35
+
36
+
// #high - replace with EGADS
37
+
RAND_screen();
38
+
39
+
if (RAND_bytes(m_sessionKey, EVP_MAX_KEY_LENGTH) == 0) {
40
+
returnfalse; // failed to initialize the random session key
41
+
}
42
+
if (RAND_pseudo_bytes(m_initializationVector, EVP_MAX_IV_LENGTH) == 0) {
43
+
returnfalse; // failed to initialize the initialization vector
returnfalse; // CryptoManager failed to initialize
90
+
}
91
+
92
+
// #med - extend support for inOutBufferSize > int::max()
93
+
if (inOutBufferSize > static_cast<size_t>(std::numeric_limits<int>::max())) {
94
+
// note: We check the inOutBufferSize here rather than the dataLength due to the indirect size limitation due to the EVP_DecryptUpdate()/EVP_DecryptFinal_ex() calls
95
+
// being limited to int::max() through their returned written bytes values. Due to the next check (inOutBufferSize < dataLength) it's implicitly ensured that
96
+
// dataLength doesn't exceed the limit either.
97
+
returnfalse; // specified length exceeds max supported size
98
+
}
99
+
100
+
if (inOutBufferSize < dataLength) {
101
+
// prevent potential buffer overflow, even though it's possible that the encryptedtext is padded and hence the effectively required
102
+
// inOutBufferSize is less than the provided dataLength, since we cannot determine this before running the actual decryption - so consider
103
+
// this an invalid call, if the provided inOutBufferSize is smaller than the incoming encrypted text's length
104
+
returnfalse;
105
+
}
106
+
107
+
// #high - review usage of the CBC mode here --- not the best nowadays
108
+
// #med - add engine support to use HW-acceleration
109
+
if (EVP_DecryptInit_ex(&m_decryptionContext, EVP_aes_256_cbc(), nullptr, m_sessionKey, m_initializationVector) == 0) {
110
+
returnfalse; // failed to initialize the decryption context
111
+
}
112
+
113
+
int bytesWritten1;
114
+
// static cast safe due to size-check above
115
+
if (EVP_DecryptUpdate(&m_decryptionContext, outBuffer, &bytesWritten1, encryptedtext, static_cast<int>(dataLength)) == 0) {
// EVP_EncryptUpdate() can write up to dataLength + blockSize - 1. The final EVP_EncryptFinal_ex() call can write up to blockSize. (reference: OpenSSL 1.0.2 documentation)
135
+
// Hence, by definition the required encryption buffer size is dataLength + blockSize*2 -1.
136
+
// Note: Practically the limit should actually never exceed dataLength + blockSize due to the encryption we use (AES 256 / CBC). However, we want to be safe
137
+
// on the design level to prevent possible incompatibilities with future OpenSSL changes.
0 commit comments