3isenHeim
3isenHeim

Reputation: 243

SecByteBlock to string conversion errors

I have to send a randomly generated number (rng) within a packet, and, thus, have to convert a SecByteBlock. I use libcrafter to put rng array into a RawLayer packet.

I followed this answer; but it gets me an invalid conversion error.

Here's the code I use:

AutoSeededRandomPool prng;
SecByteBlock rng1;
prng.GenerateBlock( rng1, rng1.size() );

string rng1_str(reinterpret_cast<char const*>(rng1));

std::string rng1_str = std::string(rng1.data(), rng1.size());

Crafter::RawLayer number(rng1_str);

The two ideas don't work, both give me:

error: invalid conversion from ‘CryptoPP::AllocatorWithCleanup<unsigned char>::pointer {aka unsigned char*}’
to ‘const char*’ [-fpermissive]
std::string rng1_str = std::string(rng1.data(), rng1.size());

Since the RawLayer accepts as constructor a std::string or a const byte*, I'd like to convert the SecBlockByte into one of these two formats...

Upvotes: 0

Views: 638

Answers (2)

jww
jww

Reputation: 102376

The output of the PRNG likely has an embedded NULL, so you can't operate on its data with customary C-string operations. That means the first statement is probably wrong.

string rng1_str(reinterpret_cast<char const*>(rng1));

std::string rng1_str = std::string(rng1.data(), rng1.size());

I'm not sure what you are doing with the second statement, but it needs to be cast just like the first one (and you can do away with the assignment):

std::string rng1_str(reinterpret_cast<const char*>(rng1.data()), rng1.size());

Since you said you "the RawLayer accepts as constructor a std::string or a const byte*", you might try:

SecByteBlock rng(16);
prng.GenerateBlock( rng, rng.size() );

Crafter::RawLayer number( rng.data(), rng.size() );

Also, be sure to size the SecByteBlock. A raw declaration of one is a 0-sized array with no memory block backing it. That is, rng.size() will be 0 with just the following:

SecByteBlock rng;

You can also do the following:

SecByteBlock rng;
// Make it 16-bytes in size, memory uninitialized
rng.New(16);

Or:

SecByteBlock rng;
// Make it 16-bytes in size, memory initialized to 0
rng.CleanNew(16);

If you want to get really fancy and avoid the runtime allocation of the memory block, then use a FixedSizeSecBlock:

FixedSizeSecBlock<byte, 16> rng;

But this is a more advanced technique, so don't get bogged down with it.


I find C/C++ unwillingness to automatically convert between a signed char and an unsigned char very annoying because its all just 8-bit binary data to me (I understand the need for the language rules). But I think its ridiculous I need a reinterpret_cast rather than a static_cast.

Upvotes: 1

3isenHeim
3isenHeim

Reputation: 243

As the aim was to put the SecByteBlock into a Crafter::RawLayer, I simply had to cast it into a const byte*...

The following lines do the thing.

SecByteBlock rng1;
prng.GenerateBlock( rng1, rng1.size() );

Crafter::RawLayer number(reinterpret_cast<const byte*>(rng1.data()), rng1.size());

Upvotes: 0

Related Questions