summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Nindl <nine@wirdorange.org>2007-12-24 17:05:26 +0000
committerErwin Nindl <nine@wirdorange.org>2007-12-24 17:05:26 +0000
commit00febb25de92b1cd01309cc0f253ed4c3a761b13 (patch)
treeba0ffffdaf897e96ec2237a03cc523a4025b52f5
parentmesh syncing works now (diff)
weihnachtlicher checkin
* packet processing now with less memory operations than before * todo: * testing * set cipher / authalgo via commandline * set key operations for hmac calculation
-rw-r--r--Makefile4
-rw-r--r--anytun.cpp169
-rw-r--r--authAlgo.cpp1
-rw-r--r--authAlgo.h11
-rw-r--r--authTag.h5
-rw-r--r--cypher.cpp40
-rw-r--r--cypher.h20
-rw-r--r--encryptedPacket.cpp287
-rw-r--r--encryptedPacket.h134
-rw-r--r--packet.cpp5
-rw-r--r--packet.h13
-rw-r--r--plainPacket.cpp17
-rw-r--r--plainPacket.h44
13 files changed, 592 insertions, 158 deletions
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 <iostream>
#include <poll.h>
-#include <gcrypt.h>
-#include <cerrno>
+
+#include <gcrypt.h> // for thread safe libgcrypt initialisation
+#include <cerrno> // 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<ThreadParam*>(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<ThreadParam*>(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<ThreadParam*>(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 <gcrypt.h>
#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<buf.getLength(); ++i)
- buf[i] ^= bit_stream[i];
+ for(u_int32_t i; i<length; ++i)
+ out[i] = in[i];
}
catch(std::out_of_range& o) {}
}
-Buffer NullCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id)
-{
- Buffer buf(length);
- for(u_int32_t i; i<length; ++i)
- buf[i] = 0;
- return buf;
-}
-
const char* AesIcmCypher::MIN_GCRYPT_VERSION = "1.2.3";
AesIcmCypher::AesIcmCypher() : salt_(Buffer(14))
@@ -127,18 +112,17 @@ void AesIcmCypher::setSalt(Buffer salt)
salt_ = salt;
}
-Buffer AesIcmCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id)
+void AesIcmCypher::cypher(Buffer& out, Buffer& in, u_int32_t length, seq_nr_t seq_nr, sender_id_t sender_id)
{
gcry_error_t err;
- Buffer buf(length);
-
- // // set IV
+ // set the IV
+ //==========================================================================
// // where the 128-bit integer value IV SHALL be defined by the SSRC, the
// // SRTP packet index i, and the SRTP session salting key k_s, as below.
// //
// // IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16)
- // // sizeof(k_s) = 112 bit, random
+ // // sizeof(k_s) = 112 bit, random
Mpi iv(128);
Mpi salt = Mpi(salt_.getBuf(), salt_.getLength());
@@ -152,21 +136,19 @@ Buffer AesIcmCypher::getBitStream(u_int32_t length, seq_nr_t seq_nr, sender_id_t
delete[] iv_buf;
if( err ) {
cLog.msg(Log::PRIO_ERR) << "AesIcmCypher: Failed to set cipher IV: " << gpg_strerror( err );
- return Buffer(0);
+ return;
}
err = gcry_cipher_reset( cipher_ );
if( err ) {
cLog.msg(Log::PRIO_ERR) << "AesIcmCypher: Failed to reset cipher: " << gpg_strerror( err );
- return Buffer(0);
+ return;
}
- err = gcry_cipher_encrypt( cipher_, buf, buf.getLength(), 0, 0 );
+ err = gcry_cipher_encrypt( cipher_, out, out.getLength(), in, in.getLength() );
if( err ) {
cLog.msg(Log::PRIO_ERR) << "AesIcmCypher: Failed to generate cipher bitstream: " << gpg_strerror( err );
- return Buffer(0);
+ return;
}
-
- return buf;
}
diff --git a/cypher.h b/cypher.h
index ae56881..e408cd4 100644
--- a/cypher.h
+++ b/cypher.h
@@ -31,14 +31,10 @@
#ifndef _CYPHER_H_
#define _CYPHER_H_
-
-
#include "datatypes.h"
#include "buffer.h"
-extern "C" {
#include <gcrypt.h>
-}
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 <satp@wirdorange.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 <stdexcept>
+#include <iostream>
+#include <arpa/inet.h>
+#include <cstdio> // 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<struct HeaderStruct*>(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<AuthTag*>( buf_ + sizeof(struct HeaderStruct) );
+ buf_ = buf_ + AUTHTAG_SIZE;
+ length_ -= AUTHTAG_SIZE;
+ size_ -= AUTHTAG_SIZE;
+ } else {
+ buf_ = reinterpret_cast<u_int8_t*>( 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<struct HeaderStruct*>(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<payload_type_t*>(buf_ + length_ - sizeof(payload_type_t));
+// else
+// payload_type = reinterpret_cast<payload_type_t*>(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<payload_type_t*>(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<AuthTag*>(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<AuthTag*>(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 <satp@wirdorange.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<u_int8_t*>(payload_type_);
+ length_ = size_;
}
PlainPacket::PlainPacket(u_int32_t max_payload_length) : Buffer(max_payload_length + sizeof(payload_type_t))
{
payload_type_ = reinterpret_cast<payload_type_t*>(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