I have this strange error in botan 1.10.9.
When I want to store the private key bytes vector and the publics key byte vector i get an std::bad_alloc error. Could it be that is not possible to initialize a std::vector from the SecureVector from botan?
Botan::LibraryInitializer init;
Botan::AutoSeeded_RNG rng;
rng.reseed(10096);
Botan::RSA_PrivateKey rsaPrivate(rng, 1024);
std::vector<unsigned char> privateArray(rsaPrivate.pkcs8_private_key().begin(), rsaPrivate.pkcs8_private_key().end());
std::vector<unsigned char> publicArray(rsaPrivate.x509_subject_public_key().begin(), rsaPrivate.x509_subject_public_key().end());
If i encode the keys, then the operation works fine:
Botan::SecureVector<Botan::byte> publicBytes = std::move(Botan::X509::BER_encode(rsaPrivate));
Botan::SecureVector<Botan::byte> privateBytes = std::move(Botan::PKCS8::BER_encode(rsaPrivate, rng, info.passphrase()));
std::vector<unsigned char> publicArray(publicBytes.begin(), publicBytes.end());
std::vector<unsigned char> privateArray(privateBytes.begin(), privateBytes.end());
Any ideas why this could be happening? The weird thing is that if i remove one of the vectors initialization, soooooometimes it works but most of the time i get the crash.
A little bit old of a reply, but for Botan the unlock function turns a Botan::secure_vector<T> into a std::vector<T>.
Related
The compiler wants my lvalue to be a rvalue reference and I dont see why.
My questions are:
Why is "dataLen" const, even though it was declared non const and the lambda is told to catch by reference as default?
Why does the compiler try to convert to rvalue reference "unsigned __int64 &&", even though it was declared "unsigned long long" (no rvalue reference) for tupleByteVector_content?
I think it is because of the lambda capture, but please see this simplified workflow below:
void read_socket()
{
std::vector<std::tuple<unsigned long long, std::vector<unsigned char>>> tupleByteVector_content;
read_socket_readSome(tupleByteVector_content, [this, &tupleByteVector_content]() {
//use tuple vector
});
}
//catch the tuple vector by reference
void read_socket_readSome(std::vector<std::tuple<unsigned long long, const std::shared_ptr<Session>& session, std::vector<unsigned char>>> & tupleByteVector_content, std::function<void()> && continueReadFunction)
{
//Read data length from a asio socket
std::shared_ptr<asio::streambuf> len_buffer = std::make_shared<asio::streambuf>();
asio::async_read(session->connection->socket->next_layer(), *len_buffer, asio::transfer_exactly(1), [&,
this, session, len_buffer, tupleByteVector_content, continueReadFunction](const error_code& ec, std::size_t bytes_transferred) {
//the first value I want to save
unsigned long long dataLen = BytesToLength(len_buffer);
//Read data from a asio socket
std::shared_ptr<asio::streambuf> data_buffer = std::make_shared<asio::streambuf>();
asio::async_read(session->connection->socket->next_layer(), *data_buffer, asio::transfer_exactly(dataLen), [&, this, dataLen, data_buffer, tupleByteVector_content, session, continueReadFunction](const error_code& ec, std::size_t bytes_transferred) {
//ERROR HERE: ----------->
std::tuple<unsigned long long, std::vector<unsigned char>> t =
std::make_tuple<unsigned long long, std::vector<unsigned char>>(
dataLen, // ERROR C2664, cant convert argument 1 from "const unsigned __int64" to "unsigned __int64 &&"
{ asio::buffers_begin(data_buffer->data()), asio::buffers_end(data_buffer->data()) });
//ERROR HERE: <-----------
tupleByteVector_content.push_back(t);
continueReadFunction();
});
});
}
EDIT:
I was able to compile this tuple:
std::tuple<unsigned long long, std::vector<unsigned char>> t = { dataLen, { asio::buffers_begin(data_buffer->data()), asio::buffers_end(data_buffer->data()) } };
But then the push_back to the vector gives the error:
error C2663: [...] ::push_back": for 2 overloads there is no conversion for the this-pointer (free translation into english from myself)
dataLen is treated as const because you capture it by value:
[&, this, dataLen,
^^^
By default function call operator generated for closure is marked as const, so inside const method you can only read data. Modifications are not allowed, unless you add mutable to definition of lambda.
When you use make_tuple you should rely on template argument deduction instead putting types in explicit way, as you did it. Short version of your issue:
int i;
std::tuple<int> t = std::make_tuple<int>(i);
i is named object, so it is lvalue. By make_tuple<int> you make make_tuple signature look like: make_tuple(int&&). This is the place where compiler complains, because i as lvalue cannot be bound to rvalue reference. With argument deduction, parameter of make_tuple is deduced to be: int&, and in this case i can be bound.
push_back on vector doesn't work, because again you captured vector by value. push_back modifies object, which is not allowed when calling on const object. You should capture it by reference.
For a research project, I have a long-running process that uses various buffers and stack variables. I'd like to be able to launch this process multiple times such that the physical addresses backing its heap, stack, code, and static variables are equal each time. I know the exact size of all of these variables, and the size of the heap and stack stay constant during execution. To help with this, I use some helper code to translate arbitrary virtual addresses in my program to their corresponding physical addresses (sourced from here):
struct pagemap
{
union status
{
struct present
{
unsigned long long pfn : 54;
unsigned char soft_dirty : 1;
unsigned char exclusive : 1;
unsigned char zeroes : 4;
unsigned char type : 1;
unsigned char swapped : 1;
unsigned char present : 1;
} present;
struct swapped
{
unsigned char swaptype : 4;
unsigned long long offset : 50;
unsigned char soft_dirty : 1;
unsigned char exclusive : 1;
unsigned char zeroes : 4;
unsigned char type : 1;
unsigned char swapped : 1;
unsigned char present : 1;
} swapped;
} status;
} __attribute__ ((packed));
unsigned long get_pfn_for_addr(void *addr)
{
unsigned long offset;
struct pagemap pagemap;
FILE *pagemap_file = fopen("/proc/self/pagemap", "rb");
offset = (unsigned long) addr / getpagesize() * 8;
if(fseek(pagemap_file, offset, SEEK_SET) != 0)
{
fprintf(stderr, "failed to seek pagemap to offset\n");
exit(1);
}
fread(&pagemap, 1, sizeof(struct pagemap), pagemap_file);
fclose(pagemap_file);
return pagemap.status.present.pfn;
}
unsigned long virt_to_phys(void *addr)
{
unsigned long pfn, page_offset, phys_addr;
pfn = get_pfn_for_addr(addr);
page_offset = (unsigned long) addr % getpagesize();
phys_addr = (pfn << PAGE_SHIFT) + page_offset;
return phys_addr;
}
So far, my methodology has only required that a specific buffer in my program is located at the same physical address for each run. For this, I was just able to exit and relaunch the process whenever the physical address for that buffer was wrong, and I would end up with the correct location relatively quickly each time. However, I'd like to extend my experiment to ensure that my process is loaded identically in physical memory between runs, and this try-and-restart method does not seem to work well for this. Ideally, I would like to be able to set apart some small number of physical page frames that can't be allocated to another process, or to the kernel itself. Then, I would pass a flag down to do_fork that notifies the kernel that this is my special process and to allocate specific page frames to it.
My questions are:
Is there any sort of isolation mechanism already built into the kernel that would let me set aside an exclusive physical memory space that I could launch my process in?
If not, what would be a starting point for modifying the kernel to support behavior like this?
Is there any other solution (not involving either of the two above) that I could use for my desired behavior?
This is something that the kernel, using virtual memory, is tasked to abstract from you, so I'm not sure it is even possible to do (without insane amounts of work).
May I ask what experiment requires this? Perhaps if you describe what you want to achieve, it is easier to offer advice.
Moving from Boost 1.54 to 1.55 I now get this error during compilation (VS2010):
void GzipDecompression::Decompress(const unsigned char * src, int length)
{
if(src)
{
// Create an input-stream source for the data buffer so we can used the boost filtering buffer
std::ifstream inputstream;
typedef boost::iostreams::basic_array_source<char> Device;
boost::iostreams::stream_buffer<Device> buffer((char *)src, length);
// Inflate using the GZIP filter
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(buffer);
// Get the result into a vector
boost::interprocess::basic_vectorstream<std::vector<char>> vectorStream;
copy(in, vectorStream);
std::vector<char> output(vectorStream.vector());
}
}
error C2243: 'type cast' : conversion from 'boost::interprocess::basic_vectorstream<CharVector> *' to 'volatile const std::basic_streambuf<_Elem,_Traits> *' exists, but is inaccessible c:\boost\boost_1_55_0\boost\iostreams\traits.hpp 57 1
It appears this is now failing:
boost::interprocess::basic_vectorstream<std::vector<char>> vectorStream;
What has changed so this doesn't compile?
Update After Reply: I've tried changing the output to this:
std::istream instream(&in);
typedef std::istream_iterator<char> istream_iterator;
typedef std::ostream_iterator<char> ostream_iterator;
std::vector<char> output;
std::copy(istream_iterator(instream), istream_iterator(), std::back_inserter(output));
But the output is different. Do I have to flush the stream or something?
Update2: Apparently the istream_iterator strips CR LF etc. Here is my working function
void GzipDecompression::Decompress(const unsigned char * src, int length)
{
if(src)
{
// Create an input-stream source for the data buffer so we can used the boost filtering buffer
std::ifstream inputstream;
typedef boost::iostreams::basic_array_source<char> Device;
boost::iostreams::stream_buffer<Device> buffer((char *)src, length);
// Inflate using the GZIP filter
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(buffer);
// Get the result into a vector
std::istream instream(&in);
typedef std::istreambuf_iterator<char> istreambuf_iterator;
std::vector<char> output;
std::copy(istreambuf_iterator(instream), istreambuf_iterator(), std::back_inserter(output));
}
}
Thanks
Of course the error doesn't emerge from the line you mention. Instead, it's generated deep in the template instantiations for copy_impl. The problem seems to be that Boost Iostreams tries to be smart about detecting when people use "raw buffers" as devices/streams.
The problem with that is that the Interprocess stream implementation (privately) inherits its buffer class and as such, this confuses the detection because a conversion to base seems to be available but not accessible.
This can be reproduced in GCC as well as VS2013 update 4 and all using Boost 1_58_0 as well. As such it is an error that can be reported to the Boost developers. I'd suggest it is a weakness in the Boost Interprocess implementation, although Boost Iostreams devs might be interested in making their overload selection more robust in the presence of private base classes...
In the mean time, consider using a simple boost::iostreams::array_sink or boost::iostreams::back_insert_device (IIRC) which is pretty much guaranteed to play well with Boost Iostreams, and achieves the same goals.
I'm working on a port from some old Delphi code to VC++ 2013, and I'm encountering an error that I feel should be an easy fix but cannot for the life of me figure out...
The problem is this: I have a number of common utility functions in a local file Utils.h that I am deploying as part of a windows form. Most (90%) of the functions in this header work as normal. GetMsg(...), however, throws a C3861 Identifier not found error...
Utils.h (snippet): GetMsg declared at bottom
#pragma once
/*------------------------------------------------------------------------*
Includes:
*------------------------------------------------------------------------*/
using namespace std;
/*------------------------------------------------------------------------*
Constants:
*------------------------------------------------------------------------*/
#define GET_MSG_TIMEOUT 2
/*------------------------------------------------------------------------*
Typedefs, Structs, Enums:
*------------------------------------------------------------------------*/
typedef union
{
unsigned long ui32;
unsigned char ui8[4];
} UI32_UI8;
typedef union
{
unsigned short ui16;
unsigned char ui8[2];
} UI16_UI8;
typedef union
{
float f;
unsigned char ui8[4];
} F_UI8;
typedef struct
{
string sName;
string sVersion;
string sCompany;
string sCopyright;
} PRODUCT_INFORMATION;
/*------------------------------------------------------------------------*
Prototypes:
*------------------------------------------------------------------------*/
unsigned short SwapShort(unsigned short aShort);
float SwapFloat(float aFloat);
unsigned long SwapLong(unsigned long aLong);
unsigned int ReadLine(unsigned char *msgBuf, SerialPort^ Hdl, bool ReturnLF);
void __stdcall FillTheBuffer(char *buf, String sss, int length);
string __stdcall FillTheString(string sss, int length);
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf);
GetMsg Definition in Utils.cpp:
//---------------------------------------------------------
unsigned int __stdcall GetMsg(SerialPort^ Hdl, unsigned char *msgBuf)
{
...
}
And, finally, GetMsg usage in form file:
#include "Utils.h"
...
void MainForm::UploadButton_Click
(System::Object^ object, System::EventArgs^ e)
{
...
SwapShort(1); //Works fine, also declared in Utils.h
GetMsg(spCom, inBuf); //C3861 ERROR
...
}
Where spCom is a (SerialPort^) contained, configured, and opened within the windows form. inBuf is a simple array of characters (char*) to buffer the input. I've tried renaming the function, thinking that there may have been an unintentional conflict / overload in other files, to no avail.
Any advice? Thanks, in advance
Solved the problem -- As it turns out I needed to be more explicit in my function definitions. Changing the declaration to read
GetMsg(System::IO::Ports::SerialPort^ Hdl, unsigned char *msgBuf)
eliminated the C3861 error. It would seem that the lack of a specific namespace on the declaration passed Intellisense but confused the compiler, rendering it unable to determine which prototype to use with the function call.
I'm working on socket programming.. my code executes the way I want it to, I'm able to use it. BUT it gives me a warning on compilation.
I compile using
gcc server1.c -o server1 -lpthread
And I get the warning
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
This error comes for the following code
int newsockfd;
newsockfd = (int)newsockfdd; //this line
And I'm using newsockfdd (which is int) in the following chunk of code
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
{
perror("Thread create error");
}
As you can probably tell, the code is not written too well (I am working on making it better). I know that this warning comes because of something to do with the size of int. But I really dunno how to fix it. Before I put in (intptr_t) in the pthread_create statement, it was showing a warning on that line, but that time the warning was
warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
It seems like there should be a simple fix to this? But I can't find it. I'm using Ubuntu 64-bit. Is that a reason for the warning?
As has been established in the comments, the situation is (modulo renaming to avoid confusing occurrences of newsockfdd as passed argument or received parameter)
void *serverThread(void *arg) {
// ...
int newsockfd = (int)arg;
// ...
}
and in main (or a function called from there)
// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
// ..
So when the int newsockfdd is passed as an argument to serverThread, it is cast to a void*. Originally, that cast was direct, but the intermediate cast to intptr_t was inserted to remove the warning about the cast to pointer from integer of different size.
And in serverThread, the received void* is cast to int, resulting in the warning about the cast from pointer to integer of different size.
That warning could probably also be removed by inserting an intermediate cast to intptr_t.
But, while the standard allows casting integers to pointers and vice versa, the results are implementation-defined and there's no guarantee that int -> void* -> int round-trips (although, a footnote in the standard says
The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to
be consistent with the addressing structure of the execution environment.
so probably it will round-trip and work as intended in this case - but it would likely not work [only for values of small enough absolute value] if the size of a void* is smaller than that of the integer type [consider long long -> void* -> long long on 32-bit systems]).
The proper fix is to avoid the casting between integers and pointers,
void *serverThread(void *arg) {
// ... check that arg isn't NULL
int newsockfd = *(int *)arg;
// ...
}
in severThread, cast the received pointer to a pointer of appropriate type, and read the pointed-to value, and in main
if// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, &newsockfdd) != 0)
pass the address of newsockfdd.
One caveat: if serverThread is called from multiple places, the calls in all these places need to be fixed.