148 #include "util/stacktrace.h"
150 #include <bigint/BigIntegerLibrary.hh>
157 #include <arpa/inet.h>
159 #include <sys/types.h>
160 #include <sys/resource.h>
164 #if defined(OT_CRYPTO_USING_OPENSSL)
167 #include <openssl/bio.h>
168 #include <openssl/buffer.h>
169 #include <openssl/evp.h>
170 #include <openssl/pem.h>
171 #include <openssl/rsa.h>
172 #include <openssl/dsa.h>
173 #include <openssl/err.h>
174 #include <openssl/ui.h>
175 #include <openssl/rand.h>
176 #include <openssl/crypto.h>
177 #include <openssl/asn1.h>
178 #include <openssl/objects.h>
179 #include <openssl/ssl.h>
180 #include <openssl/sha.h>
181 #include <openssl/conf.h>
182 #include <openssl/x509v3.h>
184 #ifndef OPENSSL_NO_ENGINE
185 #include <openssl/engine.h>
192 #elif defined(OT_CRYPTO_USING_GPG)
199 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
206 #if defined(OT_CRYPTO_USING_GPG)
210 #elif defined(OT_CRYPTO_USING_OPENSSL)
218 const EVP_PKEY* pkey,
223 const OTString& strContractToVerify,
const EVP_PKEY* pkey,
235 const EVP_PKEY* pkey,
const OTSignature& theSignature,
242 #else // Apparently NO crypto engine is defined!
246 #endif // if defined (OT_CRYPTO_USING_OPENSSL), elif defined
258 #define OT_DEFAULT_ITERATION_COUNT 65535 // in bytes
259 #define OT_DEFAULT_SYMMETRIC_SALT_SIZE 8 // in bytes
260 #define OT_DEFAULT_SYMMETRIC_KEY_SIZE 16 // in bytes
261 #define OT_DEFAULT_SYMMETRIC_KEY_SIZE_MAX 64 // in bytes == 512 bits
262 #define OT_DEFAULT_SYMMETRIC_IV_SIZE 16 // in bytes
263 #define OT_DEFAULT_SYMMETRIC_BUFFER_SIZE 4096 // in bytes
264 #define OT_DEFAULT_PUBLIC_KEYSIZE 128 // in bytes == 4096 bits
265 #define OT_DEFAULT_PUBLIC_KEYSIZE_MAX 512 // in bytes == 1024 bits
266 #define OT_DEFAULT_DIGEST_1_SIZE 32 // in bytes == 256 bits.
267 #define OT_DEFAULT_DIGEST_2_SIZE 64 // in bytes == 512 bits.
269 #define OT_KEY_ITERATION_COUNT "iteration_count"
270 #define OT_KEY_SYMMETRIC_SALT_SIZE "symmetric_salt_size"
271 #define OT_KEY_SYMMETRIC_KEY_SIZE "symmetric_key_size"
272 #define OT_KEY_SYMMETRIC_KEY_SIZE_MAX "symmetric_key_size_max"
273 #define OT_KEY_SYMMETRIC_IV_SIZE "symmetric_iv_size"
274 #define OT_KEY_SYMMETRIC_BUFFER_SIZE "symmetric_buffer_size"
275 #define OT_KEY_PUBLIC_KEYSIZE "public_keysize"
276 #define OT_KEY_PUBLIC_KEYSIZE_MAX "public_keysize_max"
277 #define OT_KEY_DIGEST_1_SIZE "digest_1_size"
278 #define OT_KEY_DIGEST_2_SIZE "digest_2_size"
280 const int32_t* OTCryptoConfig::sp_nIterationCount =
nullptr;
281 const int32_t* OTCryptoConfig::sp_nSymmetricSaltSize =
nullptr;
282 const int32_t* OTCryptoConfig::sp_nSymmetricKeySize =
nullptr;
283 const int32_t* OTCryptoConfig::sp_nSymmetricKeySizeMax =
nullptr;
284 const int32_t* OTCryptoConfig::sp_nSymmetricIvSize =
nullptr;
285 const int32_t* OTCryptoConfig::sp_nSymmetricBufferSize =
nullptr;
286 const int32_t* OTCryptoConfig::sp_nPublicKeysize =
nullptr;
287 const int32_t* OTCryptoConfig::sp_nPublicKeysizeMax =
nullptr;
288 const int32_t* OTCryptoConfig::sp_nDigest1Size =
nullptr;
289 const int32_t* OTCryptoConfig::sp_nDigest2Size =
nullptr;
291 bool OTCryptoConfig::GetSetAll()
297 if (!config.Load())
return false;
310 sp_nSymmetricKeySizeMax))
331 if (!config.Save())
return false;
338 bool OTCryptoConfig::GetSetValue(OTSettings& config, std::string strKeyName,
339 int32_t nDefaultValue,
340 const int32_t*& out_nValue)
343 if (strKeyName.empty())
return false;
344 if (3 > strKeyName.size())
return false;
349 config.CheckSet_long(
"crypto", strKeyName, nDefaultValue, nValue,
352 if (
nullptr != out_nValue) {
354 out_nValue =
nullptr;
358 new int32_t(bIsNew ? nDefaultValue : static_cast<int32_t>(nValue));
364 const int32_t& OTCryptoConfig::GetValue(
const int32_t*& pValue)
366 if (
nullptr == pValue) {
369 if (
nullptr == pValue) {
377 return GetValue(sp_nIterationCount);
381 return GetValue(sp_nSymmetricSaltSize);
385 return GetValue(sp_nSymmetricKeySize);
389 return GetValue(sp_nSymmetricKeySizeMax);
393 return GetValue(sp_nSymmetricIvSize);
397 return GetValue(sp_nSymmetricBufferSize);
401 return GetValue(sp_nPublicKeysize);
405 return GetValue(sp_nPublicKeysizeMax);
409 return GetValue(sp_nDigest1Size);
413 return GetValue(sp_nDigest2Size);
417 int32_t OTCrypto::s_nCount =
429 return str.find_first_not_of(
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHI"
430 "JKLMNOPQRSTUVWXYZ") == std::string::npos;
484 #ifndef _PASSWORD_LEN
485 #define _PASSWORD_LEN 128
489 const char* szPrompt)
const
495 std::cout << szPrompt;
498 std::string strPassword =
"";
502 const wchar_t enter[] = {L
'\x000D', L
'\x0000'};
503 const std::wstring wstrENTER = enter;
505 std::wstring wstrPass = L
"";
508 const wchar_t ch[] = {_getwch(), L
'\x0000'};
509 const std::wstring wstrCH = ch;
510 if (wstrENTER == wstrCH)
break;
511 wstrPass.append(wstrCH);
513 strPassword = OTString::ws2s(wstrPass);
517 const char enter[] = {
'\x0D',
'\x00'};
518 const std::string strENTER = enter;
520 std::string strPass =
"";
523 const char ch[] = {_getch(),
'\x00'};
524 const std::string strCH = ch;
525 if (strENTER == strCH)
break;
526 strPass.append(strCH);
528 strPassword = strPass;
533 static_cast<int32_t
>(strPassword.length() - 1));
536 std::cout << std::endl;
539 #elif defined(OT_CRYPTO_USING_OPENSSL)
549 if (UI_UTIL_read_pw(buf, buff,
_PASSWORD_LEN, szPrompt, 0) == 0) {
562 otErr <<
"__FUNCTION__: Open-Transactions is not compiled to collect "
563 <<
"the passphrase from the console!\n";
589 int32_t nAttempts = 0;
596 std::cout << std::endl;
601 std::cout <<
"Sorry." << std::endl;
608 "(Verifying) passphrase again: ")) {
609 std::cout <<
"Sorry." << std::endl;
613 if (!tempPassword.
Compare(theOutput)) {
614 if (++nAttempts >= 3)
break;
616 std::cout <<
"(Mismatch, try again.)\n" << std::endl;
619 std::cout << std::endl;
624 std::cout <<
"Sorry." << std::endl;
636 #ifdef OT_CRYPTO_USING_OPENSSL
641 return &s_theSingleton;
650 if (0 == OTCrypto::s_nCount) {
651 ++(OTCrypto::s_nCount);
653 otWarn <<
"OT_Init: Setting up rlimits, and crypto library...\n";
659 #if !defined(PREDEF_MODE_DEBUG) && defined(PREDEF_PLATFORM_UNIX)
661 getrlimit(RLIMIT_CORE, &rlim);
662 rlim.rlim_max = rlim.rlim_cur = 0;
663 if (setrlimit(RLIMIT_CORE, &rlim)) {
664 OT_FAIL_MSG(
"OTCrypto::Init: ASSERT: setrlimit failed. (Used for "
665 "preventing core dumps.)\n");
672 otErr <<
"OTCrypto::Init: ERROR: Somehow this erroneously got called "
673 "more than once! (Doing nothing.)\n";
682 if (1 == OTCrypto::s_nCount) {
683 --(OTCrypto::s_nCount);
692 otErr <<
"OTCrypto::Cleanup: ERROR: Somehow this erroneously got "
693 "called more than once! (Doing nothing.)\n";
699 otErr <<
"OTCrypto::Init_Override: ERROR: This function should NEVER be "
700 "called (you should be overriding it...)\n";
706 otErr <<
"OTCrypto::Cleanup_Override: ERROR: This function should NEVER be "
707 "called (you should be overriding it...)\n";
711 bool bLineBreaks)
const
714 const uint8_t* pDataIn =
static_cast<const uint8_t*
>(theInput.
GetPointer());
715 int32_t nLength =
static_cast<int32_t
>(theInput.
GetSize());
717 OT_ASSERT_MSG(nLength >= 0,
"ASSERT!!! nLength is an int32_t, matching the "
718 "openssl interface, and a size was just "
719 "attempted that wouldn't fit into an int32_t, "
720 "after static casting.\n");
723 char* pChar =
Base64Encode(pDataIn, nLength, bLineBreaks);
725 if (
nullptr == pChar) {
726 otErr << __FUNCTION__
727 <<
": Base64Encode returned nullptr. (Failure.)\n";
733 strOutput.
Set(pChar);
741 bool bLineBreaks)
const
744 const char* szInput = strInput.
Get();
748 uint8_t* pOutput =
Base64Decode(szInput, &theSize, bLineBreaks);
750 if (
nullptr == pOutput) {
751 otErr << __FUNCTION__
752 <<
": Base64Decode returned nullptr. (Failure.)\n";
758 const void* pVoid =
reinterpret_cast<void*
>(pOutput);
759 uint32_t lNewSize =
static_cast<uint32_t
>(theSize);
761 theOutput.
Assign(pVoid, lNewSize);
768 OTCrypto_Decrypt_Output::OTCrypto_Decrypt_Output()
769 : m_pPassword(nullptr)
770 , m_pPayload(nullptr)
780 m_pPassword =
nullptr;
781 m_pPayload =
nullptr;
792 OTCrypto_Decrypt_Output::OTCrypto_Decrypt_Output(
794 : m_pPassword(nullptr),
797 m_pPassword = rhs.m_pPassword;
798 m_pPayload = rhs.m_pPayload;
801 OTCrypto_Decrypt_Output::OTCrypto_Decrypt_Output(
OTPassword& thePassword)
802 : m_pPassword(&thePassword)
803 , m_pPayload(nullptr)
807 OTCrypto_Decrypt_Output::OTCrypto_Decrypt_Output(
OTPayload& thePayload)
808 : m_pPassword(nullptr)
809 , m_pPayload(&thePayload)
820 if (&other !=
this) {
821 std::swap(m_pPassword, other.m_pPassword);
822 std::swap(m_pPayload, other.m_pPayload);
839 OT_ASSERT((m_pPassword !=
nullptr) || (m_pPayload !=
nullptr));
850 if (
nullptr != m_pPassword) m_pPassword->
zeroMemory();
852 if (
nullptr != m_pPayload) m_pPayload->
Release();
856 uint32_t lAppendSize)
const
858 OT_ASSERT((m_pPassword !=
nullptr) || (m_pPayload !=
nullptr));
860 if (
nullptr != m_pPassword) {
861 if (static_cast<int32_t>(lAppendSize) ==
862 static_cast<int32_t>(m_pPassword->
addMemory(
863 pAppendData, static_cast<uint32_t>(lAppendSize))))
869 if (
nullptr != m_pPayload) {
876 #if defined(OT_CRYPTO_USING_OPENSSL)
880 #include <openssl/crypto.h>
881 #include <openssl/asn1.h>
882 #include <openssl/evp.h>
883 #include <openssl/objects.h>
884 #include <openssl/sha.h>
885 #include <openssl/pem.h>
886 #include <openssl/rsa.h>
887 #include <openssl/err.h>
888 #include <openssl/rand.h>
889 #include <openssl/ssl.h>
890 #include <openssl/conf.h>
893 #include <openssl/whrlpool.h>
924 #ifndef OPENSSL_THREAD_DEFINES
925 #define OPENSSL_THREAD_DEFINES
926 #include <openssl/opensslconf.h>
929 #include <openssl/opensslv.h>
1074 #if OPENSSL_VERSION_NUMBER - 0 < 0x10000000L
1102 #if OPENSSL_VERSION_NUMBER - 0 < 0x10000000L
1105 uint64_t ret = this_thread::get_raw_id();
1120 std::hash<std::thread::id>()(std::this_thread::get_id());
1125 CRYPTO_THREADID_set_numeric(
id, val);
1150 if (mode & CRYPTO_LOCK) {
1252 int32_t bLineBreaks)
1254 char* buf =
nullptr;
1255 BUF_MEM* bptr =
nullptr;
1258 "OT_base64_encode: Abort: in_len is a negative number!");
1262 if (!b64)
return buf;
1264 if (!bLineBreaks) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1273 if (BIO_write(b64join, input, in_len) == in_len) {
1274 (void)BIO_flush(b64join);
1275 BIO_get_mem_ptr(b64join, &bptr);
1278 buf =
new char[bptr->length + 1];
1280 memcpy(buf, bptr->data, bptr->length);
1281 buf[bptr->length] =
'\0';
1285 OT_FAIL_MSG(
"Failed creating new Bio in base64_encode.\n");
1292 int32_t bLineBreaks)
1298 static_cast<int32_t
>(strlen(input));
1299 int32_t out_max_len = (in_len * 6 + 7) / 8;
1300 uint8_t* buf =
new uint8_t[out_max_len];
1302 memset(buf, 0, out_max_len);
1307 if (!bLineBreaks) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1310 BIO_new_mem_buf((
char*)input, in_len);
1318 *out_len = BIO_read(b64join, buf, out_max_len);
1322 OT_FAIL_MSG(
"Failed creating new Bio in base64_decode.\n");
1331 bool bLineBreaks)
const
1338 bool bLineBreaks)
const
1362 const std::string strINPUT = strInput.
Get();
1367 BigInteger bigIntFromBase62 = stringToBigIntegerBase62(strINPUT);
1385 std::string strHEX_VERSION = bigIntegerToStringBase16(bigIntFromBase62);
1390 BIGNUM* pBigNum = BN_new();
1394 const int32_t nToHex = BN_hex2bn(&pBigNum, strHEX_VERSION.c_str());
1400 uint32_t nBigNumBytes = BN_num_bytes(pBigNum);
1401 theOutput.
SetSize(nBigNumBytes);
1403 const int32_t nConverted =
1404 BN_bn2bin(pBigNum, (uint8_t*)(theOutput.
GetPointer()));
1427 if (theInput.
IsEmpty())
return;
1431 BIGNUM* pBigNum = BN_new();
1439 char* szBigNumInHex = BN_bn2hex(pBigNum);
1445 BigInteger theBigInt = stringToBigIntegerBase16(szBigNumInHex);
1446 OPENSSL_free(szBigNumInHex);
1447 szBigNumInHex =
nullptr;
1452 std::string strBigInt = bigIntegerToStringBase62(theBigInt);
1454 strOutput.
Set(strBigInt.c_str());
1458 uint32_t nNewSize)
const
1471 const int32_t nRAND_bytes =
1472 RAND_bytes(reinterpret_cast<uint8_t*>(szDestination),
1473 static_cast<int32_t>(nNewSize));
1475 if ((-1) == nRAND_bytes) {
1478 <<
": ERROR: RAND_bytes is apparently not supported by the current "
1479 "RAND method. OpenSSL: "
1480 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
1483 else if (0 == nRAND_bytes) {
1484 otErr << __FUNCTION__
1485 <<
": Failed: The PRNG is apparently not seeded. OpenSSL error: "
1486 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
1516 uint32_t uIterations,
1526 uint32_t uIterations,
1533 <<
": Using a text passphrase, salt, and iteration count, "
1534 "to make a derived key...\n";
1545 PKCS5_PBKDF2_HMAC_SHA1(
1546 reinterpret_cast<const char*>
1550 static_cast<const int32_t>(
1555 static_cast<const int32_t>(dataSalt.
GetSize()),
1556 static_cast<const int32_t>(uIterations),
1557 static_cast<const int32_t
>(
1559 static_cast<uint8_t*>(
1564 bool bHaveCheckHash = !dataCheckHash.
IsEmpty();
1573 PKCS5_PBKDF2_HMAC_SHA1(
1574 reinterpret_cast<const char*>(pDerivedKey->
getMemory()),
1575 static_cast<const int32_t>(
1578 static_cast<const int32_t>(dataSalt.
GetSize()),
1579 static_cast<const int32_t>(uIterations),
1580 static_cast<const int32_t
>(tmpHashCheck.
GetSize()),
1581 const_cast<uint8_t*>(static_cast<const uint8_t*>(
1585 if (bHaveCheckHash) {
1586 OTString strDataCheck, strTestCheck;
1594 if (!strDataCheck.
Compare(strTestCheck)) {
1595 dataCheckHash.
reset();
1596 dataCheckHash = tmpHashCheck;
1603 dataCheckHash.
reset();
1604 dataCheckHash = tmpHashCheck;
1641 else if (theName.
Compare(
"SHA224"))
1642 return EVP_sha224();
1643 else if (theName.
Compare(
"SHA256"))
1644 return EVP_sha256();
1645 else if (theName.
Compare(
"SHA384"))
1646 return EVP_sha384();
1647 else if (theName.
Compare(
"SHA512"))
1648 return EVP_sha512();
1650 else if (theName.
Compare(
"WHIRLPOOL"))
1654 return EVP_whirlpool();
1672 const EVP_MD* md =
nullptr;
1674 uint32_t md_len = 0;
1675 uint8_t md_value[EVP_MAX_MD_SIZE];
1684 otErr <<
"OTCrypto_OpenSSL::CalculateDigest"
1685 <<
": Unknown message digest algorithm: " << strHashAlgorithm
1690 EVP_MD_CTX_init(&mdctx);
1691 EVP_DigestInit_ex(&mdctx, md,
nullptr);
1692 EVP_DigestUpdate(&mdctx, strInput.
Get(), strInput.
GetLength());
1693 EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
1694 EVP_MD_CTX_cleanup(&mdctx);
1696 theOutput.
Assign(md_value, md_len);
1714 const EVP_MD* md =
nullptr;
1716 uint32_t md_len = 0;
1717 uint8_t md_value[EVP_MAX_MD_SIZE];
1726 otErr <<
"OTCrypto_OpenSSL::CalculateDigest"
1727 <<
": Unknown message digest algorithm: " << strHashAlgorithm
1732 EVP_MD_CTX_init(&mdctx);
1733 EVP_DigestInit_ex(&mdctx, md,
nullptr);
1735 EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
1736 EVP_MD_CTX_cleanup(&mdctx);
1738 theOutput.
Assign(md_value, md_len);
1761 OT_ASSERT_MSG(
nullptr != pNewKey,
"pNewKey = new OTPassword");
1763 if (
nullptr != tmp_data) {
1786 #if OPENSSL_VERSION_NUMBER - 0 < 0x10000000L
1805 CRYPTO_set_locking_callback(
nullptr);
1816 const char* szFunc =
"OTCrypto_OpenSSL::Init_Override";
1818 otWarn << szFunc <<
": Setting up OpenSSL: SSL_library_init, error "
1819 "strings and algorithms, and OpenSSL config...\n";
1848 #if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER - 0 < 0x10000000L
1849 OT_FAIL_MSG(
"ASSERT: Must use OpenSSL version 1.0.0 or higher.\n");
1867 CRYPTO_malloc_init();
1936 SSL_load_error_strings();
1994 OpenSSL_add_all_algorithms();
2040 #if defined(USE_RAND_POLL)
2068 ERR_print_errors_fp(stderr);
2077 #if defined(OPENSSL_THREADS)
2080 otWarn << szFunc <<
": OpenSSL WAS compiled with thread support, FYI. "
2081 "Setting up mutexes...\n";
2088 otErr << __FUNCTION__
2089 <<
": WARNING: OpenSSL was NOT compiled with thread support. "
2090 <<
"(Also: Master Key will not expire.)\n";
2124 const char* szFunc =
"OTCrypto_OpenSSL::Cleanup_Override";
2126 otLog4 << szFunc <<
": Cleaning up OpenSSL...\n";
2134 #if defined(OPENSSL_THREADS)
2154 CONF_modules_free();
2161 CRYPTO_cleanup_all_ex_data();
2179 ERR_remove_thread_state(
nullptr);
2197 const char* szInput,
2198 const uint32_t lInputLength,
const OTPayload& theIV,
2203 const char* szFunc =
"OTCrypto_OpenSSL::Encrypt";
2207 theRawSymmetricKey.getMemorySize());
2216 int32_t len_out = 0;
2219 memset(&vBuffer_out.at(0), 0,
2226 theEncryptedOutput.Release();
2228 class _OTEnv_Enc_stat
2231 const char* m_szFunc;
2232 EVP_CIPHER_CTX& m_ctx;
2235 _OTEnv_Enc_stat(
const char* param_szFunc, EVP_CIPHER_CTX& param_ctx)
2236 : m_szFunc(param_szFunc)
2241 EVP_CIPHER_CTX_init(&m_ctx);
2247 if (0 == EVP_CIPHER_CTX_cleanup(&m_ctx))
2248 otErr << m_szFunc <<
": Failure in EVP_CIPHER_CTX_cleanup. (It "
2254 _OTEnv_Enc_stat theInstance(szFunc, ctx);
2256 const EVP_CIPHER* cipher_type = EVP_aes_128_cbc();
2258 if (!EVP_EncryptInit(
2260 const_cast<uint8_t*>(theRawSymmetricKey.getMemory_uint8()),
2261 static_cast<uint8_t*>(
2262 const_cast<void*>(theIV.GetPayloadPointer())))) {
2263 otErr << szFunc <<
": EVP_EncryptInit: failed.\n";
2270 uint32_t lRemainingLength = lInputLength;
2271 uint32_t lCurrentIndex = 0;
2273 while (lRemainingLength > 0) {
2281 uint32_t len =
static_cast<uint32_t
>(
2286 if (!EVP_EncryptUpdate(
2287 &ctx, &vBuffer_out.at(0), &len_out,
2288 const_cast<uint8_t*
>(
reinterpret_cast<const uint8_t*
>(
2289 &(szInput[lCurrentIndex]))),
2291 otErr << szFunc <<
": EVP_EncryptUpdate: failed.\n";
2294 lRemainingLength -= len;
2295 lCurrentIndex += len;
2298 theEncryptedOutput.Concatenate(
2299 reinterpret_cast<void*>(&vBuffer_out.at(0)),
2300 static_cast<uint32_t>(len_out));
2303 if (!EVP_EncryptFinal(&ctx, &vBuffer_out.at(0), &len_out)) {
2304 otErr << szFunc <<
": EVP_EncryptFinal: failed.\n";
2311 theEncryptedOutput.Concatenate(
2312 reinterpret_cast<void*>(&vBuffer_out.at(0)),
2313 static_cast<uint32_t>(len_out));
2320 const char* szInput,
2321 const uint32_t lInputLength,
const OTPayload& theIV,
2330 const char* szFunc =
"OTCrypto_OpenSSL::Decrypt";
2334 theRawSymmetricKey.getMemorySize());
2343 int32_t len_out = 0;
2346 memset(&vBuffer_out.at(0), 0,
2352 theDecryptedOutput.Release();
2354 class _OTEnv_Dec_stat
2357 const char* m_szFunc;
2358 EVP_CIPHER_CTX& m_ctx;
2361 _OTEnv_Dec_stat(
const char* param_szFunc, EVP_CIPHER_CTX& param_ctx)
2362 : m_szFunc(param_szFunc)
2367 EVP_CIPHER_CTX_init(&m_ctx);
2373 if (0 == EVP_CIPHER_CTX_cleanup(&m_ctx))
2374 otErr << m_szFunc <<
": Failure in EVP_CIPHER_CTX_cleanup. (It "
2379 _OTEnv_Dec_stat theInstance(szFunc, ctx);
2381 const EVP_CIPHER* cipher_type = EVP_aes_128_cbc();
2383 if (!EVP_DecryptInit(
2385 const_cast<uint8_t*>(theRawSymmetricKey.getMemory_uint8()),
2386 static_cast<uint8_t*>(
2387 const_cast<void*>(theIV.GetPayloadPointer())))) {
2388 otErr << szFunc <<
": EVP_DecryptInit: failed.\n";
2395 uint32_t lRemainingLength = lInputLength;
2396 uint32_t lCurrentIndex = 0;
2398 while (lRemainingLength > 0) {
2409 lRemainingLength -= len;
2411 if (!EVP_DecryptUpdate(
2412 &ctx, &vBuffer_out.at(0), &len_out,
2413 const_cast<uint8_t*
>(
reinterpret_cast<const uint8_t*
>(
2414 &(szInput[lCurrentIndex]))),
2416 otErr << szFunc <<
": EVP_DecryptUpdate: failed.\n";
2419 lCurrentIndex += len;
2423 theDecryptedOutput.Concatenate(
2424 reinterpret_cast<void*>(&vBuffer_out.at(0)),
2425 static_cast<uint32_t>(len_out))) {
2426 otErr << szFunc <<
": Failure: theDecryptedOutput isn't large "
2427 "enough for the decrypted output (1).\n";
2432 if (!EVP_DecryptFinal(&ctx, &vBuffer_out.at(0), &len_out)) {
2433 otErr << szFunc <<
": EVP_DecryptFinal: failed.\n";
2441 theDecryptedOutput.Concatenate(
2442 reinterpret_cast<void*>(&vBuffer_out.at(0)),
2443 static_cast<uint32_t>(len_out))) {
2444 otErr << szFunc <<
": Failure: theDecryptedOutput isn't large "
2445 "enough for the decrypted output (2).\n";
2458 "OTCrypto_OpenSSL::Seal: ASSERT: RecipPubKeys.size() > 0");
2460 const char* szFunc =
"OTCrypto_OpenSSL::Seal";
2464 uint8_t buffer[4096];
2465 uint8_t buffer_out[4096 + EVP_MAX_IV_LENGTH];
2466 uint8_t iv[EVP_MAX_IV_LENGTH];
2469 int32_t len_out = 0;
2471 memset(buffer, 0, 4096);
2472 memset(buffer_out, 0, 4096 + EVP_MAX_IV_LENGTH);
2473 memset(iv, 0, EVP_MAX_IV_LENGTH);
2482 EVP_PKEY** array_pubkey =
2484 uint8_t** ek =
nullptr;
2485 int32_t* eklen =
nullptr;
2487 bool bFinalized =
false;
2501 _OTEnv_Seal(
const _OTEnv_Seal&);
2502 _OTEnv_Seal& operator=(
const _OTEnv_Seal&);
2503 const char* m_szFunc;
2504 EVP_CIPHER_CTX& m_ctx;
2505 EVP_PKEY*** m_array_pubkey;
2512 int32_t m_nLastPopulatedIndex;
2518 _OTEnv_Seal(
const char* param_szFunc, EVP_CIPHER_CTX& theCTX,
2519 EVP_PKEY*** param_array_pubkey, uint8_t*** param_ek,
2520 int32_t** param_eklen,
2522 bool& param_Finalized)
2523 : m_szFunc(param_szFunc)
2525 , m_array_pubkey(
nullptr)
2528 , m_RecipPubKeys(param_RecipPubKeys)
2529 , m_nLastPopulatedIndex(-1)
2530 , m_bFinalized(param_Finalized)
2532 if (
nullptr == param_szFunc)
OT_FAIL;
2533 if (
nullptr == param_array_pubkey)
OT_FAIL;
2534 if (
nullptr == param_ek)
OT_FAIL;
2535 if (
nullptr == param_eklen)
OT_FAIL;
2543 m_array_pubkey = param_array_pubkey;
2545 m_eklen = param_eklen;
2554 EVP_CIPHER_CTX_init(&m_ctx);
2561 (EVP_PKEY**)malloc(m_RecipPubKeys.size() *
sizeof(EVP_PKEY*));
2563 memset(*m_array_pubkey, 0,
2564 m_RecipPubKeys.size() *
2571 *m_ek = (uint8_t**)malloc(m_RecipPubKeys.size() *
sizeof(uint8_t*));
2572 if (
nullptr == *m_ek)
OT_FAIL;
2573 memset(*m_ek, 0, m_RecipPubKeys.size() *
2580 *m_eklen =
static_cast<int32_t*
>(
2581 malloc(m_RecipPubKeys.size() *
sizeof(int32_t)));
2583 memset(*m_eklen, 0, m_RecipPubKeys.size() *
2595 int32_t nKeyIndex = -1;
2597 for (
auto& it : m_RecipPubKeys) {
2599 m_nLastPopulatedIndex = nKeyIndex;
2609 EVP_PKEY* public_key =
2610 const_cast<EVP_PKEY*
>(pPublicKey->
dp->GetKey());
2616 (*m_array_pubkey)[nKeyIndex] =
2628 (*m_ek)[nKeyIndex] = (uint8_t*)malloc(
2629 EVP_PKEY_size(public_key));
2631 OT_ASSERT(
nullptr != (*m_ek)[nKeyIndex]);
2632 memset((*m_ek)[nKeyIndex], 0, EVP_PKEY_size(public_key));
2654 int32_t nKeyIndex = -1;
2655 while (nKeyIndex < m_nLastPopulatedIndex)
2664 OT_ASSERT(
nullptr != (*m_ek)[nKeyIndex]);
2666 free((*m_ek)[nKeyIndex]);
2667 (*m_ek)[nKeyIndex] =
nullptr;
2685 free(*m_array_pubkey);
2686 *m_array_pubkey =
nullptr;
2687 m_array_pubkey =
nullptr;
2688 if (
nullptr != *m_ek) free(*m_ek);
2691 if (
nullptr != *m_eklen) free(*m_eklen);
2701 if (!m_bFinalized) {
2706 if (0 == EVP_CIPHER_CTX_cleanup(&m_ctx))
2707 otErr << m_szFunc <<
": Failure in EVP_CIPHER_CTX_cleanup. "
2708 "(It returned 0.)\n";
2716 _OTEnv_Seal local_RAII(szFunc, ctx, &array_pubkey, &ek, &eklen,
2717 RecipPubKeys, bFinalized);
2725 const EVP_CIPHER* cipher_type = EVP_aes_128_cbc();
2749 &ctx, cipher_type, ek,
2757 static_cast<int32_t>(RecipPubKeys.size())))
2761 otErr << szFunc <<
": EVP_SealInit: failed.\n";
2772 uint16_t temp_env_type = 1;
2773 uint16_t env_type_n =
static_cast<uint16_t
>(
2774 htons(static_cast<uint16_t>(temp_env_type)));
2778 dataOutput.
Concatenate(reinterpret_cast<void*>(&env_type_n),
2779 static_cast<uint32_t>(
sizeof(env_type_n)));
2783 uint32_t array_size_n =
static_cast<uint32_t
>(
2784 htonl(static_cast<uint32_t>(RecipPubKeys.size())));
2789 dataOutput.
Concatenate(reinterpret_cast<void*>(&array_size_n),
2790 static_cast<uint32_t>(
sizeof(array_size_n)));
2793 <<
": Envelope type: " <<
static_cast<int32_t
>(ntohs(env_type_n))
2794 <<
" Array size: " << static_cast<int64_t>(ntohl(array_size_n))
2808 for (
auto& it : RecipPubKeys) {
2811 std::string str_nym_id = it.first;
2830 const OTString strNymID(str_nym_id.c_str());
2832 uint32_t nymid_len =
static_cast<uint32_t
>(
2833 strNymID.GetLength() + 1);
2834 uint32_t nymid_len_n =
static_cast<uint32_t
>(
2840 dataOutput.
Concatenate(reinterpret_cast<void*>(&nymid_len_n),
2841 static_cast<uint32_t>(
sizeof(nymid_len_n)));
2844 reinterpret_cast<const void*>(strNymID.Get()),
2845 static_cast<uint32_t>(nymid_len));
2849 otLog5 << __FUNCTION__ <<
": INDEX: " <<
static_cast<int64_t
>(ii)
2850 <<
" NymID length: "
2851 << static_cast<int64_t>(ntohl(nymid_len_n))
2852 <<
" Nym ID: " << strNymID
2853 <<
" Strlen (should be a byte shorter): "
2854 << static_cast<int64_t>(strNymID.GetLength()) <<
"\n";
2869 uint32_t eklen_n =
static_cast<uint32_t
>(htonl(static_cast<uint32_t>(
2872 dataOutput.
Concatenate(reinterpret_cast<void*>(&eklen_n),
2873 static_cast<uint32_t>(
sizeof(eklen_n)));
2875 dataOutput.
Concatenate(reinterpret_cast<void*>(ek[ii]),
2876 static_cast<uint32_t>(eklen[ii]));
2879 <<
": EK length: " <<
static_cast<int64_t
>(ntohl(eklen_n))
2880 <<
" First byte: " << static_cast<int32_t>((ek[ii])[0])
2882 << static_cast<int32_t>((ek[ii])[eklen[ii] - 1]) <<
"\n";
2887 uint32_t ivlen =
static_cast<uint32_t
>(
2888 EVP_CIPHER_iv_length(cipher_type));
2893 uint32_t ivlen_n =
static_cast<uint32_t
>(htonl(static_cast<uint32_t>(
2896 dataOutput.
Concatenate(reinterpret_cast<void*>(&ivlen_n),
2897 static_cast<uint32_t>(
sizeof(ivlen_n)));
2899 dataOutput.
Concatenate(reinterpret_cast<void*>(iv),
2900 static_cast<uint32_t>(ivlen));
2903 <<
": iv_size: " <<
static_cast<int64_t
>(ntohl(ivlen_n))
2904 <<
" IV first byte: " << static_cast<int32_t>(iv[0])
2905 <<
" IV last byte: " <<
static_cast<int32_t
>(iv[ivlen - 1])
2914 OTData plaintext(static_cast<const void*>(theInput.
Get()),
2921 (len = plaintext.OTfread(reinterpret_cast<uint8_t*>(buffer),
2922 static_cast<uint32_t>(
sizeof(buffer))))) {
2923 if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer,
2924 static_cast<int32_t>(len))) {
2925 otErr << szFunc <<
": EVP_SealUpdate failed.\n";
2928 else if (len_out > 0)
2929 dataOutput.
Concatenate(reinterpret_cast<void*>(buffer_out),
2930 static_cast<uint32_t>(len_out));
2935 if (!EVP_SealFinal(&ctx, buffer_out, &len_out)) {
2936 otErr << szFunc <<
": EVP_SealFinal failed.\n";
2941 else if (len_out > 0) {
2943 dataOutput.
Concatenate(reinterpret_cast<void*>(buffer_out),
2944 static_cast<uint32_t>(len_out));
3011 const char* szFunc =
"OTCrypto_OpenSSL::Open";
3013 uint8_t buffer[4096];
3014 uint8_t buffer_out[4096 + EVP_MAX_IV_LENGTH];
3015 uint8_t iv[EVP_MAX_IV_LENGTH];
3018 int32_t len_out = 0;
3019 bool bFinalized =
false;
3023 memset(buffer, 0, 4096);
3024 memset(buffer_out, 0, 4096 + EVP_MAX_IV_LENGTH);
3025 memset(iv, 0, EVP_MAX_IV_LENGTH);
3045 EVP_PKEY* private_key =
3046 const_cast<EVP_PKEY*
>(pPrivateKey->
dp->GetKey(pPWData));
3048 if (
nullptr == private_key) {
3050 <<
": Null private key on recipient. (Returning false.)\n";
3055 <<
": Private key is available for NymID: " << strNymID <<
" \n";
3062 const char* m_szFunc;
3063 EVP_CIPHER_CTX& m_ctx;
3068 _OTEnv_Open(
const char* param_szFunc, EVP_CIPHER_CTX& theCTX,
3070 : m_szFunc(param_szFunc)
3072 , m_privateKey(param_privateKey)
3073 , m_bFinalized(param_Finalized)
3077 EVP_CIPHER_CTX_init(&m_ctx);
3082 m_privateKey.ReleaseKey();
3092 if (!m_bFinalized) {
3093 if (0 == EVP_CIPHER_CTX_cleanup(&m_ctx))
3094 otErr << m_szFunc <<
": Failure in EVP_CIPHER_CTX_cleanup. "
3095 "(It returned 0.)\n";
3104 _OTEnv_Open theNestedInstance(szFunc, ctx, *pPrivateKey, bFinalized);
3108 uint32_t nRunningTotal =
3111 uint32_t nReadEnvType = 0;
3112 uint32_t nReadArraySize = 0;
3113 uint32_t nReadIV = 0;
3140 uint16_t env_type_n = 0;
3142 if (0 == (nReadEnvType = dataInput.
OTfread(
3143 reinterpret_cast<uint8_t*>(&env_type_n),
3144 static_cast<uint32_t>(
sizeof(env_type_n))))) {
3145 otErr << szFunc <<
": Error reading Envelope Type. Expected "
3146 "asymmetric(1) or symmetric (2).\n";
3149 nRunningTotal += nReadEnvType;
3150 OT_ASSERT(nReadEnvType == static_cast<uint32_t>(
sizeof(env_type_n)));
3154 const uint16_t env_type =
3155 static_cast<uint16_t
>(ntohs(static_cast<uint16_t>(env_type_n)));
3159 if (1 != env_type) {
3160 otErr << szFunc <<
": Error : Expected Envelope for Asymmetric "
3161 "key(type 1) but instead found type "
3162 <<
static_cast<int32_t
>(env_type) <<
".\n";
3168 <<
": Envelope type: " <<
static_cast<int32_t
>(env_type) <<
"\n";
3172 uint32_t array_size_n = 0;
3174 if (0 == (nReadArraySize = dataInput.
OTfread(
3175 reinterpret_cast<uint8_t*>(&array_size_n),
3176 static_cast<uint32_t>(
sizeof(array_size_n))))) {
3178 <<
": Error reading Array Size for encrypted symmetric keys.\n";
3181 nRunningTotal += nReadArraySize;
3182 OT_ASSERT(nReadArraySize == static_cast<uint32_t>(
sizeof(array_size_n)));
3186 const uint32_t array_size = ntohl(array_size_n);
3189 <<
": Array size: " <<
static_cast<int64_t
>(array_size) <<
"\n";
3201 bool bFoundKeyAlready =
3210 for (uint32_t ii = 0; ii < array_size; ++ii) {
3218 uint32_t nymid_len_n = 0;
3219 uint32_t nReadNymIDSize = 0;
3221 if (0 == (nReadNymIDSize = dataInput.
OTfread(
3222 reinterpret_cast<uint8_t*>(&nymid_len_n),
3223 static_cast<uint32_t>(
sizeof(nymid_len_n))))) {
3224 otErr << szFunc <<
": Error reading NymID length for an encrypted "
3228 nRunningTotal += nReadNymIDSize;
3229 OT_ASSERT(nReadNymIDSize == static_cast<uint32_t>(
sizeof(nymid_len_n)));
3233 uint32_t nymid_len =
static_cast<uint32_t
>(ntohl(static_cast<uint32_t>(
3237 <<
": NymID length: " <<
static_cast<int64_t
>(nymid_len) <<
"\n";
3242 static_cast<uint8_t*
>(malloc(
sizeof(uint8_t) * nymid_len));
3246 uint32_t nReadNymID = 0;
3248 if (0 == (nReadNymID = dataInput.
OTfread(
3249 reinterpret_cast<uint8_t*>(nymid),
3250 static_cast<uint32_t>(
sizeof(uint8_t) *
3257 <<
": Error reading NymID for an encrypted symmetric key.\n";
3262 nRunningTotal += nReadNymID;
3264 static_cast<uint32_t>(
sizeof(uint8_t) * nymid_len));
3267 nymid[nymid_len - 1] =
'\0';
3270 const OTString loopStrNymID(reinterpret_cast<char*>(nymid));
3274 otLog5 << __FUNCTION__ <<
": (LOOP) Current NymID: " << loopStrNymID
3276 <<
static_cast<int64_t
>(loopStrNymID.
GetLength()) <<
"\n";
3289 uint8_t* ek =
nullptr;
3291 uint32_t eklen_n = 0;
3292 uint32_t nReadLength = 0;
3293 uint32_t nReadKey = 0;
3297 if (0 == (nReadLength = dataInput.
OTfread(
3298 reinterpret_cast<uint8_t*>(&eklen_n),
3299 static_cast<uint32_t>(
sizeof(eklen_n))))) {
3300 otErr << szFunc <<
": Error reading encrypted key size.\n";
3303 nRunningTotal += nReadLength;
3304 OT_ASSERT(nReadLength == static_cast<uint32_t>(
sizeof(eklen_n)));
3308 eklen =
static_cast<uint32_t
>(ntohl(static_cast<uint32_t>(eklen_n)));
3313 <<
": EK length: " <<
static_cast<int64_t
>(eklen) <<
" \n";
3317 ek =
static_cast<uint8_t*
>(
3318 malloc(static_cast<int32_t>(eklen) *
3321 memset(static_cast<void*>(ek), 0, static_cast<int32_t>(eklen));
3325 if (0 == (nReadKey = dataInput.
OTfread(reinterpret_cast<uint8_t*>(ek),
3326 static_cast<uint32_t>(eklen)))) {
3327 otErr << szFunc <<
": Error reading encrypted key.\n";
3332 nRunningTotal += nReadKey;
3335 <<
": EK First byte: " <<
static_cast<int32_t
>(ek[0])
3336 <<
" EK Last byte: " << static_cast<int32_t>(ek[eklen - 1])
3339 OT_ASSERT(nReadKey == static_cast<uint32_t>(eklen));
3349 if (!bFoundKeyAlready) {
3353 const bool bNymIDMatches =
3354 strNymID.Compare(loopStrNymID);
3356 if ((ii == (array_size - 1)) ||
3371 if (!(loopStrNymID.
Exists() &&
3375 bFoundKeyAlready =
true;
3377 theRawEncryptedKey.Assign(static_cast<void*>(ek),
3378 static_cast<uint32_t>(eklen));
3390 if (!bFoundKeyAlready)
3393 otOut << __FUNCTION__
3394 <<
": Sorry: Unable to find a session key for the Nym attempting "
3395 "to open this envelope: " << strNymID <<
"\n";
3403 const uint32_t max_iv_length =
3410 uint32_t iv_size_n = 0;
3411 uint32_t nReadIVSize = 0;
3413 if (0 == (nReadIVSize = dataInput.
OTfread(
3414 reinterpret_cast<uint8_t*>(&iv_size_n),
3415 static_cast<uint32_t>(
sizeof(iv_size_n))))) {
3417 <<
": Error reading IV Size for encrypted symmetric keys.\n";
3420 nRunningTotal += nReadIVSize;
3421 OT_ASSERT(nReadIVSize == static_cast<uint32_t>(
sizeof(iv_size_n)));
3425 const uint32_t iv_size_host_order = ntohl(static_cast<uint32_t>(iv_size_n));
3427 if (iv_size_host_order > max_iv_length) {
3428 const int64_t l1 = iv_size_host_order, l2 = max_iv_length;
3429 otErr << __FUNCTION__ <<
": Error: iv_size (" << l1
3430 <<
") is larger than max_iv_length (" << l2 <<
").\n";
3435 <<
": IV size: " <<
static_cast<int64_t
>(iv_size_host_order)
3440 if (0 == (nReadIV = dataInput.
OTfread(
3441 reinterpret_cast<uint8_t*>(iv),
3442 static_cast<uint32_t>(iv_size_host_order)))) {
3443 otErr << szFunc <<
": Error reading initialization vector.\n";
3447 nRunningTotal += nReadIV;
3448 OT_ASSERT(nReadIV == static_cast<uint32_t>(iv_size_host_order));
3451 <<
": IV First byte: " <<
static_cast<int32_t
>(iv[0])
3452 <<
" IV Last byte: "
3453 << static_cast<int32_t>(iv[iv_size_host_order - 1]) <<
"\n";
3468 OTData ciphertext(static_cast<const void*>(
3469 static_cast<const uint8_t*>(dataInput.
GetPointer()) +
3471 dataInput.
GetSize() - nRunningTotal);
3474 const EVP_CIPHER* cipher_type = EVP_aes_128_cbc();
3500 static_cast<const uint8_t*>(theRawEncryptedKey.GetPayloadPointer()),
3501 static_cast<int32_t>(theRawEncryptedKey.GetSize()),
3502 static_cast<const uint8_t*>(iv), private_key)) {
3510 otErr << szFunc <<
": EVP_OpenInit: failed.\n";
3521 (len = ciphertext.OTfread(reinterpret_cast<uint8_t*>(buffer),
3522 static_cast<uint32_t>(
sizeof(buffer))))) {
3523 if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer,
3524 static_cast<int32_t>(len))) {
3525 otErr << szFunc <<
": EVP_OpenUpdate: failed.\n";
3528 else if (len_out > 0)
3529 plaintext.
Concatenate(reinterpret_cast<void*>(buffer_out),
3530 static_cast<uint32_t>(len_out));
3535 if (!EVP_OpenFinal(&ctx, buffer_out, &len_out)) {
3536 otErr << szFunc <<
": EVP_OpenFinal: failed.\n";
3539 else if (len_out > 0) {
3541 plaintext.
Concatenate(reinterpret_cast<void*>(buffer_out),
3542 static_cast<uint32_t>(len_out));
3556 (
static_cast<uint8_t*
>(
const_cast<void*
>(plaintext.
GetPointer())))[nIndex] =
3568 const bool bSetMem = theOutput.
MemSet(
3572 otLog5 << __FUNCTION__ <<
": Output:\n" << theOutput <<
"\n\n";
3574 otErr << __FUNCTION__ <<
": Error: Failed while trying to memset from "
3575 "plaintext OTData to output OTString.\n";
3739 const OTString& strContractUnsigned,
const EVP_PKEY* pkey,
3742 const char* szFunc =
"OTCrypto_OpenSSL::SignContractDefaultHash";
3744 bool bReturnValue =
false;
3760 uint32_t uDigest1Len =
3763 uint32_t uDigest2Len =
3767 EVP_MD_CTX mdHash1_ctx, mdHash2_ctx;
3784 RSA* pRsaKey = EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pkey));
3787 otErr << szFunc <<
": EVP_PKEY_get1_RSA failed with error "
3788 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
3797 const EVP_MD* digest1 =
3801 if (
nullptr == digest1) {
3802 otErr << szFunc <<
": Failure to load message digest algorithm.\n";
3809 EVP_MD_CTX_init(&mdHash1_ctx);
3810 EVP_DigestInit(&mdHash1_ctx, digest1);
3811 EVP_DigestUpdate(&mdHash1_ctx, strContractUnsigned.
Get(),
3813 EVP_DigestFinal(&mdHash1_ctx, &vOutputHash1.at(0),
3815 EVP_MD_CTX_cleanup(&mdHash1_ctx);
3828 const EVP_MD* digest2 =
3832 if (
nullptr == digest2) {
3833 otErr << szFunc <<
": Failure to load message digest algorithm.\n";
3840 EVP_MD_CTX_init(&mdHash2_ctx);
3841 EVP_DigestInit(&mdHash2_ctx, digest2);
3842 EVP_DigestUpdate(&mdHash2_ctx, strContractUnsigned.
Get(),
3844 EVP_DigestFinal(&mdHash2_ctx, &vOutputHash2.at(0),
3846 EVP_MD_CTX_cleanup(&mdHash2_ctx);
3849 const uint32_t uDigestMergedLength =
3850 (uDigest1Len > uDigest2Len ? uDigest2Len : uDigest1Len);
3854 for (uint32_t i = 0; i < uDigestMergedLength; i++) {
3855 vDigest.at(i) = ((vOutputHash1.at(i)) ^ (vOutputHash2.at(i)));
3908 RSA_padding_add_PKCS1_PSS(pRsaKey, &vEM.at(0), &vDigest.at(0), digest1,
3933 otErr << __FILE__ <<
": RSA_padding_add_PKCS1_PSS failure: "
3934 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
3962 status = RSA_private_encrypt(
3971 otErr << szFunc <<
": RSA_private_encrypt failure: "
3972 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
3979 OTData binSignature(&vpSignature.at(0), status);
3989 theSignature.
SetData(binSignature,
true);
3992 bReturnValue =
true;
3994 if (pRsaKey) RSA_free(pRsaKey);
3997 return bReturnValue;
4009 const OTString& strContractToVerify,
const EVP_PKEY* pkey,
4012 const char* szFunc =
"OTCrypto_OpenSSL::VerifyContractDefaultHash";
4014 bool bReturnValue =
false;
4016 std::vector<uint8_t> vOutputHash1(
4019 std::vector<uint8_t> vOutputHash2(
4022 std::vector<uint8_t> vDigest(
4027 std::vector<uint8_t> vDecrypted(
4031 uint32_t uDigest1Len =
4034 uint32_t uDigest2Len =
4038 EVP_MD_CTX mdHash1_ctx, mdHash2_ctx;
4051 RSA* pRsaKey = EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pkey));
4054 otErr << szFunc <<
": EVP_PKEY_get1_RSA failed with error "
4055 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
4062 const EVP_MD* digest1 =
4065 if (
nullptr == digest1) {
4066 otErr << szFunc <<
": Failure to load message digest algorithm.\n";
4073 EVP_MD_CTX_init(&mdHash1_ctx);
4074 EVP_DigestInit(&mdHash1_ctx, digest1);
4075 EVP_DigestUpdate(&mdHash1_ctx, strContractToVerify.
Get(),
4077 EVP_DigestFinal(&mdHash1_ctx, &vOutputHash1.at(0),
4079 EVP_MD_CTX_cleanup(&mdHash1_ctx);
4082 const EVP_MD* digest2 =
4085 if (
nullptr == digest2) {
4086 otErr << szFunc <<
": Failure to load message digest algorithm.\n";
4093 EVP_MD_CTX_init(&mdHash2_ctx);
4094 EVP_DigestInit(&mdHash2_ctx, digest2);
4095 EVP_DigestUpdate(&mdHash2_ctx, strContractToVerify.
Get(),
4097 EVP_DigestFinal(&mdHash2_ctx, &vOutputHash2.at(0),
4099 EVP_MD_CTX_cleanup(&mdHash2_ctx);
4102 const uint32_t uDigestMergedLength =
4103 (uDigest1Len > uDigest2Len ? uDigest2Len : uDigest1Len);
4106 for (uint32_t i = 0; i < uDigestMergedLength; i++) {
4107 vDigest.at(i) = ((vOutputHash1.at(i)) ^ (vOutputHash2.at(i)));
4131 (
false == theSignature.
GetData(binSignature))) {
4132 otErr << szFunc <<
": Error decoding base64 data for Signature.\n";
4138 const int32_t nSignatureSize =
static_cast<int32_t
>(
4142 if ((binSignature.
GetSize() <
static_cast<uint32_t
>(RSA_size(pRsaKey))) ||
4143 (nSignatureSize < RSA_size(pRsaKey)))
4145 otErr << szFunc <<
": Decoded base64-encoded data for signature, but "
4146 "resulting size was < RSA_size(pRsaKey): "
4147 "Signed: " << nSignatureSize
4148 <<
". Unsigned: " << binSignature.
GetSize() <<
".\n";
4169 int32_t status = RSA_public_decrypt(
4171 static_cast<const uint8_t*>(
4198 otErr << szFunc <<
": RSA_public_decrypt failed with error "
4199 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
4216 status = RSA_verify_PKCS1_PSS(pRsaKey, &vDigest.at(0), digest1,
4221 otLog5 <<
" *Signature verified*\n";
4222 bReturnValue =
true;
4225 otLog5 << szFunc <<
": RSA_verify_PKCS1_PSS failed with error: "
4226 << ERR_error_string(ERR_get_error(),
nullptr) <<
"\n";
4632 if (pRsaKey) RSA_free(pRsaKey);
4635 return bReturnValue;
4641 const OTString& strContractUnsigned,
const EVP_PKEY* pkey,
4646 "Null private key sent to OTCrypto_OpenSSL::SignContract.\n");
4648 const char* szFunc =
"OTCrypto_OpenSSL::SignContract";
4650 class _OTCont_SignCont1
4653 const char* m_szFunc;
4657 _OTCont_SignCont1(
const char* param_szFunc, EVP_MD_CTX& param_ctx)
4658 : m_szFunc(param_szFunc)
4663 EVP_MD_CTX_init(&m_ctx);
4665 ~_OTCont_SignCont1()
4667 if (0 == EVP_MD_CTX_cleanup(&m_ctx))
4668 otErr << m_szFunc <<
": Failure in cleanup. (It returned 0.)\n";
4680 const bool bUsesDefaultHashAlgorithm =
4682 EVP_MD* md =
nullptr;
4685 if (bUsesDefaultHashAlgorithm) {
4699 return SignContractDefaultHash(strContractUnsigned, pkey, theSignature,
4714 if (
nullptr == md) {
4716 <<
": Unable to decipher Hash algorithm: " << strHashType <<
"\n";
4728 _OTCont_SignCont1 theInstance(szFunc, md_ctx);
4734 EVP_SignInit_ex(&md_ctx, md,
nullptr);
4743 EVP_SignUpdate(&md_ctx, strContractUnsigned.
Get(),
4747 uint8_t sig_buf[4096];
4749 int32_t sig_len =
sizeof(sig_buf);
4750 int32_t err = EVP_SignFinal(&md_ctx, sig_buf, (uint32_t*)&sig_len,
4754 otErr << szFunc <<
": Error signing xml contents.\n";
4758 otLog3 << szFunc <<
": Successfully signed xml contents.\n";
4763 tempData.
Assign(sig_buf, sig_len);
4764 theSignature.
SetData(tempData);
4782 const EVP_PKEY* pkey = pTempOpenSSLKey->
dp->GetKey(pPWData);
4786 dp->
SignContract(strContractUnsigned, pkey, theSignature, strHashType,
4788 otErr <<
"OTCrypto_OpenSSL::SignContract: "
4789 <<
"SignContract returned false.\n";
4807 const EVP_PKEY* pkey = pTempOpenSSLKey->
dp->GetKey(pPWData);
4812 strHashType, pPWData)) {
4813 otLog3 <<
"OTCrypto_OpenSSL::VerifySignature: "
4814 <<
"VerifySignature returned false.\n";
4824 const OTString& strContractToVerify,
const EVP_PKEY* pkey,
4829 "OTCrypto_OpenSSL::VerifySignature: ASSERT FAILURE: "
4830 "strContractToVerify.Exists()");
4832 "Null pkey in OTCrypto_OpenSSL::VerifySignature.\n");
4834 const char* szFunc =
"OTCrypto_OpenSSL::VerifySignature";
4838 const bool bUsesDefaultHashAlgorithm =
4840 EVP_MD* md =
nullptr;
4842 if (bUsesDefaultHashAlgorithm) {
4856 return VerifyContractDefaultHash(strContractToVerify, pkey,
4857 theSignature, pPWData);
4869 <<
": Unknown message digest algorithm: " << strHashType <<
"\n";
4877 if (!theSignature.
GetData(binSignature)) {
4878 otErr << szFunc <<
": Error decoding base64 data for Signature.\n";
4883 EVP_MD_CTX_init(&ctx);
4885 EVP_VerifyInit(&ctx, md);
4899 EVP_VerifyUpdate(&ctx, strContractToVerify.
Get(),
4907 int32_t nErr = EVP_VerifyFinal(
4909 (uint32_t)binSignature.
GetSize(), (EVP_PKEY*)pkey);
4911 EVP_MD_CTX_cleanup(&ctx);
4924 const std::string& strCertFileContents,
4929 "SignContract: ASSERT FAILURE: "
4930 "strContractUnsigned.Exists()");
4932 strCertFileContents.size() > 2,
4933 "Empty strCertFileContents passed to OTCrypto_OpenSSL::SignContract");
4938 BIO_new_mem_buf((
void*)strCertFileContents.c_str(), -1);
4952 OTPasswordData thePWData(
"(OTCrypto_OpenSSL::SignContract is trying to "
4953 "read the private key...)");
4955 if (
nullptr == pPWData) pPWData = &thePWData;
4957 bool bSigned =
false;
4958 EVP_PKEY* pkey = PEM_read_bio_PrivateKey(
4960 const_cast<OTPasswordData*>(pPWData));
4962 if (
nullptr == pkey) {
4963 otErr <<
"OTCrypto_OpenSSL::SignContract: "
4964 <<
"Error reading private key from BIO.\n";
4967 bSigned =
dp->
SignContract(strContractUnsigned, pkey, theSignature,
4968 strSigHashType, pPWData);
4970 EVP_PKEY_free(pkey);
4983 const std::string& strCertFileContents,
4988 "OTCrypto_OpenSSL::VerifySignature: ASSERT FAILURE: "
4989 "strContractToVerify.Exists()");
4991 "Empty strCertFileContents passed to "
4992 "OTCrypto_OpenSSL::VerifySignature");
4994 const char* szFunc =
"OTCrypto_OpenSSL::VerifySignature";
4999 BIO_new_mem_buf((
void*)strCertFileContents.c_str(), -1);
5002 OTPasswordData thePWData(
"(OTCrypto_OpenSSL::VerifySignature is trying to "
5003 "read the public key...)");
5005 if (
nullptr == pPWData) pPWData = &thePWData;
5009 const_cast<OTPasswordData*>(pPWData));
5011 if (
nullptr == x509) {
5012 otErr << szFunc <<
": Failed reading x509 out of cert file...\n";
5016 bool bVerifySig =
false;
5017 EVP_PKEY* pkey = X509_get_pubkey(x509);
5019 if (
nullptr == pkey) {
5021 <<
": Failed reading public key from x509 from certfile...\n";
5025 theSignature, strSigHashType, pPWData);
5027 EVP_PKEY_free(pkey);
5042 BIO* OpenSSL_BIO::assertBioNotNull(BIO* pBIO)
5049 : m_refBIO(*assertBioNotNull(pBIO))
5059 BIO_free(&m_refBIO);
5062 BIO_free_all(&m_refBIO);
5067 OpenSSL_BIO::operator BIO*()
const
5082 #elif defined(OT_CRYPTO_USING_GPG)
5086 #else // Apparently NO crypto engine is defined!
5090 #endif // if defined (OT_CRYPTO_USING_OPENSSL), elif defined
EXPORT const uint8_t * getMemory_uint8() const
static EXPORT OTCrypto * It()
virtual void Cleanup_Override() const
OTLOG_IMPORT OTLogStream otLog4
virtual bool CalculateDigest(const OTString &strInput, const OTString &strHashAlgorithm, OTIdentifier &theOutput) const
static EXPORT uint32_t SymmetricIvSize()
char * ot_openssl_base64_encode(const uint8_t *input, int32_t in_len, int32_t bLineBreaks)
#define OT_DEFAULT_DIGEST_1_SIZE
#define OT_KEY_SYMMETRIC_IV_SIZE
EXPORT uint32_t getMemorySize() const
#define OT_KEY_DIGEST_2_SIZE
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
static EXPORT uint32_t IterationCount()
#define OT_DEFAULT_SYMMETRIC_KEY_SIZE_MAX
#define OT_DEFAULT_SYMMETRIC_BUFFER_SIZE
EXPORT bool GetPasswordFromConsole(OTPassword &theOutput, bool bRepeat=false) const
virtual void SetIDFromBase62String(const OTString &strInput, OTIdentifier &theOutput) const
virtual bool Decrypt(const OTPassword &theRawSymmetricKey, const char *szInput, uint32_t lInputLength, const OTPayload &theIV, OTCrypto_Decrypt_Output theDecryptedOutput) const
virtual bool SignContract(const OTString &strContractUnsigned, const OTAsymmetricKey &theKey, OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr)
static EXPORT const OTString HashAlgorithm2
#define OT_KEY_SYMMETRIC_SALT_SIZE
#define OT_KEY_SYMMETRIC_KEY_SIZE_MAX
virtual void Init_Override() const
virtual OTPassword * DeriveNewKey(const OTPassword &userPassword, const OTPayload &dataSalt, uint32_t uIterations, OTPayload &dataCheckHash) const
#define OT_DEFAULT_PUBLIC_KEYSIZE_MAX
EXPORT bool Concatenate(const void *pAppendData, uint32_t lAppendSize) const
EXPORT int32_t addMemory(const void *append, uint32_t size)
OTLOG_IMPORT OTLogStream otOut
virtual OTPassword * InstantiateBinarySecret() const
EXPORT bool isPassword() const
#define OT_DEFAULT_SYMMETRIC_SALT_SIZE
OTLOG_IMPORT OTLogStream otLog3
virtual bool RandomizeMemory(uint8_t *szDestination, uint32_t nNewSize) const
EXPORT const void * getMemory() const
EXPORT uint32_t GetLength() const
#define OT_DEFAULT_SYMMETRIC_KEY_SIZE
EXPORT int32_t setPassword(const char *input, int32_t size)
bool SignContractDefaultHash(const OTString &strContractUnsigned, const EVP_PKEY *pkey, OTSignature &theSignature, const OTPasswordData *pPWData=nullptr) const
static EXPORT uint32_t SymmetricSaltSize()
void thread_setup() const
static EXPORT uint32_t SymmetricKeySizeMax()
#define OT_DEFAULT_DIGEST_2_SIZE
EXPORT bool GetPasswordFromConsoleLowLevel(OTPassword &theOutput, const char *szPrompt) const
EXPORT bool Exists() const
static EXPORT uint32_t Digest1Size()
EXPORT bool CalculateDigestInternal(const OTString &strInput, const OTString &strHashAlgorithm)
virtual ~OTCrypto_OpenSSL()
virtual uint8_t * Base64Decode(const char *input, size_t *out_len, bool bLineBreaks) const
#define OT_DEFAULT_PUBLIC_KEYSIZE
EXPORT bool Compare(const char *compare) const
virtual bool Encrypt(const OTPassword &theRawSymmetricKey, const char *szInput, uint32_t lInputLength, const OTPayload &theIV, OTPayload &theEncryptedOutput) const
virtual void Cleanup_Override() const
static size_t safe_strlen(const char *s, size_t max)
static std::mutex * s_arrayMutex
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
static EXPORT uint32_t SymmetricBufferSize()
EXPORT void Assign(const OTData &source)
bool IsBase62(const std::string &str) const
#define OT_KEY_PUBLIC_KEYSIZE
#define OT_DEFAULT_SYMMETRIC_IV_SIZE
#define OT_DEFAULT_ITERATION_COUNT
const OTAsymmetricKey & GetPrivateEncrKey() const
virtual bool Base64Encode(const OTData &theInput, OTString &strOutput, bool bLineBreaks=true) const
static EXPORT const OTString DefaultHashAlgorithm
EXPORT ~OTCrypto_Decrypt_Output()
bool VerifySignature(const OTString &strContractToVerify, const EVP_PKEY *pkey, const OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr) const
#define OT_ASSERT_MSG(x, s)
void SetSize(uint32_t size)
EXPORT void SetPayloadSize(uint32_t lNewSize)
OTLOG_IMPORT OTLogStream otInfo
#define OT_KEY_ITERATION_COUNT
EXPORT uint32_t getPasswordSize() const
EXPORT bool GetData(OTData &theData, bool bLineBreaks=true) const
EXPORT void swap(OTCrypto_Decrypt_Output &other)
EXPORT void setFreeOnly()
std::multimap< std::string, OTAsymmetricKey * > mapOfAsymmetricKeys
virtual bool Seal(mapOfAsymmetricKeys &RecipPubKeys, const OTString &theInput, OTData &dataOutput) const
#define OT_KEY_DIGEST_1_SIZE
static EXPORT uint32_t PublicKeysizeMax()
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
uint8_t * ot_openssl_base64_decode(const char *input, size_t *out_len, int32_t bLineBreaks)
EXPORT const void * GetPayloadPointer() const
OTLOG_IMPORT OTLogStream otErr
bool VerifyContractDefaultHash(const OTString &strContractToVerify, const EVP_PKEY *pkey, const OTSignature &theSignature, const OTPasswordData *pPWData=nullptr) const
EXPORT OTCrypto_Decrypt_Output & operator=(OTCrypto_Decrypt_Output other)
#define OT_KEY_SYMMETRIC_BUFFER_SIZE
void thread_cleanup() const
const void * GetPointer() const
EXPORT const uint8_t * getPassword_uint8() const
static EXPORT uint32_t Digest2Size()
OTAsymmetricKey_OpenSSLPrivdp * dp
EXPORT void Release_Envelope_Decrypt_Output() const
static EXPORT uint32_t PublicKeysize()
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
EXPORT void * getMemoryWritable()
EXPORT int32_t setPassword_uint8(const uint8_t *input, uint32_t size)
EXPORT void Cleanup() const
#define OT_KEY_SYMMETRIC_KEY_SIZE
#define OT_KEY_PUBLIC_KEYSIZE_MAX
virtual bool Base64Decode(const OTString &strInput, OTData &theOutput, bool bLineBreaks=true) const
virtual void SetBase62StringFromID(const OTIdentifier &theInput, OTString &strOutput) const
static const EVP_MD * GetOpenSSLDigestByName(const OTString &theName)
EXPORT uint32_t OTfread(uint8_t *data, uint32_t size)
EXPORT bool SetData(const OTData &theData, bool bLineBreaks=true)
virtual void Init_Override() const
EXPORT bool IsEmpty() const
bool SignContract(const OTString &strContractUnsigned, const EVP_PKEY *pkey, OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr) const
virtual char * Base64Encode(const uint8_t *input, int32_t in_len, bool bLineBreaks) const
virtual bool VerifySignature(const OTString &strContractToVerify, const OTAsymmetricKey &theKey, const OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr) const
virtual bool Open(OTData &dataInput, const OTPseudonym &theRecipient, OTString &theOutput, const OTPasswordData *pPWData=nullptr) const
EXPORT bool Compare(OTPassword &rhs) const
virtual EXPORT void Release()
void ot_openssl_locking_callback(int32_t mode, int32_t type, char *file, int32_t line)
EXPORT bool MemSet(const char *mem, uint32_t size)
unsigned int64_t ot_openssl_thread_id(void)
virtual OTPassword * DeriveKey(const OTPassword &userPassword, const OTPayload &dataSalt, uint32_t uIterations, const OTPayload &dataCheckHash=OTPayload()) const
EXPORT void Concatenate(const void *data, uint32_t size)
static EXPORT uint32_t SymmetricKeySize()
virtual EXPORT void Release()
EXPORT OpenSSL_BIO(BIO *pBIO)
static EXPORT const OTString HashAlgorithm1
static EXPORT const OTString & GlobalConfigFile()
OTLOG_IMPORT OTLogStream otLog5