Permalink
Browse files

Correct move construction/assignment implementation (#370)

Secure Session stores a pointer to callback structure, therefore it must
be pinned in memory. We cannot simply copy secure_session_user_callbacks_t
into a different place in memory. secure_session_t will still keep a
reference to the old memory location.

We have to store the callback structure on heap as well. This keeps the
address constant and we can move the C++ wrapper structure correctly.
Other language wrappers use mostly the same approach, keeping both
secure_session_t and secure_session_user_callbacks_t allocated on heap.

Note that we have to accurately manage the objects stored in fields.
We use new/delete instead of smart pointers in order to be compatible
with C++03 (std::auto_ptr is broken and deprecated).
  • Loading branch information...
ilammy committed Feb 7, 2019
1 parent 9fedbb8 commit 3852d24afc0b6f7d4a46809f9961ebcc3a860d9a
Showing with 24 additions and 10 deletions.
  1. +24 −10 src/wrappers/themis/themispp/secure_session.hpp
@@ -63,26 +63,34 @@ namespace themispp{
typedef std::vector<uint8_t> data_t;

secure_session_t():
_session(NULL){
_session(NULL),
_callback(NULL){
}

secure_session_t(const data_t& id, const data_t& priv_key, secure_session_callback_interface_t* callbacks):
_session(NULL),
_callback(NULL),
_res(0){
_callback.get_public_key_for_id=themispp::get_public_key_for_id_callback;
_callback.send_data=themispp::send_callback;
_callback.receive_data=themispp::receive_callback;
_callback.state_changed=NULL;
_callback.user_data=callbacks;
_session=secure_session_create(&id[0], id.size(), &priv_key[0], priv_key.size(), &_callback);
if(!_session)
throw themispp::exception_t("Secure Session failde creating");
_callback=new secure_session_user_callbacks_t();
_callback->get_public_key_for_id=themispp::get_public_key_for_id_callback;
_callback->send_data=themispp::send_callback;
_callback->receive_data=themispp::receive_callback;
_callback->state_changed=NULL;
_callback->user_data=callbacks;
_session=secure_session_create(&id[0], id.size(), &priv_key[0], priv_key.size(), _callback);
if(!_session){
delete _callback;
throw themispp::exception_t("Secure Session failed creating");
}
}

virtual ~secure_session_t(){
if(_session){
secure_session_destroy(_session);
_session=NULL;
}
delete _callback;
_callback=NULL;
}

#if __cplusplus >= 201103L
@@ -94,14 +102,20 @@ namespace themispp{
_callback=other._callback;
_res=other._res;
other._session=nullptr;
other._callback=nullptr;
}

secure_session_t& operator=(secure_session_t&& other){
if(this!=&other){
if(_session){
secure_session_destroy(_session);
}
delete _callback;
_session=other._session;
_callback=other._callback;
_res=other._res;
other._session=nullptr;
other._callback=nullptr;
}
return *this;
}
@@ -192,7 +206,7 @@ namespace themispp{
}
private:
::secure_session_t* _session;
::secure_session_user_callbacks_t _callback;
::secure_session_user_callbacks_t *_callback;
std::vector<uint8_t> _res;
};
}// ns themis

0 comments on commit 3852d24

Please sign in to comment.