Update to make AES encryption modes selectable
This is a significant update to allow AES encryption modes to be selected on a per-key basis. For now, only ECB and CBC (recommended) modes are supported. The default is ECB modes in order to maintain backwards compatibility with the older perl version of fwknop and the Crypt::CBC CPAN module. This will likely be changed to use CBC mode by default because of its better security properties. In the access.conf file on the server side, there is a new configuration variable "ENCRYPTION_MODE" that controls the mode for the corresponding AES key. On the client side, a new command line argument "--encryption-mode" controls how the client encrypts SPA packets.
This commit is contained in:
+3
-1
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
enum {
|
||||
FKO_DIGEST_NAME = 0x100,
|
||||
ENCRYPTION_MODE,
|
||||
NAT_LOCAL,
|
||||
NAT_PORT,
|
||||
NAT_RAND_PORT,
|
||||
@@ -55,7 +56,7 @@ enum {
|
||||
|
||||
/* Our getopt_long options string.
|
||||
*/
|
||||
#define GETOPTS_OPTION_STRING "a:A:bB:C:D:f:gG:hH:lm:n:N:p:P:Q:rRsS:Tu:U:vV"
|
||||
#define GETOPTS_OPTION_STRING "a:A:bB:C:D:f:gG:hH:lm:M:n:N:p:P:Q:rRsS:Tu:U:vV"
|
||||
|
||||
/* Our program command-line options...
|
||||
*/
|
||||
@@ -69,6 +70,7 @@ static struct option cmd_opts[] =
|
||||
{"server-cmd", 1, NULL, 'C'},
|
||||
{"digest-type", 1, NULL, FKO_DIGEST_NAME},
|
||||
{"destination", 1, NULL, 'D'},
|
||||
{"encryption-mode", 1, NULL, ENCRYPTION_MODE},
|
||||
{"fw-timeout", 1, NULL, 'f'},
|
||||
{"gpg-encryption", 0, NULL, 'g'},
|
||||
{"gpg-recipient-key", 1, NULL, GPG_RECIP_KEY },
|
||||
|
||||
+46
-4
@@ -33,9 +33,9 @@
|
||||
#include "cmd_opts.h"
|
||||
#include "utils.h"
|
||||
|
||||
/* Convert a digest_type string to its intger value.
|
||||
/* Convert a digest_type string to its integer value.
|
||||
*/
|
||||
static int
|
||||
static short
|
||||
digest_strtoint(const char *dt_str)
|
||||
{
|
||||
if(strcasecmp(dt_str, "md5") == 0)
|
||||
@@ -52,7 +52,28 @@ digest_strtoint(const char *dt_str)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Convert a protocol string to its intger value.
|
||||
/* Convert an encryption_mode string to its integer value.
|
||||
*/
|
||||
static int
|
||||
enc_mode_strtoint(const char *enc_mode_str)
|
||||
{
|
||||
if(strcasecmp(enc_mode_str, "cbc") == 0)
|
||||
return(FKO_ENC_MODE_CBC);
|
||||
else if(strcasecmp(enc_mode_str, "ecb") == 0)
|
||||
return(FKO_ENC_MODE_ECB);
|
||||
else if(strcasecmp(enc_mode_str, "cfb") == 0)
|
||||
return(FKO_ENC_MODE_CFB);
|
||||
else if(strcasecmp(enc_mode_str, "pcbc") == 0)
|
||||
return(FKO_ENC_MODE_PCBC);
|
||||
else if(strcasecmp(enc_mode_str, "ofb") == 0)
|
||||
return(FKO_ENC_MODE_OFB);
|
||||
else if(strcasecmp(enc_mode_str, "ctr") == 0)
|
||||
return(FKO_ENC_MODE_CTR);
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Convert a protocol string to its integer value.
|
||||
*/
|
||||
static int
|
||||
proto_strtoint(const char *pr_str)
|
||||
@@ -290,6 +311,15 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
|
||||
else
|
||||
options->time_offset_plus = parse_time_offset(val);
|
||||
}
|
||||
/* symmetric encryption mode */
|
||||
else if(CONF_VAR_IS(var, "ENCRYPTION_MODE"))
|
||||
{
|
||||
tmpint = enc_mode_strtoint(val);
|
||||
if(tmpint < 0)
|
||||
return(-1);
|
||||
else
|
||||
options->encryption_mode = tmpint;
|
||||
}
|
||||
/* Use GPG ? */
|
||||
else if(CONF_VAR_IS(var, "USE_GPG"))
|
||||
{
|
||||
@@ -724,7 +754,19 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
case FKO_DIGEST_NAME:
|
||||
if((options->digest_type = digest_strtoint(optarg)) < 0)
|
||||
{
|
||||
fprintf(stderr, "* Invalid digest type: %s\n", optarg);
|
||||
fprintf(stderr,
|
||||
"* Invalid digest type: %s, use {md5,sha1,sha256,sha384,sha512}\n",
|
||||
optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
case ENCRYPTION_MODE:
|
||||
if((options->encryption_mode = enc_mode_strtoint(optarg)) < 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"* Invalid encryption mode: %s, use {cbc,ecb}\n",
|
||||
optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
+29
-2
@@ -252,6 +252,23 @@ main(int argc, char **argv)
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
res = fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_set_spa_encryption_mode", res);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if(options.encryption_mode && !options.use_gpg)
|
||||
{
|
||||
res = fko_set_spa_encryption_mode(ctx, options.encryption_mode);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_set_spa_encryption_mode", res);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set Digest type.
|
||||
@@ -328,13 +345,20 @@ main(int argc, char **argv)
|
||||
* an empty context, populate it with the encrypted data, set our
|
||||
* options, then decode it.
|
||||
*/
|
||||
res = fko_new_with_data(&ctx2, spa_data, NULL);
|
||||
res = fko_new_with_data(&ctx2, spa_data, NULL, ctx->encryption_mode);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_new_with_data", res);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = fko_set_spa_encryption_mode(ctx2, ctx->encryption_mode);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_set_spa_encryption_mode", res);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* See if we are using gpg and if we need to set the GPG home dir.
|
||||
*/
|
||||
if(options.use_gpg)
|
||||
@@ -770,6 +794,7 @@ display_ctx(fko_ctx_t ctx)
|
||||
time_t timestamp = 0;
|
||||
short msg_type = -1;
|
||||
short digest_type = -1;
|
||||
int encryption_mode = -1;
|
||||
int client_timeout = -1;
|
||||
|
||||
/* Should be checking return values, but this is temp code. --DSS
|
||||
@@ -784,6 +809,7 @@ display_ctx(fko_ctx_t ctx)
|
||||
fko_get_spa_server_auth(ctx, &server_auth);
|
||||
fko_get_spa_client_timeout(ctx, &client_timeout);
|
||||
fko_get_spa_digest_type(ctx, &digest_type);
|
||||
fko_get_spa_encryption_mode(ctx, &encryption_mode);
|
||||
fko_get_encoded_data(ctx, &enc_data);
|
||||
fko_get_spa_digest(ctx, &spa_digest);
|
||||
fko_get_spa_data(ctx, &spa_data);
|
||||
@@ -798,7 +824,8 @@ display_ctx(fko_ctx_t ctx)
|
||||
printf(" Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access);
|
||||
printf(" Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth);
|
||||
printf(" Client Timeout: %u\n", client_timeout);
|
||||
printf(" Digest Type: %u\n", digest_type);
|
||||
printf(" Digest Type: %d\n", digest_type);
|
||||
printf("Encryption Mode: %d\n", encryption_mode);
|
||||
printf("\n Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data);
|
||||
printf("\nSPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest);
|
||||
printf("\nFinal Packed/Encrypted/Encoded Data:\n\n%s\n\n", spa_data);
|
||||
|
||||
@@ -116,7 +116,8 @@ typedef struct fko_cli_options
|
||||
unsigned int spa_dst_port;
|
||||
unsigned int spa_src_port; /* only used with --source-port */
|
||||
|
||||
unsigned int digest_type;
|
||||
short digest_type;
|
||||
int encryption_mode;
|
||||
|
||||
/* Various command-line flags */
|
||||
unsigned char verbose; /* --verbose mode */
|
||||
|
||||
+19
-6
@@ -1,5 +1,5 @@
|
||||
:man source: Fwknop Client
|
||||
:man manual: Fwknop Client
|
||||
:man manual: Fwknop Client
|
||||
|
||||
FWKNOP(8)
|
||||
=========
|
||||
@@ -38,7 +38,7 @@ sequence on the server to break port knocking authentication.
|
||||
SPA packets can easily be spoofed as well (this is a good thing in this
|
||||
context), and this makes it possible to make it appear as though, say,
|
||||
www.yahoo.com is trying to authenticate to a target system but in reality
|
||||
the actual connection will come from a seemingly unrelated IP.
|
||||
the actual connection will come from a seemingly unrelated IP.
|
||||
|
||||
Authorization packets are either encrypted with the 'Rijndael' block cipher
|
||||
or via 'GnuPG' and associated asymmetric ciphers. If the symmetric encryption
|
||||
@@ -161,10 +161,10 @@ SPA OPTIONS
|
||||
*-a, --allow-ip*='<IP-address>'::
|
||||
Specify IP address that should be permitted through the destination
|
||||
*fwknopd* server firewall (this IP is encrypted within the SPA packet
|
||||
itself). This is useful to prevent a MTIM attack where a SPA packet
|
||||
itself). This is useful to prevent a MITM attack where a SPA packet
|
||||
can be intercepted en-route and sent from a different IP than the
|
||||
original. Hence, if the *fwknopd* server trusts the source address
|
||||
on the SPA packet IP header then the attacker gains access.
|
||||
on the SPA packet IP header then the attacker gains access.
|
||||
The *-a* option puts the source address within the encrypted SPA
|
||||
packet, and so thwarts this attack. The *-a* option is also
|
||||
useful to specify the IP that will be granted access when the
|
||||
@@ -197,6 +197,15 @@ SPA OPTIONS
|
||||
Specify the message digest algorithm to use in the SPA data. Choices
|
||||
are: *MD5*, *SHA1*, *SHA256* (the default), *SHA384*, and *SHA512*.
|
||||
|
||||
*-M, --encryption-mode*='<mode>'::
|
||||
Specify the encryption mode when AES is used. The default (for now) is
|
||||
ECB mode in order to remain backwards compatible with pre-2.0 versions of
|
||||
fwknop which relied on the Crypt::CBC perl module. This will be changed
|
||||
in an upcoming version of fwknop to use the more secure CBC mode. In the
|
||||
meantime, it is recommend to use this option to specify CBC mode (use the
|
||||
string "CBC" as the argument), and then also use the ENCRYPTION_MODE
|
||||
variable in the 'access.conf' file on the server.
|
||||
|
||||
*-N, --nat-access*='<internalIP:forwardPort>'::
|
||||
The *fwknopd* server offers the ability to provide SPA access through
|
||||
an iptables firewall to an internal service by interfacing with the
|
||||
@@ -205,7 +214,7 @@ SPA OPTIONS
|
||||
client can request that the server port forward an external port to an
|
||||
internal IP, i.e. ``+--NAT-access 192.168.10.2,55000+''. In this case,
|
||||
access will be granted to 192.168.10.2 via port 55000 to whatever
|
||||
service is requested via the *--access* argument (usually tcp/22).
|
||||
service is requested via the *--access* argument (usually tcp/22).
|
||||
Hence, after sending such an SPA packet, one would then do
|
||||
``ssh -p 55000 user@host'' and the connection would be forwarded on
|
||||
through to the internal 192.168.10.2 system automatically. Note that
|
||||
@@ -404,6 +413,10 @@ description and its matching command-line option(s):
|
||||
Set a value to apply to the timestamp in the SPA packet. This can
|
||||
be either a positive or negative value ('--time-offset-plus/minus').
|
||||
|
||||
*ENCRYPTION_MODE*::
|
||||
Specify the encryption mode when AES is used. This variable is a synonym
|
||||
for the '--encryption-mode' command line argument.
|
||||
|
||||
*USE_GPG*::
|
||||
Set to 'Y' to specify the use of GPG for encryption ('--gpg-encryption').
|
||||
|
||||
@@ -552,7 +565,7 @@ More information on Single Packet Authorization can be found in the paper
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Damien Stuart <dstuart@dstuart.org>,
|
||||
Damien Stuart <dstuart@dstuart.org>,
|
||||
Michael Rash <mbr@cipherdyne.org>
|
||||
|
||||
CONTRIBUTORS
|
||||
|
||||
@@ -344,6 +344,15 @@ directive starts a new stanza.
|
||||
``FW_ACCESS_TIMEOUT'' is not set then the default timeout of 30 seconds
|
||||
will automatically be set.
|
||||
|
||||
*ENCRYPTION_MODE*: '<mode>'::
|
||||
Specify the encryption mode when AES is used. The default (for now) is
|
||||
ECB mode in order to remain backwards compatible with pre-2.0 versions of
|
||||
fwknop which relied on the Crypt::CBC perl module. This will be changed
|
||||
in an upcoming version of fwknop to use the more secure CBC mode. In the
|
||||
meantime, it is recommend to use this option to specify CBC mode (use the
|
||||
string "CBC" as the argument), and then also use '--encryption-mode'
|
||||
command line argument on the *fwknop* client.
|
||||
|
||||
*ENABLE_CMD_EXEC*: '<Y/N>'::
|
||||
This instructs *fwknopd* to accept complete commands that are contained
|
||||
within an authorization packet. Any such command will be executed on
|
||||
|
||||
+9
-6
@@ -181,12 +181,13 @@ rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *da
|
||||
/* Initialization entry point.
|
||||
*/
|
||||
static void
|
||||
rijndael_init(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data)
|
||||
rijndael_init(RIJNDAEL_context *ctx, const char *pass,
|
||||
const unsigned char *data, int encryption_mode)
|
||||
{
|
||||
|
||||
/* Use ECB mode to be compatible with the Crypt::CBC perl module.
|
||||
*/
|
||||
ctx->mode = MODE_ECB;
|
||||
ctx->mode = encryption_mode;
|
||||
|
||||
/* Generate the salt and initialization vector.
|
||||
*/
|
||||
@@ -201,7 +202,8 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data
|
||||
* module would.
|
||||
*/
|
||||
size_t
|
||||
rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
|
||||
rij_encrypt(unsigned char *in, size_t in_len,
|
||||
const char *pass, unsigned char *out, int encryption_mode)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char plaintext[RIJNDAEL_BLOCKSIZE];
|
||||
@@ -211,7 +213,7 @@ rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *o
|
||||
|
||||
unsigned char *ondx = out;
|
||||
|
||||
rijndael_init(&ctx, pass, NULL);
|
||||
rijndael_init(&ctx, pass, NULL, encryption_mode);
|
||||
|
||||
/* Prepend the salt...
|
||||
*/
|
||||
@@ -255,7 +257,8 @@ rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *o
|
||||
/* Decrypt the given data.
|
||||
*/
|
||||
size_t
|
||||
rij_decrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
|
||||
rij_decrypt(unsigned char *in, size_t in_len,
|
||||
const char *pass, unsigned char *out, int encryption_mode)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char plaintext[RIJNDAEL_BLOCKSIZE];
|
||||
@@ -265,7 +268,7 @@ rij_decrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *o
|
||||
unsigned char *pad_s;
|
||||
unsigned char *ondx = out;
|
||||
|
||||
rijndael_init(&ctx, pass, in);
|
||||
rijndael_init(&ctx, pass, in, encryption_mode);
|
||||
|
||||
/* Remove the salt from the input.
|
||||
*/
|
||||
|
||||
+4
-2
@@ -47,8 +47,10 @@
|
||||
*/
|
||||
#define PREDICT_ENCSIZE(x) (1+(x>>4)+(x&0xf?1:0))<<4
|
||||
|
||||
size_t rij_encrypt(unsigned char *in, size_t len, const char *key, unsigned char *out);
|
||||
size_t rij_decrypt(unsigned char *in, size_t len, const char *key, unsigned char *out);
|
||||
size_t rij_encrypt(unsigned char *in, size_t len,
|
||||
const char *key, unsigned char *out, int encryption_mode);
|
||||
size_t rij_decrypt(unsigned char *in, size_t len,
|
||||
const char *key, unsigned char *out, int encryption_mode);
|
||||
|
||||
#endif /* CIPHER_FUNCS_H */
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "rijndael.h" /* For encryption modes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -91,6 +93,20 @@ typedef enum {
|
||||
FKO_LAST_ENCRYPTION_TYPE /* Always leave this as the last one */
|
||||
} fko_encryption_type_t;
|
||||
|
||||
/* Symmetric encryption modes derived from rijndael.h
|
||||
*/
|
||||
typedef enum {
|
||||
FKO_ENC_MODE_UNKNOWN = 0,
|
||||
FKO_ENC_MODE_ECB = MODE_ECB,
|
||||
FKO_ENC_MODE_CBC = MODE_CBC,
|
||||
FKO_ENC_MODE_CFB = MODE_CFB,
|
||||
FKO_ENC_MODE_PCBC = MODE_PCBC,
|
||||
FKO_ENC_MODE_OFB = MODE_OFB,
|
||||
FKO_ENC_MODE_CTR = MODE_CTR,
|
||||
FKO_ENC_MODE_ASYMMETRIC, /* placeholder when GPG is used */
|
||||
FKO_LAST_ENC_MODE /* Always leave this as the last one */
|
||||
} fko_encryption_mode_t;
|
||||
|
||||
/* FKO ERROR_CODES
|
||||
*
|
||||
* Note: If you change this list in any way, please be sure to make the
|
||||
@@ -160,6 +176,7 @@ typedef enum {
|
||||
#define FKO_DEFAULT_MSG_TYPE FKO_ACCESS_MSG
|
||||
#define FKO_DEFAULT_DIGEST FKO_DIGEST_SHA256
|
||||
#define FKO_DEFAULT_ENCRYPTION FKO_ENCRYPTION_RIJNDAEL
|
||||
#define FKO_DEFAULT_ENC_MODE MODE_ECB
|
||||
|
||||
/* The context holds the global state and config options, as
|
||||
* well as some intermediate results during processing. This
|
||||
@@ -189,7 +206,8 @@ enum {
|
||||
/* General api calls
|
||||
*/
|
||||
DLL_API int fko_new(fko_ctx_t *ctx);
|
||||
DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char *enc_msg, const char *dec_key);
|
||||
DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char *enc_msg, const char *dec_key,
|
||||
int encryption_mode);
|
||||
DLL_API void fko_destroy(fko_ctx_t ctx);
|
||||
DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char *enc_key);
|
||||
|
||||
@@ -207,6 +225,7 @@ DLL_API int fko_set_spa_client_timeout(fko_ctx_t ctx, const int timeout);
|
||||
DLL_API int fko_set_spa_digest_type(fko_ctx_t ctx, const short digest_type);
|
||||
DLL_API int fko_set_spa_digest(fko_ctx_t ctx);
|
||||
DLL_API int fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type);
|
||||
DLL_API int fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode);
|
||||
DLL_API int fko_set_spa_data(fko_ctx_t ctx, const char *enc_msg);
|
||||
|
||||
/* Data processing and misc utility functions
|
||||
@@ -235,6 +254,7 @@ DLL_API int fko_get_spa_client_timeout(fko_ctx_t ctx, int *client_timeout);
|
||||
DLL_API int fko_get_spa_digest_type(fko_ctx_t ctx, short *spa_digest_type);
|
||||
DLL_API int fko_get_spa_digest(fko_ctx_t ctx, char **spa_digest);
|
||||
DLL_API int fko_get_spa_encryption_type(fko_ctx_t ctx, short *spa_enc_type);
|
||||
DLL_API int fko_get_spa_encryption_mode(fko_ctx_t ctx, int *spa_enc_mode);
|
||||
DLL_API int fko_get_spa_data(fko_ctx_t ctx, char **spa_data);
|
||||
|
||||
DLL_API int fko_get_version(fko_ctx_t ctx, char **version);
|
||||
|
||||
@@ -63,6 +63,7 @@ struct fko_context {
|
||||
/* FKO SPA user-settable message encoding types */
|
||||
short digest_type;
|
||||
short encryption_type;
|
||||
int encryption_mode;
|
||||
|
||||
/* Computed or predefined data */
|
||||
char *version;
|
||||
|
||||
+41
-4
@@ -66,7 +66,8 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
cipher_len = rij_encrypt(
|
||||
(unsigned char*)plain, strlen(plain), (char*)enc_key, cipher
|
||||
(unsigned char*)plain, strlen(plain), (char*)enc_key, cipher,
|
||||
ctx->encryption_mode
|
||||
);
|
||||
|
||||
/* Now make a bucket for the base64-encoded version and populate it.
|
||||
@@ -95,7 +96,7 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Decode, decrypt, and parse SPA data into the context.
|
||||
*/
|
||||
static int
|
||||
_rijndael_decrypt(fko_ctx_t ctx, const char *dec_key)
|
||||
_rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int encryption_mode)
|
||||
{
|
||||
char *tbuf;
|
||||
unsigned char *ndx;
|
||||
@@ -143,7 +144,8 @@ _rijndael_decrypt(fko_ctx_t ctx, const char *dec_key)
|
||||
if(ctx->encoded_msg == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
pt_len = rij_decrypt(cipher, cipher_len, dec_key, (unsigned char*)ctx->encoded_msg);
|
||||
pt_len = rij_decrypt(cipher, cipher_len, dec_key,
|
||||
(unsigned char*)ctx->encoded_msg, encryption_mode);
|
||||
|
||||
/* Done with cipher...
|
||||
*/
|
||||
@@ -351,6 +353,41 @@ fko_get_spa_encryption_type(fko_ctx_t ctx, short *enc_type)
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
/* Set the SPA encryption mode.
|
||||
*/
|
||||
int
|
||||
fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode)
|
||||
{
|
||||
/* Must be initialized
|
||||
*/
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
|
||||
if(encrypt_mode < 0 || encrypt_mode >= FKO_LAST_ENC_MODE)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
ctx->encryption_mode = encrypt_mode;
|
||||
|
||||
ctx->state |= FKO_ENCRYPT_MODE_MODIFIED;
|
||||
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
/* Return the SPA encryption mode.
|
||||
*/
|
||||
int
|
||||
fko_get_spa_encryption_mode(fko_ctx_t ctx, int *enc_mode)
|
||||
{
|
||||
/* Must be initialized
|
||||
*/
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
|
||||
*enc_mode = ctx->encryption_mode;
|
||||
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
/* Encrypt the encoded SPA data.
|
||||
*/
|
||||
int
|
||||
@@ -425,7 +462,7 @@ fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
|
||||
else if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
{
|
||||
ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
|
||||
res = _rijndael_decrypt(ctx, dec_key);
|
||||
res = _rijndael_decrypt(ctx, dec_key, ctx->encryption_mode);
|
||||
}
|
||||
else
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
+26
-3
@@ -133,6 +133,18 @@ fko_new(fko_ctx_t *r_ctx)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Default Encryption Mode (Rijndael in EBC mode for backwards
|
||||
* compatibility - it recommended to change this to CBC mode)
|
||||
*/
|
||||
ctx->initval = FKO_CTX_INITIALIZED;
|
||||
res = fko_set_spa_encryption_mode(ctx, FKO_DEFAULT_ENC_MODE);
|
||||
ctx->initval = 0;
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
fko_destroy(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
#if HAVE_LIBGPGME
|
||||
/* Set gpg signature verify on.
|
||||
*/
|
||||
@@ -156,7 +168,8 @@ fko_new(fko_ctx_t *r_ctx)
|
||||
* and parsing the provided data into the context data.
|
||||
*/
|
||||
int
|
||||
fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg, const char *dec_key)
|
||||
fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg,
|
||||
const char *dec_key, int encryption_mode)
|
||||
{
|
||||
fko_ctx_t ctx;
|
||||
int res = FKO_SUCCESS; /* Are we optimistic or what? */
|
||||
@@ -174,13 +187,23 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg, const char *dec_key)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
}
|
||||
|
||||
/* Default Encryption Mode (Rijndael in CBC mode)
|
||||
*/
|
||||
ctx->initval = FKO_CTX_INITIALIZED;
|
||||
res = fko_set_spa_encryption_mode(ctx, encryption_mode);
|
||||
ctx->initval = 0;
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
fko_destroy(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Consider it initialized here.
|
||||
*/
|
||||
ctx->initval = FKO_CTX_INITIALIZED;
|
||||
FKO_SET_CTX_INITIALIZED(ctx);
|
||||
|
||||
/* If a decryption password is provided, go ahead and decrypt and
|
||||
* decode.
|
||||
/* If a decryption key is provided, go ahead and decrypt and decode.
|
||||
*/
|
||||
if(dec_key != NULL)
|
||||
{
|
||||
|
||||
+2
-1
@@ -49,7 +49,8 @@ typedef enum {
|
||||
FKO_DIGEST_TYPE_MODIFIED = 1 << 12,
|
||||
FKO_ENCRYPT_TYPE_MODIFIED = 1 << 13,
|
||||
STATE_RESERVED_14 = 1 << 14,
|
||||
FKO_BACKWARD_COMPATIBLE = 1 << 15
|
||||
FKO_BACKWARD_COMPATIBLE = 1 << 15,
|
||||
FKO_ENCRYPT_MODE_MODIFIED = 1 << 16,
|
||||
} fko_state_flags_t;
|
||||
|
||||
/* This is used in conjunction with the ctx->initial value as a means to
|
||||
|
||||
+40
-3
@@ -132,6 +132,27 @@ add_acc_expire_time_epoch(fko_srv_options_t *opts, time_t *access_expire_time, c
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert an encryption_mode string to its integer value.
|
||||
*/
|
||||
static int
|
||||
enc_mode_strtoint(const char *enc_mode_str)
|
||||
{
|
||||
if(strcasecmp(enc_mode_str, "cbc") == 0)
|
||||
return(FKO_ENC_MODE_CBC);
|
||||
else if(strcasecmp(enc_mode_str, "ecb") == 0)
|
||||
return(FKO_ENC_MODE_ECB);
|
||||
else if(strcasecmp(enc_mode_str, "cfb") == 0)
|
||||
return(FKO_ENC_MODE_CFB);
|
||||
else if(strcasecmp(enc_mode_str, "pcbc") == 0)
|
||||
return(FKO_ENC_MODE_PCBC);
|
||||
else if(strcasecmp(enc_mode_str, "ofb") == 0)
|
||||
return(FKO_ENC_MODE_OFB);
|
||||
else if(strcasecmp(enc_mode_str, "ctr") == 0)
|
||||
return(FKO_ENC_MODE_CTR);
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#if FIREWALL_IPTABLES
|
||||
static void
|
||||
add_acc_force_nat(fko_srv_options_t *opts, acc_stanza_t *curr_acc, const char *val)
|
||||
@@ -708,8 +729,15 @@ set_acc_defaults(fko_srv_options_t *opts)
|
||||
|
||||
/* set default gpg keyring path if necessary
|
||||
*/
|
||||
if(acc->gpg_decrypt_pw != NULL && acc->gpg_home_dir == NULL)
|
||||
add_acc_string(&(acc->gpg_home_dir), opts->config[CONF_GPG_HOME_DIR]);
|
||||
if(acc->gpg_decrypt_pw != NULL)
|
||||
{
|
||||
acc->encryption_mode = FKO_ENC_MODE_ASYMMETRIC;
|
||||
if(acc->gpg_home_dir == NULL)
|
||||
add_acc_string(&(acc->gpg_home_dir), opts->config[CONF_GPG_HOME_DIR]);
|
||||
}
|
||||
|
||||
if (acc->encryption_mode == FKO_ENC_MODE_UNKNOWN)
|
||||
acc->encryption_mode = FKO_DEFAULT_ENC_MODE;
|
||||
|
||||
acc = acc->next;
|
||||
}
|
||||
@@ -869,6 +897,16 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
{
|
||||
add_acc_int(&(curr_acc->fw_access_timeout), val);
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "ENCRYPTION_MODE"))
|
||||
{
|
||||
if((curr_acc->encryption_mode = enc_mode_strtoint(val)) < 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[*] Unrecognized ENCRYPTION_MODE '%s', use {cbc,ecb}\n",
|
||||
val);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "ENABLE_CMD_EXEC"))
|
||||
{
|
||||
add_acc_bool(&(curr_acc->enable_cmd_exec), val);
|
||||
@@ -1005,7 +1043,6 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
expand_acc_ent_lists(opts);
|
||||
|
||||
/* Make sure default values are set where needed.
|
||||
* a default value.
|
||||
*/
|
||||
set_acc_defaults(opts);
|
||||
|
||||
|
||||
@@ -282,6 +282,7 @@ typedef struct acc_stanza
|
||||
acc_string_list_t *gpg_remote_id_list;
|
||||
time_t access_expire_time;
|
||||
int expired;
|
||||
int encryption_mode;
|
||||
unsigned char force_nat;
|
||||
char *force_nat_ip;
|
||||
char *force_nat_proto;
|
||||
|
||||
@@ -242,7 +242,8 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
{
|
||||
if(acc->key != NULL)
|
||||
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, acc->key);
|
||||
res = fko_new_with_data(&ctx,
|
||||
(char *)spa_pkt->packet_data, acc->key, acc->encryption_mode);
|
||||
else
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
@@ -260,7 +261,8 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
*/
|
||||
if(acc->gpg_decrypt_pw != NULL)
|
||||
{
|
||||
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL);
|
||||
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL,
|
||||
acc->encryption_mode);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
log_msg(LOG_WARNING,
|
||||
|
||||
Reference in New Issue
Block a user