n2n/n2n_keyfile.h

118 lines
4.7 KiB
C

/**
* (C) 2007-18 - ntop.org and contributors
*
* This program 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 see <http://www.gnu.org/licenses/>
*
*/
/** Key files
*
* Edge implements a very simple interface for getting instructions about
* rolling keys.
*
* Key definitions are written as individual files in <transform>/<sa>.key. The
* format of each key is a single line of hex nibbles as follows:
*
* 0102030405060708090a0b0c0d0e0f
*
* Any external key exchange mechanism can receive the key data write it into
* the keyfiles.
*
* To control which keys are active at what times the key control file is
* used. This is a single file which is periodically reread. It contains key
* definitions in chronological order with one line per key definition as
* follows:
*
* <valid_from> <valid_until> <transform> <opaque>
*
* edge reads the key control file periodically to get updates in policy. edge
* holds a number of keys in memory. Data can be decoded if it was encoded by
* any of the keys still in memory. By having at least 2 keys in memory it
* allows for clock skew and transmission delay when encoder and decoder roll
* keys at slightly different times. The amount of overlap in the valid time
* ranges provides the tolerance to timing skews in the system.
*
* The keys have the same level of secrecy as any other user file. Existing
* UNIX permission systems can be used to provide access controls.
*
*/
/** How Edge Uses The Key Schedule
*
* Edge provides state space for a number of transform algorithms. Each
* transform uses its state space to store the SA information for its keys as
* found in the key file. When a packet is received the transform ID is in
* plain text. The packets is then sent to that transform for decoding. Each
* transform can store its SA numbers differently (or not at all). The
* transform code then finds the SA number, then finds the cipher (with key) in
* the state space and uses this to decode the packet.
*
* To support this, as edge reads each key line, it passes it to the
* appropriate transform to parse the line and store the SA information in its
* state space.
*
* When encoding a packet, edge has several transforms and potentially valid
* SAs to choose from. To keep track of which one to use for encoding edge does
* its own book-keeping as each key line is passed to the transform code: it
* stores a lookup of valid_from -> transform. When encoding a packet it then
* just calls the transform with the best valid_from in the table. The
* transform's own state space has all the SAs for its keys and the best of
* those is chosen.
*/
#if !defined( N2N_KEYFILE_H_ )
#define N2N_KEYFILE_H_
#include "n2n_wire.h"
#include <time.h>
#define N2N_MAX_KEYSIZE 256 /* bytes */
#define N2N_MAX_NUM_CIPHERSPECS 8
#define N2N_KEYPATH_SIZE 256
#define N2N_KEYFILE_LINESIZE 256
/** This structure stores an encryption cipher spec. */
struct n2n_cipherspec
{
n2n_transform_t t; /* N2N_TRANSFORM_ID_xxx for this spec. */
time_t valid_from; /* Start using the key at this time. */
time_t valid_until; /* Key is valid if time < valid_until. */
uint16_t opaque_size; /* Size in bytes of key. */
uint8_t opaque[N2N_MAX_KEYSIZE];/* Key matter. */
};
typedef struct n2n_cipherspec n2n_cipherspec_t;
static const char * const DELIMITERS=" \t\n\r";
/** @return number of cipherspec items filled. */
int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */
size_t numspecs, /* number of slots in the array. */
const char * ctrlfile_path ); /* path to control file */
int validCipherSpec( const n2n_cipherspec_t * k,
time_t now );
ssize_t n2n_parse_hex( uint8_t * keyBuf,
size_t keyMax,
const char * textKey,
size_t textLen );
/*----------------------------------------------------------------------------*/
#endif /* #if !defined( N2N_KEYFILE_H_ ) */