bool LegacySymmetric::Decrypt(
    const api::Crypto& crypto,
    const String& strKey,
    String& strCiphertext,
    String& strOutput,
    const String& pstrDisplay,
    const OTPassword* pAlreadyHavePW)
{

    if (!strKey.Exists()) {
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Nonexistent: The symmetric key. Please supply. (Failure).")
            .Flush();
        return false;
    }

    implementation::LegacySymmetric theKey(crypto);

    if (!theKey.SerializeFrom(strKey)) {
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Failed trying to load symmetric key from "
            "string. (Returning false).")
            .Flush();
        return false;
    }

    // By this point, we know we have a ciphertext envelope and a symmetric Key.
    //
    return Decrypt(
        theKey, strCiphertext, strOutput, pstrDisplay, pAlreadyHavePW);
}
bool LegacySymmetric::CreateNewKey(
    const api::Crypto& crypto,
    String& strOutput,
    const String& pstrDisplay,
    const OTPassword* pAlreadyHavePW)
{
    std::unique_ptr<OTPassword> pPassUserInput;

    if (nullptr == pAlreadyHavePW) {
        const char* szDisplay = "Creating new symmetric key.";
        const auto strDisplay = String::Factory(
            (!pstrDisplay.Exists()) ? szDisplay : pstrDisplay.Get());

        pPassUserInput.reset(GetPassphraseFromUser(
            strDisplay, true));  // bAskTwice=false by default.
    } else
        pPassUserInput.reset(new OTPassword(*pAlreadyHavePW));

    bool bSuccess = false;

    if (pPassUserInput)  // Success retrieving the passphrase from the
                         // user. (Now let's generate the key...)
    {
        LogDebug(OT_METHOD)(__FUNCTION__)(
            ": Calling LegacySymmetric theKey.GenerateKey()...")
            .Flush();
        implementation::LegacySymmetric theKey(crypto, *pPassUserInput);
        const bool bGenerated = theKey.IsGenerated();

        if (bGenerated && theKey.SerializeTo(strOutput))
            bSuccess = true;
        else
            LogDetail(OT_METHOD)(__FUNCTION__)(
                ": Sorry, unable to generate key. (Failure).")
                .Flush();
    } else
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Sorry, unable to retrieve password from user. (Failure).")
            .Flush();

    return bSuccess;
}
// static
bool LegacySymmetric::Encrypt(
    const LegacySymmetric& theKey,
    const String& strPlaintext,
    String& strOutput,
    const String& pstrDisplay,
    bool bBookends,
    const OTPassword* pAlreadyHavePW)
{
    if (!theKey.IsGenerated()) {
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Failure: theKey.IsGenerated() was false. (The calling "
            "code probably should have checked that key already...).")
            .Flush();
        return false;
    }

    if (!strPlaintext.Exists()) {
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Plaintext is empty. Please supply. (Failure).")
            .Flush();
        return false;
    }

    // By this point, we know we have a plaintext and a symmetric Key.
    //
    std::unique_ptr<OTPassword> pPassUserInput;

    if (nullptr == pAlreadyHavePW) {
        const char* szDisplay = "Password-protecting a plaintext.";
        const auto strDisplay = String::Factory(
            (!pstrDisplay.Exists()) ? szDisplay : pstrDisplay.Get());

        pPassUserInput.reset(
            GetPassphraseFromUser(strDisplay));  // bAskTwice=false
                                                 // by default.
    } else
        pPassUserInput.reset(new OTPassword(*pAlreadyHavePW));

    auto ascOutput = Armored::Factory();
    bool bSuccess = false;

    if (nullptr != pPassUserInput)  // Success retrieving the passphrase from
                                    // the user. (Now let's encrypt...)
    {
        OTEnvelope theEnvelope;

        if (theEnvelope.Encrypt(
                strPlaintext,
                const_cast<LegacySymmetric&>(theKey),
                *pPassUserInput) &&
            theEnvelope.GetCiphertext(ascOutput)) {
            bSuccess = true;

            if (bBookends) {
                return ascOutput->WriteArmoredString(
                    strOutput,
                    "SYMMETRIC MSG",  // todo hardcoding.
                    false);           // bEscaped=false
            } else {
                strOutput.Set(ascOutput->Get());
            }
        } else {
            LogDetail(OT_METHOD)(__FUNCTION__)(
                ": Failed trying to encrypt. (Sorry).")
                .Flush();
        }
    } else
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Sorry, unable to retrieve passphrase from user. (Failure).")
            .Flush();

    return bSuccess;
}
bool LegacySymmetric::Decrypt(
    const LegacySymmetric& theKey,
    const String& strCiphertext,
    String& strOutput,
    const String& pstrDisplay,
    const OTPassword* pAlreadyHavePW)
{
    if (!theKey.IsGenerated()) {
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Failure: theKey.IsGenerated() was false. (The calling "
            "code probably should have checked for that...).")
            .Flush();
        return false;
    }

    auto ascArmor = Armored::Factory();
    const bool bLoadedArmor = Armored::LoadFromString(
        ascArmor, strCiphertext);  // str_bookend="-----BEGIN" by default

    if (!bLoadedArmor || !ascArmor->Exists()) {
        otErr << __FUNCTION__ << ": Failure loading ciphertext envelope:\n\n"
              << strCiphertext << "\n\n";
        return false;
    }

    // By this point, we know we have a ciphertext envelope and a symmetric Key.
    //
    std::unique_ptr<OTPassword> pPassUserInput;

    if (nullptr == pAlreadyHavePW) {
        const char* szDisplay = "Decrypting a password-protected ciphertext.";
        const auto strDisplay = String::Factory(
            (!pstrDisplay.Exists()) ? szDisplay : pstrDisplay.Get());

        pPassUserInput.reset(
            GetPassphraseFromUser(strDisplay));  // bAskTwice=false
                                                 // by default.
    }

    bool bSuccess = false;

    if (pPassUserInput ||  // Success retrieving the passphrase from the
        pAlreadyHavePW)    // user, or passphrase was provided out of scope.
    {
        OTEnvelope theEnvelope(ascArmor);

        if (theEnvelope.Decrypt(
                strOutput,
                theKey,
                pPassUserInput ? *pPassUserInput : *pAlreadyHavePW)) {
            bSuccess = true;
        } else {
            LogDetail(OT_METHOD)(__FUNCTION__)(
                ": Failed trying to decrypt. (Sorry).")
                .Flush();
        }
    } else
        LogDetail(OT_METHOD)(__FUNCTION__)(
            ": Sorry, unable to retrieve passphrase from user. (Failure).")
            .Flush();

    return bSuccess;
}
Example #5
0
// return -1 if error, 0 if nothing, and 1 if the node was processed.
int32_t OTOffer::ProcessXMLNode(irr::io::IrrXMLReader*& xml)
{
    int32_t nReturnVal = 0;

    // Here we call the parent class first.
    // If the node is found there, or there is some error,
    // then we just return either way.  But if it comes back
    // as '0', then nothing happened, and we'll continue executing.
    //
    // -- Note you can choose not to call the parent if
    // you don't want to use any of those xml tags.
    // As I do below, in the case of OTAccount.
    // if (nReturnVal = Contract::ProcessXMLNode(xml))
    //    return nReturnVal;

    if (!strcmp("marketOffer", xml->getNodeName())) {
        m_strVersion = xml->getAttributeValue("version");

        String strIsSelling;
        strIsSelling = xml->getAttributeValue("isSelling");
        if (strIsSelling.Compare("true"))
            m_bSelling = true;
        else
            m_bSelling = false;

        m_strContractType.Set((m_bSelling ? "ASK" : "BID"));

        const String strNotaryID(xml->getAttributeValue("notaryID")),
            strInstrumentDefinitionID(
                xml->getAttributeValue("instrumentDefinitionID")),
            strCurrencyTypeID(xml->getAttributeValue("currencyTypeID"));

        const Identifier NOTARY_ID(strNotaryID),
            INSTRUMENT_DEFINITION_ID(strInstrumentDefinitionID),
            CURRENCY_TYPE_ID(strCurrencyTypeID);

        SetNotaryID(NOTARY_ID);
        SetInstrumentDefinitionID(INSTRUMENT_DEFINITION_ID);
        SetCurrencyID(CURRENCY_TYPE_ID);

        const String strScale = xml->getAttributeValue("marketScale");
        const int64_t lScale =
            strScale.Exists() ? strScale.ToLong() : 0; // if it doesn't exist,
                                                       // the 0 here causes the
                                                       // below error to fire.

        if (!isPowerOfTen(lScale)) {
            otOut << "OTOffer::ProcessXMLNode: Failure: marketScale *must* be "
                     "1, or a power of 10. Instead I got: " << lScale << ".\n";
            return (-1);
        }
        else
            SetScale(lScale);

        const String strPriceLimit = xml->getAttributeValue("priceLimit");
        const int64_t lPriceLimit = strPriceLimit.Exists()
                                        ? strPriceLimit.ToLong()
                                        : 0; // if it doesn't exist, the 0 here
                                             // causes the below error to fire.

        // NOTE: Market Orders (new) have a 0 price, so this error condition was
        // changed.
        if (!strPriceLimit.Exists())
        //      if (lPriceLimit < 1)
        {
            otOut << "OTOffer::ProcessXMLNode: Failure: priceLimit *must* be "
                     "provided(" << lPriceLimit << ").\n";
            return (-1);
        }
        else
            SetPriceLimit(lPriceLimit);

        const String strTotal = xml->getAttributeValue("totalAssetsOnOffer");
        const int64_t lTotal =
            strTotal.Exists() ? strTotal.ToLong() : 0; // if it doesn't exist,
                                                       // the 0 here causes the
                                                       // below error to fire.
        if (lTotal < 1) {
            otOut << "OTOffer::ProcessXMLNode: Failure: totalAssetsOnOffer "
                     "*must* be larger than 0. Instead I got: " << lTotal
                  << ".\n";
            return (-1);
        }
        else
            SetTotalAssetsOnOffer(lTotal);

        const String strFinished = xml->getAttributeValue("finishedSoFar");
        const int64_t lFinished = strFinished.Exists()
                                      ? strFinished.ToLong()
                                      : 0; // if it doesn't exist, the 0 here
                                           // causes the below error to fire.
        if (lFinished < 0) {
            otOut << "OTOffer::ProcessXMLNode: Failure: finishedSoFar *must* "
                     "be 0 or larger. Instead I got: " << lFinished << ".\n";
            return (-1);
        }
        else
            SetFinishedSoFar(lFinished);

        const String strMinInc = xml->getAttributeValue("minimumIncrement");
        // if it doesn't exist, the 0 here causes the below error to fire.
        const int64_t lMinInc = strMinInc.Exists() ? strMinInc.ToLong() : 0;

        if ((lMinInc < 1) || (lMinInc > lTotal)) // Minimum increment cannot
                                                 // logically be higher than the
                                                 // total assets on offer...
        {
            otOut << "OTOffer::ProcessXMLNode: Failure: minimumIncrement "
                     "*must* be 1 or larger, \n"
                     "and must also be less than the total assets on offer. "
                     "Instead I got: " << lMinInc << ".\n";
            return (-1);
        }
        else
            SetMinimumIncrement(lMinInc);

        const String strTransNum = xml->getAttributeValue("transactionNum");
        const int64_t lTransNum =
            strTransNum.Exists() ? strTransNum.ToLong() : 0;

        SetTransactionNum(lTransNum);

        const String str_valid_from = xml->getAttributeValue("validFrom");
        const String str_valid_to = xml->getAttributeValue("validTo");

        int64_t tValidFrom =
            str_valid_from.Exists() ? parseTimestamp(str_valid_from.Get()) : 0;
        int64_t tValidTo =
            str_valid_to.Exists() ? parseTimestamp(str_valid_to.Get()) : 0;

        if ((tValidTo < tValidFrom) && (tValidTo != 0)) {
            otOut << "OTOffer::" << __FUNCTION__ << ": Failure: validTo date ("
                  << tValidFrom << ") cannot be earlier than "
                                   "validFrom date (" << tValidTo << ").\n";
            return (-1);
        }

        SetValidFrom(OTTimeGetTimeFromSeconds(tValidFrom));
        SetValidTo(OTTimeGetTimeFromSeconds(tValidTo));

        otLog4 << "\n\nOffer. Transaction Number: " << m_lTransactionNum
               << "\n Valid From: " << tValidFrom << "\n Valid To: " << tValidTo
               << "\n"
                  " InstrumentDefinitionID: " << strInstrumentDefinitionID
               << "\n  CurrencyTypeID: " << strCurrencyTypeID
               << "\n NotaryID: " << strNotaryID
               << "\n"
                  " Price Limit: " << GetPriceLimit()
               << ",  Total Assets on Offer: " << GetTotalAssetsOnOffer()
               << ",  " << (m_bSelling ? "sold" : "bought")
               << " so far: " << GetFinishedSoFar() << "\n "
                                                       " Scale: " << GetScale()
               << ".   Minimum Increment: " << GetMinimumIncrement()
               << ".  This offer is a" << (m_bSelling ? "n ASK" : " BID")
               << ".\n";

        nReturnVal = 1;
    }

    return nReturnVal;
}