148 #if defined(OT_CRYPTO_USING_OPENSSL)
150 #include <openssl/opensslconf.h>
154 #define OT_DEFAULT_PASSWORD "test"
159 std::mutex OTCachedKey::s_mutexThreadTimeout;
160 std::mutex OTCachedKey::s_mutexCachedKeys;
165 std::lock_guard<std::mutex> lock(m_Mutex);
167 bool bReturnVal =
false;
169 if (
nullptr != m_pSymmetricKey) {
178 std::lock_guard<std::mutex> lock(m_Mutex);
180 bool bReturnVal =
false;
182 if (
nullptr != m_pSymmetricKey) {
201 static std::shared_ptr<OTCachedKey> s_theSingleton(
new OTCachedKey);
203 if (
nullptr == pIdentifier)
204 return s_theSingleton;
212 std::lock_guard<std::mutex> lock(OTCachedKey::s_mutexCachedKeys);
214 const OTString strIdentifier(*pIdentifier);
215 const std::string str_identifier(strIdentifier.
Get());
217 auto it_keys = s_mapCachedKeys.find(str_identifier);
219 if (s_mapCachedKeys.end() != it_keys)
221 std::shared_ptr<OTCachedKey> pShared(it_keys->second);
227 s_mapCachedKeys.erase(it_keys);
239 return std::shared_ptr<OTCachedKey>();
272 if (!(const_cast<OTCachedKey&>(theSourceKey))
275 otErr <<
"OTCachedKey::" << __FUNCTION__
276 <<
": theSourceKey.IsGenerated() returned false. "
277 "(Returning nullptr.)\n";
278 return std::shared_ptr<OTCachedKey>();
281 std::lock_guard<std::mutex> lock_keys(OTCachedKey::s_mutexCachedKeys);
285 const OTString strIdentifier(theSourceID);
286 const std::string str_identifier(strIdentifier.
Get());
290 auto it_keys = s_mapCachedKeys.find(str_identifier);
292 if (s_mapCachedKeys.end() != it_keys)
294 std::shared_ptr<OTCachedKey> pMaster(it_keys->second);
299 s_mapCachedKeys.erase(it_keys);
311 if ((const_cast<OTCachedKey&>(theSourceKey)).
SerializeTo(
314 std::shared_ptr<OTCachedKey> pMaster(
317 pMaster->SetCachedKey(ascCachedKey);
319 s_mapCachedKeys.insert(
320 std::pair<std::string, std::shared_ptr<OTCachedKey>>(
321 str_identifier, pMaster));
326 otErr << __FUNCTION__
327 <<
": theSourceKey.SerializeTo(ascCachedKey) failed. "
328 "Returning nullptr.\n";
330 return std::shared_ptr<OTCachedKey>();
336 std::lock_guard<std::mutex> lock(OTCachedKey::s_mutexCachedKeys);
338 s_mapCachedKeys.clear();
349 OTCachedKey::OTCachedKey(int32_t nTimeoutSeconds)
351 , m_nTimeoutSeconds(nTimeoutSeconds)
352 , m_pMasterPassword(nullptr)
355 m_bUse_System_Keyring(false)
357 m_pSymmetricKey(nullptr)
366 , m_nTimeoutSeconds(
OTCachedKey::It()->GetTimeoutSeconds())
367 , m_pMasterPassword(nullptr)
370 m_bUse_System_Keyring(
OTCachedKey::It()->IsUsingSystemKeyring())
374 m_pSymmetricKey(nullptr)
404 std::lock_guard<std::mutex> lock(m_Mutex);
415 std::lock_guard<std::mutex> lock(m_Mutex);
434 if (
nullptr != m_pThread) {
435 std::unique_ptr<std::thread> pThread(m_pThread);
438 if (pThread->joinable()) {
446 std::lock_guard<std::mutex> lock(
452 if (
nullptr != m_pMasterPassword)
457 m_pMasterPassword =
nullptr;
469 m_pSymmetricKey =
nullptr;
471 delete pSymmetricKey;
472 pSymmetricKey =
nullptr;
478 std::lock_guard<std::mutex> lock(m_Mutex);
480 const int32_t nTimeout = m_nTimeoutSeconds;
489 std::lock_guard<std::mutex> lock(m_Mutex);
491 OT_ASSERT_MSG(nTimeoutSeconds >= (-1),
"OTCachedKey::SetTimeoutSeconds: "
492 "ASSERT: nTimeoutSeconds must be >= "
495 m_nTimeoutSeconds = nTimeoutSeconds;
502 std::lock_guard<std::mutex> lock(m_Mutex);
506 if (
nullptr != m_pSymmetricKey) {
507 otErr <<
"OTCachedKey::SetCachedKey: Warning: This was already set. "
512 m_pSymmetricKey =
nullptr;
514 delete pSymmetricKey;
515 pSymmetricKey =
nullptr;
537 std::lock_guard<std::mutex> lock(m_Mutex);
539 if (
nullptr == m_pSymmetricKey)
return false;
546 std::lock_guard<std::mutex> lock(m_Mutex);
548 if (
nullptr == m_pSymmetricKey)
return false;
559 std::lock_guard<std::mutex> lock((const_cast<OTCachedKey*>(
this))->m_Mutex);
561 if ((
nullptr == m_pSymmetricKey) || !m_pSymmetricKey->
IsGenerated())
570 std::lock_guard<std::mutex> lock((const_cast<OTCachedKey*>(
this))->m_Mutex);
572 if ((
nullptr == m_pSymmetricKey) || !m_pSymmetricKey->
IsGenerated())
594 OTPassword& theOutput,
const char* szDisplay, int32_t nTimeoutSeconds)
596 std::shared_ptr<OTCachedKey> pMaster(
new OTCachedKey(nTimeoutSeconds));
599 (
nullptr == szDisplay)
600 ?
"Creating a passphrase..."
603 const bool bGotPassphrase =
604 pMaster->GetMasterPassword(pMaster, theOutput, strDisplay.
Get(),
616 return std::shared_ptr<OTCachedKey>();
625 const char* szDisplay,
bool bVerifyTwice)
627 std::lock_guard<std::mutex> lock(m_Mutex);
629 std::string str_display(
630 nullptr != szDisplay ? szDisplay :
"(Display string was blank.)");
632 const char* szFunc =
"OTCachedKey::GetMasterPassword";
639 if (
nullptr != m_pMasterPassword) {
641 <<
": Master password was available. (Returning it now.)\n";
643 theOutput = *m_pMasterPassword;
647 otInfo << szFunc <<
": Master password wasn't loaded. Instantiating...\n";
699 bool bReturnVal =
false;
719 std::unique_ptr<OTPassword> theDerivedAngel;
721 if (
nullptr == m_pSymmetricKey) {
728 otWarn << szFunc <<
": Master key didn't exist. Need to collect a "
729 "passphrase from the user, "
730 "so we can generate a master key...\n ";
762 const bool bFoundOnKeyring =
772 *pDerivedKey, *m_pMasterPassword);
815 otWarn << szFunc <<
": Finished calling "
816 "m_pSymmetricKey->GetRawKeyFromDerivedKey "
818 theOutput = *m_pMasterPassword;
819 theDerivedAngel.reset(
826 otOut << szFunc <<
": Unable to unlock master key using "
827 "derived key found on system keyring.\n";
829 pDerivedKey =
nullptr;
838 <<
": Unable to find derived key on system keyring.\n";
849 if (
nullptr == pDerivedKey)
868 default_password.c_str(),
869 static_cast<int32_t
>(default_password.length()));
890 nullptr, 0, bVerifyTwice ? 1 : 0,
891 static_cast<void*>(&thePWData))) {
892 otErr << __FUNCTION__ <<
": Failed to get password from user!";
898 bool bUsingDefaultPassword =
false;
900 if (4 > std::string(passUserInput.
getPassword()).length()) {
901 otOut <<
"\n Password entered was less than 4 characters "
902 "int64_t! This is NOT secure!!\n"
903 "... Assuming password is for testing only... "
904 "setting to default password: "
906 bUsingDefaultPassword =
true;
914 bUsingDefaultPassword ? passwordDefault : passUserInput,
921 if (
nullptr != pDerivedKey)
922 theDerivedAngel.reset(pDerivedKey);
924 otErr << __FUNCTION__ <<
": FYI: Derived key is still nullptr "
926 "OTSymmetricKey::GenerateKey.\n";
958 if (
nullptr == pDerivedKey) {
959 otOut <<
"\n\n" << __FUNCTION__
960 <<
": Please enter your password.\n\n";
967 static_cast<void*>(&thePWData))) {
968 otErr <<
"\n\n" << __FUNCTION__
969 <<
": Failed to get password from user!\n\n";
975 if (
nullptr != pDerivedKey)
break;
977 otOut <<
"\n\n" << __FUNCTION__
978 <<
": Wrong Password, Please Try Again.\n\n";
983 otOut <<
"\n Please enter your current password twice, (not a "
984 "new password!!) \n";
987 nullptr, 0,
true, static_cast<void*>(&thePWData))) {
988 otErr << __FUNCTION__
989 <<
": Failed to get password from user!";
998 theDerivedAngel.reset(pDerivedKey);
1000 otWarn << szFunc <<
": FYI, symmetric key was already generated. "
1001 "Proceeding to try and use it...\n";
1021 <<
": Calling m_pSymmetricKey->GetRawKeyFromPassphrase()...\n";
1045 passUserInput, *m_pMasterPassword, pDerivedKey);
1047 otInfo << szFunc <<
": Finished calling "
1048 "m_pSymmetricKey->GetRawKeyFromPassphrase "
1050 theOutput = *m_pMasterPassword;
1055 const std::string str_display(
1056 nullptr != szDisplay ? szDisplay
1057 :
"(Display string was blank.)");
1070 otWarn << szFunc <<
": Strange: Problem with either: "
1071 "IsUsingSystemKeyring"
1075 "or: (nullptr != pDerivedKey) ("
1076 << ((
nullptr != pDerivedKey) ?
"true" :
"false")
1084 <<
": m_pSymmetricKey->GetRawKeyFromPassphrase() failed.\n";
1087 otErr << szFunc <<
": bGenerated is still false, even after trying "
1088 "to generate it, yadda yadda yadda.\n";
1097 #if defined(OT_CRYPTO_USING_OPENSSL)
1099 #if defined(OPENSSL_THREADS)
1102 otInfo << szFunc <<
": Starting thread for Master Key...\n";
1104 std::shared_ptr<OTCachedKey>* pthreadSharedPtr =
1105 new std::shared_ptr<OTCachedKey>(mySharedPtr);
1108 static_cast<void*>(pthreadSharedPtr));
1114 <<
": WARNING: OpenSSL was NOT compiled with thread support. "
1115 "(Master Key will not expire.)\n";
1119 #elif defined(OT_CRYPTO_USING_GPG)
1121 otErr << szFunc <<
": WARNING: OT was compiled for GPG, which is not "
1123 "(Master Key will not expire.)\n";
1125 #else // OT_CRYPTO_USING_ ... nothing?
1128 <<
": WARNING: OT wasn't compiled for any crypto library "
1129 "(such as OpenSSL or GPG). Which is very strange, and I doubt "
1130 "things will even work, with it in this condition. (Plus, "
1132 "Key will not expire.)\n";
1134 #endif // if defined(OT_CRYPTO_USING_OPENSSL), elif
1138 else if (m_nTimeoutSeconds != (-1)) {
1139 if (
nullptr != m_pMasterPassword) {
1140 OTPassword* pMasterPassword = m_pMasterPassword;
1142 m_pMasterPassword =
nullptr;
1144 delete pMasterPassword;
1145 pMasterPassword =
nullptr;
1189 std::shared_ptr<OTCachedKey>* pthreadSharedPtr =
1190 static_cast<std::shared_ptr<OTCachedKey>*
>(pArg);
1191 std::shared_ptr<OTCachedKey> pMyself = *pthreadSharedPtr;
1194 OT_FAIL_MSG(
"OTCachedKey::ThreadTimeout: Need ptr to master key here, "
1195 "that activated this thread.\n");
1200 int32_t nTimeoutSeconds = 0;
1203 std::lock_guard<std::mutex> lock(OTCachedKey::s_mutexThreadTimeout);
1207 pMyself->GetTimeoutSeconds();
1211 if (nTimeoutSeconds > 0) {
1213 std::this_thread::sleep_for(
1214 std::chrono::seconds(nTimeoutSeconds));
1218 std::lock_guard<std::mutex> lock(OTCachedKey::s_mutexThreadTimeout);
1220 if (pMyself && (nTimeoutSeconds != (-1))) {
1221 pMyself->DestroyMasterPassword();
1236 std::lock_guard<std::mutex> lock(m_Mutex);
1238 if (m_nTimeoutSeconds != (-1)) {
1242 if (
nullptr != m_pMasterPassword) {
1245 m_pMasterPassword =
nullptr;
1248 pPassword =
nullptr;
1261 if (
nullptr != m_pSymmetricKey) {
1262 const std::string str_display;
1268 const bool bDeletedSecret =
1273 if (bDeletedSecret) {
1274 otOut <<
"OTCachedKey::DestroyMasterPassword: FYI, deleted "
1275 "the derived key (used for unlocking the master key "
1277 "from system keychain at the same time as we deleted the "
1279 "password from OT internally, due to password timeout.\n";
1293 std::lock_guard<std::mutex> lock(m_Mutex);
1297 if (
nullptr != m_pMasterPassword) {
1300 m_pMasterPassword =
nullptr;
1303 pPassword =
nullptr;
1306 if (
nullptr != m_pSymmetricKey) {
1309 const std::string str_display;
1316 const bool bDeletedSecret =
1321 if (bDeletedSecret) {
1322 otOut <<
"OTCachedKey::ResetMasterPassword: FYI, deleted "
1323 "the derived key (used for unlocking the master key "
1325 "from system keychain at the same time as we deleted the "
1327 "itself, presumably due to the passphrase being reset.\n";
1333 if (
nullptr != m_pSymmetricKey) {
1336 m_pSymmetricKey =
nullptr;
1338 delete pSymmetricKey;
1339 pSymmetricKey =
nullptr;
static EXPORT OTCrypto * It()
static EXPORT void Cleanup()
EXPORT OTPassword * CalculateNewDerivedKeyFromPassphrase(const OTPassword &thePassphrase)
EXPORT void ResetMasterPassword()
virtual OTPassword * InstantiateBinarySecret() const =0
static EXPORT std::shared_ptr< OTCachedKey > CreateMasterPassword(OTPassword &theOutput, const char *szDisplay=nullptr, int32_t nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT)
#define OT_DEFAULT_PASSWORD
EXPORT void LowLevelReleaseThread()
EXPORT bool IsUsingSystemKeyring() const
EXPORT void SetCachedKey(const OTASCIIArmor &ascCachedKey)
EXPORT bool SerializeFrom(OTPayload &theInput)
OTLOG_IMPORT OTLogStream otOut
std::map< std::string, std::shared_ptr< OTCachedKey > > mapOfCachedKeys
EXPORT int32_t setPassword(const char *input, int32_t size)
EXPORT void DestroyMasterPassword()
EXPORT bool GetRawKeyFromPassphrase(const OTPassword &thePassphrase, OTPassword &theRawKeyOutput, OTPassword *pDerivedKey=nullptr) const
EXPORT bool Exists() const
static EXPORT std::shared_ptr< OTCachedKey > It(OTIdentifier *pIdentifier=nullptr)
EXPORT bool GetRawKeyFromDerivedKey(const OTPassword &theDerivedKey, OTPassword &theRawKeyOutput) const
EXPORT void SetTimeoutSeconds(int32_t nTimeoutSeconds)
EXPORT bool GenerateKey(const OTPassword &thePassphrase, OTPassword **ppDerivedKey=nullptr)
EXPORT bool SerializeTo(OTPayload &theOutput) const
#define OT_ASSERT_MSG(x, s)
EXPORT bool IsGenerated()
OTLOG_IMPORT OTLogStream otInfo
EXPORT OTPassword * CalculateDerivedKeyFromPassphrase(const OTPassword &thePassphrase, bool bCheckForHashCheck=true) const
EXPORT bool GetIdentifier(OTIdentifier &theIdentifier) const
EXPORT bool HasHashCheck()
static EXPORT void ThreadTimeout(void *pArg)
EXPORT const char * getPassword() const
EXPORT bool SerializeFrom(const OTASCIIArmor &ascInput)
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
EXPORT int32_t GetTimeoutSeconds()
OTLOG_IMPORT OTLogStream otErr
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
EXPORT bool SerializeTo(OTASCIIArmor &ascOutput)
static EXPORT bool RetrieveSecret(const OTString &strUser, OTPassword &thePassword, const std::string &str_display)
bool HasHashCheck() const
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
EXPORT bool GetMasterPassword(std::shared_ptr< OTCachedKey > &mySharedPtr, OTPassword &theOutput, const char *szDisplay=nullptr, bool bVerifyTwice=false)
static EXPORT bool DeleteSecret(const OTString &strUser, const std::string &str_display)
static EXPORT bool StoreSecret(const OTString &strUser, const OTPassword &thePassword, const std::string &str_display)