doing replay protection before learning remote host
[anytun.git] / src / encryptedPacket.cpp
blob692d2217f5797d29bfdb1da1ec6262e4f385fcd0
1 /*
2 * anytun
4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include <stdexcept>
33 #include <iostream>
34 #include <cstdio> // for std::memcpy
36 #include "encryptedPacket.h"
37 #include "endian.h"
38 #include "datatypes.h"
39 #include "log.h"
41 EncryptedPacket::EncryptedPacket(u_int32_t payload_length, bool allow_realloc)
42 : Buffer(payload_length + sizeof(struct HeaderStruct), allow_realloc)
44 header_ = reinterpret_cast<struct HeaderStruct*>(buf_);
45 payload_ = buf_ + sizeof(struct HeaderStruct);
46 auth_tag_ = NULL;
47 if(header_)
49 header_->seq_nr = 0;
50 header_->sender_id = 0;
51 header_->mux = 0;
55 u_int32_t EncryptedPacket::getHeaderLength()
57 return sizeof(struct HeaderStruct);
60 seq_nr_t EncryptedPacket::getSeqNr() const
62 if(header_)
63 return SEQ_NR_T_NTOH(header_->seq_nr);
65 return 0;
68 sender_id_t EncryptedPacket::getSenderId() const
70 if(header_)
71 return SENDER_ID_T_NTOH(header_->sender_id);
73 return 0;
76 mux_t EncryptedPacket::getMux() const
78 if(header_)
79 return MUX_T_NTOH(header_->mux);
81 return 0;
84 void EncryptedPacket::setSeqNr(seq_nr_t seq_nr)
86 if(header_)
87 header_->seq_nr = SEQ_NR_T_HTON(seq_nr);
90 void EncryptedPacket::setSenderId(sender_id_t sender_id)
92 if(header_)
93 header_->sender_id = SENDER_ID_T_HTON(sender_id);
96 void EncryptedPacket::setMux(mux_t mux)
98 if(header_)
99 header_->mux = MUX_T_HTON(mux);
102 void EncryptedPacket::setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
104 if(!header_)
105 return;
107 header_->seq_nr = SEQ_NR_T_HTON(seq_nr);
108 header_->sender_id = SENDER_ID_T_HTON(sender_id);
109 header_->mux = MUX_T_HTON(mux);
112 u_int32_t EncryptedPacket::getPayloadLength() const
114 if(!payload_)
115 return 0;
117 if(!auth_tag_)
118 return (length_ > sizeof(struct HeaderStruct)) ? (length_ - sizeof(struct HeaderStruct)) : 0;
120 return (length_ > (sizeof(struct HeaderStruct) + AUTHTAG_SIZE)) ? (length_ - sizeof(struct HeaderStruct) - AUTHTAG_SIZE) : 0;
123 void EncryptedPacket::setPayloadLength(u_int32_t payload_length)
125 Buffer::setLength(payload_length + sizeof(struct HeaderStruct));
126 // depending on allow_realloc buf_ may point to another address
127 // therefore in this case reinit() gets called by Buffer::setLength()
130 void EncryptedPacket::reinit()
132 header_ = reinterpret_cast<struct HeaderStruct*>(buf_);
133 payload_ = buf_ + sizeof(struct HeaderStruct);
135 if(length_ <= (sizeof(struct HeaderStruct)))
136 payload_ = NULL;
138 if(length_ < (sizeof(struct HeaderStruct))) {
139 header_ = NULL;
140 throw std::runtime_error("packet can't be initialized, buffer is too small");
143 if(auth_tag_)
145 if(length_ < (sizeof(struct HeaderStruct) + AUTHTAG_SIZE)) {
146 auth_tag_ = NULL;
147 throw std::runtime_error("auth-tag can't be enabled, buffer is too small");
149 auth_tag_ = buf_ + length_ - AUTHTAG_SIZE;
153 u_int8_t* EncryptedPacket::getPayload()
155 return payload_;
158 u_int8_t* EncryptedPacket::getAuthenticatedPortion()
160 return buf_;
163 u_int32_t EncryptedPacket::getAuthenticatedPortionLength()
165 if(!buf_)
166 return 0;
168 if(!auth_tag_)
169 return length_;
171 return (length_ > AUTHTAG_SIZE) ? (length_ - AUTHTAG_SIZE) : 0;
174 void EncryptedPacket::withAuthTag(bool b)
176 if((b && auth_tag_) || (!b && !auth_tag_))
177 return;
179 if(b)
181 if(length_ < (sizeof(struct HeaderStruct) + AUTHTAG_SIZE))
182 throw std::runtime_error("auth-tag can't be enabled, buffer is too small");
184 auth_tag_ = buf_ + length_ - AUTHTAG_SIZE;
186 else
187 auth_tag_ = NULL;
190 void EncryptedPacket::addAuthTag()
192 if(auth_tag_)
193 return;
195 auth_tag_ = buf_; // will be set to the correct value @ reinit
196 setLength(length_ + AUTHTAG_SIZE);
197 if(auth_tag_ == buf_) // reinit was not called by setLength
198 reinit();
201 void EncryptedPacket::removeAuthTag()
203 if(!auth_tag_)
204 return;
206 auth_tag_ = NULL;
207 setLength(length_ - AUTHTAG_SIZE);
210 u_int8_t* EncryptedPacket::getAuthTag()
212 return auth_tag_;
215 u_int32_t EncryptedPacket::getAuthTagLength()
217 if(auth_tag_)
218 return AUTHTAG_SIZE;
220 return 0;