More code dedupe.

This commit is contained in:
Ian Gulliver
2015-02-07 15:25:22 -08:00
parent d82cb789e3
commit 4274c7ca1d
2 changed files with 66 additions and 82 deletions

130
crypto.cc
View File

@@ -165,6 +165,44 @@ bool CryptoConnBase::HandleSecureHandshake(const TLVNode& node) {
return true; return true;
} }
void CryptoConnBase::OnReadable_(struct bufferevent* bev, void* this__) {
auto this_ = (CryptoConnBase*)this__;
this_->OnReadable();
}
void CryptoConnBase::OnReadable() {
char buf[UINT16_MAX];
int bytes = bufferevent_read(bev_, buf, UINT16_MAX);
const std::string input(buf, bytes);
std::unique_ptr<TLVNode> decoded(TLVNode::Decode(input));
if (!decoded.get()) {
// TODO: re-buffer?
return;
}
if (state_ == AWAITING_HANDSHAKE) {
OnHandshake(*decoded);
return;
}
if (decoded->GetType() != TLV_TYPE_ENCRYPTED) {
LogFatal() << "Protocol error (wrong message type)" << std::endl;
return;
}
std::unique_ptr<TLVNode> decrypted(CryptoUtil::DecryptDecode(ephemeral_secret_key_, peer_ephemeral_public_key_, *decoded));
if (!decrypted.get()) {
LogFatal() << "Protocol error (decryption failure)" << std::endl;
return;
}
if (!OnMessage(*decrypted)) {
LogFatal() << "Protocol error (message handling)" << std::endl;
return;
}
}
CryptoPubServer::CryptoPubServer(const std::string& secret_key) CryptoPubServer::CryptoPubServer(const std::string& secret_key)
: secret_key_(secret_key), : secret_key_(secret_key),
@@ -211,8 +249,8 @@ void CryptoPubServer::Loop() {
CryptoPubServerConnection::CryptoPubServerConnection(struct bufferevent* bev, const std::string& secret_key) CryptoPubServerConnection::CryptoPubServerConnection(struct bufferevent* bev, const std::string& secret_key)
: CryptoConnBase(secret_key), : CryptoConnBase(secret_key) {
bev_(bev) { bev_ = bev;
} }
CryptoPubServerConnection::~CryptoPubServerConnection() { CryptoPubServerConnection::~CryptoPubServerConnection() {
@@ -220,42 +258,6 @@ CryptoPubServerConnection::~CryptoPubServerConnection() {
bufferevent_free(bev_); bufferevent_free(bev_);
} }
void CryptoPubServerConnection::OnReadable_(struct bufferevent* bev, void* this__) {
auto this_ = (CryptoPubServerConnection*)this__;
this_->OnReadable();
}
void CryptoPubServerConnection::OnReadable() {
char buf[UINT16_MAX];
int bytes = bufferevent_read(bev_, buf, UINT16_MAX);
const std::string input(buf, bytes);
std::unique_ptr<TLVNode> decoded(TLVNode::Decode(input));
if (!decoded.get()) {
// TODO: re-buffer?
return;
}
if (state_ == AWAITING_HANDSHAKE) {
OnHandshake(*decoded);
return;
}
if (decoded->GetType() != TLV_TYPE_ENCRYPTED) {
LogFatal() << "Protocol error (wrong message type)" << std::endl;
return;
}
std::unique_ptr<TLVNode> decrypted(CryptoUtil::DecryptDecode(ephemeral_secret_key_, peer_ephemeral_public_key_, *decoded));
if (!decrypted.get()) {
LogFatal() << "Protocol error (decryption failure)" << std::endl;
return;
}
switch (decrypted->GetType()) {
}
}
void CryptoPubServerConnection::OnHandshake(const TLVNode& decoded) { void CryptoPubServerConnection::OnHandshake(const TLVNode& decoded) {
if (decoded.GetType() != TLV_TYPE_HANDSHAKE) { if (decoded.GetType() != TLV_TYPE_HANDSHAKE) {
LogFatal() << "Protocol error (client handshake -- wrong message type)" << std::endl; LogFatal() << "Protocol error (client handshake -- wrong message type)" << std::endl;
@@ -288,6 +290,13 @@ void CryptoPubServerConnection::OnHandshake(const TLVNode& decoded) {
Log() << "Handshake successful (client ID: " << CryptoUtil::BinToHex(peer_public_key_) << ")" << std::endl; Log() << "Handshake successful (client ID: " << CryptoUtil::BinToHex(peer_public_key_) << ")" << std::endl;
} }
bool CryptoPubServerConnection::OnMessage(const TLVNode& message) {
switch (message.GetType()) {
default:
return false;
}
}
void CryptoPubServerConnection::SendHandshake() { void CryptoPubServerConnection::SendHandshake() {
auto handshake = BuildSecureHandshake(); auto handshake = BuildSecureHandshake();
std::string out; std::string out;
@@ -308,8 +317,8 @@ void CryptoPubServerConnection::OnError(const short what) {
CryptoPubClient::CryptoPubClient(struct sockaddr* addr, socklen_t addrlen, const std::string& secret_key, const std::string& server_public_key, const std::list<uint64_t>& channel_bitrates) CryptoPubClient::CryptoPubClient(struct sockaddr* addr, socklen_t addrlen, const std::string& secret_key, const std::string& server_public_key, const std::list<uint64_t>& channel_bitrates)
: CryptoConnBase(secret_key), : CryptoConnBase(secret_key),
event_base_(event_base_new()), event_base_(event_base_new()),
bev_(bufferevent_socket_new(event_base_, -1, BEV_OPT_CLOSE_ON_FREE)),
channel_bitrates_(channel_bitrates) { channel_bitrates_(channel_bitrates) {
bev_ = bufferevent_socket_new(event_base_, -1, BEV_OPT_CLOSE_ON_FREE);
peer_public_key_ = server_public_key; peer_public_key_ = server_public_key;
assert(secret_key_.length() == crypto_box_SECRETKEYBYTES); assert(secret_key_.length() == crypto_box_SECRETKEYBYTES);
assert(peer_public_key_.length() == crypto_box_PUBLICKEYBYTES); assert(peer_public_key_.length() == crypto_box_PUBLICKEYBYTES);
@@ -337,42 +346,6 @@ CryptoPubClient* CryptoPubClient::FromHostname(const std::string& server_address
return ret; return ret;
} }
void CryptoPubClient::OnReadable_(struct bufferevent* bev, void* this__) {
auto this_ = (CryptoPubClient*)this__;
this_->OnReadable();
}
void CryptoPubClient::OnReadable() {
char buf[UINT16_MAX];
int bytes = bufferevent_read(bev_, buf, UINT16_MAX);
const std::string input(buf, bytes);
std::unique_ptr<TLVNode> decoded(TLVNode::Decode(input));
if (!decoded.get()) {
// TODO: re-buffer?
return;
}
if (state_ == AWAITING_HANDSHAKE) {
OnHandshake(*decoded);
return;
}
if (decoded->GetType() != TLV_TYPE_ENCRYPTED) {
LogFatal() << "Protocol error (unexpected message type)" << std::endl;
return;
}
std::unique_ptr<TLVNode> decrypted(CryptoUtil::DecryptDecode(ephemeral_secret_key_, peer_ephemeral_public_key_, *decoded));
if (!decrypted.get()) {
LogFatal() << "Protocol error (decryption failure)" << std::endl;
return;
}
switch (decrypted->GetType()) {
}
}
void CryptoPubClient::OnHandshake(const TLVNode& decoded) { void CryptoPubClient::OnHandshake(const TLVNode& decoded) {
if (!HandleSecureHandshake(decoded)) { if (!HandleSecureHandshake(decoded)) {
return; return;
@@ -384,6 +357,13 @@ void CryptoPubClient::OnHandshake(const TLVNode& decoded) {
SendTunnelRequest(); SendTunnelRequest();
} }
bool CryptoPubClient::OnMessage(const TLVNode& message) {
switch (message.GetType()) {
default:
return false;
}
}
void CryptoPubClient::OnConnectOrError_(struct bufferevent* bev, const short what, void* this__) { void CryptoPubClient::OnConnectOrError_(struct bufferevent* bev, const short what, void* this__) {
auto this_ = (CryptoPubClient*)this__; auto this_ = (CryptoPubClient*)this__;
if (what == BEV_EVENT_CONNECTED) { if (what == BEV_EVENT_CONNECTED) {

View File

@@ -33,11 +33,18 @@ class CryptoConnBase : public CryptoBase {
std::unique_ptr<TLVNode> BuildSecureHandshake(); std::unique_ptr<TLVNode> BuildSecureHandshake();
bool HandleSecureHandshake(const TLVNode& node); bool HandleSecureHandshake(const TLVNode& node);
static void OnReadable_(struct bufferevent* bev, void* this__);
void OnReadable();
virtual void OnHandshake(const TLVNode& decoded) = 0;
virtual bool OnMessage(const TLVNode& node) = 0;
enum { enum {
AWAITING_HANDSHAKE, AWAITING_HANDSHAKE,
READY, READY,
} state_; } state_;
struct bufferevent* bev_;
const std::string secret_key_; const std::string secret_key_;
std::string peer_public_key_; std::string peer_public_key_;
std::string ephemeral_secret_key_; std::string ephemeral_secret_key_;
@@ -68,16 +75,14 @@ class CryptoPubServerConnection : public CryptoConnBase {
~CryptoPubServerConnection(); ~CryptoPubServerConnection();
private: private:
static void OnReadable_(struct bufferevent* bev, void* this__);
void OnReadable();
void OnHandshake(const TLVNode& decoded); void OnHandshake(const TLVNode& decoded);
bool OnMessage(const TLVNode& node);
static void OnError_(struct bufferevent* bev, const short what, void* this__); static void OnError_(struct bufferevent* bev, const short what, void* this__);
void OnError(const short what); void OnError(const short what);
void SendHandshake(); void SendHandshake();
struct bufferevent* bev_;
friend CryptoPubServer; friend CryptoPubServer;
}; };
@@ -91,9 +96,9 @@ class CryptoPubClient : public CryptoConnBase {
void Loop(); void Loop();
private: private:
static void OnReadable_(struct bufferevent* bev, void* this__);
void OnReadable();
void OnHandshake(const TLVNode& decoded); void OnHandshake(const TLVNode& decoded);
bool OnMessage(const TLVNode& node);
static void OnConnectOrError_(struct bufferevent* bev, const short what, void* this__); static void OnConnectOrError_(struct bufferevent* bev, const short what, void* this__);
void OnConnect(); void OnConnect();
void OnError(); void OnError();
@@ -102,7 +107,6 @@ class CryptoPubClient : public CryptoConnBase {
void SendTunnelRequest(); void SendTunnelRequest();
struct event_base* event_base_; struct event_base* event_base_;
struct bufferevent* bev_;
const std::list<uint64_t> channel_bitrates_; const std::list<uint64_t> channel_bitrates_;
}; };