31 #include <ibrcommon/data/File.h>
32 #include <ibrcommon/Logger.h>
33 #include <ibrcommon/ssl/HMacStream.h>
44 #ifdef HAVE_OPENSSL_JPAKE_H
60 const std::string KeyExchanger::TAG =
"KeyExchanger";
65 AbstractWorker::initialize(
"key-exchange");
74 #ifdef HAVE_OPENSSL_JPAKE_H
85 for (std::map<std::string, KeyExchangeSession*>::iterator it = _sessionmap.begin(); it != _sessionmap.end(); ++it)
110 for (std::map<int, KeyExchangeProtocol*>::iterator it = _protocols.begin(); it != _protocols.end(); ++it)
120 Task *t = _queue.poll();
121 std::auto_ptr<Task> killer(t);
126 ibrcommon::Thread::yield();
129 catch (
const ibrcommon::QueueUnblockedException &e)
143 return "KeyExchanger";
158 ibrcommon::BLOB::Reference ref = p.
getBLOB();
159 ibrcommon::BLOB::iostream stream = ref.iostream();
169 }
catch (
const ibrcommon::Exception&) {}
174 _queue.push(
new ExchangeTask(kee.getEID(), kee.getData()));
181 ibrcommon::MutexLock l(_expiration_lock);
182 if ((_next_expiration > 0) && (_next_expiration <= now))
185 _next_expiration = 0;
188 _queue.push(
new ExpireTask(now));
197 ibrcommon::BLOB::Reference ref = ibrcommon::BLOB::create();
201 ibrcommon::BLOB::iostream stream = ref.iostream();
236 }
catch (
const ibrcommon::IOException &ex) {
237 IBRCOMMON_LOGGER_TAG(KeyExchanger::TAG,
error) <<
"error while key exchange, Exception: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
251 throw ibrcommon::Exception(
"Error while reading temp key");
262 if (newKey == oldKey)
303 if (reportError)
submit(session, error);
306 KeyExchanger::Task::~Task()
311 : _peer(peer), _data(data)
314 void KeyExchanger::ExchangeTask::execute(KeyExchanger &exchanger)
throw ()
319 std::map<int, KeyExchangeProtocol*>::iterator p_it;
321 switch (_data.getProtocol())
326 KeyExchangeSession &session = exchanger.getSession(_peer, _data);
328 if (_data.getStep() == 0)
331 exchanger.error(session,
false);
336 exchanger.finish(session);
344 KeyExchangeSession &session = exchanger.getSession(_peer, _data);
346 if (_data.getStep() == 0)
360 event.str(key.getFingerprint());
367 exchanger.freeSession(_peer, session.getUniqueId());
374 p_it = exchanger._protocols.find(_data.getProtocol());
379 if (p_it == exchanger._protocols.end())
382 throw ibrcommon::Exception(
"key-exchange message for unsupported protocol received");
385 KeyExchangeProtocol &p = (*p_it->second);
390 exchanger.freeSession(_peer, _data.getSessionId());
395 KeyExchangeSession &session = exchanger.createSession(p, _peer);
398 _data.setSession(session);
402 p.begin(session, _data);
403 }
catch (ibrcommon::Exception &e) {
405 exchanger.error(session,
false);
413 KeyExchangeSession &session = exchanger.createSession(p, _peer, _data);
416 _data.setSession(session);
420 p.step(session, _data);
421 }
catch (ibrcommon::Exception &e) {
423 exchanger.error(session,
true);
431 KeyExchangeSession &session = exchanger.getSession(_peer, _data);
434 _data.setSession(session);
438 p.step(session, _data);
439 }
catch (ibrcommon::Exception &e) {
441 exchanger.error(session,
true);
447 catch (ibrcommon::Exception &e)
449 IBRCOMMON_LOGGER_TAG(KeyExchanger::TAG, error) << e.what() << IBRCOMMON_LOGGER_ENDL;
454 : _timestamp(timestamp)
457 void KeyExchanger::ExpireTask::execute(KeyExchanger &exchanger)
throw ()
460 exchanger.expire(_timestamp);
468 for (std::map<std::string, KeyExchangeSession*>::iterator it = _sessionmap.begin(); it != _sessionmap.end(); ++it)
470 KeyExchangeSession &session = *(*it).second;
472 if (session.getExpiration() <= timestamp)
474 IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 25) <<
"session expired for peer " << session.getPeer().getString() <<
", ID: " << session.getUniqueId() << IBRCOMMON_LOGGER_ENDL;
478 error(session,
false);
482 if ((next_expiration == 0) || (next_expiration > session.getExpiration()))
484 next_expiration = session.getExpiration();
490 ibrcommon::MutexLock l(_expiration_lock);
491 _next_expiration = next_expiration;
496 KeyExchangeSession* session = p.createSession(peer, data.
getSessionId());
497 _sessionmap[session->getSessionKey()] = session;
499 IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 20) <<
"key-exchange session created for " << peer.
getString() <<
", ID: " << session->getUniqueId() << IBRCOMMON_LOGGER_ENDL;
502 ibrcommon::MutexLock l(_expiration_lock);
503 _next_expiration = 1;
508 KeyExchangeSession& KeyExchanger::createSession(KeyExchangeProtocol &p,
const dtn::data::EID &peer)
511 _sessionmap[session->getSessionKey()] = session;
513 IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 20) <<
"key-exchange session created for " << peer.
getString() <<
", ID: " << session->getUniqueId() << IBRCOMMON_LOGGER_ENDL;
516 ibrcommon::MutexLock l(_expiration_lock);
517 _next_expiration = 1;
526 std::map<std::string, KeyExchangeSession*>::iterator it = _sessionmap.find(session_key);
527 if (it == _sessionmap.end())
529 std::stringstream ss;
531 throw ibrcommon::Exception(ss.str());
533 return *(*it).second;
536 void KeyExchanger::freeSession(
const dtn::data::EID &peer,
const unsigned int uniqueId)
540 std::map<std::string, KeyExchangeSession*>::iterator it = _sessionmap.find(session_key);
541 if (it == _sessionmap.end())
544 IBRCOMMON_LOGGER_DEBUG_TAG(KeyExchanger::TAG, 25) <<
"Session not found for " << peer.
getString() <<
", ID: " << uniqueId << IBRCOMMON_LOGGER_ENDL;
549 _sessionmap.erase(it);
551 IBRCOMMON_LOGGER_DEBUG_TAG(TAG, 25) <<
"session free'd for " << peer.
getString() <<
", ID: " << uniqueId << IBRCOMMON_LOGGER_ENDL;
static SecurityKeyManager & getInstance()
virtual void componentDown()
const dtn::data::EID & getPeer() const
unsigned int getSessionId() const
virtual void componentRun()
static dtn::data::EID local
static void add(EventReceiver< E > *receiver)
dtn::security::SecurityKey getKey(const dtn::security::SecurityKey::KeyType type=dtn::security::SecurityKey::KEY_UNSPEC) const
bool sameHost(const std::string &other) const
unsigned int getUniqueId() const
const std::string & getSessionKey() const
virtual void callbackBundleReceived(const dtn::data::Bundle &b)
void setApplication(const dtn::data::Number &app)
static void remove(const EventReceiver< E > *receiver)
virtual void componentUp()
virtual void error(KeyExchangeSession &session, bool reportError)
virtual void __cancellation()
virtual void raiseEvent(const dtn::security::KeyExchangeEvent &evt)
virtual void finish(KeyExchangeSession &session)
virtual void initialize()
void transmit(dtn::data::Bundle &bundle)
dtn::security::SecurityKey get(const dtn::data::EID &ref, const dtn::security::SecurityKey::KeyType type=dtn::security::SecurityKey::KEY_UNSPEC) const
dtn::data::SDNV< unsigned int > flags
virtual const std::string getFingerprint() const
std::string getString() const
virtual const std::string getName() const
iterator find(block_t blocktype)
ibrcommon::BLOB::Reference getBLOB() const
static dtn::data::Timestamp getMonotonicTimestamp()
void store(const dtn::security::SecurityKey &key, const std::string &data)
virtual void submit(KeyExchangeSession &session, const KeyExchangeData &data)
void set(FLAGS flag, bool value)
static void raise(const dtn::data::EID &eid, const dtn::security::KeyExchangeData &data)