summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Nindl <nine@wirdorange.org>2007-12-27 11:57:12 +0000
committerErwin Nindl <nine@wirdorange.org>2007-12-27 11:57:12 +0000
commita3e710fbd44ca8a0f4840b4e3366c6fc946ecfc5 (patch)
treeb5b189fa102e382da25b8c7385e628ed3889b335
parentadded anytun to isakmpd (diff)
* cypher and auth-algo selectable via commandline
* libgcrypt uses secure memory now * a few bugfixes
-rw-r--r--Makefile8
-rw-r--r--anytun.cpp55
-rw-r--r--authAlgo.cpp10
-rw-r--r--authAlgo.h4
-rw-r--r--authAlgoFactory.cpp47
-rw-r--r--authAlgoFactory.h49
-rw-r--r--cypher.cpp19
-rw-r--r--cypherFactory.h13
-rw-r--r--encryptedPacket.cpp9
-rw-r--r--encryptedPacket.h7
-rw-r--r--keyDerivation.cpp16
-rw-r--r--keyDerivation.h1
-rw-r--r--options.cpp8
13 files changed, 186 insertions, 60 deletions
diff --git a/Makefile b/Makefile
index d5f6f52..9e5c414 100644
--- a/Makefile
+++ b/Makefile
@@ -58,6 +58,8 @@ OBJS = anytun.o \
authTag.o \
keyDerivation.o \
mpi.o \
+ cypherFactory.o \
+ authAlgoFactory.o \
connectionList.o \
connectionParam.o \
networkAddress.o \
@@ -117,6 +119,12 @@ keyDerivation.o: keyDerivation.cpp keyDerivation.h
mpi.o: mpi.cpp mpi.h
$(C++) $(CCFLAGS) $< -c
+cypherFactory.o: cypherFactory.cpp cypherFactory.h cypher.h
+ $(C++) $(CCFLAGS) $< -c
+
+authAlgoFactory.o: authAlgoFactory.cpp authAlgoFactory.h authAlgo.h
+ $(C++) $(CCFLAGS) $< -c
+
syncSocket.o: syncSocket.cpp syncSocket.h
$(C++) $(CCFLAGS) $< -c
diff --git a/anytun.cpp b/anytun.cpp
index 400b286..8d2f1ac 100644
--- a/anytun.cpp
+++ b/anytun.cpp
@@ -44,6 +44,8 @@
#include "keyDerivation.h"
#include "authAlgo.h"
#include "authTag.h"
+#include "cypherFactory.h"
+#include "authAlgoFactory.h"
#include "signalController.h"
#include "packetSource.h"
#include "tunDevice.h"
@@ -94,17 +96,17 @@ void createConnection(const std::string & remote_host , u_int16_t remote_port, C
}
-void addPacketAuthTag(EncryptedPacket& pack, AuthAlgo& a, ConnectionParam& conn)
+void addPacketAuthTag(EncryptedPacket& pack, AuthAlgo* a, ConnectionParam& conn)
{
- AuthTag at = a.calc(pack);
+ AuthTag at = a->calc(pack);
pack.setAuthTag( at );
}
-bool checkPacketAuthTag(EncryptedPacket& pack, AuthAlgo& a, ConnectionParam & conn)
+bool checkPacketAuthTag(EncryptedPacket& pack, AuthAlgo* a, ConnectionParam & conn)
{
// check auth_tag and remove it
AuthTag at = pack.getAuthTag();
- return (at == a.calc(pack));
+ return (at == a->calc(pack));
}
bool checkPacketSeqNr(EncryptedPacket& pack,ConnectionParam& conn)
@@ -112,7 +114,8 @@ bool checkPacketSeqNr(EncryptedPacket& pack,ConnectionParam& conn)
// compare sender_id and seq with window
if(conn.seq_window_.hasSeqNr(pack.getSenderId(), pack.getSeqNr()))
{
- cLog.msg(Log::PRIO_NOTICE) << "Replay attack from " << conn.remote_host_<<":"<< conn.remote_port_<< " seq:"<<pack.getSeqNr() << " sid: "<<pack.getSenderId();
+ cLog.msg(Log::PRIO_NOTICE) << "Replay attack from " << conn.remote_host_<<":"<< conn.remote_port_
+ << " seq:"<<pack.getSeqNr() << " sid: "<<pack.getSenderId();
return false;
}
@@ -123,9 +126,11 @@ bool checkPacketSeqNr(EncryptedPacket& pack,ConnectionParam& conn)
void* sender(void* p)
{
ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
- //TODO make Cypher selectable with command line option
- AesIcmCypher c;
- Sha1AuthAlgo a;
+
+ CypherFactory c_factory;
+ AuthAlgoFactory a_factory;
+ std::auto_ptr<Cypher> c(c_factory.create(param->opt.getCypher()));
+ std::auto_ptr<AuthAlgo> a( a_factory.create(param->opt.getAuthAlgo()) );
PlainPacket plain_packet(1600); // TODO: fix me... mtu size
EncryptedPacket packet(1600);
@@ -163,15 +168,15 @@ void* sender(void* p)
conn.kd_.generate(LABEL_SATP_SALT, conn.seq_nr_, session_salt, session_salt.getLength());
conn.kd_.generate(LABEL_SATP_MSG_AUTH, packet.getSeqNr(), session_auth_key, session_auth_key.getLength());
- c.setKey(session_key);
- c.setSalt(session_salt);
- c.cypher(packet, plain_packet, plain_packet.getLength(), conn.seq_nr_, param->opt.getSenderId());
+ c->setKey(session_key);
+ c->setSalt(session_salt);
+ c->cypher(packet, plain_packet, plain_packet.getLength(), conn.seq_nr_, param->opt.getSenderId());
packet.setHeader(conn.seq_nr_, param->opt.getSenderId(), mux);
conn.seq_nr_++;
- a.setKey(session_auth_key);
- addPacketAuthTag(packet, a, conn);
+// a->setKey(session_auth_key);
+// addPacketAuthTag(packet, a.get(), conn);
param->src.send(packet, conn.remote_host_, conn.remote_port_);
}
pthread_exit(NULL);
@@ -213,9 +218,12 @@ void* syncListener(void* p )
void* receiver(void* p)
{
- ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
- AesIcmCypher c;
- Sha1AuthAlgo a;
+ ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
+
+ CypherFactory c_factory;
+ AuthAlgoFactory a_factory;
+ std::auto_ptr<Cypher> c( c_factory.create(param->opt.getCypher()) );
+ std::auto_ptr<AuthAlgo> a( a_factory.create(param->opt.getAuthAlgo()) );
EncryptedPacket packet(1600); // TODO: dynamic mtu size
PlainPacket plain_packet(1600);
@@ -246,9 +254,9 @@ void* receiver(void* p)
ConnectionParam & conn = param->cl.getConnection(0)->second;
conn.kd_.generate(LABEL_SATP_MSG_AUTH, packet.getSeqNr(), session_auth_key, session_auth_key.getLength());
- a.setKey( session_auth_key );
- if(!checkPacketAuthTag(packet, a, conn))
- continue;
+// a->setKey( session_auth_key );
+// if(!checkPacketAuthTag(packet, a.get(), conn))
+// continue;
//Allow dynamic IP changes
//TODO add command line option to turn this off
@@ -268,9 +276,9 @@ void* receiver(void* p)
// decrypt 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());
+ 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 && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN) ||
@@ -284,7 +292,7 @@ void* receiver(void* p)
}
-
+// make libgcrypt thread safe
extern "C" {
GCRY_THREAD_OPTION_PTHREAD_IMPL;
}
@@ -325,6 +333,7 @@ int main(int argc, char* argv[])
cLog.msg(Log::PRIO_NOTICE) << "dev opened - actual name is '" << p.dev.getActualName() << "'";
cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << p.dev.getTypeString() << "'";
+ // make libgcrypt thread safe
gcry_control( GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread );
pthread_t senderThread;
diff --git a/authAlgo.cpp b/authAlgo.cpp
index d6f9565..4b5515e 100644
--- a/authAlgo.cpp
+++ b/authAlgo.cpp
@@ -44,7 +44,6 @@ AuthTag NullAuthAlgo::calc(const Buffer& buf)
const char* Sha1AuthAlgo::MIN_GCRYPT_VERSION = "1.2.3";
-
// HMAC_SHA1
Sha1AuthAlgo::Sha1AuthAlgo() : ctx_(NULL)
{
@@ -57,6 +56,15 @@ Sha1AuthAlgo::Sha1AuthAlgo() : ctx_(NULL)
cLog.msg(Log::PRIO_ERR) << "Sha1AuthAlgo::Sha1AuthAlgo: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION;
return;
}
+
+ /* Allocate a pool of secure memory.
+ * This also drops priviliges on some systems. */
+ err = gcry_control(GCRYCTL_INIT_SECMEM, GCRYPT_SEC_MEM, 0);
+ if( err ) {
+ cLog.msg(Log::PRIO_ERR) << "Failed to allocate " << GCRYPT_SEC_MEM << "bytes of secure memory: " << gpg_strerror( err );
+ return;
+ }
+
/* Tell Libgcrypt that initialization has completed. */
err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
if( err ) {
diff --git a/authAlgo.h b/authAlgo.h
index 4db534d..e3a81be 100644
--- a/authAlgo.h
+++ b/authAlgo.h
@@ -45,12 +45,15 @@ public:
virtual ~AuthAlgo() {};
virtual AuthTag calc(const Buffer& buf) { return AuthTag(0); };
+ virtual void setKey(Buffer key) {};
};
class NullAuthAlgo : public AuthAlgo
{
public:
+ NullAuthAlgo() {};
AuthTag calc(const Buffer& buf);
+ void setKey(Buffer key) {};
};
@@ -78,6 +81,7 @@ public:
AuthTag calc(const Buffer& buf);
protected:
static const char* MIN_GCRYPT_VERSION;
+ static const u_int32_t GCRYPT_SEC_MEM = 32768; // 32k secure memory
gcry_md_hd_t ctx_;
Mutex mutex_;
};
diff --git a/authAlgoFactory.cpp b/authAlgoFactory.cpp
new file mode 100644
index 0000000..262d7c3
--- /dev/null
+++ b/authAlgoFactory.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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 <string>
+#include <stdexcept>
+
+#include "authAlgoFactory.h"
+#include "authAlgo.h"
+
+
+AuthAlgo* AuthAlgoFactory::create(std::string const& type)
+{
+ if( type == "null" )
+ return new NullAuthAlgo();
+ else if( type == "sha1" )
+ return new Sha1AuthAlgo();
+ else
+ throw std::invalid_argument("auth algo not available");
+}
+
diff --git a/authAlgoFactory.h b/authAlgoFactory.h
new file mode 100644
index 0000000..5949ca3
--- /dev/null
+++ b/authAlgoFactory.h
@@ -0,0 +1,49 @@
+/*
+ * 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 _AUTHALGO_FACTORY_H_
+#define _AUTHALGO_FACTORY_H_
+
+#include <string>
+
+#include "datatypes.h"
+#include "authAlgo.h"
+
+class AuthAlgoFactory
+{
+public:
+ AuthAlgoFactory() {};
+ ~AuthAlgoFactory() {};
+
+ AuthAlgo* create(std::string const& type);
+
+};
+
+#endif
diff --git a/cypher.cpp b/cypher.cpp
index 9661428..71f064d 100644
--- a/cypher.cpp
+++ b/cypher.cpp
@@ -64,16 +64,13 @@ AesIcmCypher::AesIcmCypher() : salt_(Buffer(14))
return;
}
- // do NOT allocate a pool of secure memory!
- // this is NOT thread safe!
- // /* Allocate a pool of secure memory. This also drops priviliges
- // on some systems. */
- // err = gcry_control(GCRYCTL_INIT_SECMEM, GCRYPT_SEC_MEM, 0);
- // if( err ) {
- // std::cerr << "Failed to allocate " << GCRYPT_SEC_MEM << "bytes of secure memory: ";
- // std::cerr << gpg_strerror( err ) << std::endl;
- // return;
- // }
+ /* Allocate a pool of secure memory. This also drops priviliges
+ on some systems. */
+ err = gcry_control(GCRYCTL_INIT_SECMEM, GCRYPT_SEC_MEM, 0);
+ if( err ) {
+ cLog.msg(Log::PRIO_ERR) << "Failed to allocate " << GCRYPT_SEC_MEM << "bytes of secure memory: " << gpg_strerror( err );
+ return;
+ }
/* Tell Libgcrypt that initialization has completed. */
err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
@@ -85,7 +82,7 @@ AesIcmCypher::AesIcmCypher() : salt_(Buffer(14))
}
}
- gcry_cipher_open( &cipher_, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0 );
+ err = gcry_cipher_open( &cipher_, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, 0 );
if( err )
cLog.msg(Log::PRIO_CRIT) << "AesIcmCypher::AesIcmCypher: Failed to open cypher";
}
diff --git a/cypherFactory.h b/cypherFactory.h
index 3f44827..f245301 100644
--- a/cypherFactory.h
+++ b/cypherFactory.h
@@ -31,7 +31,6 @@
#ifndef _CYPHER_FACTORY_H_
#define _CYPHER_FACTORY_H_
-#include <stdexcept>
#include <string>
#include "datatypes.h"
@@ -43,17 +42,7 @@ public:
CypherFactory() {};
~CypherFactory() {};
- Cypher* create(std::string const& type)
- {
- if( type == "null" )
- return new NullCypher();
- else if( type == "aes" )
- return new AesIcmCypher();
- else
- throw std::invalid_argument("cypher not available");
- }
-
+ Cypher* create(std::string const& type);
};
-
#endif
diff --git a/encryptedPacket.cpp b/encryptedPacket.cpp
index 0ac0ca9..35ccda0 100644
--- a/encryptedPacket.cpp
+++ b/encryptedPacket.cpp
@@ -50,6 +50,15 @@ EncryptedPacket::EncryptedPacket(u_int32_t max_payload_length)
}
+EncryptedPacket::~EncryptedPacket()
+{
+ buf_ = reinterpret_cast<u_int8_t*>(header_);
+ if( auth_tag_ == NULL )
+ length_ = size_ + sizeof(struct HeaderStruct) + AUTHTAG_SIZE;
+ else
+ length_ = size_ + sizeof(struct HeaderStruct);
+}
+
seq_nr_t EncryptedPacket::getSeqNr() const
{
return SEQ_NR_T_NTOH(header_->seq_nr);
diff --git a/encryptedPacket.h b/encryptedPacket.h
index ffe9246..7b70e17 100644
--- a/encryptedPacket.h
+++ b/encryptedPacket.h
@@ -44,7 +44,12 @@ public:
* @param max_payload_length maximum length of encrypted payload
*/
EncryptedPacket(u_int32_t max_payload_length);
-
+
+ /**
+ * Packet destructor
+ */
+ ~EncryptedPacket();
+
/**
* Get the sequence number
* @return seqence number
diff --git a/keyDerivation.cpp b/keyDerivation.cpp
index dbef123..911ea87 100644
--- a/keyDerivation.cpp
+++ b/keyDerivation.cpp
@@ -59,14 +59,14 @@ void KeyDerivation::init(Buffer key, Buffer salt)
// do NOT allocate a pool of secure memory!
// this is NOT thread safe!
- // /* Allocate a pool of 16k secure memory. This also drops priviliges
- // * on some systems. */
- // err = gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
- // if( err )
- // {
- // std::cerr << "Failed to allocate 16k secure memory: " << gpg_strerror( err ) << std::endl;
- // return;
- // }
+ /* Allocate a pool of 16k secure memory. This also drops priviliges
+ * on some systems. */
+ err = gcry_control(GCRYCTL_INIT_SECMEM, GCRYPT_SEC_MEM, 0);
+ if( err )
+ {
+ cLog.msg(Log::PRIO_ERR) << "Failed to allocate " << GCRYPT_SEC_MEM << " bytes of secure memory: " << gpg_strerror( err );
+ return;
+ }
/* Tell Libgcrypt that initialization has completed. */
err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
diff --git a/keyDerivation.h b/keyDerivation.h
index 531d441..214a1a4 100644
--- a/keyDerivation.h
+++ b/keyDerivation.h
@@ -75,6 +75,7 @@ protected:
int8_t ld_kdr_; // ld(key_derivation_rate)
SyncBuffer salt_;
static const char* MIN_GCRYPT_VERSION;
+ static const u_int32_t GCRYPT_SEC_MEM = 32768; // 32k secure memory
gcry_cipher_hd_t cipher_;
Mutex mutex_;
diff --git a/options.cpp b/options.cpp
index 0bf39db..1158c98 100644
--- a/options.cpp
+++ b/options.cpp
@@ -103,8 +103,8 @@ Options::Options()
ifconfig_param_local_ = "192.168.200.1";
ifconfig_param_remote_netmask_ = "255.255.255.0";
seq_window_size_ = 100;
- cypher_ = "null";
- auth_algo_ = "null";
+ cypher_ = "aes";
+ auth_algo_ = "sha1";
}
bool Options::parse(int argc, char* argv[])
@@ -171,8 +171,8 @@ void Options::printUsage()
std::cout << " [-n|--ifconfig] <local> the local address for the tun/tap device" << std::endl
<< " <remote|netmask> the remote address(tun) or netmask(tap)" << std::endl;
std::cout << " [-w|--window-size] <window size> seqence number window size" << std::endl;
- std::cout << " [-c|--cypher] <cypher type> type of cypher" << std::endl;
- std::cout << " [-a|--auth-algo] <algo type> authentication algoritm" << std::endl;
+ std::cout << " [-c|--cypher] <cypher type> payload encryption algorithm" << std::endl;
+ std::cout << " [-a|--auth-algo] <algo type> message authentication algorithm" << std::endl;
}
void Options::printOptions()