Beispiel #1
0
// Base64-decode an decompress
bool OTASCIIArmor::GetString(String& strData,
                             bool bLineBreaks) const // bLineBreaks=true
{
    strData.Release();

    if (GetLength() < 1) {
        return true;
    }

    size_t outSize = 0;
    uint8_t* pData = App::Me().Crypto().Util().Base64Decode(Get(), &outSize, bLineBreaks);

    if (!pData) {
        otErr << __FUNCTION__ << "Base64Decode fail\n";
        return false;
    }

    std::string str_decoded(pData, pData + outSize);

    delete[] pData;

    std::string str_uncompressed;
    try {
        str_uncompressed = decompress_string(str_decoded);
    }
    catch (const std::runtime_error&) {
        otErr << __FUNCTION__ << ": decompress failed\n";
        return false;
    }

    strData.Set(str_uncompressed.c_str(), str_uncompressed.length());

    return true;
}
/// if we pack, compress, encode on the way in, that means, therefore, we
/// need to decode, uncompress, then unpack on our way out. Right?
///
/// This function will base64-DECODE the string contents, then uncompress them using
/// zlib, and then unpack the result using whatever is the default packer (MsgPack, Protobuf, etc).
/// 
/// I originally added compression because message sizes were too big. Now I'm adding packing, 
/// to solve any issues of binary compatibility across various platforms.
//
bool OTASCIIArmor::GetAndUnpackString(OTString & strData, bool bLineBreaks) const //bLineBreaks=true
{	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	strData.Release();
	
	if (GetLength() < 1)
	{
		return true;
	}
	// --------------------------------------------------------------
	pData = OTCrypto::It()->Base64Decode(this->Get(), &outSize, bLineBreaks);
//	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
        
        std::string str_decoded( pData, pData+outSize );
        
        delete [] pData; pData=NULL;

        std::string str_uncompressed = decompress_string( str_decoded );
		// ---------------------------------------
		// PUT THE PACKED BUFFER HERE, AND UNPACK INTO strData
		// --------------------------------------------------------
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // This will make sure buffer is deleted later.
		      
        pBuffer->SetData(reinterpret_cast<const uint8_t *>(str_uncompressed.data()), str_uncompressed.size());
		// -----------------------------
		OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING));
		OT_ASSERT(NULL != pOTDBString);
		OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // clean up this string.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pOTDBString);
		// ----------------------
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking string in OTASCIIArmor::GetAndUnpackString.\n");
			
			return false;
		}
		// --------------------------------------------------------
		// This enforces the null termination. (using the 2nd parameter as nEnforcedMaxLength)
		strData.Set(pOTDBString->m_string.c_str(), static_cast<uint32_t> (pOTDBString->m_string.length()));
		
		return true;
	}
	else 
	{
		OTLog::Error("OTASCIIArmor::GetAndUnpackString: NULL pData while base64-decoding pData.\n");
		return false;
	}
}
void DlgDecrypt::on_pushButtonDecrypt_clicked()
{
    bool bSuccessDecrypting = false;
    bool bSuccessVerifying  = false;

    QString qstrNymWhoDecrypted;
    QString qstrNymWhoVerified;

    QString qstrText = ui->plainTextEdit->toPlainText().trimmed();
    // --------------------------------
    if (qstrText.isEmpty())
    {
        // pop up a message box warning that the input text is empty.
        //
        QMessageBox::warning(this, tr("Ciphertext is Empty"),
                             tr("Please paste something to be decrypted/verified."));
        return;
    }
    // --------------------------------
    else //qstrText not empty.
    {
        std::string str_input(qstrText.toStdString());
        opentxs::String    strInput (str_input.c_str());

        if (strInput.Exists())
        {
            if (strInput.Contains("-----BEGIN OT ARMORED ENVELOPE-----"))
            {
                opentxs::OTEnvelope theEnvelope;

                if (theEnvelope.SetFromBookendedString(strInput))
                {
                    opentxs::String strOutput;
                    // -------------------------
                    // First we'll try the default nym, if one is available.
                    //
                    QString qstrTempID = Moneychanger::It()->get_default_nym_id();

                    if (!qstrTempID.isEmpty()) // Default Nym IS available.
                    {
                        std::string  str_nym    (qstrTempID.toStdString());
                        opentxs::String     strNym     (str_nym.c_str());
                        opentxs::Identifier nym_id     (strNym);

                        if (!nym_id.IsEmpty())
                        {
                            opentxs::OTPasswordData thePWData("Recipient passphrase");

                            opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadPrivateNym(nym_id,
                                                                                   false, //bChecking=false
                                                                                   __FUNCTION__,
                                                                                   &thePWData);
                            if (NULL != pNym)
                            {
                                if (theEnvelope.Open(*pNym, strOutput) && strOutput.Exists())
                                {
                                    bSuccessDecrypting = true;
                                    qstrNymWhoDecrypted = qstrTempID;

                                    strInput  = strOutput;
                                    str_input = strInput.Get();
                                    qstrText  = QString::fromStdString(str_input);
                                }
                            }
                        }
                    }
                    // ------------
                    if (!bSuccessDecrypting) // Default nym is NOT available. Okay let's loop through all the Nyms in the wallet then, and try then all...
                    {
                        const int32_t nym_count = opentxs::OTAPI_Wrap::It()->GetNymCount();
                        // -----------------------------------------------
                        for (int32_t ii = 0; ii < nym_count; ++ii)
                        {
                            //Get OT Nym ID
                            QString OT_nym_id = QString::fromStdString(opentxs::OTAPI_Wrap::It()->GetNym_ID(ii));

                            if (!OT_nym_id.isEmpty())
                            {
                                std::string         str_nym    (OT_nym_id.toStdString());
                                opentxs::String     strNym     (str_nym.c_str());
                                opentxs::Identifier nym_id     (strNym);

                                if (!nym_id.IsEmpty())
                                {
                                    opentxs::OTPasswordData thePWData("Recipient passphrase");

                                    opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadPrivateNym(nym_id,
                                                                                           false, //bChecking=false
                                                                                           "DlgEncrypt::on_pushButtonDecrypt_clicked",
                                                                                           &thePWData);
                                    if (NULL != pNym)
                                    {
                                        // Okay there is a private key available for this Nym, so let's
                                        // try to open the envelope using it.
                                        //
                                        if (theEnvelope.Open(*pNym, strOutput) && strOutput.Exists())
                                        {
                                            bSuccessDecrypting = true;
                                            qstrNymWhoDecrypted = OT_nym_id;

                                            strInput  = strOutput;
                                            str_input = strInput.Get();
                                            qstrText  = QString::fromStdString(str_input);

                                            break;
                                        }
                                    }
                                }
                                // ------------
                            }
                        } // for
                    } // else default nym not available.
                    // -----------------------
                    if (!bSuccessDecrypting)
                    {
                        QMessageBox::warning(this, tr("Failed Decrypting"),
                                             tr("None of the identities in your wallet (including your default identity, "
                                                "if applicable) were able to open this message."));
                        return;

                    }
                    // -----------------------
                } // if (theEnvelope.SetFromBookendedString(strInput))

            } // if (strInput.Contains("-----BEGIN OT ARMORED ENVELOPE-----"))
            // --------------------------------------------
            // This call to DecodeIfArmored is what handles the: "-----BEGIN OT ARMORED ... -----"

            if (strInput.DecodeIfArmored(false)) // bEscapedIsAllowed=true by default.
            {
                std::string str_decoded(strInput.Get());
                QString qstrDecoded(QString::fromStdString(str_decoded));

                if (!qstrDecoded.isEmpty())
                    qstrText = qstrDecoded;
                // -----------------------------------
                // At this point, we know it's been decrypted, if applicable, and it's been
                // de-armored, if applicable. So now we check to see if it's a signed file.
                //
                if (strInput.Contains("-----BEGIN SIGNED FILE-----"))
                {
                    opentxs::OTSignedFile theSignedFile;

                    if (theSignedFile.LoadContractFromString(strInput))
                    {
                        opentxs::String strSignerNymID = theSignedFile.GetSignerNymID();
                        std::string str_signer_nym(strSignerNymID.Get());
                        QString qstrSignerNym(QString::fromStdString(str_signer_nym));

                        if (!str_signer_nym.empty())
                        {
                            opentxs::OTPasswordData thePWData("Sometimes need to load private part of nym in order to use its public key. (Fix that!)");
                            opentxs::Identifier id_signer_nym(strSignerNymID);
                            const opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadNym(id_signer_nym,
                                                                                   false, //bChecking=false
                                                                                   __FUNCTION__,
                                                                                   &thePWData);
                            if (NULL != pNym)
                            {
                                if (theSignedFile.VerifySignature(*pNym, &thePWData))
                                {
                                    bSuccessVerifying = true;
                                    qstrNymWhoVerified = qstrSignerNym;

                                    opentxs::String strContents = theSignedFile.GetFilePayload();

                                    if (strContents.Exists())
                                    {
                                        strInput  = strContents;
                                        str_input = strInput.Get();
                                        qstrText  = QString::fromStdString(str_input);
                                    }
                                } // signature verified
                            } // pNym exists
                        } // if str_signer_nym exists
                    } // signed file: load contract from string.
                } // "BEGIN SIGNED FILE"
            } // Decode If Armored.
            // -----------------------------------------------
            // if qstrText still contains something, pop up a dialog to display the result to the user.
            //
            if (!qstrText.isEmpty())
            {
                MTNameLookupQT theLookup;
                QString qstrNymWhoDecryptedName(""), qstrNymWhoVerifiedName("");

                if (!qstrNymWhoDecrypted.isEmpty())
                    qstrNymWhoDecryptedName = QString::fromStdString(theLookup.GetNymName(qstrNymWhoDecrypted.toStdString(), ""));
                if (!qstrNymWhoVerified.isEmpty())
                    qstrNymWhoVerifiedName = QString::fromStdString(theLookup.GetNymName(qstrNymWhoVerified.toStdString(), ""));
                // -------------------------------
                if (qstrNymWhoDecryptedName.isEmpty())
                    qstrNymWhoDecryptedName = qstrNymWhoDecrypted;
                else if (qstrNymWhoDecryptedName != qstrNymWhoDecrypted)
                    qstrNymWhoDecryptedName += QString(" (%1)").arg(qstrNymWhoDecrypted);
                // -------------------------------
                if (qstrNymWhoVerifiedName.isEmpty())
                    qstrNymWhoVerifiedName = qstrNymWhoVerified;
                else if (qstrNymWhoVerifiedName != qstrNymWhoVerified)
                    qstrNymWhoVerifiedName += QString(" (%1)").arg(qstrNymWhoVerified);
                // -------------------------------
                QString qstrType("Output:");

                if (bSuccessVerifying)
                {
                    qstrType = QString("%1: %2").arg(tr("Verified signature by Nym")).arg(qstrNymWhoVerifiedName);
                }
                // -----------
                if (bSuccessDecrypting)
                {
                    if (bSuccessVerifying)
                        qstrType = QString("%1: %2\n%3: %4").arg(tr("Decrypted using Nym")).arg(qstrNymWhoDecryptedName).arg(tr("Verified signature by Nym")).arg(qstrNymWhoVerifiedName);
                    else
                        qstrType = QString("%1: %2").arg(tr("Decrypted using Nym")).arg(qstrNymWhoDecryptedName);
                }
                // -----------
                QString qstrSubTitle(tr("Be sure to copy it somewhere before closing this dialog."));
                // -----------
                // Pop up the result dialog.
                //
                DlgExportedToPass dlgExported(this, qstrText,
                                              qstrType,
                                              qstrSubTitle, false);
                dlgExported.exec();
            } // if (!qstrText.isEmpty())
        } // if strInput
    } //qstrText not empty
}