Reputation: 243
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
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
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