1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/*
*
* OpenSAND is an emulation testbed aiming to represent in a cost effective way a
* satellite telecommunication system for research and engineering activities.
*
*
* Copyright © 2014 TAS
*
*
* This file is part of the OpenSAND testbed.
*
*
* OpenSAND is free software : you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* 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. If not, see http://www.gnu.org/licenses/.
*
*/
/**
* @file UleExtSecurity.cpp
* @brief Optional Security ULE extension
* @author Didier Barvaux <didier.barvaux@toulouse.viveris.com>
*/
#include "UleExtSecurity.h"
#include <opensand_output/Output.h>
#include <cryptopp/arc4.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <iostream>
#include <string>
using namespace CryptoPP;
using namespace std;
UleExtSecurity::UleExtSecurity(): UleExt()
{
this->is_mandatory = false; //sould be true
/*
* TODO: Need to ask didier about this behavior. Could be something with
* hdr_len in the decode process
*/
this->_type = 0x10; //secure ULE type can be changed later
}
UleExtSecurity::~UleExtSecurity()
{
}
ule_ext_status UleExtSecurity::build(uint16_t ptype, Data payload)
{
// TODO: the length of the extension is currently arbitrary choosen,
// Length is 1 * 32 bits + 1 * 16-bit field (next payload type field)
/* get the ULE-SID from database --manual text tab delimited text file
* in te future use hash structures-- quicker
* This should also give the necessary keys and length to fill in
* CLASS KEY_STORAGE get_sad_data(int ULE_SID); */
int i;
int ULE_SID = 4444;
int uli_netval = htonl(ULE_SID); //convert host to network for integers
unsigned char temp[4];
int plen;
byte *p;
ARC4 rc4((unsigned char *)"12345678", 8);
this-> _payload.clear(); //very important doesnt work without that
for(i = 0; i < 4; i++)
{
temp[i]= '\0';
}
memcpy( temp, &uli_netval, 4);
// this->_payload is where we append all the extra security header stuff
// in the future like integrity check and seq numbers.
this->_payload.append(temp,4);
// this->_payload.append(4 * 2, 0x00);
// here is the next payload which is the ip payload
// add the next header/payload
this->_payload.append(1, (ptype >> 8) & 0xff);
this->_payload.append(1, ptype & 0xff);
// do the encryption here
// need to copy the the string object to a char type
// get the key from the ULE_SID
// now put it into the rc4 stream cipher with the length of the keys
plen = payload.length();
p = new byte[plen];
memcpy(p, payload.c_str(), plen);
rc4.ProcessString(p, plen);
payload.clear();
//append the encrypted output to payload object
payload.append(p, plen);
delete []p;
//add the encrypted payload
this->_payload += payload;
//printf("\n the length of the ULE payload is %d\n", this->_payload.length());
//
// build the Next Header field for this extension
// - 5-bit zero prefix
// - 3-bit H-LEN field (= 3 is choosen for the moment)
// - 8-bit H-Type field (= 0x10 type of Security extension)
this->_payloadType = ((3 & 0x07) << 8) | (this->type() & 0xff);
return ULE_EXT_OK;
}
ule_ext_status UleExtSecurity::decode(uint8_t hlen, Data payload)
{
ARC4 rc4d((unsigned char *)"12345678",8);
int i;
int plen;
byte *p;
// extension is optional, hlen must be 1-5
if(hlen < 1 || hlen > 5)
{
LOG(ule_log, LEVEL_ERROR,
"optional extension, but hlen (0x%x) != 1-5\n",
hlen);
goto error;
}
// check if payload is large enough
if(payload.length() < (size_t) hlen * 2)
{
LOG(ule_log, LEVEL_ERROR,
"too few data (%u bytes) for %d-byte extension\n",
payload.length(), hlen * 2);
goto error;
}
/*
* this is where we need to first separate the payload to decrypt
* with the security header extension
* size of ULE_SID --always present is 4 bytes
* if we have additonal components then we should know how long it will be
* for example after the ULE-SID there might be 4 byte seq num followed by
* 20 byte HMAC using SHA1 algo so the overall length of the header is
* 4(ULE-SID)+4(seq. num) + 20 (hmac)=28
* in this case the lines below will be
* this->_payloadType = (payload.at(28 - 2) << 8) |
* payload.at(28 - 1);
* this->_payload = payload.substr(28);
*/
printf("\n the size of the payload is %d\n", payload.length());
this->_payloadType = (payload.at(hlen * 2 - 2) << 8) |
payload.at(hlen * 2 - 1);
printf("\n the payload type is %u\n",this->_payloadType);
this->_payload = payload.substr(hlen * 2);
// printf("\n the size of the payload is %d\n", this->_payload.length());
// start decrypting
// int ULE_SID=4444;
// int uli_netval=htonl(ULE_SID); //convert host to network for integers
// unsigned char temp[4];
// for( int i=0;i<4;i++)
// temp[i]= '\0';
// memcpy(temp,&uli_netval,4);
// this->_payload is where we append all the extra security header stuff
// in the future like integrity check and seq numbers.
// now put it into the rc4 stream cipher with the length of the keys
plen = this->_payload.length();
p = new byte[plen];
memcpy(p, this->_payload.c_str(), plen);
rc4d.ProcessString(p, plen);
this->_payload.clear();
//append the decrypted output to payload object
this->_payload.append(p, plen);
delete []p;
return ULE_EXT_OK;
error:
return ULE_EXT_ERROR;
}
|