133 #include "../core/stdafx.hpp"
138 #include "../core/crypto/OTSymmetricKey.hpp"
139 #include "../core/crypto/OTCachedKey.hpp"
140 #include "../core/crypto/OTEnvelope.hpp"
141 #include "../core/crypto/OTNymOrSymmetricKey.hpp"
142 #include "../core/crypto/OTPassword.hpp"
143 #include "../core/util/OTFolders.hpp"
144 #include "../core/OTLog.hpp"
145 #include "../core/OTStorage.hpp"
147 #include <irrxml/irrXML.hpp>
156 bool bSuccess =
false;
181 const char* szFunc =
"Purse::GetPassphrase";
185 <<
": Failed: this purse isn't even password-protected.\n";
192 const OTString strReason((
nullptr == szDisplay) ? szFunc : szDisplay);
194 const bool bGotMasterPassword = pCachedKey->GetMasterPassword(
195 pCachedKey, theOutput, strReason.
Get());
196 return bGotMasterPassword;
213 otOut << __FUNCTION__
214 <<
": Failed: no internal master key exists, in this purse.\n";
215 return std::shared_ptr<OTCachedKey>();
222 otOut << __FUNCTION__
223 <<
": Error: internal master key has not yet been generated.\n";
224 return std::shared_ptr<OTCachedKey>();
262 otOut << __FUNCTION__
263 <<
": Failed: internal Key or master key already exists. "
264 "Or IsPasswordProtected was true.\n";
269 otOut << __FUNCTION__
270 <<
": Failed: The purse must be EMPTY before you create a "
271 "new symmetric key, internal to that purse. (For the purposes "
273 "adding a passphrase to the purse, normally.) Otherwise I "
275 "to loop through all the tokens and re-assign ownership of "
277 "Instead, I'm just going to return false. That's easier.\n";
296 "Enter the new passphrase for this new password-protected "
311 otOut << __FUNCTION__
312 <<
": Failed: While calling OTCachedKey::CreateMasterPassword.\n";
323 otOut << __FUNCTION__ <<
": Failed: generating m_pSymmetricKey.\n";
334 <<
": Successfully created a purse's internal key.\n";
340 otErr << __FUNCTION__
341 <<
": Failed trying to cache the master key for this purse.\n";
354 const char* szFunc =
"Purse::Merge";
358 while (
Count() > 0) {
361 "Purse::Merge: Assert: nullptr != Pop(theOldNym) \n");
365 std::list<mapOfTokenPointers::iterator> listOfTokenMapIterators;
371 for (
auto it(theMap.begin()); it != theMap.end(); ++it) {
372 Token* pTempToken = it->second;
380 if (ascTempTokenID == ascTokenID) {
381 listOfTokenMapIterators.push_back(it);
389 while (!listOfTokenMapIterators.empty()) {
390 Token* pTempToken = (listOfTokenMapIterators.back())->second;
391 theMap.erase(listOfTokenMapIterators.back());
393 pTempToken =
nullptr;
394 listOfTokenMapIterators.pop_back();
399 std::string theKey = ascTokenID.
Get();
400 theMap.insert(std::pair<std::string, Token*>(theKey, pToken));
408 while (theNewPurse.
Count() > 0) {
409 Token* pToken = theNewPurse.
Pop(theNewNym);
412 "Purse::Merge: Assert: nullptr != theNewPurse.Pop(theNewNym) \n");
416 std::list<mapOfTokenPointers::iterator> listOfTokenMapIterators;
421 for (
auto it(theMap.begin()); it != theMap.end(); ++it) {
422 Token* pTempToken = it->second;
430 if (ascTempTokenID == ascTokenID) {
431 listOfTokenMapIterators.push_back(it);
439 while (!listOfTokenMapIterators.empty()) {
440 Token* pTempToken = (listOfTokenMapIterators.back())->second;
441 theMap.erase(listOfTokenMapIterators.back());
443 pTempToken =
nullptr;
444 listOfTokenMapIterators.pop_back();
450 std::string theKey = ascTokenID.
Get();
451 theMap.insert(std::pair<std::string, Token*>(theKey, pToken));
471 otErr << szFunc <<
": Error: Failed while attempting to re-assign "
472 "ownership of token during purse merge.\n";
475 otWarn << szFunc <<
": FYI: Success re-assigning ownership of "
476 "token during purse merge.\n";
494 bool bSuccess =
true;
496 for (
auto& it : theMap) {
497 Token* pToken = it.second;
500 bool bPush =
Push(theOldNym,
505 otErr << szFunc <<
": Error: Failure pushing token into purse.\n";
516 while (!theMap.empty()) {
517 Token* pToken = theMap.begin()->second;
523 theMap.erase(theMap.begin());
539 Purse* pPurse =
nullptr;
540 if (strFirstLine.
Contains(
"-----BEGIN SIGNED PURSE-----"))
545 pPurse =
new Purse(SERVER_ID, ASSET_ID);
554 Purse* pPurse =
nullptr;
555 if (strFirstLine.
Contains(
"-----BEGIN SIGNED PURSE-----"))
560 pPurse =
new Purse(SERVER_ID);
568 Purse* pPurse =
nullptr;
569 if (strFirstLine.
Contains(
"-----BEGIN SIGNED PURSE-----"))
574 pPurse =
new Purse();
588 const bool bProcessed =
596 if (
nullptr == pPurse)
return nullptr;
600 const char* szFunc =
"Purse::PurseFactory";
602 const OTString strServerID(SERVER_ID),
604 otErr << szFunc <<
": Failure: ServerID on purse ("
605 << strPurseServerID <<
") doesn't match expected "
606 "server ID (" << strServerID
612 const OTString strAssetID(ASSET_ID),
614 otErr << szFunc <<
": Failure: AssetID on purse ("
615 << strPurseAssetID <<
") doesn't match expected "
616 "asset ID (" << strAssetID
638 const bool bProcessed =
645 if (
nullptr == pPurse)
return nullptr;
650 const OTString strServerID(SERVER_ID),
652 otErr <<
"Purse::PurseFactory"
653 <<
": Failure: ServerID on purse (" << strPurseServerID
654 <<
") doesn't match expected server ID (" << strServerID
676 const bool bProcessed =
683 if (
nullptr == pPurse)
return nullptr;
702 , m_bPasswordProtected(false)
703 , m_bIsNymIDIncluded(false)
704 , m_pSymmetricKey(nullptr)
714 , m_ServerID(thePurse.GetServerID())
715 , m_AssetID(thePurse.GetAssetID())
717 , m_bPasswordProtected(false)
718 , m_bIsNymIDIncluded(false)
719 , m_pSymmetricKey(nullptr)
731 , m_ServerID(SERVER_ID)
733 , m_bPasswordProtected(false)
734 , m_bIsNymIDIncluded(false)
735 , m_pSymmetricKey(nullptr)
744 , m_ServerID(SERVER_ID)
745 , m_AssetID(ASSET_ID)
747 , m_bPasswordProtected(false)
748 , m_bIsNymIDIncluded(false)
749 , m_pSymmetricKey(nullptr)
760 , m_ServerID(SERVER_ID)
761 , m_AssetID(ASSET_ID)
763 , m_bPasswordProtected(false)
764 , m_bIsNymIDIncluded(false)
765 , m_pSymmetricKey(nullptr)
833 const char* szAssetTypeID)
843 if (
nullptr != szServerID) strServerID = szServerID;
844 if (
nullptr != szUserID) strUserID = szUserID;
845 if (
nullptr != szAssetTypeID) strAssetTypeID = szAssetTypeID;
854 const char* szFolder2name = strServerID.Get();
855 const char* szFolder3name = strUserID.Get();
856 const char* szFilename =
857 strAssetTypeID.
Get();
860 OTDB::Exists(szFolder1name, szFolder2name, szFolder3name, szFilename)) {
861 otInfo <<
"Purse::LoadPurse: File does not exist: " << szFolder1name
868 std::string strFileContents(
872 if (strFileContents.length() < 2) {
873 otErr <<
"Purse::LoadPurse: Error reading file: " << szFolder1name
884 OTString strRawFile(strFileContents.c_str());
890 const char* szAssetTypeID)
900 if (
nullptr != szServerID) strServerID = szServerID;
901 if (
nullptr != szUserID) strUserID = szUserID;
902 if (
nullptr != szAssetTypeID) strAssetTypeID = szAssetTypeID;
911 const char* szFolder2name = strServerID.Get();
912 const char* szFolder3name = strUserID.Get();
913 const char* szFilename =
914 strAssetTypeID.
Get();
919 otErr <<
"Purse::SavePurse: Error saving Pursefile (to string):\n"
931 otErr <<
"Purse::SavePurse: Error saving Pursefile (failed writing "
939 strFinal.
Get(), szFolder1name, szFolder2name, szFolder3name,
942 otErr <<
"Purse::SavePurse: Error writing to file: " << szFolder1name
965 "<purse version=\"%s\"\n"
966 " totalValue=\"%" PRId64
"\"\n"
967 " validFrom=\"%" PRId64
969 " validTo=\"%" PRId64
971 " isPasswordProtected=\"%s\"\n"
972 " isNymIDIncluded=\"%s\"\n"
974 " assetTypeID=\"%s\"\n"
975 " serverID=\"%s\">\n\n",
1007 <<
": Error: m_pCachedKey is unexpectedly nullptr, even though "
1008 "m_bPasswordProtected is true!\n";
1010 otErr << __FUNCTION__ <<
": Error: m_pSymmetricKey is unexpectedly "
1011 "nullptr, even though "
1012 "m_bPasswordProtected is true!\n";
1017 otErr << __FUNCTION__ <<
": Error: m_pCachedKey wasn't a "
1018 "generated key! Even though "
1019 "m_bPasswordProtected is true.\n";
1021 otErr << __FUNCTION__ <<
": Error: m_pSymmetricKey wasn't a "
1022 "generated key! Even though "
1023 "m_bPasswordProtected is true.\n";
1028 !ascCachedKey.
Exists() ||
1030 !ascSymmetricKey.
Exists())
1031 otErr << __FUNCTION__
1032 <<
": Error: m_pCachedKey or m_pSymmetricKey failed "
1033 "trying to serialize to OTASCIIArmor.\n";
1041 "<cachedKey>\n%s</cachedKey>\n\n",
1042 ascCachedKey.
Get());
1046 "<internalKey>\n%s</internalKey>\n\n",
1047 ascSymmetricKey.
Get());
1055 for (int32_t i = 0; i <
Count(); i++) {
1065 const char* szFunc =
"Purse::ProcessXMLNode";
1067 const OTString strNodeName(xml->getNodeName());
1069 if (strNodeName.Compare(
"purse")) {
1072 const OTString strTotalValue = xml->getAttributeValue(
"totalValue");
1074 if (strTotalValue.
Exists() && (atol(strTotalValue.
Get()) > 0))
1079 const OTString str_valid_from = xml->getAttributeValue(
"validFrom");
1080 const OTString str_valid_to = xml->getAttributeValue(
"validTo");
1082 if (str_valid_from.
Exists()) {
1083 int64_t lValidFrom = str_valid_from.
ToLong();
1087 if (str_valid_to.
Exists()) {
1088 int64_t lValidTo = str_valid_to.
ToLong();
1093 const OTString strPasswdProtected =
1094 xml->getAttributeValue(
"isPasswordProtected");
1098 xml->getAttributeValue(
"isNymIDIncluded");
1104 const OTString strServerID = xml->getAttributeValue(
"serverID");
1105 if (strServerID.
Exists())
1110 <<
": Failed loading serverID, when one was expected.\n";
1117 const OTString strAssetTypeID = xml->getAttributeValue(
"assetTypeID");
1118 if (strAssetTypeID.
Exists())
1123 <<
": Failed loading assetTypeID, when one was expected.\n";
1128 xml->getAttributeValue(
"userID");
1136 <<
": Failed loading userID, when one was expected. "
1137 "(isNymIDIncluded was true.)\n";
1149 otLog4 << szFunc <<
": Loaded purse... ("
1151 :
"NOT password-protected")
1152 <<
")\n ServerID: " << strServerID
1154 <<
"\n Asset ID: " << strAssetTypeID <<
"\n----------\n";
1170 else if (strNodeName.Compare(
"internalKey")) {
1175 otErr << szFunc <<
": Error: Unexpected 'internalKey' data, "
1176 "since m_bPasswordProtected is set to false!\n";
1183 otErr << szFunc <<
": Error: Unexpected 'internalKey' data, since "
1184 "m_UserID is not blank! "
1185 "(The UserID should have loaded before THIS "
1186 "node ever popped up...)\n";
1194 otErr << szFunc <<
": Error: Expected "
1196 <<
" element to have text field.\n";
1205 <<
": WARNING: While loading internal Key for a purse, "
1206 "noticed the pointer was ALREADY set! (I'm deleting old "
1207 "one to make room, "
1208 "and then allowing this one to load instead...)\n";
1223 OT_ASSERT_MSG(
nullptr != pSymmetricKey,
"Purse::ProcessXMLNode: "
1224 "Assert: nullptr != new "
1225 "OTSymmetricKey \n");
1234 <<
": Error: While loading internal Key for a purse, failed "
1235 "serializing from stored string! (Failed loading purse.)\n";
1236 delete pSymmetricKey;
1237 pSymmetricKey =
nullptr;
1244 otWarn << szFunc <<
": Successfully loaded a purse's internal key.\n";
1253 else if (strNodeName.Compare(
"cachedKey")) {
1258 otErr << szFunc <<
": Error: Unexpected 'cachedKey' data, "
1259 "since m_bPasswordProtected is set to false!\n";
1266 otErr << szFunc <<
": Error: Unexpected 'cachedKey' data, since "
1267 "m_UserID is not blank!\n";
1275 otErr << szFunc <<
": Error: Expected "
1277 <<
" element to have text field.\n";
1286 <<
": WARNING: While loading master Key for a purse, "
1287 "noticed the pointer was ALREADY set! (I'm deleting old "
1288 "one to make room, "
1289 "and then allowing this one to load instead...)\n";
1302 std::shared_ptr<OTCachedKey> pCachedKey(
new OTCachedKey(ascValue));
1310 if (!pCachedKey->SerializeFrom(ascValue)) {
1313 <<
": Error: While loading master Key for a purse, failed "
1314 "serializing from stored string! (Failed loading purse.)\n";
1322 otWarn << szFunc <<
": Successfully loaded a purse's master key.\n";
1342 else if (strNodeName.Compare(
"token")) {
1348 otErr << szFunc <<
": Error: token field without value.\n";
1433 const OTString strDisplay(__FUNCTION__);
1437 const bool bSuccess =
1450 otErr << __FUNCTION__
1451 <<
": ERROR: Cash token with wrong server or asset type.\n";
1459 otErr << __FUNCTION__ <<
": Failure: theOwner.Open_or_Decrypt.\n";
1479 if (
nullptr == pToken) {
1480 otErr << __FUNCTION__ <<
": Failure: Peek(theOwner) "
1481 "(And m_dequeTokens isn't empty, either.)\n";
1533 const OTString strDisplay(__FUNCTION__);
1538 const bool bSuccess =
1547 if (m_tLatestValidFrom < pToken->GetValidFrom()) {
1557 otErr << __FUNCTION__
1558 <<
": WARNING: This purse has a 'valid from' date LATER "
1559 "than the 'valid to' date. "
1560 "(due to different tokens with different date "
1565 otErr << __FUNCTION__
1566 <<
": Failure while trying to decrypt a token.\n";
1578 const OTString strDisplay(__FUNCTION__);
1585 const bool bSuccess =
1609 otErr << __FUNCTION__
1610 <<
": WARNING: This purse has a 'valid from' date LATER "
1611 "than the 'valid to' date. "
1612 "(due to different tokens with different date "
1620 otErr << __FUNCTION__ <<
": Failed while calling: "
1621 "theOwner.Seal_or_Encrypt(theEnvelope, "
1622 "strToken)\nPurse Asset Type:\n"
1623 << strPurseAssetType <<
"\n"
1624 "Token Asset Type:\n"
1625 << strTokenAssetType <<
"\n";
1631 otErr << __FUNCTION__ <<
": ERROR: Tried to push token with wrong "
1632 "asset type.\nPurse Asset Type:\n"
1633 << strPurseAssetType <<
"\n"
1634 "Token Asset Type:\n" << strTokenAssetType
EXPORT bool StorePlainString(std::string strContents, std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
OTLOG_IMPORT OTLogStream otLog4
EXPORT bool GetPassphrase(OTPassword &theOutput, const char *szDisplay=nullptr)
EXPORT bool IsNymIDIncluded() const
EXPORT int32_t Count() const
static EXPORT bool DearmorAndTrim(const OTString &strInput, OTString &strOutput, OTString &strFirstLine)
EXPORT bool IsPasswordProtected() const
std::map< std::string, Token * > mapOfTokenPointers
time64_t GetValidTo() const
static EXPORT std::shared_ptr< OTCachedKey > CreateMasterPassword(OTPassword &theOutput, const char *szDisplay=nullptr, int32_t nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT)
virtual bool SaveContractWallet(std::ofstream &ofs) const
EXPORT bool Push(OTNym_or_SymmetricKey theOwner, const Token &theToken)
EXPORT bool SaveContract()
EXPORT int64_t ToLong() const
static EXPORT const char * PathSeparator()
EXPORT bool SerializeFrom(OTPayload &theInput)
const OTIdentifier & GetAssetID() const
time64_t m_tLatestValidFrom
OTLOG_IMPORT OTLogStream otOut
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
time64_t m_tEarliestValidTo
EXPORT bool VerifyCurrentDate()
const OTIdentifier & GetAssetID() const
static EXPORT Purse * PurseFactory(OTString strInput)
EXPORT bool SaveContractRaw(OTString &strOutput) const
OTSymmetricKey * m_pSymmetricKey
time64_t OTTimeGetTimeFromSeconds(int64_t seconds)
EXPORT void Concatenate(const char *arg,...)
EXPORT bool WriteArmoredString(OTString &strOutput, const std::string str_type, bool bEscaped=false) const
const OTASCIIArmor & GetSpendable() const
EXPORT void ReleaseSignatures()
EXPORT bool Exists() const
static EXPORT std::shared_ptr< OTCachedKey > It(OTIdentifier *pIdentifier=nullptr)
EXPORT void SetString(const char *szString)
const OTIdentifier & GetServerID() const
EXPORT void Format(const char *fmt,...)
time64_t GetValidFrom() const
EXPORT bool Compare(const char *compare) const
virtual bool LoadContract()
EXPORT bool Seal_or_Encrypt(OTEnvelope &outputEnvelope, const OTString &strInput, const OTString *pstrDisplay=nullptr)
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
EXPORT std::shared_ptr< OTCachedKey > GetInternalMaster()
time64_t OTTimeGetCurrentTime()
EXPORT Token * Peek(OTNym_or_SymmetricKey theOwner) const
EXPORT std::string QueryPlainString(std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
int64_t GetDenomination() const
EXPORT void Release_Purse()
OTString m_strContractType
EXPORT bool SerializeTo(OTPayload &theOutput) const
#define OT_ASSERT_MSG(x, s)
OTLOG_IMPORT OTLogStream otInfo
std::shared_ptr< OTCachedKey > m_pCachedKey
bool m_bPasswordProtected
EXPORT time64_t GetLatestValidFrom() const
EXPORT void ReleaseTokens()
OTStringXML m_xmlUnsigned
EXPORT bool Merge(const OTPseudonym &theSigner, OTNym_or_SymmetricKey theOldNym, OTNym_or_SymmetricKey theNewNym, Purse &theNewPurse)
static EXPORT const OTString & Purse()
void RecalculateExpirationDates(OTNym_or_SymmetricKey &theOwner)
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
EXPORT bool ReassignOwnership(OTNym_or_SymmetricKey &oldOwner, OTNym_or_SymmetricKey &newOwner)
virtual EXPORT bool SignContract(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
OTLOG_IMPORT OTLogStream otErr
EXPORT time64_t GetEarliestValidTo() const
EXPORT bool SavePurse(const char *szServerID=nullptr, const char *szUserID=nullptr, const char *szAssetTypeID=nullptr)
virtual EXPORT void Release()
EXPORT bool Exists(std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
EXPORT bool LoadPurse(const char *szServerID=nullptr, const char *szUserID=nullptr, const char *szAssetTypeID=nullptr)
static EXPORT Purse * LowLevelInstantiate(const OTString &strFirstLine)
EXPORT bool Contains(const char *compare) const
static EXPORT Token * TokenFactory(OTString strInput)
EXPORT bool IsEmpty() const
int64_t OTTimeGetSecondsFromTime(time64_t time)
EXPORT bool LoadContractFromString(const OTString &theStr)
virtual EXPORT void Release()
EXPORT bool GetNymID(OTIdentifier &theOutput) const
EXPORT bool GenerateInternalKey()
dequeOfTokens m_dequeTokens
virtual EXPORT void Release()
EXPORT bool Open_or_Decrypt(const OTEnvelope &inputEnvelope, OTString &strOutput, const OTString *pstrDisplay=nullptr)
EXPORT bool IsEmpty() const
virtual void UpdateContents()
const OTIdentifier & GetServerID() const
EXPORT Token * Pop(OTNym_or_SymmetricKey theOwner)