// Decodes a private key from ASCII armor into an actual key pointer // and sets that as the m_pPrivateKey on this object. // This is the version that will handle the bookends ( -----BEGIN ENCRYPTED PRIVATE KEY-----) bool OTKeypair::SetPrivateKey(const OTString & strKey, bool bEscaped/*=false*/) { OT_ASSERT(NULL != m_pkeyPrivate); // --------------------------------------------------------------- const char * szOverride = "PGP PRIVATE KEY"; if (strKey.Contains(szOverride)) { OTASCIIArmor theArmor; if (theArmor.LoadFromString(const_cast<OTString &>(strKey), bEscaped, szOverride)) // szOverride == "PGP PRIVATE KEY" { // This function expects that the bookends are already removed. // The ascii-armor loading code removes them and handles the escapes also. // return m_pkeyPrivate->LoadPrivateKeyFromPGPKey(theArmor); // OTLog::vOutput(0, "OTKeypair::SetPrivateKey 1: Failure: PGP private keys are NOT YET SUPPORTED.\n\n"); // OTLog::vOutput(0, "OTKeypair::SetPrivateKey 1: Failure: PGP private keys are NOT YET SUPPORTED:\n\n%s\n\n", // strKey.Get()); return false; } else { OTLog::vOutput(0, "OTKeypair::SetPrivateKey 2: Failure: PGP private keys are NOT YET SUPPORTED.\n\n"); // OTLog::vOutput(0, "OTKeypair::SetPrivateKey 2: Failure: PGP private keys are NOT YET SUPPORTED:\n\n%s\n\n", // strKey.Get()); return false; } } else // the below function SetPrivateKey (in the return call) expects the // bookends to still be there, and it will handle removing them. (Unlike PGP code above.) // return m_pkeyPrivate->SetPrivateKey(strKey, bEscaped); }
bool OTEnvelope::SetFromBookendedString( const String& strArmorWithBookends, // input bool bEscaped) { OTASCIIArmor theArmoredText; const bool bLoaded = theArmoredText.LoadFromString( const_cast<String&>(strArmorWithBookends), bEscaped); // std::string str_override="-----BEGIN"); if (bLoaded) { // This function will base64 DECODE theArmoredText's string contents // and return them as binary in m_dataContents const bool bGotData = theArmoredText.GetData(m_dataContents, true); // bLineBreaks = true if (!bGotData) otErr << __FUNCTION__ << ": Failed while calling: " "theArmoredText.GetData\n"; else return true; } else otErr << __FUNCTION__ << ": Failed while calling: " "theArmoredText.LoadFromString\n"; return false; }
// Decodes a public key from bookended key string into an actual key // pointer, and sets that as the m_pkeyPublic on this object. // This is the version that will handle the bookends ( -----BEGIN PUBLIC KEY-----) // bool OTKeypair::SetPublicKey(const OTString & strKey, bool bEscaped/*=false*/) { OT_ASSERT(NULL != m_pkeyPublic); // --------------------------------------------------------------- if (strKey.Contains("PGP PUBLIC KEY")) { OTASCIIArmor theArmor; if (theArmor.LoadFromString(const_cast<OTString &>(strKey), bEscaped)) { // This function expects that the bookends are already removed. // The ascii-armor loading code removes them and handles the escapes also. return m_pkeyPublic->LoadPublicKeyFromPGPKey(theArmor); } else { OTLog::Output(2, "OTKeypair::SetPublicKey: Failed extracting PGP public key from ascii-armored text.\n"); return false; } } else // the below function SetPublicKey (in the return call) expects the // bookends to still be there, and it will handle removing them. (Unlike PGP code above.) return m_pkeyPublic->SetPublicKey(strKey, bEscaped); }
// Let's say you don't know if the input string is raw base64, or if it has // bookends // on it like -----BEGIN BLAH BLAH ... // And if it DOES have Bookends, you don't know if they are escaped: - // -----BEGIN ... // Let's say you just want an easy function that will figure that crap out, and // load the // contents up properly into an OTASCIIArmor object. (That's what this function // will do.) // // str_bookend is a default. // So you could make it more specific like, -----BEGIN ENCRYPTED KEY (or // whatever.) // // static bool OTASCIIArmor::LoadFromString(OTASCIIArmor& ascArmor, const String& strInput, std::string str_bookend) { if (strInput.Contains(str_bookend)) // YES there are bookends around this. { const std::string str_escaped("- " + str_bookend); const bool bEscaped = strInput.Contains(str_escaped); String strLoadFrom(strInput); if (!ascArmor.LoadFromString(strLoadFrom, bEscaped)) // removes the // bookends so we // have JUST the // coded part. { // otErr << "%s: Failure loading string into OTASCIIArmor // object:\n\n%s\n\n", // __FUNCTION__, strInput.Get()); return false; } } else ascArmor.Set(strInput.Get()); return true; }
// 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; }
// Let's say you don't know if the input string is raw base64, or if it has bookends // on it like -----BEGIN BLAH BLAH ... // And if it DOES have Bookends, you don't know if they are escaped: - -----BEGIN ... // Let's say you just want an easy function that will figure that crap out, and load the // contents up properly into an OTASCIIArmor object. (That's what this function will do.) // // str_bookend is a default. // So you could make it more specific like, -----BEGIN ENCRYPTED KEY (or whatever.) // //static bool OTASCIIArmor::LoadFromString(OTASCIIArmor & ascArmor, const OTString & strInput, const std::string str_bookend/*="-----BEGIN"*/) { // ----------------------------------------------------- if (strInput.Contains(str_bookend)) // YES there are bookends around this. { const std::string str_escaped("- " + str_bookend); // ----------------------------------- const bool bEscaped = strInput.Contains(str_escaped); // ----------------------------------- OTString strLoadFrom(strInput); if (!ascArmor.LoadFromString(strLoadFrom, bEscaped)) // removes the bookends so we have JUST the coded part. { // OTLog::vError("%s: Failure loading string into OTASCIIArmor object:\n\n%s\n\n", // __FUNCTION__, strInput.Get()); return false; } } else ascArmor.Set(strInput.Get()); // ------------------------------------------------- return true; }
// 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; }
// If this string starts with -----BEGIN OT ARMORED... // Then this function will load it up into an OTASCIIArmor (removing // the bookends) and then decode it back into this string. This code // has been repeated around so I'm doing this as a refactoring exercise. // // Return value: true == There is a string in here that is not armored. // (Whether I actually HAD to unarmor it or not... it's unarmored now.) // false == There was some error or the string is empty. // bool OTString::DecodeIfArmored(bool bEscapedIsAllowed/*=true*/) { if (!this->Exists()) return false; // ---------------------- bool bArmoredAndALSOescaped = false; // "- -----BEGIN OT ARMORED" bool bArmoredButNOTescaped = false; // "-----BEGIN OT ARMORED" if (this->Contains(OT_BEGIN_ARMORED_escaped)) // check this one first... { bArmoredAndALSOescaped = true; if (!bEscapedIsAllowed) { OTLog::vError("%s: Armored and escaped value passed in, but escaped are forbidden here. " "(Returning.)\n"); return false; } } else if (this->Contains(OT_BEGIN_ARMORED)) { bArmoredButNOTescaped = true; } // ---------------------------------------- const bool bArmored = (bArmoredAndALSOescaped || bArmoredButNOTescaped); // ---------------------------------------- // Whether the string is armored or not, (-----BEGIN OT ARMORED) // either way, we'll end up with the decoded version in this variable: // std::string str_Trim; // ------------------------------------------------ if (bArmored) // it's armored, we have to decode it first. { OTASCIIArmor ascTemp; if (false == (ascTemp.LoadFromString(*this, bArmoredAndALSOescaped, // if it IS escaped or not, this variable will be true or false to show it. // The below szOverride sub-string determines where the content starts, when loading. OT_BEGIN_ARMORED))) // Default is: "-----BEGIN" // We're doing this: "-----BEGIN OT ARMORED" (Should worked for escaped as well, here.) { OTLog::vError("%s: Error loading string contents from ascii-armored encoding. " "Contents: \n%s\n", __FUNCTION__, this->Get()); return false; } else // success loading the actual contents out of the ascii-armored version. { OTString strTemp(ascTemp); // <=== ascii-decoded here. std::string str_temp(strTemp.Get(), strTemp.GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. } } else { std::string str_temp(this->Get(), this->GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. (Wasn't armored, so here we use it as passed in.) } // ------------------------------------------------ // At this point, str_Trim contains the actual contents, whether they // were originally ascii-armored OR NOT. (And they are also now trimmed, either way.) // ------------------------------------------ this->Release(); // ------------------------------------------ if (str_Trim.size() > 0) this->Set(str_Trim.c_str()); // ------------------------------------------ return this->Exists(); }
bool OTPayment::SetPayment(const OTString & strPayment) { if (!strPayment.Exists()) return false; // -------------------------------------------------------------------- // // To support legacy data, we check here to see if it's armored or not. // If it's not, we support it. But if it IS, we ALSO support it (we de-armor it here.) // bool bArmoredAndALSOescaped = false; // "- -----BEGIN OT ARMORED" bool bArmoredButNOTescaped = false; // "-----BEGIN OT ARMORED" if (strPayment.Contains(OT_BEGIN_ARMORED_escaped)) // check this one first... { bArmoredAndALSOescaped = true; OTLog::Error("OTPayment::SetPayment: Armored and escaped value passed in, but escaped are forbidden here. (Returning false.)\n"); return false; } else if (strPayment.Contains(OT_BEGIN_ARMORED)) { bArmoredButNOTescaped = true; } // ---------------------------------------- const bool bArmored = (bArmoredAndALSOescaped || bArmoredButNOTescaped); // ---------------------------------------- // Whether the string is armored or not, (-----BEGIN OT ARMORED) // either way, we'll end up with the decoded version in this variable: // std::string str_Trim; // ------------------------------------------------ if (bArmored) // it's armored, we have to decode it first. { OTASCIIArmor ascTemp; OTString strPaymentTemp(strPayment); if (false == (ascTemp.LoadFromString(strPaymentTemp, bArmoredAndALSOescaped, // if it IS escaped or not, this variable will be true or false to show it. // The below szOverride sub-string determines where the content starts, when loading. OT_BEGIN_ARMORED))) // Default is: "-----BEGIN" // We're doing this: "-----BEGIN OT ARMORED" (Should worked for escaped as well, here.) { OTLog::vError("OTPayment::SetPayment: Error loading string contents from ascii-armored encoding. Contents: \n%s\n", strPayment.Get()); return false; } else // success loading the actual contents out of the ascii-armored version. { OTString strTemp(ascTemp); // <=== ascii-decoded here. std::string str_temp(strTemp.Get(), strTemp.GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. } } else { std::string str_temp(strPayment.Get(), strPayment.GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. (Wasn't armored, so here we use it as passed in.) } // ------------------------------------------------ // At this point, str_Trim contains the actual contents, whether they // were originally ascii-armored OR NOT. (And they are also now trimmed, either way.) // ------------------------------------------ OTString strContract(str_Trim.c_str()); m_strPayment.Release(); // ---------------------- // todo: should be "starts with" and perhaps with a trim first // if (strContract.Contains("-----BEGIN SIGNED CHEQUE-----")) m_Type = OTPayment::CHEQUE; else if (strContract.Contains("-----BEGIN SIGNED VOUCHER-----")) m_Type = OTPayment::VOUCHER; else if (strContract.Contains("-----BEGIN SIGNED INVOICE-----")) m_Type = OTPayment::INVOICE; // ------------------- else if (strContract.Contains("-----BEGIN SIGNED PAYMENT PLAN-----")) m_Type = OTPayment::PAYMENT_PLAN; else if (strContract.Contains("-----BEGIN SIGNED SMART CONTRACT-----")) m_Type = OTPayment::SMART_CONTRACT; // ------------------- else if (strContract.Contains("-----BEGIN SIGNED PURSE-----")) m_Type = OTPayment::PURSE; else m_Type = OTPayment::ERROR_STATE; // ---------------------- if (OTPayment::ERROR_STATE == m_Type) return false; // ********************************* m_strPayment.Set(strContract); // ********************************* return true; }
// static -- class factory. // OTTransactionType * OTTransactionType::TransactionFactory(const OTString & strInput) { static char buf[45] = ""; OTTransactionType * pItem = NULL; if (!strInput.Exists()) return NULL; // -------------------------------------------------------------------- // // To support legacy data, we check here to see if it's armored or not. // If it's not, we support it. But if it IS, we ALSO support it (we de-armor it here.) // bool bArmoredAndALSOescaped = false; // "- -----BEGIN OT ARMORED" bool bArmoredButNOTescaped = false; // "-----BEGIN OT ARMORED" if (strInput.Contains(OT_BEGIN_ARMORED_escaped)) // check this one first... { bArmoredAndALSOescaped = true; OTLog::Error("OTTransactionType::TransactionFactory: Armored and escaped value passed in, " "but escaped are forbidden here. (Returning NULL.)\n"); return NULL; } else if (strInput.Contains(OT_BEGIN_ARMORED)) { bArmoredButNOTescaped = true; } // ---------------------------------------- const bool bArmored = (bArmoredAndALSOescaped || bArmoredButNOTescaped); // ---------------------------------------- // Whether the string is armored or not, (-----BEGIN OT ARMORED) // either way, we'll end up with the decoded version in this variable: // std::string str_Trim; // ------------------------------------------------ if (bArmored) // it's armored, we have to decode it first. { OTASCIIArmor ascTemp; OTString strInputTemp(strInput); if (false == (ascTemp.LoadFromString(strInputTemp, bArmoredAndALSOescaped, // if it IS escaped or not, this variable will be true or false to show it. // The below szOverride sub-string determines where the content starts, when loading. OT_BEGIN_ARMORED))) // Default is: "-----BEGIN" // We're doing this: "-----BEGIN OT ARMORED" (Should worked for escaped as well, here.) { OTLog::vError("OTTransactionType::TransactionFactory: Error " "loading string contents from ascii-armored encoding. Contents: \n%s\n", strInput.Get()); return NULL; } else // success loading the actual contents out of the ascii-armored version. { OTString strTemp(ascTemp); // <=== ascii-decoded here. std::string str_temp(strTemp.Get(), strTemp.GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. } } else { std::string str_temp(strInput.Get(), strInput.GetLength()); str_Trim = OTString::trim(str_temp); // This is the std::string for the trim process. (Wasn't armored, so here we use it as passed in.) } // ------------------------------------------------ // At this point, str_Trim contains the actual contents, whether they // were originally ascii-armored OR NOT. (And they are also now trimmed, either way.) // ------------------------------------------ OTString strContract(str_Trim.c_str()); strContract.reset(); // for sgets buf[0] = 0; // probably unnecessary. bool bGotLine = strContract.sgets(buf, 40); if (!bGotLine) return NULL; OTString strFirstLine(buf); strContract.reset(); // set the "file" pointer within this string back to index 0. // Now I feel pretty safe -- the string I'm examining is within // the first 45 characters of the beginning of the contract, and // it will NOT contain the escape "- " sequence. From there, if // it contains the proper sequence, I will instantiate that type. if (!strFirstLine.Exists() || strFirstLine.Contains("- -")) return NULL; if (strFirstLine.Contains("-----BEGIN SIGNED TRANSACTION-----")) // this string is 34 chars long. { pItem = new OTTransaction(); OT_ASSERT(NULL != pItem); } else if (strFirstLine.Contains("-----BEGIN SIGNED TRANSACTION ITEM-----")) // this string is 39 chars long. { pItem = new OTItem(); OT_ASSERT(NULL != pItem); } else if (strFirstLine.Contains("-----BEGIN SIGNED LEDGER-----")) // this string is 29 chars long. { pItem = new OTLedger(); OT_ASSERT(NULL != pItem); } else if (strFirstLine.Contains("-----BEGIN SIGNED ACCOUNT-----")) // this string is 30 chars long. { pItem = new OTAccount(); OT_ASSERT(NULL != pItem); } // The string didn't match any of the options in the factory. if (NULL == pItem) return NULL; // This causes pItem to load ASSUMING that the PurportedAcctID and PurportedServerID are correct. // The object is still expected to be internally consistent with its sub-items, regarding those IDs, // but the big difference is that it will SET the Real Acct and Real Server IDs based on the purported // values. This way you can load a transaction without knowing the account in advance. // pItem->m_bLoadSecurely = false; // OTLog::Error("\n\nTESTING DEBUGGING LOL LOL LOL LOL \n\n\n"); // Does the contract successfully load from the string passed in? if (pItem->LoadContractFromString(strContract)) { // NOTE: this already happens in OTTransaction::ProcessXMLNode and OTLedger::ProcessXMLNode. // Specifically, it happens when m_bLoadSecurely is set to false. // // pItem->SetRealServerID(pItem->GetPurportedServerID()); // pItem->SetRealAccountID(pItem->GetPurportedAccountID()); // return pItem; } else delete pItem; return NULL; }