String CryptoUtil::Base58CheckEncode(const OTData& input) { OTPassword transformedInput; transformedInput.setMemory(input); return Base58CheckEncode(transformedInput); }
// static bool OTKeyring::Mac_StoreSecret(const OTString& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); const std::string service_name = "opentxs"; const std::string account_name = strUser.Get(); OTMacKeychain theKeychain; void* vData = const_cast<void*>(static_cast<const void*>(thePassword.getMemory())); OSStatus theError = theKeychain.AddSecret( nullptr, service_name.size(), service_name.data(), account_name.size(), account_name.data(), thePassword.getMemorySize(), vData, // thePassword.getMemory() nullptr); if (theError != noErr) { otErr << "OTKeyring::Mac_StoreSecret: Error in theKeychain.AddSecret.\n"; return false; } return true; }
serializedAsymmetricKey TrezorCrypto::HDNodeToSerialized( const HDNode& node, const DerivationMode privateVersion) const { serializedAsymmetricKey key = std::make_shared<proto::AsymmetricKey>(); key->set_version(1); key->set_type(proto::AKEYTYPE_SECP256K1); if (privateVersion) { key->set_mode(proto::KEYMODE_PRIVATE); key->set_chaincode(node.chain_code, sizeof(node.chain_code)); OTPassword plaintextKey; plaintextKey.setMemory(node.private_key, sizeof(node.private_key)); OTData encryptedKey; BinarySecret masterPassword( App::Me().Crypto().AES().InstantiateBinarySecretSP()); masterPassword = CryptoSymmetric::GetMasterKey(""); bool encrypted = Libsecp256k1::EncryptPrivateKey( plaintextKey, *masterPassword, encryptedKey); if (encrypted) { key->set_key(encryptedKey.GetPointer(), encryptedKey.GetSize()); } } else { key->set_mode(proto::KEYMODE_PUBLIC); key->set_key(node.public_key, sizeof(node.public_key)); } return key; }
// static bool OTKeyring::IOS_StoreSecret(const OTString& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); CFStringRef service_name = CFSTR("opentxs"); CFStringRef account_name = CFStringCreateWithCString(nullptr, strUser.Get(), kCFStringEncodingUTF8); CFDataRef vData = CFDataCreateWithBytesNoCopy( nullptr, thePassword.getMemory_uint8(), thePassword.getMemorySize(), kCFAllocatorNull); const void* keys[] = {kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData}; const void* values[] = {kSecClassGenericPassword, service_name, account_name, vData}; CFDictionaryRef item = CFDictionaryCreate(nullptr, keys, values, 4, nullptr, nullptr); OSStatus theError = SecItemAdd(item, nullptr); CFRelease(item); CFRelease(vData); CFRelease(account_name); if (theError != noErr) { otErr << "OTKeyring::IOS_StoreSecret: Error in SecItemAdd.\n"; return false; } return true; }
serializedAsymmetricKey TrezorCrypto::SeedToPrivateKey(const OTPassword& seed) const { serializedAsymmetricKey derivedKey; HDNode node; int result = ::hdnode_from_seed( static_cast<const uint8_t*>(seed.getMemory()), seed.getMemorySize(), &node); OT_ASSERT_MSG((1 == result), "Derivation of root node failed."); if (1 == result) { derivedKey = HDNodeToSerialized(node, TrezorCrypto::DERIVE_PRIVATE); } OTPassword root; App::Me().Crypto().Hash().Digest( CryptoHash::HASH160, seed, root); derivedKey->mutable_path()->set_root( root.getMemory(), root.getMemorySize()); return derivedKey; }
std::string TrezorCrypto::toWords(const OTPassword& seed) const { std::string wordlist( ::mnemonic_from_data( static_cast<const uint8_t*>(seed.getMemory()), seed.getMemorySize())); return wordlist; }
String CryptoUtil::Base58CheckEncode(const OTPassword& input) { const uint8_t* inputStart = static_cast<const uint8_t*>(input.getMemory()); const uint8_t* inputEnd = inputStart + input.getMemorySize(); String encodedInput = ::EncodeBase58Check(inputStart, inputEnd); return encodedInput; }
std::string HDSeed::SaveSeed( const OTPassword& words, const OTPassword& passphrase) const { OT_ASSERT(words.isPassword() && passphrase.isPassword()); auto seed = aes_.InstantiateBinarySecretSP(); bip39_.WordsToSeed(words, *seed, passphrase); OT_ASSERT(1 < seed->getMemorySize()); // the fingerprint is used as the identifier of the seed for indexing // purposes. Always use the secp256k1 version for this. auto fingerprint = bip32_.SeedToFingerprint(EcdsaCurve::SECP256K1, *seed); const OTPasswordData reason("Encrypting a new BIP39 seed"); auto key = symmetric_.Key(reason, DEFAULT_ENCRYPTION_MODE); OT_ASSERT(key.get()); proto::Seed serialized; serialized.set_version(2); serialized.set_index(0); auto& encryptedWords = *serialized.mutable_words(); auto& encryptedPassphrase = *serialized.mutable_passphrase(); serialized.set_fingerprint(fingerprint); auto empty = Data::Factory(); const bool haveWords = key->Encrypt(words, empty, reason, encryptedWords); if (false == haveWords) { otErr << OT_METHOD << __FUNCTION__ << ": Failed to encrypt seed." << std::endl; return ""; } bool havePassphrase = key->Encrypt(passphrase, empty, reason, encryptedPassphrase, false); if (!havePassphrase) { otErr << OT_METHOD << __FUNCTION__ << ": Failed to encrypt passphrase." << std::endl; return ""; } const bool stored = storage_.Store(serialized, fingerprint); if (!stored) { otErr << OT_METHOD << __FUNCTION__ << ": Failed to store seed." << std::endl; return ""; } return fingerprint; }
bool Server::SetPrivateKey(const OTPassword& key) const { if (CURVE_KEY_BYTES != key.getMemorySize()) { otErr << OT_METHOD << __FUNCTION__ << ": Invalid private key." << std::endl; return false; } return set_private_key(key.getMemory(), key.getMemorySize()); }
bool HDSeed::SeedToData( const OTPassword& words, const OTPassword& passphrase, OTPassword& output) const { OT_ASSERT(words.isPassword()); OT_ASSERT(passphrase.isPassword()); bip39_.WordsToSeed(words, output, passphrase); return true; }
/** * Try to unlock the wallet. If a passphrase is needed, a dialog is shown * until the correct one is entered or the user cancels the action. In the * latter case, UnlockFailure is thrown. * @throws UnlockFailure if the user cancels the unlock. */ void NMC_WalletUnlocker::unlock () { std::string pwd; qDebug () << "Trying to unlock the Namecoin wallet."; /* If we need a password, show the dialog. */ if (nc.needWalletPassphrase ()) { OTPassword otPwd; MTDlgPassword dlg (nullptr, otPwd); dlg.setDisplay ("Your Namecoin wallet is locked. For the operations to" " proceed, please enter the passphrase to temporarily" " unlock the wallet."); const int res = dlg.exec (); /* Return code is 0 for cancel button or closing the window. It is 1 in case of ok. */ if (res == 0) { qDebug () << "Wallet unlock was cancelled."; throw UnlockFailure("Wallet unlock was cancelled."); } dlg.extractPassword (); pwd = otPwd.getPassword (); } /* Now try to unlock. If the passphrase is wrong, retry by a tail-recursive call to unlock(). */ try { unlocker.unlock (pwd); qDebug () << "Unlock successful (or not necessary)."; } catch (const nmcrpc::NamecoinInterface::UnlockFailure& exc) { qDebug () << "Wrong passphrase, retrying."; unlock (); } catch (const nmcrpc::JsonRpc::RpcError& exc) { qDebug () << "NMC RPC Error " << exc.getErrorCode () << ": " << exc.getErrorMessage ().c_str (); } catch (const std::exception& exc) { qDebug () << "Error: " << exc.what (); } }
// The highest-level possible interface (used by the API) // // NOTE: this version circumvents the master key. OTPassword* LegacySymmetric::GetPassphraseFromUser( const String& pstrDisplay, bool bAskTwice) // returns a // text // OTPassword, // or nullptr. { OTPassword* pPassUserInput = OTPassword::CreateTextBuffer(); // already asserts. // pPassUserInput->zeroMemory(); // This was causing the password to come // out blank. // // Below this point, pPassUserInput must be returned, or deleted. (Or it // will leak.) const char* szDisplay = "LegacySymmetric::GetPassphraseFromUser"; OTPasswordData thePWData( (!pstrDisplay.Exists()) ? szDisplay : pstrDisplay.Get()); // ------------------------------------------------------------------- // // OLD SYSTEM! (NO MASTER KEY INVOLVEMENT.) // thePWData.setUsingOldSystem(); // So the cached key doesn't interfere, // since // this is for a plain symmetric key. // ------------------------------------------------------------------- const auto& native = dynamic_cast<const api::internal::Native&>(OT::App()); auto* callback = native.GetInternalPasswordCallback(); const std::int32_t nCallback = (*callback)( pPassUserInput->getPasswordWritable_char(), pPassUserInput->getBlockSize(), bAskTwice ? 1 : 0, static_cast<void*>(&thePWData)); const std::uint32_t uCallback = static_cast<uint32_t>(nCallback); if ((nCallback > 0) && // Success retrieving the passphrase from the user. pPassUserInput->SetSize(uCallback)) { // otOut << "%s: Retrieved passphrase (blocksize %d, actual size // %d) from " // "user: %s\n", __FUNCTION__, // pPassUserInput->getBlockSize(), nCallback, // pPassUserInput->getPassword()); return pPassUserInput; // Caller MUST delete! } else { delete pPassUserInput; pPassUserInput = nullptr; otOut << __FUNCTION__ << ": Sorry, unable to retrieve passphrase from user. (Failure.)\n"; } return nullptr; }
String CryptoUtil::Nonce(const uint32_t size, OTData& rawOutput) const { rawOutput.zeroMemory(); rawOutput.SetSize(size); OTPassword source; source.randomizeMemory(size); String nonce(Base58CheckEncode(source)); rawOutput.Assign(source.getMemory(), source.getMemorySize()); return nonce; }
// static bool OTKeyring::Gnome_StoreSecret(const OTString& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); OTData theData(thePassword.getMemory(), thePassword.getMemorySize()); OTASCIIArmor ascData(theData); theData.zeroMemory(); // security reasons. OTString strOutput; const bool bSuccess = ascData.Exists() && ascData.WriteArmoredString(strOutput, "DERIVED KEY"); // There's no // default, to // force you to // enter the right // string. ascData.zeroMemory(); GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR; if (bSuccess && strOutput.Exists()) { theResult = gnome_keyring_store_password_sync( GNOME_KEYRING_NETWORK_PASSWORD, GNOME_KEYRING_DEFAULT, // GNOME_KEYRING_SESSION, str_display.c_str(), strOutput.Get(), "user", strUser.Get(), "protocol", "opentxs", // todo: hardcoding. nullptr); strOutput.zeroMemory(); bool bResult = false; if (theResult == GNOME_KEYRING_RESULT_OK) bResult = true; else otErr << "OTKeyring::Gnome_StoreSecret: " << "Failure in gnome_keyring_store_password_sync: " << gnome_keyring_result_to_message(theResult) << '\n'; return bResult; } otOut << "OTKeyring::Gnome_StoreSecret: No secret to store.\n"; return false; }
// static bool OTKeyring::Mac_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); const std::string service_name = "opentxs"; const std::string account_name = strUser.Get(); uint32_t password_length = 0; void* password_data = nullptr; OTMacKeychain theKeychain; OSStatus theError = theKeychain.FindSecret( nullptr, service_name.size(), service_name.data(), account_name.size(), account_name.data(), &password_length, // output. &password_data, nullptr); if (theError == noErr) { thePassword.setMemory(password_data, password_length); theKeychain.ItemFreeContent(nullptr, password_data); return true; } else otErr << "OTKeyring::Mac_RetrieveSecret: Error in " "theKeychain.FindSecret.\n"; return false; }
// static bool OTKeyring::IOS_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); CFStringRef service_name = CFSTR("opentxs"); CFStringRef account_name = CFStringCreateWithCString(nullptr, strUser.Get(), kCFStringEncodingUTF8); CFDataRef vData = nullptr; const void* keys[] = {kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData}; const void* values[] = {kSecClassGenericPassword, service_name, account_name, kCFBooleanTrue}; CFDictionaryRef query = CFDictionaryCreate(nullptr, keys, values, 4, nullptr, nullptr); OSStatus theError = SecItemCopyMatching(query, (CFTypeRef*)&vData); CFRelease(query); CFRelease(account_name); if (theError != noErr) { otErr << "OTKeyring::IOS_RetrieveSecret: Error in SecItemCopyMatching.\n"; return false; } thePassword.setMemory(CFDataGetBytePtr(vData), CFDataGetLength(vData)); CFRelease(vData); return true; }
// The password will be stored here by the Java dialog, so that the C callback can retrieve it and pass it to OpenSSL // bool OTCaller::GetPassword(OTPassword & theOutput) const // Get the password.... { OTLog::Output(0, "OTCaller::GetPassword: FYI, returning password after invoking a (probably Java) password dialog.\n"); theOutput.setPassword_uint8(m_Password.getPassword_uint8(), m_Password.getPasswordSize()); return true; }
// static bool OTKeyring::KWallet_StoreSecret(const OTString& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); OTData theData(thePassword.getMemory(), thePassword.getMemorySize()); OTASCIIArmor ascData(theData); theData.zeroMemory(); // security reasons. OTString strOutput; const bool bSuccess = ascData.Exists() && ascData.WriteArmoredString( strOutput, "DERIVED KEY"); // There's no default, to force you // to enter the right string. ascData.zeroMemory(); // Set the password // bool bReturnVal = false; if (bSuccess && strOutput.Exists() && pWallet->writePassword(qstrKey, QString::fromUtf8(strOutput.Get())) == 0) bReturnVal = true; else otErr << "OTKeyring::KWallet_StoreSecret: Failed trying to store " "secret into KWallet.\n"; strOutput.zeroMemory(); return bReturnVal; } otErr << "OTKeyring::KWallet_StoreSecret: Unable to open kwallet.\n"; return false; }
OTSymmetricKey Symmetric::Factory( const crypto::SymmetricProvider& engine, const OTPassword& raw) { std::unique_ptr<implementation::Symmetric> output; if (!raw.isMemory()) { return OTSymmetricKey(output.release()); } output.reset(new implementation::Symmetric(engine)); if (!output) { return OTSymmetricKey(output.release()); } OTPasswordData password("Encrypting a symmetric key."); output->EncryptKey(raw, password); output->key_size_ = raw.getMemorySize(); return OTSymmetricKey(output.release()); }
// static bool OTKeyring::KWallet_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); KWallet::Wallet* pWallet = OTKeyring::OpenKWallet(); if (nullptr != pWallet) { const QString qstrKey(strUser.Get()); QString qstrPwd; // Get the password // if (pWallet->readPassword(qstrKey, qstrPwd) == 0) { const std::string str_password = qstrPwd.toStdString(); // todo security: notice str_password // isn't zero'd here. OTString strData(str_password); OTASCIIArmor ascData; const bool bLoaded = strData.Exists() && ascData.LoadFromString(strData); strData.zeroMemory(); if (!bLoaded) otErr << __FUNCTION__ << ": Failed trying to decode secret " "from KWallet contents.\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor from " "KWallet contents.\n"; else { thePassword.setMemory(thePayload.GetPayloadPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } } } else otErr << __FUNCITON__ << ": Failed trying to retrieve secret from KWallet.\n"; } // Not an error: what if it just hasn't been set there yet? // otWarn << "OTKeyring::KWallet_RetrieveSecret: No secret found.\n"; return false; }
bool CryptoUtil::GetPasswordFromConsole(OTPassword& theOutput, bool bRepeat) const { int32_t nAttempts = 0; for (;;) { theOutput.zeroMemory(); if (GetPasswordFromConsole(theOutput, "(OT) passphrase: ")) { if (!bRepeat) { std::cout << std::endl; return true; } } else { std::cout << "Sorry." << std::endl; return false; } OTPassword tempPassword; if (!GetPasswordFromConsole(tempPassword, "(Verifying) passphrase again: ")) { std::cout << "Sorry." << std::endl; return false; } if (!tempPassword.Compare(theOutput)) { if (++nAttempts >= 3) break; std::cout << "(Mismatch, try again.)\n" << std::endl; } else { std::cout << std::endl; return true; } } std::cout << "Sorry." << std::endl; return false; }
bool HDSeed::DecryptSeed( const proto::Seed& seed, OTPassword& words, OTPassword& phrase) const { if (!proto::Validate(seed, VERBOSE)) { return false; } const auto& cwords = seed.words(); const auto& cphrase = seed.passphrase(); const OTPasswordData reason("Decrypting a new BIP39 seed"); auto key = symmetric_.Key(cwords.key(), cwords.mode()); OT_ASSERT(key.get()); OT_ASSERT(words.isPassword()); const bool haveWords = key->Decrypt(seed.words(), reason, words); if (!haveWords) { otErr << OT_METHOD << __FUNCTION__ << ": Failed to decrypt words." << std::endl; return false; } OT_ASSERT(phrase.isPassword()); if (seed.has_passphrase()) { const bool havePassphrase = key->Decrypt(cphrase, reason, phrase); if (!havePassphrase) { otErr << OT_METHOD << __FUNCTION__ << ": Failed to decrypt passphrase." << std::endl; return false; } } return true; }
bool CryptoUtil::Base58CheckDecode(const String& input, OTPassword& output) { OTData decodedOutput; bool decoded = Base58CheckDecode(input, decodedOutput); if (decoded) { output.setMemory(decodedOutput); return true; } else { return false; } }
// static bool OTKeyring::FlatFile_StoreSecret(const String& strUser, const OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OT_ASSERT(thePassword.getMemorySize() > 0); const std::string str_pw_folder(OTKeyring::FlatFile_GetPasswordFolder()); if (!str_pw_folder.empty()) { String strExactPath; strExactPath.Format("%s%s%s", str_pw_folder.c_str(), Log::PathSeparator(), strUser.Get()); const std::string str_ExactPath(strExactPath.Get()); OTData theData(thePassword.getMemory(), thePassword.getMemorySize()); OTASCIIArmor ascData(theData); theData.zeroMemory(); // security reasons. // Save the password // const bool bSaved = ascData.Exists() && ascData.SaveToExactPath(str_ExactPath); ascData.zeroMemory(); if (!bSaved) otErr << "OTKeyring::FlatFile_StoreSecret: Failed trying to store " "secret.\n"; return bSaved; } otErr << "OTKeyring::FlatFile_StoreSecret: Unable to cache derived key, " "since password_folder not provided in config file.\n"; return false; }
// static bool OTKeyring::FlatFile_RetrieveSecret(const String& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); const std::string str_pw_folder(OTKeyring::FlatFile_GetPasswordFolder()); if (!str_pw_folder.empty()) { String strExactPath; strExactPath.Format("%s%s%s", str_pw_folder.c_str(), Log::PathSeparator(), strUser.Get()); const std::string str_ExactPath(strExactPath.Get()); // Get the password // OTASCIIArmor ascData; if (!ascData.LoadFromExactPath(str_ExactPath)) otErr << "OTKeyring::FlatFile_RetrieveSecret: " << "Failed trying to decode secret from flat file contents." << "\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor from " "flat file contents.\n"; else { thePassword.setMemory(thePayload.GetPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } } } // Not an error: what if it just hasn't been set there yet? // otWarn << __FUNCTION__ << ": Unable to retrieve any derived key, since " "password_folder not provided in config file.\n"; return false; }
OTPassword::OTPassword(const OTPassword& rhs) : size_(0) , isText_(rhs.isPassword()) , isBinary_(rhs.isMemory()) , isPageLocked_(false) , blockSize_( rhs.blockSize_) // The buffer has this size+1 as its static size. { if (isText_) { data_[0] = '\0'; setPassword_uint8(rhs.getPassword_uint8(), rhs.getPasswordSize()); } else if (isBinary_) { setMemory(rhs.getMemory_uint8(), rhs.getMemorySize()); } }
OTPassword::OTPassword(const OTPassword & rhs) : m_nPasswordSize(0), m_bIsText(rhs.isPassword()), m_bIsBinary(rhs.isMemory()), m_bIsPageLocked(false), m_theBlockSize(rhs.m_theBlockSize) // The buffer has this size+1 as its static size. { if (m_bIsText) { m_szPassword[0] = '\0'; setPassword_uint8(rhs.getPassword_uint8(), rhs.getPasswordSize()); } else if (m_bIsBinary) { setMemory(rhs.getMemory_uint8(), rhs.getMemorySize()); } }
bool OTPassword::Compare(OTPassword & rhs) const { OT_ASSERT(this->isPassword() || this->isMemory()); OT_ASSERT(rhs.isPassword() || rhs.isMemory()); if (this->isPassword() && !rhs.isPassword()) return false; if (this->isMemory() && !rhs.isMemory()) return false; const uint32_t nThisSize = this->isPassword() ? this->getPasswordSize() : this->getMemorySize(); const uint32_t nRhsSize = rhs.isPassword() ? rhs.getPasswordSize() : rhs.getMemorySize(); if (nThisSize != nRhsSize) return false; if (0 == memcmp(this->isPassword() ? this->getPassword_uint8() : this->getMemory_uint8(), rhs. isPassword() ? rhs. getPassword_uint8() : rhs. getMemory_uint8(), rhs. isPassword() ? rhs. getPasswordSize() : rhs. getMemorySize()) ) return true; return false; }
// static bool OTKeyring::Gnome_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); GnomeKeyringResult theResult = GNOME_KEYRING_RESULT_IO_ERROR; gchar* gchar_p_password = nullptr; // if the password exists in the keyring, set it in // thePassword (output argument.) // int32_t nCount = -1; int64_t lSleep = 1; while ((GNOME_KEYRING_RESULT_OK != theResult)) { ++nCount; // 0 on first iteration. theResult = gnome_keyring_find_password_sync( GNOME_KEYRING_NETWORK_PASSWORD, &gchar_p_password, "user", strUser.Get(), "protocol", "opentxs", // todo: hardcoding. nullptr); if (GNOME_KEYRING_RESULT_OK == theResult) break; if (nCount > 2) // todo hardcoding. break; // we try a few times -- not infinite times! OTString strGnomeError(gnome_keyring_result_to_message(theResult)); // OTString strGnomeError; // switch (theResult) { // case GNOME_KEYRING_RESULT_OK: strGnomeError // = "GNOME_KEYRING_RESULT_OK"; break; // case GNOME_KEYRING_RESULT_DENIED: strGnomeError // = "GNOME_KEYRING_RESULT_DENIED"; break; // case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON: strGnomeError // = "GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON"; break; // case GNOME_KEYRING_RESULT_ALREADY_UNLOCKED: strGnomeError // = "GNOME_KEYRING_RESULT_ALREADY_UNLOCKED"; break; // case GNOME_KEYRING_RESULT_NO_SUCH_KEYRING: strGnomeError // = "GNOME_KEYRING_RESULT_NO_SUCH_KEYRING"; break; // case GNOME_KEYRING_RESULT_BAD_ARGUMENTS: strGnomeError // = "GNOME_KEYRING_RESULT_BAD_ARGUMENTS"; break; // case GNOME_KEYRING_RESULT_IO_ERROR: strGnomeError // = "GNOME_KEYRING_RESULT_IO_ERROR"; break; // case GNOME_KEYRING_RESULT_CANCELLED: strGnomeError // = "GNOME_KEYRING_RESULT_CANCELLED"; break; // case GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS: // strGnomeError = "GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS"; break; // case GNOME_KEYRING_RESULT_NO_MATCH: strGnomeError // = "GNOME_KEYRING_RESULT_NO_MATCH"; break; // // default: // strGnomeError = "Unknown! Very strange!"; // break; // } otErr << __FUNCTION__ << ": gnome_keyring_find_password_sync returned " << strGnomeError.Get() << '\n'; otErr << "Remedy: Sleeping for " << lSleep << " seconds and then retrying (attempt " << (nCount + 2) << '\n'; // on first iteration, nCount is 0, and this will say "attempt 2" aka // "second attempt," which is correct. sleep(lSleep); lSleep *= 2; // double it each time } if ((theResult == GNOME_KEYRING_RESULT_OK) && (nullptr != gchar_p_password)) { size_t sizePassword = OTString::safe_strlen(gchar_p_password, MAX_STRING_LENGTH); if (sizePassword > 0) { OTString strData(gchar_p_password, sizePassword); gnome_keyring_free_password(gchar_p_password); gchar_p_password = nullptr; OTASCIIArmor ascData; const bool bLoaded = strData.Exists() && ascData.LoadFromString(strData); strData.zeroMemory(); if (!bLoaded) otErr << __FUNCTION__ << ": Failed trying to decode secret " "from Gnome Keyring contents:\n\n" << strData.Get() << "\n\n"; else { OTData thePayload(ascData); ascData.zeroMemory(); if (thePayload.IsEmpty()) otErr << __FUNCTION__ << ": Failed trying to decode secret " "OTData from OTASCIIArmor " << "from Gnome Keyring contents:\n\n" << strData.Get() << "\n\n"; else { thePassword.setMemory(thePayload.GetPayloadPointer(), thePayload.GetSize()); thePayload.zeroMemory(); // for security. return true; } return false; } } } // Not an error: what if it just hasn't been set there yet? // otOut << "OTKeyring::Gnome_RetrieveSecret: " << "No secret found: gnome_keyring_find_password_sync: " << gnome_keyring_result_to_message(theResult) << '\n'; return false; }
// static bool OTKeyring::Windows_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OTString strFoldername("win32_data"); // todo hardcoding. OTASCIIArmor ascFileContents; bool bLoaded = (strFoldername.Exists() && ascFileContents.LoadFromFile(strFoldername, strUser) && ascFileContents.Exists()); if (!bLoaded) { otWarn << "%s: No cached ciphertext of master key loaded during " "attempted retrieval. " "(However, once one is available, it WILL be cached using " "DPAPI.) \n"; return false; } // Below this point, we know for sure the ciphertext of the master // key loaded, and exists. // const OTData theCipherblob(ascFileContents); // if (theCipherblob.IsEmpty()) { otErr << __FUNCTION__ << ": Error: OTData is empty after decoding " "OTASCIIArmor (that wasn't empty.)\n"; } else { DATA_BLOB input; input.pbData = const_cast<BYTE*>( reinterpret_cast<const BYTE*>(theCipherblob.GetPayloadPointer())); input.cbData = static_cast<DWORD>(theCipherblob.GetSize()); // CRYPTPROTECT_PROMPTSTRUCT PromptStruct; // ZeroMemory(&PromptStruct, sizeof(PromptStruct)); // PromptStruct.cbSize = sizeof(PromptStruct); // PromptStruct.dwPromptFlags = CRYPTPROTECT_PROMPT_ON_PROTECT; // PromptStruct.szPrompt = L"This is a user prompt."; // LPWSTR pDescrOut = nullptr; DATA_BLOB output; BOOL result = CryptUnprotectData(&input, nullptr, // &pDescrOut nullptr, // optional entropy nullptr, // reserved nullptr, //&PromptStruct 0, &output); if (!result) { otErr << __FUNCTION__ << ": Error: Output of Win32 CryptUnprotectData was empty.\n"; } else { thePassword.setMemory(reinterpret_cast<void*>(output.pbData), static_cast<uint32_t>(output.cbData)); SecureZeroMemory(output.pbData, output.cbData); LocalFree(output.pbData); // LocalFree(pDescrOut); return true; } } return false; }