Another night's work - move to ECDH + AES256 from RSA pubkey

This commit is contained in:
Nick Thomas
2013-08-08 00:48:02 +01:00
parent c77557b6ee
commit 118b7b8125
10 changed files with 364 additions and 148 deletions

View File

@@ -1,7 +1,6 @@
#!/usr/bin/make -f
CFLAGS := $(CFLAGS) -Wall -Werror --std=c99
LDFLAGS := $(LDFLAGS) -ljson-c -lssl -lcrypto
CFLAGS := $(CFLAGS) -Wall -Werror --std=c99
LDFLAGS := $(LDFLAGS) -ljson-c -lssl -lcrypto
.PHONY: clean

View File

@@ -108,7 +108,11 @@ int wrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* o
unsigned short *pkt_enc_size = (unsigned short *) scratch;
scratch += 2;
enc_size = rloc_encrypt( d_rloc, (unsigned char *)&pkt->hdr, bytes_to_encrypt, scratch, enc_max_len - 2 );
enc_size = rlocs_encrypt(
reg, s_rloc, d_rloc,
(unsigned char *)&pkt->hdr, bytes_to_encrypt, scratch, enc_max_len - 2
);
if ( enc_size < 0 ) {
warn( "failed to encrypt, dropping packet" );
return 0;
@@ -118,8 +122,6 @@ int wrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* o
enc_size += 2;
scratch = (unsigned char*) pkt_enc_size;
warn( "Encrypted size: 2 + %zu", enc_size - 2);
out->iovs[1].iov_base = scratch;
@@ -163,12 +165,19 @@ int unwrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data*
return 0;
}
// We need to know destination rloc to decrypt the packet
struct rloc* rloc;
// We need to know source and destination rloc to decrypt the packet
struct rloc *s_rloc, *d_rloc;
struct in_addr tmp;
tmp.s_addr = pkt->hdr.ip.saddr;
if ( ( s_rloc = rloc_find_by_address( reg, &tmp, NULL ) ) == NULL ) {
warn( "Couldn't find rloc from source IP, dropping packet" );
// TODO: we should be able to specify we need it to have a private key
return 0;
}
tmp.s_addr = pkt->hdr.ip.daddr;
if ( ( rloc = rloc_find_by_address( reg, &tmp, NULL ) ) == NULL ) {
if ( ( d_rloc = rloc_find_by_address( reg, &tmp, NULL ) ) == NULL ) {
warn( "Couldn't find rloc from destination IP, dropping packet" );
// TODO: we should be able to specify we need it to have a private key
return 0;
@@ -182,7 +191,10 @@ int unwrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data*
unsigned char *encrypted_data = ((unsigned char *)pkt) + hdr_size + 2;
unsigned char *scratch = &out->scratch[0];
int decrypted_size = rloc_decrypt( rloc, encrypted_data, encrypted_size, scratch, IP_MAXPACKET );
int decrypted_size = rlocs_decrypt(
reg, d_rloc, s_rloc,
encrypted_data, encrypted_size, scratch, IP_MAXPACKET
);
if ( decrypted_size < 0 ) {
warn( "Failed to decrypt packet!" );

View File

@@ -2,77 +2,25 @@
"type": "rloc-registry",
"eid_rloc_map": [
{ "family":"ipv4", "network":"172.16.10.0", "netmask":24, "rloc":"172.16.10.2"},
{ "family":"ipv4", "network":"172.16.11.0", "netmask":24, "rloc":"172.16.10.2"},
{ "family":"ipv4", "network":"172.16.12.0", "netmask":24, "rloc":"172.16.12.2"},
{ "family":"ipv6", "network":"fc00:1::", "netmask":64, "rloc":"fc00::2" },
{ "family":"ipv6", "network":"fc00:2::", "netmask":64, "rloc":"fc00:2::2" }
{ "family":"ipv4", "network":"172.16.10.0", "netmask":24, "rloc":"81.187.47.40"},
{ "family":"ipv4", "network":"172.16.11.0", "netmask":24, "rloc":"213.138.102.147"}
],
"keys": {
"172.16.10.2":
"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0FxctMUibDqkVhChIvJg
6GhzKzaMEKza+9MhO1H0VEnvgMsvZ6S15iSxHVxiO5KpjwYAakW4ELLK7We+exsH
zOSAioh1Po3uxTLga7PrEvLkv7hI/2vxWPYk2j2j++WHKXjyNoAKpdC5nrauRPT2
DAlbRcRu9gnhLIIDu/HCLLxT1qQgWOaVZBJVxxcPYwrBPSjDAvKn5GKbN8wh4k1h
WIkedhHIjzM7mYQfXTaJttP2+9Gco5sOntKVldy2nGWWtaPDtlMmmCdclgrBpxT9
EPEZ+H9ApPWHAMEgVvLn9nKPNJ/06jPFEcA5ZEtu6N+lPjkjRU9JfuMPt/jz3otY
1iA/Utx1tQQqEzote5V5zxHnBcYtqtftf7PKANVfPnLQxQ9msKmrcBb0bNwn3KdX
pavbsPp5W4WGFalt499u3CGmd6AQ9/tZfafTEsAPCpNQrfZ4v0AVIiT6ZuQQ1Vip
q14pHlpN3xepxwHZtCJTyU7kHaWKvImFZRY6dg0dRkvWl2bO6xJsYYXTaYHre+Sx
ivtEZcM7VPEZlQyBlwTYYHmnllBlnXMJpx20p26Sy4iPX6hzn9sT3UQHE6NAlfON
He5Cw+4ma5DA2jQvvIBfYA1ipVfGKD8LyrPrxuD9qErYpPBP23EdJwT0ZL+jKjyT
t39smrDydkWUQWYPiiUKKM0CAwEAAQ==
-----END PUBLIC KEY-----",
"172.16.12.2":
"81.187.47.40":
"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvYljSQd/jHZtSTc6Z2E1
6D37s/MDGmWux/0ulRLsnGRnIj/cd8b3wV2AKbucjEOZ70MH5mU3szz/eZwD5z3A
hU+2ok9GV3vL1COg692RRV9ydizxc/8PduYyojeBiOgwBQvCS0PM6IcEDbNvgtfY
yzcnMf56Iadqukp5ovCZU/xl4zPMNwtVonMoeOgpdPBd9POBAhXI5zvZDEIF+PM3
Lfuy+ybn5alJKDQwWE2tjWnNWx3e34JKTulN7xC9Cw4xw+zmoG5GYua5RtM7AYsJ
cCBmF4V3XhpPnxgGhO5S3tKWyke317FjNBqbG1Gj30ADYliHZI1KEQbaXCHxB8lQ
bII6OEz9liz4QNSDd2iTInA7yv2djOIdEoPCgtY7oXQZi5Ch8q2M9sAVGAyyF2sR
2SlUiP0fuH2S5CviI/5KKTHMA8HNg2rH6gPeTDiLDluw+oL3tIy3XEmhUJS3ZSzG
PhN1So0n3XwsnAUWvm33ujTtvAGTuUwBKsG8nIb3iwr7Vh8O617yuOl7ab68Dxym
fJZZE5wzjzYbNxup8E9VSfHKSCUHptg9cB/1kF5HoshZCZwA62eAtQgaamr64NrT
Uuyz1Ng3KTiD1cObXeirB88yyYd1W21deRfGaGZlWpJTAMjy/bXjR6ZAA+xTXllO
QFqgpMLJRNxWj7UUOWm3xjECAwEAAQ==
-----END PUBLIC KEY-----",
MD4wEAYHKoZIzj0CAQYFK4EEAB4DKgAEdlvMHCK1rsACyk53Oo5PEfmj/ZON3oKt
wXgyHsydIb6JMt2tD3bFZA==
-----END PUBLIC KEY-----",
"fc00::2":
"213.138.102.147":
"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnQhQ9S190q/+t0/QqplD
+aRHLrVm8oWFHKqfaE11zZ+7adse4NFgzEWMRN2bUIl47W/VuTHn3NtsF3myYjtX
n9bXW/fibVj1xFXk5qpsHvC1xgdUTP3msqiEXigHIgJKgaTCDOaYykfBaFKNP334
Dz0mZ4xTmMwmp/9MEiaj8ieFWBTJ5+QFJZCwYUCNGI3hWaXrmlNoKBIj4vfpnFv1
MUSCcvc3yl4+KBnIqq0rNfQqlvwNl1NfI2P80eGKW6urQSIjxqb966pOilVePoj8
iY8LUtT4WknCacM1oi9rVE0sjtZxeLUs5EuToFn6O2L576SJvNg9GvGA4YmqPTkS
fkxunarY+I7frdZyTWg/Bgr5rWXP7QJ5VY11VbsTo7vGblWQ6MqYH00owGuKXFqg
7Fl+dr+Ko3uLLnWXF92f4xvP5//0YmRADDGNu1Elgr7NxEoIe7iWFuaga2tV3BPf
//3nneHhPv3d4OYnImMQLih+OF25hfYFI8V1ef5dpKXuSNQ01nxIexRHTd0sQnTS
Agq3TFQzB5U54k554plWUjPvHFvUDmCyAdTAEn2/0xJQZ3X1RqFZfzjW+rcARjnt
lxtMZOyE1S1kAg0HS0uEGLYrIp0K+moEKhm3Upvv3ad3FP1695tJUBec0KH8/PbX
XlTdlmviw5Fo15QnPOLcsW8CAwEAAQ==
-----END PUBLIC KEY-----",
MD4wEAYHKoZIzj0CAQYFK4EEAB4DKgAEaDuTFicM87FKVqEHUMGW4BaFz9GAwjAC
+pnmMUh00yFgDEyi6ozUrw==
-----END PUBLIC KEY-----"
"fc00:2::2":
"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt/rGbJ46DIciiRHaknkV
pQ0ulKtZl5UApOaKTP8SxuEoDDrUZ7w3FnItPYkDh41RisVf7hBAKe+BwCRxodo0
++MeMcbrWG16rT/2AVi7V5te936L3O/WiF/BFgWXgJ1+bgXlZlIsJWLqMT5ozcaM
XRIosgoYMkvvS4tBYLwQIx3ov+PVfZELOmqtoesv5e70Xg0iXNVb57wTnsnBPHo0
u4Pw1oSsqDNM4oblDwXtfJEUMcBA+q12L5lqBEnXGlFQgeViCFnpaR03oc0btn0S
PZtAgZ88WPdnf+jAeSeEnVvTmhQtNxmnZXtEy/T0emD+163/lpcr7vIK/iFXvZsx
Bf2xdRs7EU/6M+YaE8rhI/uTNgMpR2RGAIyQn8aGCydGf/FCxXMBg99mk5R0h2cD
BkGyVbmFzXrsoitw5Foz/JC5svvoR/z16w/+lIbRRx2OMSaMtoRqYO6At2GC30TZ
DSDQ5nNOo4hmySZnrEWq+t4BJjJ1wu7eAJpsCVXkyRZUtNt6c98VaAuJQv7FHW/O
75XaEHewVAAGTmQEjI/cTY72bHkbtE3vpi0aK8Wc7K4g7slUld0HUsh8xszIhdxu
8Y+yuP72oOpicPK8LCDyI28V0HCz44bo1TDrDUC0YZ1fDr8Pk2A+jrlt4/yMcgkn
PBcctUqN/b2cIfCA8UDAMZ0CAwEAAQ==
-----END PUBLIC KEY-----"
}

View File

@@ -17,30 +17,41 @@
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <json/json_tokener.h>
#include <json/linkhash.h>
#include <arpa/inet.h>
#include "util.h"
//#include "util.h"
#include "rlocs.h"
#define JSON_TYPE "rloc-registry"
void show_ssl_errors(void)
{
ERR_print_errors_fp(stderr);
return;
}
void rlocs_init(void)
{
uint32_t seed;
SSL_load_error_strings(); /* readable error messages */
SSL_library_init(); /* initialize library */
OpenSSL_add_all_algorithms();
// set the random seed to something good
if ( RAND_bytes( (unsigned char*)&seed, sizeof( uint32_t ) ) != 1 ) {
warn( "Failed to initialize random seed" );
show_ssl_errors();
exit(1);
}
srand( seed );
return;
}
@@ -50,7 +61,8 @@ int rlocs_rloc_from_json(struct rlocs* reg, const char* key, json_object* val )
ssize_t pem_data_size;
const char* pem_data;
struct rloc *rloc;
RSA *rsa_key, *result;
EVP_PKEY *evp_key = NULL;
EC_KEY *ec_key = NULL;
BIO *bp;
if ( !json_object_is_type( val, json_type_string ) ) {
@@ -80,20 +92,47 @@ int rlocs_rloc_from_json(struct rlocs* reg, const char* key, json_object* val )
pem_data = json_object_get_string( val );
pem_data_size = json_object_get_string_len( val );
rsa_key = RSA_new();
bp = BIO_new_mem_buf( (void*)pem_data, pem_data_size );
result = PEM_read_bio_RSA_PUBKEY( bp, &rsa_key, NULL, NULL );
BIO_vfree( bp );
if ( result == NULL ) {
RSA_free( rsa_key );
warn( "Couldn't parse key for %s as an RSA public key", key );
return 0;
if ( ( evp_key = EVP_PKEY_new() ) == NULL ) {
warn( "couldn't allocate new EVP_pkey for rloc %s", key );
goto fail;
}
rloc->key = rsa_key;
if ( !( bp = BIO_new_mem_buf( (void*)pem_data, pem_data_size ) ) ) {
warn( "couldn't allocate new BIO to interpret key for rloc %s", key );
goto fail;
}
ec_key = PEM_read_bio_EC_PUBKEY( bp, &ec_key, NULL, NULL );
BIO_vfree( bp );
if ( ec_key == NULL ) {
warn( "Couldn't parse key for rloc %s as an EC secp160r2 public key", key );
goto fail;
}
// assign so we don't have to free the EC_KEY object any more
if ( !EVP_PKEY_assign_EC_KEY( evp_key, ec_key ) ) {
warn( "couldn't assign key for rloc %s to container", key );
goto fail;
}
rloc->key = evp_key;
rloc->context_id = reg->num_entries;
reg->num_entries++;
return 1;
fail:
show_ssl_errors();
if ( evp_key != NULL ) {
EVP_PKEY_free( evp_key );
}
if ( ec_key != NULL ) {
EC_KEY_free( ec_key );
}
return 0;
}
int rlocs_eid_from_json( struct rlocs *reg, json_object *map)
@@ -410,53 +449,182 @@ struct rloc *rloc_find_by_address( struct rlocs *reg, struct in_addr *ipv4, stru
*/
int rloc_add_private_key( struct rloc *rloc, char *filename )
{
BIO *key_data = BIO_new_file( filename, "r" );
RSA* key = PEM_read_bio_RSAPrivateKey( key_data, NULL, NULL, NULL );
BIO *key_data = BIO_new_file( filename, "r" );
EC_KEY* key = PEM_read_bio_ECPrivateKey( key_data, NULL, NULL, NULL );
if ( key == NULL ) {
warn( "Failed to add private key %s", filename );
return 0;
goto fail;
}
RSA_free( rloc->key );
rloc->key = key;
if ( !EVP_PKEY_assign_EC_KEY( rloc->key, key ) ) {
warn( "Failed to assign private key in %s to rloc", filename );
goto fail;
}
return 1;
fail:
show_ssl_errors();
if ( key != NULL ) {
EC_KEY_free( key );
}
return 0;
}
void show_ssl_errors(void)
int rlocs_update_key_context(struct rlocs *reg, struct rloc *x, struct rloc *y)
{
long err;
char msg[256];
struct key_context *entry = &reg->key_contexts[x->context_id][y->context_id];
unsigned char secret[1024]; // Should be enough buffer space
size_t secret_len = 1024;
while ( ( err = ERR_get_error() ) ) {
ERR_error_string( err, &msg[0] );
warn( "Error %lu in crypto: %s", err, &msg[0] );
unsigned char secret_hash[SHA256_DIGEST_LENGTH];
EVP_PKEY_CTX *ctx = NULL;
int result;
/* Create the context for the shared secret derivation */
if( ( ctx = EVP_PKEY_CTX_new( x->key, NULL ) ) == NULL) {
warn( "EVP_PKEY_CTX_new failed" );
goto fail;
}
/* Initialise */
if( ( result = EVP_PKEY_derive_init( ctx ) ) != 1 ) {
warn( "EVP_PKEY_derive_init failed: %i", result );
goto fail;
}
/* Provide the peer public key */
if( ( result = EVP_PKEY_derive_set_peer( ctx, y->key ) ) != 1 ) {
warn( "EV_PKEY_derive_set_peer failed: %i", result );
goto fail;
}
/* Derive the shared secret */
if( ( result = EVP_PKEY_derive( ctx, &secret[0], &secret_len ) ) != 1 ) {
warn( "EVP_PKEY_derive failed: %i", result );
goto fail;
}
/* SHA256 hash of the shared secret. TODO: Add a salt if we want one... */
if ( !sha256sum( &secret[0], secret_len, secret_hash ) ) {
warn( "SHA256( secret ) failed!" );
goto fail;
}
memcpy( &entry->secret[0], &secret_hash[0], SHA256_DIGEST_LENGTH );
EVP_PKEY_CTX_free( ctx );
/* Now we finally have our secret key, we can set up an AES256
* symmetric key cipher with it, which is what will be used to encrypt /
* decrypt packet data. */
EVP_CIPHER_CTX_init( &entry->ctx );
entry->in_use = 1;
return 1;
fail:
show_ssl_errors();
if ( ctx != NULL) {
EVP_PKEY_CTX_free( ctx );
}
return 0;
}
ssize_t rloc_encrypt( struct rloc *rloc, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len )
{
ssize_t result = RSA_public_encrypt( data_len, data, dest, rloc->key, RSA_PKCS1_OAEP_PADDING );
if ( result < 0 ) {
show_ssl_errors();
ssize_t rlocs_encrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len )
{
struct key_context *entry = &reg->key_contexts[x->context_id][y->context_id];
if ( !entry->in_use && !rlocs_update_key_context( reg, x, y ) ) {
warn( "Couldn't build an encryption context for these rlocs" );
return -1;
}
return result;
// FIXME: I don't know that this is good. It could be terrible.
// We use a PRNG to generate an IV per message, and put it at the start of
// the encrypted blob. Since we're using aes256 (hardcoded), IV is 128 bits
if ( dest_len < 48 ) {
warn( "dest_len must be at least 48 bytes, maybe more");
goto fail;
}
unsigned char *iv = dest;
unsigned char *secret = (unsigned char *)&entry->secret[0];
size_t written = 16;
int outl = dest_len - written;
RAND_pseudo_bytes( iv, 16 );
if ( !EVP_EncryptInit_ex( &entry->ctx, EVP_aes_256_cbc(), NULL, secret, iv ) ) {
warn( "EVP_EncryptInit_ex() failed" );
goto fail;
}
if ( !EVP_EncryptUpdate( &entry->ctx, dest + written, &outl, data, data_len ) ) {
warn( "EVP_EncryptUpdate() failed" );
goto fail;
}
written += outl;
outl = dest_len - written;
if ( !EVP_EncryptFinal_ex( &entry->ctx, dest + written, &outl ) ) {
warn( "EVP_EncryptFinal_ex() failed" );
goto fail;
}
return written + outl;
fail:
show_ssl_errors();
return -1;
}
ssize_t rloc_decrypt( struct rloc *rloc, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len )
ssize_t rlocs_decrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len )
{
ssize_t result = RSA_private_decrypt( data_len, data, dest, rloc->key, RSA_PKCS1_OAEP_PADDING );
if ( result < 0 ) {
show_ssl_errors();
struct key_context *entry = &reg->key_contexts[x->context_id][y->context_id];
if ( !entry->in_use && !rlocs_update_key_context( reg, x, y ) ) {
warn( "Couldn't build a decryption context for these rlocs" );
return -1;
}
return result;
unsigned char *iv = data;
unsigned char *secret = (unsigned char *)&entry->secret[0];
size_t written = 0;
int outl = dest_len;
if ( !EVP_DecryptInit_ex( &entry->ctx, EVP_aes_256_cbc(), NULL, secret, iv ) ) {
warn( "EVP_DecrypttInit_ex() failed" );
goto fail;
}
if ( !EVP_DecryptUpdate( &entry->ctx, dest, &outl, data, data_len ) ) {
warn( "EVP_DecryptUpdate() failed" );
goto fail;
}
written += outl;
outl = dest_len - written;
if ( !EVP_DecryptFinal_ex( &entry->ctx, dest + written, &outl ) ) {
warn( "EVP_DecryptFinal_ex() failed" );
goto fail;
}
return written + outl;
fail:
show_ssl_errors();
return -1;
}
@@ -497,7 +665,7 @@ void rlocs_free( struct rlocs* registry )
for( i = 0; i < registry->num_entries; i++ ) {
if ( registry->entries[i].key != NULL ) {
RSA_free( registry->entries[i].key );
EVP_PKEY_free( registry->entries[i].key );
}
}
// No need to do json_object_put() here.

View File

@@ -1,15 +1,30 @@
#ifndef _RLOCS_H_
#define _RLOCS_H_
#include "util.h"
#include <json/json_object.h>
#include <netinet/in.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
// For now. We can dynamically allocate later.
#define MAX_RLOCS 64
#define MAX_EID_MAPPINGS 256
struct key_context {
int in_use;
char secret[SHA256_DIGEST_LENGTH];
EVP_CIPHER_CTX ctx;
/* Probably don't need these
struct rloc *rloc_x;
struct rloc *rloc_y;
*/
};
struct rloc {
short family;
union {
@@ -17,7 +32,9 @@ struct rloc {
struct in6_addr ip6;
} addr;
RSA* key;
EVP_PKEY *key;
// We use this to index our rloc for shared keys
int context_id;
};
@@ -36,7 +53,7 @@ struct ip6_eid_map_entry {
};
struct rlocs {
json_object* config;
json_object *config;
size_t num_entries;
struct rloc entries[MAX_RLOCS];
@@ -46,6 +63,16 @@ struct rlocs {
size_t num_ip6_map_entries;
struct ip6_eid_map_entry ip6_mappings[MAX_EID_MAPPINGS];
/* Don't do this, kids.
* 2D array - [wrapping_rloc->id][unwrapping_rloc->id]
* Obviously, half of the contexts would be identical. So some rules:
* - if you're wrapping a packet, you are x. they are y
* - if you're unwrapping a packet, you are y. they are x.
* Half of the allocated memory goes unused, but we can worry about dynamic
* allocation at the same time as MAX_RLOCS and MAX_EID_MAPPINGS
*/
struct key_context key_contexts[MAX_RLOCS][MAX_RLOCS];
};
@@ -62,8 +89,8 @@ int rloc_add_private_key( struct rloc *rloc, char *filename );
void rlocs_debug_output( struct rlocs *reg );
/* Returns -1 on error, or number of bytes written */
ssize_t rloc_encrypt( struct rloc *rloc, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len );
ssize_t rloc_decrypt( struct rloc *rloc, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len );
ssize_t rlocs_encrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len );
ssize_t rlocs_decrypt( struct rlocs *reg, struct rloc *x, struct rloc *y, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len );
void rlocs_free( struct rlocs *registry );

View File

@@ -1,5 +1,4 @@
#include "util.h"
#include "rlocs.h"
#include <unistd.h>
#include <sys/types.h>
@@ -187,4 +186,22 @@ void session_teardown( struct session *session )
if ( session->output_if >= 0 && !session->same_if ) {
close( session->output_if );
}
}
// TODO: we can speed this one up, if necessary, by re-using the context.
// TODO: some error-checking
int sha256sum( unsigned char *src, size_t src_len, unsigned char dst[SHA256_DIGEST_LENGTH] )
{
unsigned int size = SHA256_DIGEST_LENGTH;
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex( ctx, EVP_sha256(), NULL );
EVP_DigestUpdate( ctx, src, src_len );
EVP_DigestFinal_ex( ctx, &dst[0], &size );
EVP_MD_CTX_destroy( ctx );
return size == SHA256_DIGEST_LENGTH;
}

View File

@@ -1,10 +1,14 @@
#ifndef _UTIL_H_
#define _UTIL_H
#define _UTIL_H_
#include "rlocs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#define info(msg, ...) { fprintf( stdout, msg, ##__VA_ARGS__ ) ; fprintf( stdout, "\n" ); }
#define warn(msg, ...) { fprintf( stderr, msg, ##__VA_ARGS__ ) ; fprintf( stderr, "\n" ); }
@@ -31,6 +35,8 @@ int session_setup( struct session *session, char *config_file, char *listen_if,
int session_upgrade_rlocs( struct session *session, int argc, char** args );
void session_teardown( struct session *session );
int sha256sum( unsigned char *src, size_t src_len, unsigned char dst[SHA256_DIGEST_LENGTH] );
#endif

View File

@@ -23,8 +23,8 @@ int main(int argc, char** argv)
ssize_t count;
int result;
if ( argc < 4 ) {
warn( "Usage: %s <rloc database> <listen_ifname> <output_ifname>", argv[0] );
if ( argc < 6 ) {
warn( "Usage: %s <rloc database> <listen_ifname> <output_ifname> <rloc> <keyfile> [<rloc> <keyfile>]n", argv[0] );
return 1;
}