// 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; }
String CryptoUtil::Base58CheckEncode(const OTData& input) { OTPassword transformedInput; transformedInput.setMemory(input); return Base58CheckEncode(transformedInput); }
// 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; }
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::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::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_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; }
// 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; }