From 00febb25de92b1cd01309cc0f253ed4c3a761b13 Mon Sep 17 00:00:00 2001 From: Erwin Nindl Date: Mon, 24 Dec 2007 17:05:26 +0000 Subject: weihnachtlicher checkin * packet processing now with less memory operations than before * todo: * testing * set cipher / authalgo via commandline * set key operations for hmac calculation --- Makefile | 4 + anytun.cpp | 169 +++++++++++++------------------ authAlgo.cpp | 1 + authAlgo.h | 11 +- authTag.h | 5 + cypher.cpp | 40 ++------ cypher.h | 20 ++-- encryptedPacket.cpp | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++ encryptedPacket.h | 134 ++++++++++++++++++++++++ packet.cpp | 5 +- packet.h | 13 ++- plainPacket.cpp | 17 +++- plainPacket.h | 44 ++++++-- 13 files changed, 592 insertions(+), 158 deletions(-) create mode 100644 encryptedPacket.cpp create mode 100644 encryptedPacket.h diff --git a/Makefile b/Makefile index c643e07..d5f6f52 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ OBJS = anytun.o \ syncCommand.o \ packet.o \ plainPacket.o \ + encryptedPacket.o \ cypher.o \ authAlgo.o \ authTag.o \ @@ -98,6 +99,9 @@ packet.o: packet.cpp packet.h buffer.h plainPacket.o: plainPacket.cpp plainPacket.h buffer.h $(C++) $(CCFLAGS) $< -c +encryptedPacket.o: encryptedPacket.cpp encryptedPacket.h buffer.h + $(C++) $(CCFLAGS) $< -c + cypher.o: cypher.cpp cypher.h buffer.h $(C++) $(CCFLAGS) $< -c diff --git a/anytun.cpp b/anytun.cpp index 2a01045..291352e 100644 --- a/anytun.cpp +++ b/anytun.cpp @@ -30,18 +30,20 @@ #include #include -#include -#include + +#include // for thread safe libgcrypt initialisation +#include // for ENOMEM #include "datatypes.h" #include "log.h" #include "buffer.h" -#include "packet.h" +#include "plainPacket.h" +#include "encryptedPacket.h" #include "cypher.h" #include "keyDerivation.h" #include "authAlgo.h" -//#include "authTag.h" +#include "authTag.h" #include "signalController.h" #include "packetSource.h" #include "tunDevice.h" @@ -91,73 +93,21 @@ void createConnection(const std::string & remote_host , u_int16_t remote_port, C } -void encryptPacket(Packet & pack, Cypher & c, ConnectionParam & conn, void* p) -{ - ThreadParam* param = reinterpret_cast(p); - // cypher the packet - Buffer session_key(SESSION_KEYLEN_ENCR), session_salt(SESSION_KEYLEN_SALT); - conn.kd_.generate(LABEL_SATP_ENCRYPTION, conn.seq_nr_, session_key, session_key.getLength()); - conn.kd_.generate(LABEL_SATP_SALT, conn.seq_nr_, session_salt, session_salt.getLength()); - - c.setKey(session_key); - c.setSalt(session_salt); - - cLog.msg(Log::PRIO_NOTICE) << "Send Package: seq: " << conn.seq_nr_ - << ", sID: " << param->opt.getSenderId(); - //cLog.msg(Log::PRIO_NOTICE) << "Package dump: " << pack.getHexDump(); - - c.cypher(pack, conn.seq_nr_, param->opt.getSenderId()); -} - -bool decryptPacket(Packet & pack, Cypher & c, ConnectionParam & conn) -{ - u_int16_t sid = pack.getSenderId(); - u_int16_t seq = pack.getSeqNr(); - - pack.removeHeader(); - - // decypher the packet - Buffer session_key(SESSION_KEYLEN_SALT), session_salt(SESSION_KEYLEN_SALT); - conn.kd_.generate(LABEL_SATP_ENCRYPTION, seq, session_key, session_key.getLength()); - conn.kd_.generate(LABEL_SATP_SALT, seq, session_salt, session_salt.getLength()); - - c.setKey(session_key); - c.setSalt(session_salt); - c.cypher(pack, seq, sid); - - cLog.msg(Log::PRIO_NOTICE) << "Received Package: seq: " << seq - << ", sID: " << sid; - //cLog.msg(Log::PRIO_NOTICE) << "Package dump: " << pack.getHexDump(); - - return true; -} - -void addPacketAuthTag(Packet & pack, Cypher & c, ConnectionParam & conn) +void addPacketAuthTag(EncryptedPacket& pack, AuthAlgo& a, ConnectionParam& conn) { - -// // calc auth_tag and add it to the packet -// AuthTag at = a.calc(pack); -// if(at != AuthTag(0)) { -// //auth_tag_t at = a.calc(pack); -// pack.addAuthTag(at); -// } -// - // send it out to remote host + AuthTag at = a.calc(pack); + pack.setAuthTag( at ); } -bool checkPacketAuthTag(Packet & pack, Cypher & c, ConnectionParam & conn) +bool checkPacketAuthTag(EncryptedPacket& pack, AuthAlgo& a, ConnectionParam & conn) { -// // check auth_tag and remove it -// AuthTag at = pack.getAuthTag(); - pack.removeAuthTag(); - //return at == a.calc(pack); - return true; + // check auth_tag and remove it + AuthTag at = pack.getAuthTag(); + return (at == a.calc(pack)); } -bool checkPacketSeqNr(Packet & pack,ConnectionParam & conn) +bool checkPacketSeqNr(EncryptedPacket& pack,ConnectionParam& conn) { -// u_int16_t sid = pack.getSenderId(); -// u_int16_t seq = pack.getSeqNr(); // compare sender_id and seq with window if(conn.seq_window_.hasSeqNr(pack.getSenderId(), pack.getSeqNr())) { @@ -173,42 +123,53 @@ void* sender(void* p) { ThreadParam* param = reinterpret_cast(p); //TODO make Cypher selectable with command line option -// NullCypher c; AesIcmCypher c; -// NullAuthAlgo a; + Sha1AuthAlgo a; + + //TODO make pack global, reduce dynamic memory! + PlainPacket plain_packet(1600); // TODO: fix me... mtu size + EncryptedPacket packet(1600); + + Buffer session_key(SESSION_KEYLEN_ENCR), session_salt(SESSION_KEYLEN_SALT); + //TODO replace mux + u_int16_t mux = 0; while(1) { - //TODO make pack global, reduce dynamic memory! - Packet pack(1600); // fix me... mtu size - + packet.setLength( packet.getSize() ); + plain_packet.setLength( plain_packet.getSize() ); + // read packet from device - int len = param->dev.read(pack); - //TODO remove, no dynamic memory resizing - pack.resizeBack(len); + u_int32_t len = param->dev.read(plain_packet); + plain_packet.setLength(len); if( param->cl.empty()) continue; - //TODO replace 0 with mux - ConnectionMap::iterator cit = param->cl.getConnection(0); + ConnectionMap::iterator cit = param->cl.getConnection(mux); if(cit==param->cl.getEnd()) continue; ConnectionParam & conn = cit->second; + // add payload type if(param->dev.getType() == TunDevice::TYPE_TUN) - pack.addPayloadType(PAYLOAD_TYPE_TUN); + plain_packet.setPayloadType(PAYLOAD_TYPE_TUN); else if(param->dev.getType() == TunDevice::TYPE_TAP) - pack.addPayloadType(PAYLOAD_TYPE_TAP); + plain_packet.setPayloadType(PAYLOAD_TYPE_TAP); else - pack.addPayloadType(0); + plain_packet.setPayloadType(0); - encryptPacket(pack, c, conn, param); + // encrypt packet + conn.kd_.generate(LABEL_SATP_ENCRYPTION, conn.seq_nr_, session_key, session_key.getLength()); + conn.kd_.generate(LABEL_SATP_SALT, conn.seq_nr_, session_salt, session_salt.getLength()); + c.setKey(session_key); + c.setSalt(session_salt); + c.cypher(packet, plain_packet, plain_packet.getLength(), conn.seq_nr_, param->opt.getSenderId()); - pack.addHeader(conn.seq_nr_, param->opt.getSenderId()); + packet.setHeader(conn.seq_nr_, param->opt.getSenderId(), mux); conn.seq_nr_++; - addPacketAuthTag(pack, c, conn); - param->src.send(pack, conn.remote_host_, conn.remote_port_); + addPacketAuthTag(packet, a, conn); + param->src.send(packet, conn.remote_host_, conn.remote_port_); } pthread_exit(NULL); } @@ -250,22 +211,24 @@ void* syncListener(void* p ) void* receiver(void* p) { ThreadParam* param = reinterpret_cast(p); -// NullCypher c; AesIcmCypher c; -// NullAuthAlgo a; - + Sha1AuthAlgo a; + + EncryptedPacket packet(1600); // TODO: dynamic mtu size + PlainPacket plain_packet(1600); + Buffer session_key(SESSION_KEYLEN_SALT), session_salt(SESSION_KEYLEN_SALT); + while(1) { string remote_host; u_int16_t remote_port; - // u_int16_t sid = 0, seq = 0; - Packet pack(1600); // fix me... mtu size + packet.setLength( packet.getSize() ); + plain_packet.setLength( plain_packet.getSize() ); + // u_int16_t sid = 0, seq = 0; // read packet from socket - u_int32_t len = param->src.recv(pack, remote_host, remote_port); - pack.resizeBack(len); - pack.withPayloadType(true).withHeader(true).withAuthTag(false); - + u_int32_t len = param->src.recv(packet, remote_host, remote_port); + packet.setLength(len); // autodetect peer // TODO check auth tag first @@ -279,7 +242,7 @@ void* receiver(void* p) //TODO Add multi connection support here ConnectionParam & conn = param->cl.getConnection(0)->second; - if (!checkPacketAuthTag(pack, c, conn)) + if(!checkPacketAuthTag(packet, a, conn)) continue; //Allow dynamic IP changes @@ -292,24 +255,30 @@ void* receiver(void* p) param->queue.push(SyncCommand(param->cl,0)); } - //Replay Protection - if (!checkPacketSeqNr(pack,conn)) + // Replay Protection + if (!checkPacketSeqNr(packet, conn)) continue; - if (!decryptPacket(pack, c, conn)) - continue; + // decypher the packet + conn.kd_.generate(LABEL_SATP_ENCRYPTION, packet.getSeqNr(), session_key, session_key.getLength()); + conn.kd_.generate(LABEL_SATP_SALT, packet.getSeqNr(), session_salt, session_salt.getLength()); + c.setKey(session_key); + c.setSalt(session_salt); + c.cypher(plain_packet, packet, packet.getLength(), packet.getSeqNr(), packet.getSenderId()); + // check payload_type and remove it - if((param->dev.getType() == TunDevice::TYPE_TUN && pack.getPayloadType() != PAYLOAD_TYPE_TUN) || - (param->dev.getType() == TunDevice::TYPE_TAP && pack.getPayloadType() != PAYLOAD_TYPE_TAP)) + if((param->dev.getType() == TunDevice::TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN) || + (param->dev.getType() == TunDevice::TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP)) continue; - pack.removePayloadType(); - + // write it on the device - param->dev.write(pack); + param->dev.write(plain_packet); } pthread_exit(NULL); } + + extern "C" { GCRY_THREAD_OPTION_PTHREAD_IMPL; } diff --git a/authAlgo.cpp b/authAlgo.cpp index 0ffd76b..d6f9565 100644 --- a/authAlgo.cpp +++ b/authAlgo.cpp @@ -44,6 +44,7 @@ AuthTag NullAuthAlgo::calc(const Buffer& buf) const char* Sha1AuthAlgo::MIN_GCRYPT_VERSION = "1.2.3"; + // HMAC_SHA1 Sha1AuthAlgo::Sha1AuthAlgo() : ctx_(NULL) { diff --git a/authAlgo.h b/authAlgo.h index de813e6..4c9c960 100644 --- a/authAlgo.h +++ b/authAlgo.h @@ -44,7 +44,7 @@ public: AuthAlgo() {}; virtual ~AuthAlgo() {}; - virtual AuthTag calc(const Buffer& buf) = 0; + virtual AuthTag calc(const Buffer& buf) { return AuthTag(0); }; }; class NullAuthAlgo : public AuthAlgo @@ -65,9 +65,16 @@ public: ~Sha1AuthAlgo(); /** - * + * set the key for the auth algo + * @param key key for hmac sha1 calculation */ void setKey(Buffer key); + + /** + * calculate the sha1 hmac + * @param buf buffer for message digest + * @return sha1 hmac + */ AuthTag calc(const Buffer& buf); protected: static const char* MIN_GCRYPT_VERSION; diff --git a/authTag.h b/authTag.h index 95f2805..22237e6 100644 --- a/authTag.h +++ b/authTag.h @@ -34,6 +34,11 @@ #include "datatypes.h" #include "buffer.h" + +/** + * Authtag class + */ + class AuthTag : public Buffer { public: diff --git a/cypher.cpp b/cypher.cpp index 58b971c..9661428 100644 --- a/cypher.cpp +++ b/cypher.cpp @@ -35,36 +35,21 @@ #include #include "cypher.h" -#include "keyDerivation.h" #include "mpi.h" #include "log.h" -void Cypher::cypher(Buffer& buf, seq_nr_t seq_nr, sender_id_t sender_id) -{ - Buffer stream = getBitStream(buf.getLength(), seq_nr, sender_id); - exor(buf, stream); -} - -void Cypher::exor(Buffer& buf, const Buffer& bit_stream) +void NullCypher::cypher(Buffer& out, Buffer& in, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) { try { - for(u_int32_t i; i -} class Cypher @@ -49,17 +45,16 @@ public: void setKey(Buffer key) {}; void setSalt(Buffer salt) {}; - void cypher(Buffer& buf, seq_nr_t seq_nr, sender_id_t sender_id); - -protected: - void exor(Buffer& buf, const Buffer& bit_stream); - virtual Buffer getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) = 0; + virtual void cypher(Buffer& in, Buffer& out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id) {}; }; class NullCypher : public Cypher { +public: + NullCypher() {}; + ~NullCypher() {}; protected: - Buffer getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); + void cypher(Buffer& in, Buffer& out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); }; class AesIcmCypher : public Cypher @@ -69,17 +64,14 @@ public: ~AesIcmCypher(); void setKey(Buffer key); void setSalt(Buffer salt); + void cypher(Buffer& in, Buffer& out, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); static const char* MIN_GCRYPT_VERSION; static const u_int32_t GCRYPT_SEC_MEM = 16384; // 16k secure memory protected: - Buffer getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id); gcry_cipher_hd_t cipher_; Buffer salt_; - -private: - static bool gcrypt_initialized_; }; diff --git a/encryptedPacket.cpp b/encryptedPacket.cpp new file mode 100644 index 0000000..0ac0ca9 --- /dev/null +++ b/encryptedPacket.cpp @@ -0,0 +1,287 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007 anytun.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include // for std::memcpy + +#include "encryptedPacket.h" +#include "datatypes.h" +#include "authTag.h" +#include "log.h" + + +EncryptedPacket::EncryptedPacket(u_int32_t max_payload_length) + : Buffer(max_payload_length + sizeof(struct HeaderStruct) + AUTHTAG_SIZE) +{ + header_ = reinterpret_cast(buf_); + auth_tag_ = NULL; + buf_ = buf_ + sizeof(struct HeaderStruct); // no authtag yet + length_ = length_ - sizeof(struct HeaderStruct); + size_ = max_payload_length + AUTHTAG_SIZE; +} + + +seq_nr_t EncryptedPacket::getSeqNr() const +{ + return SEQ_NR_T_NTOH(header_->seq_nr); +} + +sender_id_t EncryptedPacket::getSenderId() const +{ + return SENDER_ID_T_NTOH(header_->sender_id); +} + +mux_t EncryptedPacket::getMux() const +{ + return MUX_T_NTOH(header_->mux); +} + +u_int32_t EncryptedPacket::getSize() const +{ + return size_; +} + +void EncryptedPacket::setLength(u_int32_t length) +{ + if(length > size_) + throw std::out_of_range("can't set length greater then size ofsize of allocated memory"); + + length_ = length; +} + +void EncryptedPacket::setSeqNr(seq_nr_t seq_nr) +{ + header_->seq_nr = SEQ_NR_T_HTON(seq_nr); +} + +void EncryptedPacket::setSenderId(sender_id_t sender_id) +{ + header_->sender_id = SENDER_ID_T_HTON(sender_id); +} + +void EncryptedPacket::setMux(mux_t mux) +{ + header_->mux = MUX_T_HTON(mux); +} + +void EncryptedPacket::setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + header_->seq_nr = SEQ_NR_T_HTON(seq_nr); + header_->sender_id = SENDER_ID_T_HTON(sender_id); + header_->mux = MUX_T_HTON(mux); +} + +bool EncryptedPacket::hasAuthTag() const +{ + if( auth_tag_ == NULL ) + return false; + return true; +} + +void EncryptedPacket::withAuthTag(bool b) +{ + if( b && (auth_tag_ != NULL) ) + throw std::runtime_error("packet already has auth tag function enabled"); + + if( b ) { + auth_tag_ = reinterpret_cast( buf_ + sizeof(struct HeaderStruct) ); + buf_ = buf_ + AUTHTAG_SIZE; + length_ -= AUTHTAG_SIZE; + size_ -= AUTHTAG_SIZE; + } else { + buf_ = reinterpret_cast( auth_tag_ ); + length_ += AUTHTAG_SIZE; + size_ += AUTHTAG_SIZE; + auth_tag_ = NULL; + } +} + +void EncryptedPacket::setAuthTag(AuthTag& tag) +{ + if( auth_tag_ == NULL ) + throw std::runtime_error("auth tag not enabled"); + + if( tag == AuthTag(0) ) + return; + + if( tag.getLength() != AUTHTAG_SIZE ) + throw std::length_error("authtag length mismatch with AUTHTAG_SIZE"); + + std::memcpy( auth_tag_, tag.getBuf(), AUTHTAG_SIZE ); +} + +AuthTag EncryptedPacket::getAuthTag() const +{ + if( auth_tag_ == NULL ) + throw std::runtime_error("auth tag not enabled"); + + AuthTag at(AUTHTAG_SIZE); + std::memcpy(at, auth_tag_, AUTHTAG_SIZE ); + return at; +} + + +//Packet& Packet::addHeader(seq_nr_t seq_nr, sender_id_t sender_id) +//{ +// if(!has_header_) +// { +// if(sizeof(struct HeaderStruct) > resizeFront(length_ + sizeof(struct HeaderStruct))) +// return *this; +// +// has_header_ = true; +// } +// struct HeaderStruct* header; +// header = reinterpret_cast(buf_); +// header->seq_nr = SEQ_NR_T_HTON(seq_nr); +// header->sender_id = SENDER_ID_T_HTON(sender_id); +// return *this; +//} +// +// +//bool Packet::hasPayloadType() const +//{ +// return has_payload_type_; +//} +// +//Packet& Packet::withPayloadType(bool b) +//{ +// if(b && length_ >= sizeof(payload_type_t)) +// has_payload_type_ = true; +// else +// has_payload_type_ = false; +// +// return *this; +//} +// +//payload_type_t Packet::getPayloadType() const +//{ +// if(!has_payload_type_) +// return 0; +// +// if((!has_auth_tag_ && length_ < sizeof(payload_type_t)) || +// (has_auth_tag_ && length_ < (sizeof(payload_type_t) + AUTHTAG_SIZE))) +// return 0; +// +// payload_type_t* payload_type; +// +// if(!has_auth_tag_) +// payload_type = reinterpret_cast(buf_ + length_ - sizeof(payload_type_t)); +// else +// payload_type = reinterpret_cast(buf_ + length_ - sizeof(payload_type_t) - AUTHTAG_SIZE); +// return PAYLOAD_TYPE_T_NTOH(*payload_type); +//} +// +//Packet& Packet::addPayloadType(payload_type_t payload_type) +//{ +// if(has_auth_tag_) +// throw std::runtime_error("can't add payload_type with existing auth_tag"); +// +// if(!has_payload_type_) +// { +// u_int32_t new_length = length_ + sizeof(payload_type_t); +// if(new_length > resizeBack(new_length)) +// return *this; +// +// has_payload_type_ = true; +// } +// payload_type_t* payload_type_ptr; +// payload_type_ptr = reinterpret_cast(buf_ + length_ - sizeof(payload_type_t)); +// *payload_type_ptr = PAYLOAD_TYPE_T_HTON(payload_type); +// return *this; +//} +// +//Packet& Packet::removePayloadType() +//{ +// if(has_auth_tag_) +// throw std::runtime_error("can't remove payload_type with existing auth_tag"); +// +// if(!has_payload_type_) +// return *this; +// +// if(length_ >= sizeof(payload_type_t)) +// resizeBack(length_ - sizeof(payload_type_t)); +// +// has_payload_type_ = false; +// +// return *this; +//} +// +// +// +// +//AuthTag Packet::getAuthTag() const +//{ +// if(!has_auth_tag_) +// return AuthTag(0); +// +// if(length_ < AUTHTAG_SIZE) +// return AuthTag(0); +// +// //AuthTag* auth_tag; +// //auth_tag = reinterpret_cast(buf_ + length_ - AUTHTAG_SIZE); +// //return AUTH_TAG_T_NTOH(*auth_tag); +// AuthTag auth_tag; +// auth_tag = AuthTag(buf_ + length_ - AUTHTAG_SIZE, AUTHTAG_SIZE); +// return auth_tag; +//} +// +//Packet& Packet::addAuthTag(AuthTag auth_tag) +//{ +// if(!has_auth_tag_) +// { +// u_int32_t new_length = length_ + auth_tag.getLength(); +// if(new_length > resizeBack(new_length)) +// return *this; +// +// has_auth_tag_ = true; +// } +// +// AuthTag* auth_tag_ptr; +// auth_tag_ptr = reinterpret_cast(buf_ + length_ - auth_tag.getLength()); +// std::memcpy(auth_tag_ptr, auth_tag.getBuf(), auth_tag.getLength()); +// +// return *this; +//} +// +//Packet& Packet::removeAuthTag() +//{ +// if(!has_auth_tag_) +// return *this; +// +// if(length_ >= AUTHTAG_SIZE) +// resizeBack(length_ - AUTHTAG_SIZE); +// +// has_auth_tag_ = false; +// +// return *this; +//} +// diff --git a/encryptedPacket.h b/encryptedPacket.h new file mode 100644 index 0000000..ffe9246 --- /dev/null +++ b/encryptedPacket.h @@ -0,0 +1,134 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007 anytun.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ENCRYPTED_PACKET_H_ +#define _ENCRYPTED_PACKET_H_ + +#include "datatypes.h" +#include "buffer.h" +#include "authTag.h" + +class EncryptedPacket : public Buffer +{ +public: + + /** + * Packet constructor + * @param max_payload_length maximum length of encrypted payload + */ + EncryptedPacket(u_int32_t max_payload_length); + + /** + * Get the sequence number + * @return seqence number + */ + seq_nr_t getSeqNr() const; + + /** + * Set the seqence number + * @param seq_nr sequence number + */ + void setSeqNr(seq_nr_t seq_nr); + + /** + * Get the sender id + * @return sender id + */ + sender_id_t getSenderId() const; + + /** + * Set the sender id + * @param sender_id sender id + */ + void setSenderId(sender_id_t sender_id); + + /** + * Get the mulitplex id + * @return multiplex id + */ + mux_t getMux() const; + + /** + * Set the multiplex id + * @param mux multiplex id + */ + void setMux(mux_t mux); + + /** + * Set the header of a packet + * @param seq_nr sequence number + * @param sender_id sender id + * @param mux multiplex id + */ + void setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + + /** + * Get the maximum payload size + * @return maximum payload size + */ + u_int32_t getSize() const; + + /** + * Set the real length of the payload + * @param length the real length of the payload, has to be smaller than the maximum payload size! + */ + void setLength(u_int32_t length); + + bool hasAuthTag() const; + void withAuthTag(bool b); + AuthTag getAuthTag() const; + void setAuthTag(AuthTag& tag); + + +// bool hasHeader() const; +// Packet& withHeader(bool b); +// Packet& addHeader(seq_nr_t seq_nr, sender_id_t sender_id); +// Packet& withAuthTag(bool b); +// AuthTag getAuthTag() const; +// Packet& addAuthTag(AuthTag auth_tag); + +private: + EncryptedPacket(); + EncryptedPacket(const EncryptedPacket &src); + struct HeaderStruct + { + seq_nr_t seq_nr; + sender_id_t sender_id; + mux_t mux; + }__attribute__((__packed__)); + + struct HeaderStruct* header_; + AuthTag* auth_tag_; + u_int32_t size_; + + static const u_int32_t AUTHTAG_SIZE = 10; // 10byte +}; + +#endif diff --git a/packet.cpp b/packet.cpp index d592e1e..3a80682 100644 --- a/packet.cpp +++ b/packet.cpp @@ -46,11 +46,12 @@ Packet::Packet() has_auth_tag_ = false; } -Packet::Packet(u_int32_t length) : Buffer(length) +Packet::Packet(u_int32_t payload_length) + : Buffer(payload_length + sizeof(struct HeaderStruct) + sizeof(payload_type_t) + AUTHTAG_SIZE) { has_header_ = false; has_payload_type_ = false; - has_auth_tag_ = false; + has_auth_tag_ = false; } Packet::Packet(const Buffer &src) : Buffer(src) diff --git a/packet.h b/packet.h index 813b694..72c7b6b 100644 --- a/packet.h +++ b/packet.h @@ -39,7 +39,12 @@ class Packet : public Buffer { public: Packet(); - Packet(u_int32_t length); + + /** + * Packet Constructor + * @param payload_length Payload Length + */ + Packet(u_int32_t payload_length); Packet(const Buffer &src); bool hasHeader() const; @@ -72,7 +77,11 @@ private: bool has_header_; bool has_payload_type_; bool has_auth_tag_; - // FIXXMEE: remove hardcoded authtag-size + + struct HeaderStruct* header_; + payload_type_t* payload_type_; + AuthTag* auth_tag_; + static const u_int32_t AUTHTAG_SIZE = 10; }; diff --git a/plainPacket.cpp b/plainPacket.cpp index c48cd8c..1df611d 100644 --- a/plainPacket.cpp +++ b/plainPacket.cpp @@ -41,12 +41,15 @@ PlainPacket::~PlainPacket() { buf_ = reinterpret_cast(payload_type_); + length_ = size_; } PlainPacket::PlainPacket(u_int32_t max_payload_length) : Buffer(max_payload_length + sizeof(payload_type_t)) { payload_type_ = reinterpret_cast(buf_); - buf_ = buf_ + sizeof(payload_type_t); + buf_ += sizeof(payload_type_t); + length_ = max_payload_length; + size_ = length_; } payload_type_t PlainPacket::getPayloadType() const @@ -59,3 +62,15 @@ void PlainPacket::setPayloadType(payload_type_t payload_type) payload_type = PAYLOAD_TYPE_T_HTON(payload_type); } +void PlainPacket::setLength(u_int32_t length) +{ + if(length > size_) + throw std::out_of_range("can't set length greater then size ofsize of allocated memory"); + + length_ = length; +} + +u_int32_t PlainPacket::getSize() const +{ + return size_; +} diff --git a/plainPacket.h b/plainPacket.h index cd02196..8234f41 100644 --- a/plainPacket.h +++ b/plainPacket.h @@ -46,24 +46,52 @@ public: ~PlainPacket(); /** - * Packet Constructor - * @param max_payload_length Payload Length + * Packet constructor + * @param max_payload_length maximum payload length */ PlainPacket(u_int32_t max_payload_length); + /** + * Get the payload type + * @return the id of the payload type + */ payload_type_t getPayloadType() const; + + /** + * Set the payload type + * @param payload_type payload type id + */ void setPayloadType(payload_type_t payload_type); -// bool hasPayloadType() const; -// Packet& withPayloadType(bool b); -// payload_type_t getPayloadType() const; -// Packet& addPayloadType(payload_type_t payload_type); -// Packet& removePayloadType(); - + /** + * Set the real payload length + * @param length the real payload length + */ + void setRealPayloadLengt(u_int32_t length); + + /** + * Get the real payload length + * @return the real length of the payload + */ + u_int32_t getRealPayloadLength(); + + /** + * Set the length of the payload + * @param length length of the payload + */ + void setLength(u_int32_t length); + + /** + * Get the size of the allocated memory for the payload + * @return maximum size of payload + */ + u_int32_t getSize() const; + private: PlainPacket(); PlainPacket(const PlainPacket &src); payload_type_t* payload_type_; + u_int32_t size_; }; #endif -- cgit v1.2.3