On Wednesday, 24 August 2016 00:02:43 UTC+1, Jeffrey Walton wrote:
>
>
>
> On Tuesday, August 23, 2016 at 11:18:23 AM UTC-4, Andrew Marlow wrote:
>>
>> Hello everyone,
>>
>> I have a function to decrypt a string using cryptopp 563. It is quite old 
>> code that has been working for ages on linux and windows. But recently I 
>> ran the unit test for the first time on solaris 10. It core dumped. The 
>> stack trace is shown below. CountWords has reg.m_ptr as null even though 
>> the size is non-null. Is this an internal error? Perhaps it should return 
>> zero if the reg.m_ptr is zero. Not sure. Anyhow, the stack trace shows that 
>> the Integer object is returned from RSAFunction::PreimageBound, which 
>> returns the private data member m_n. This is created using the default 
>> ctor. The comment in integer.h says this ctor creates the zero integer. 
>> Looking at the code of the ctor it seems ok so it seems to me that m_n must 
>> have been re-assigned to an Integer with m_ptr as null.
>>
>> =>[1] CryptoPP::CountWords(X = (nil), N = 81U), line 11 in "words.h"
>>   [2] CryptoPP::Integer::WordCount(this = 0x1085f7a68), line 3106 in 
>> "integer.cpp"
>>   [3] CryptoPP::Integer::Integer(this = 0xffffffff7fffd328, t = CLASS), 
>> line 2828 in "integer.cpp"
>>   [4] CryptoPP::RSAFunction::PreimageBound(this = 0x1085f7a50), line 42 
>> in "rsa.h"
>>   [5] 
>> CryptoPP::NameValuePairs::GetValue<CryptoPP::InvertibleRSAFunction>(this = 
>> 0xffffffff7fffd328, name = 0x1085f7a50 
>> "ThisObject:CryptoPP::InvertibleRSAFunction", value = CLASS), line 321 in 
>> "cryptlib.h"
>>   [6] 
>> CryptoPP::NameValuePairs::GetThisObject<CryptoPP::InvertibleRSAFunction>(this
>>  
>> = 0xffffffff7fffd328, object = CLASS), line 299 in "cryptlib.h"
>>   [7] 
>> CryptoPP::AssignFromHelperClass<CryptoPP::InvertibleRSAFunction,CryptoPP::RSAFunction>::AssignFromHelperClass(this
>>  
>> = 0xffffffff7fffc888, pObject = 0xffffffff7fffcf98, source = CLASS), line 
>> 260 in "algparam.h"
>>   [8] 
>> CryptoPP::AssignFromHelper<CryptoPP::RSAFunction,CryptoPP::InvertibleRSAFunction>(pObject
>>  
>> = 0xffffffff7fffcf98, source = CLASS, dummy = (nil)), line 306 in 
>> "algparam.h"
>>   [9] CryptoPP::InvertibleRSAFunction::AssignFrom(this = 
>> 0xffffffff7fffcf98, source = CLASS), line 289 in "rsa.cpp"
>>   [10] 
>> CryptoPP::PK_FinalTemplate<CryptoPP::TF_DecryptorImpl<CryptoPP::TF_CryptoSchemeOptions<CryptoPP::TF_ES<CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>,CryptoPP::RSA,int>,CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>
>>  
>> > > >::PK_FinalTemplate(this = 0xffffffff7fffcf80, key = CLASS), line 1776 
>> in "pubkey.h"
>>   [11] decryptString(0xffffffff7fffd908, 0xffffffff7fffda58, 
>> 0xffffffff7fffda38, 0xffffffff4afb0010, 0xffffffff7fffd9c0, 0x0), at 
>> 0x104c6a4a4 
>>   [12] StringServicesTest::testDecryptString(0x108717ab0, 0x1, 0x1, 
>> 0x100, 0x10859dc00, 0x1085a40e0), at 0x101b1b0b8 
>>
>> There seems to be a logic error somewhere such that an invalid Integer 
>> object is created. When I hack CountWords to return zero if the array 
>> pointer is null I get a core dump in CopyWords where it tries to copy from 
>> a null array (using memcpy). If I put in another hack to make CopyWords a 
>> no-op when given a null input array then this avoids the crash but the 
>> decryption produces an empty string.
>>
>> I am using the oracle compiler sunCC version 12.4. It also core dumps on 
>> solaris 11.
>>
>
> We need to know the Crypto++ library version (5.6.3 ZIP, Master, etc). 
>

cryptopp 563 ZIP.
 

> We need to know how the library was built (Makefile, Cmake, custom build, 
> etc). 
>

 We have a makefile called makefile-solaris. I am not sure where it came 
from. It is attached.

We need to see the test program, how it was compiled, and how it was linked.
>

At last I have managed to reproduce the problem in a standalone test 
program, apmtest.cpp. It is attached.
 

>
> The reason is: I don't think think you have a trivial error. I'm leaning 
> towards either a memory problem from a library; or a static initialization 
> problem.
>
> For completeness, we are actively testing Solaris i86pc (both i386 and 
> x86_64) under Solaris Studio 12.2 through 12.5. In our test 
> environment/clean room, we don't experience the crash.
>

Maybe the problem is confined to SPARC. I have not tried it on my SPARC 
machine at home yet. It is a cheap machine I picked up on ebay for 200 
pounds.
 

>
> Jeff
>

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Attachment: makefile-solaris
Description: Binary data

#include <string>
#include <stdexcept>
#include <sstream>

//Cryptopp include files
#include "rsa.h"
#include "aes.h"
#include "base64.h"
#include "default.h"
#include "files.h"
#include "time.h"
#include "randpool.h"
#include "algparam.h"
#include "filters.h"

void replaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace)
{
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

bool decodeBase64(const std::string& input, unsigned char* pData, unsigned int& len)
{
    CryptoPP::Base64Decoder decoder;
    size_t inLen = input.length();
    decoder.Put((byte*)input.data(), inLen);
    decoder.MessageEnd();

    CryptoPP::lword size = decoder.MaxRetrievable();
    if(size && size <= len)
    {
            len=(unsigned int)size;
            decoder.Get(pData, len);
            return true;
    }
    else
        return false;
}

std::string decryptString(const std::string& cipherText, const std::string& privateKeyFile)
{
    std::string result;

    try
    {
        CryptoPP::ByteQueue queue;
        CryptoPP::FileSource file(privateKeyFile.c_str(), true);
        file.TransferTo(queue);
        queue.MessageEnd();
        CryptoPP::RSA::PrivateKey rsaPrivate;
        rsaPrivate.Load(queue);

        std::string seed = CryptoPP::IntToString(time(NULL));
        seed.resize(16);
        CryptoPP::OFB_Mode<CryptoPP::AES>::Encryption rng;
        rng.SetKeyWithIV((byte *)seed.c_str(), 16, (byte *)seed.c_str());

        CryptoPP::RSAES_OAEP_SHA_Decryptor decryptor(rsaPrivate);

        std::string decryptedString;
        decryptedString.reserve(256);
        CryptoPP::StringSource(cipherText.c_str(), true,
                               new CryptoPP::Base64Decoder(new CryptoPP::PK_DecryptorFilter(rng, decryptor,
                                                                       new CryptoPP::StringSink(decryptedString))));

        //Need to strip off any terminating line feed or spaces
        std::string delimitedStr = decryptedString;
        replaceStringInPlace(delimitedStr, " ", "");
        replaceStringInPlace(delimitedStr, "\r", "");
        replaceStringInPlace(delimitedStr, "\n", "");
        result = delimitedStr;
    }
    catch(CryptoPP::Exception &e)
    {
        std::ostringstream ostr;
        ostr << "Unable to decrypt the following cipher text: " << cipherText << ". Exception: " << e.what();
        std::string m = ostr.str();
        throw std::runtime_error(m);
    }
    catch(std::exception &e)
    {
        std::ostringstream ostr;
        ostr << "Unable to decrypt the following cipher text: " << cipherText << ". Exception: " << e.what();
        std::string m = ostr.str();
        throw std::runtime_error(m);
    }

    return result;
}

void testDecryptString()
{
    std::string password = "EypPI030k4sZYc86pD4glRIkWTb+bPyt3xvRajlsJCKN8EAbuaJJx4dq9tEd5t1c"
                         "oU9jDyKQnWPcoQlSMboMBIZ8algKAL47CVxN8SzDD8FfLK9Jxk5ih7yIEUbPeLDr"
                         "16FEhluOHMsIzgexEbhs2szmMEBRtyqh8JBeOfyXSZYvW7w9Bnf0aHJnth43zaDa"
                         "Jn29/7JuMd2j4sHHD9qfoY/8pM9SOKOva8NQGzKpJSUkYlWY/R+ycOFKtcr2x0H7"
                         "p2zyjhOO5v9jo3+uCGHOmWVJnKYzmtJqAw+7ndzdHawaAap1gMENgZm7k9tvE2oD"
                         "ABT5ICzr04AE7j7ZEwjMlg==";

    std::string base64EncodedPrivateKey =
              "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDD9YyGGTSwdFGcZyjG2uY1NcOW"
              "hvf7AHuTFPAdqhHLhqfWHtKM7AV2SQMrba546+l4dxXh+kMq901bDmA+vWuG2sU2UCs/EiXG2X3P"
              "gHuaMYucVzZHu9UWdiMAva7+vZde7zib6epUo/CblvuRlAOBoPud1GBb9pwlmdZz2Fpwrgd/dVDL"
              "eSLv7XVEnj1ks2hkGRN1veATIXmWeElLkF468y9AxFyrTk8ExiVEODIOtdRl/9C1Ktb5VllGB2D9"
              "17k+YbBhAn1aQSuCCD/fqy3Q1jDWZMI/IQyuP+FRBGmewkiHMV1nncEMIh/RqsiKuGO2rtDmI9b9"
              "bksB1X9Tu453AgMBAAECggEAIeRrXJopccd8ggeZluMvY86buII5i7Emrma1rPvIPiJZDwCfu/3q"
              "Z+3y3WUIAyQSamJ2Z3JIgbrqJzCSVueeHGHkMCOnhy4VWJIvX19CgYXGNtEisz96eHsQTMWB6c9S"
              "yfmoGddYTzFXoSF4+1HVVWtJeZ/M1rsNgLddzwWBhvFUyywnym/TBGhKwOQFqLqsmgufaVi/rAdt"
              "t3/FlnkkbS+d+A4J+m59xLG7lxkDwnpFzQKkNRuFFn7C62u/scaXgdPlSwyroHyTcMf8ZwkYq3kV"
              "I0mG+I9xKYfExfPT8f/AtaC2RMlk27xVxdwcAS5Fh0DP/T4tkWjhi24O+ODhOQKBgQD1//ctZO58"
              "EEoPoHIqL7wDQ/9frvvQ1zHGeRa5sld67QEiRQiSWwejxQ69rQi0BDpVasJBmw0y7BZEUZsaAYxx"
              "CzppxsvlpPGIaHF/cnzuHciV/sQMFjMRMFE2jjCFIzVLGmBC/Xg57bfVLeKwsM5JRA6z6kXVN8Aq"
              "qG1AhgplFQKBgQDL7NPThuRTh6+FgSXlnRNHqI2qW/NLUKT40D4ZxHp6DSX+Fa72GFhe+bbmv1m0"
              "7wp/Vhy3Mib8j8tmGSdM5BOalIIE7Tx41MRs41pVNyVyhnQanpAyN4KY7pZgMSQ07xobaMO8OWp8"
              "0TFpSHk1Bj4O2Y9N+CMNo3n6lIshQ4sgWwKBgQDF6KD+R0ZKT3yV59oRMIgNBIaOfyOeF5K2/zIW"
              "QXF5tvUDkhBcVpnl2qKKXIw073XSxGn2B/zta9xaKGEk4fwP8h2TfdkKLtIWkRhGlWAG3bVDX0xw"
              "AOgiuwGLZ4eHhRTaECVDn9I6oJIWEq1ew0+ix/sgKaj26bxTVV9X2r7AJQJ/BMeIL2z57PtBId/l"
              "A3yq9wL8TwHYsesx8qLu0avJMxMb0NixQRNQ/ujbYI0bjSINHO7nvWNvhnvYSIxOX3749qaEZZkp"
              "0asq72Jku5qPRh/gmL8eog6rAOqWm6qLLrJr6jiKXd76n/JHNjB8psF+stpmgW1PZQJv2W+h0yXC"
              "HQKBgQDonI6zcayQkeGGjhtcC6LG4SzswSOJyhBUDmzcIE+SuSo+vBZ8811Eo1vr2TS3EEunkAlo"
              "Y/k/Fe8ULw09F97kiCVF43QJsamxQyQTgv4HWs9FLf3Y587xlmcpIMDiPfl+ZhAMEObm9fjNcPxF"
              "oOkCrp2hkEb2dLoY5u/VRoS8ig==";

    unsigned int len = static_cast<unsigned int>(base64EncodedPrivateKey.length());
    unsigned char* base64decodedPrivateKey = new unsigned char[len];
    ::decodeBase64(base64EncodedPrivateKey, base64decodedPrivateKey, len);

    std::string privateKeyFileLocation = "tempPrivateKey";
    std::ofstream outfile;
    outfile.open(privateKeyFileLocation.c_str(), std::ios::out | std::ios::binary);
    outfile.write((const char*)base64decodedPrivateKey, len);
    outfile.close();

    delete [] base64decodedPrivateKey;

    std::string decryptedPassword = ::decryptString(password, privateKeyFileLocation);
    if (decryptedPassword != "gobbledegook")
    {
        std::cerr << "Error: decrypt failed.\n";
        return;
    }

    password += "gunk"; // to make it fail.
    decryptedPassword = ::decryptString(password, privateKeyFileLocation);

    if (decryptedPassword == "gobbledegook")
    {
        std::cerr << "Decrypt succeeded when it should not have.\n";
        return;
    }
}

int main(int argc, char* argv[])
{
    testDecryptString();
    return 0;
}

Reply via email to