From 47e39272edcdd20b226c77c45704041be25a38ad Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Tue, 10 Jul 2012 21:44:06 -0400 Subject: [PATCH] Make encrypt/decrypt code accept integer key lengths instead of using strlen() Now that encryptions keys and hmac keys may be acquired from /dev/random with --key-gen (and base64 encoded), they may contain NULL bytes. This emphasizes the need to not leverage code that assumes C-style strings when making use of key information. --- client/fwknop.c | 40 ++++++++++++++++++++++++++++++---------- lib/cipher_funcs.c | 39 +++++++++++++++++++++------------------ lib/cipher_funcs.h | 6 ++++-- lib/fko.h | 35 +++++++++++++++++++++++------------ lib/fko_encryption.c | 21 ++++++++++++--------- lib/fko_funcs.c | 24 +++++++++++++----------- lib/fko_hmac.c | 9 ++++++--- lib/rijndael.c | 4 ++-- lib/rijndael.h | 5 +++-- server/access.c | 36 ++++++++++++++++++++++++++++++++---- server/fwknopd_common.h | 2 ++ server/incoming_spa.c | 34 ++++------------------------------ 12 files changed, 152 insertions(+), 103 deletions(-) diff --git a/client/fwknop.c b/client/fwknop.c index 1174db28..1f376a75 100644 --- a/client/fwknop.c +++ b/client/fwknop.c @@ -37,7 +37,8 @@ /* prototypes */ static void get_keys(fko_ctx_t ctx, fko_cli_options_t *options, - char *key, char *hmac_key, const int crypt_op); + char *key, int *key_len, char *hmac_key, + int *hmac_key_len, const int crypt_op); static void display_ctx(fko_ctx_t ctx); static void errmsg(const char *msg, const int err); static void show_last_command(void); @@ -59,6 +60,7 @@ main(int argc, char **argv) char access_buf[MAX_LINE_LEN] = {0}; char key[MAX_KEY_LEN+1] = {0}; char hmac_key[MAX_KEY_LEN+1] = {0}; + int key_len = 0, hmac_key_len = 0; fko_cli_options_t options; @@ -301,11 +303,12 @@ main(int argc, char **argv) /* Acquire the necessary encryption/hmac keys */ - get_keys(ctx, &options, key, hmac_key, CRYPT_OP_ENCRYPT); + get_keys(ctx, &options, key, &key_len, + hmac_key, &hmac_key_len, CRYPT_OP_ENCRYPT); /* Finalize the context data (encrypt and encode the SPA data) */ - res = fko_spa_data_final(ctx, key, hmac_key); + res = fko_spa_data_final(ctx, key, key_len, hmac_key, hmac_key_len); if(res != FKO_SUCCESS) { errmsg("fko_spa_data_final", res); @@ -366,7 +369,7 @@ main(int argc, char **argv) * options, then decode it. */ res = fko_new_with_data(&ctx2, spa_data, NULL, - ctx->encryption_mode, hmac_key); + 0, ctx->encryption_mode, hmac_key, hmac_key_len); if(res != FKO_SUCCESS) { errmsg("fko_new_with_data", res); @@ -395,12 +398,13 @@ main(int argc, char **argv) } } - get_keys(ctx2, &options, key, hmac_key, CRYPT_OP_DECRYPT); + get_keys(ctx2, &options, key, &key_len, + hmac_key, &hmac_key_len, CRYPT_OP_DECRYPT); /* Verify HMAC first */ if(options.use_hmac) - res = fko_verify_hmac(ctx2, hmac_key); + res = fko_verify_hmac(ctx2, hmac_key, hmac_key_len); /* Decrypt */ @@ -409,7 +413,7 @@ main(int argc, char **argv) /* check fko_verify_hmac() return value */ } else - res = fko_decrypt_spa_data(ctx2, key); + res = fko_decrypt_spa_data(ctx2, key, key_len); if(res != FKO_SUCCESS) { @@ -751,7 +755,8 @@ set_message_type(fko_ctx_t ctx, fko_cli_options_t *options) */ static void get_keys(fko_ctx_t ctx, fko_cli_options_t *options, - char *key, char *hmac_key, const int crypt_op) + char *key, int *key_len, char *hmac_key, + int *hmac_key_len, const int crypt_op) { int use_hmac = 0, res = 0; @@ -767,10 +772,14 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options, return; if (options->have_key) + { strlcpy(key, options->key, MAX_KEY_LEN+1); + *key_len = strlen(key); + } else if (options->have_base64_key) { - fko_base64_decode(options->key_base64, (unsigned char *) options->key); + *key_len = fko_base64_decode(options->key_base64, + (unsigned char *) options->key); memcpy(key, options->key, RIJNDAEL_MAX_KEYSIZE); } else @@ -781,15 +790,22 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options, { strlcpy(key, getpasswd_file(options->get_key_file, options->spa_server_str), MAX_KEY_LEN+1); + *key_len = strlen(key); } else if (options->use_gpg) { if(crypt_op == CRYPT_OP_DECRYPT) + { strlcpy(key, getpasswd("Enter passphrase for secret key: "), MAX_KEY_LEN+1); + *key_len = strlen(key); + } else if(options->gpg_signer_key && strlen(options->gpg_signer_key)) + { strlcpy(key, getpasswd("Enter passphrase for signing: "), MAX_KEY_LEN+1); + *key_len = strlen(key); + } } else { @@ -802,6 +818,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options, else strlcpy(key, getpasswd("Enter key: "), MAX_KEY_LEN+1); + *key_len = strlen(key); } } @@ -809,11 +826,13 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options, if (options->have_hmac_key) { strlcpy(hmac_key, options->hmac_key, MAX_KEY_LEN+1); + *hmac_key_len = strlen(hmac_key); use_hmac = 1; } else if (options->have_hmac_base64_key) { - fko_base64_decode(options->hmac_key_base64, (unsigned char *) options->hmac_key); + *hmac_key_len = fko_base64_decode(options->hmac_key_base64, + (unsigned char *) options->hmac_key); memcpy(hmac_key, options->hmac_key, SHA256_BLOCK_LENGTH); use_hmac = 1; } @@ -830,6 +849,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options, { #endif strlcpy(hmac_key, getpasswd("Enter HMAC key: "), MAX_KEY_LEN+1); + *hmac_key_len = strlen(hmac_key); use_hmac = 1; } diff --git a/lib/cipher_funcs.c b/lib/cipher_funcs.c index 1b79065d..51d5e3f9 100644 --- a/lib/cipher_funcs.c +++ b/lib/cipher_funcs.c @@ -115,27 +115,27 @@ get_random_data(unsigned char *data, const size_t len) * the Perl Crypt::CBC module's use of Rijndael. */ static void -rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data) +rij_salt_and_iv(RIJNDAEL_context *ctx, const char *key, + const int key_len, const unsigned char *data) { - char pw_buf[16]; + char pw_buf[RIJNDAEL_MIN_KEYSIZE]; unsigned char tmp_buf[64]; /* How big does this need to be? */ unsigned char kiv_buf[48]; /* Key and IV buffer */ unsigned char md5_buf[16]; /* Buffer for computed md5 hash */ size_t kiv_len = 0; - size_t plen = strlen(pass); - /* First make pw 16 bytes (pad with "0" (ascii 0x30)) or truncate. + /* First make pw 32 bytes (pad with "0" (ascii 0x30)) or truncate. * Note: pw_buf was initialized with '0' chars (again, not the value * 0, but the digit '0' character). */ - if(plen < 16) + if(key_len < RIJNDAEL_MIN_KEYSIZE) { - memcpy(pw_buf, pass, plen); - memset(pw_buf+plen, '0', 16 - plen); + memcpy(pw_buf, key, key_len); + memset(pw_buf+key_len, '0', RIJNDAEL_MIN_KEYSIZE - key_len); } else - strncpy(pw_buf, pass, 16); + memcpy(pw_buf, key, RIJNDAEL_MIN_KEYSIZE); /* If we are decrypting, data will contain the salt. Otherwise, * for encryption, we generate a random salt. @@ -157,7 +157,7 @@ rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *da * (again it is the perl Crypt::CBC way, with a touch of * fwknop). */ - memcpy(tmp_buf+16, pw_buf, 16); + memcpy(tmp_buf+RIJNDAEL_MIN_KEYSIZE, pw_buf, RIJNDAEL_MIN_KEYSIZE); memcpy(tmp_buf+32, ctx->salt, 8); while(kiv_len < sizeof(kiv_buf)) @@ -181,8 +181,9 @@ 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, int encryption_mode) +rijndael_init(RIJNDAEL_context *ctx, const char *key, + const int key_len, const unsigned char *data, + int encryption_mode) { /* The default (set in fko.h) is ECB mode to be compatible with the @@ -192,11 +193,11 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass, /* Generate the salt and initialization vector. */ - rij_salt_and_iv(ctx, pass, data); + rij_salt_and_iv(ctx, key, key_len, data); - /* Intialize our rinjdael context. + /* Intialize our Rijndael context. */ - rijndael_setup(ctx, 32, ctx->key); + rijndael_setup(ctx, RIJNDAEL_MAX_KEYSIZE, ctx->key); } /* Take a chunk of data, encrypt it in the same way the perl Crypt::CBC @@ -204,13 +205,14 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass, */ size_t rij_encrypt(unsigned char *in, size_t in_len, - const char *pass, unsigned char *out, int encryption_mode) + const char *key, const int key_len, + unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val; unsigned char *ondx = out; - rijndael_init(&ctx, pass, NULL, encryption_mode); + rijndael_init(&ctx, key, key_len, NULL, encryption_mode); /* Prepend the salt to the ciphertext... */ @@ -237,14 +239,15 @@ rij_encrypt(unsigned char *in, size_t in_len, */ size_t rij_decrypt(unsigned char *in, size_t in_len, - const char *pass, unsigned char *out, int encryption_mode) + const char *key, const int key_len, + unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val, pad_err = 0; unsigned char *pad_s; unsigned char *ondx = out; - rijndael_init(&ctx, pass, in, encryption_mode); + rijndael_init(&ctx, key, key_len, in, encryption_mode); /* Remove the first block since it contains the salt (it was consumed * by the rijndael_init() function above). diff --git a/lib/cipher_funcs.h b/lib/cipher_funcs.h index 7a7298be..7d43c2b8 100644 --- a/lib/cipher_funcs.h +++ b/lib/cipher_funcs.h @@ -49,9 +49,11 @@ void get_random_data(unsigned char *data, const size_t len); size_t rij_encrypt(unsigned char *in, size_t len, - const char *key, unsigned char *out, int encryption_mode); + const char *key, const int key_len, + 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); + const char *key, const int key_len, + unsigned char *out, int encryption_mode); #endif /* CIPHER_FUNCS_H */ diff --git a/lib/fko.h b/lib/fko.h index 2350b0a0..56fddfff 100644 --- a/lib/fko.h +++ b/lib/fko.h @@ -222,10 +222,11 @@ enum { */ 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, int encryption_mode, const char *hmac_key); + const char *dec_key, const int dec_key_len, int encryption_mode, + const char *hmac_key, const int hmac_key_len); DLL_API void fko_destroy(fko_ctx_t ctx); DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char *enc_key, - const char *hmac_key); + const int enc_key_len, const char *hmac_key, const int hmac_key_len); /* Set context data functions @@ -255,10 +256,14 @@ DLL_API int fko_base64_decode(const char *in, unsigned char *out); DLL_API int fko_encode_spa_data(fko_ctx_t ctx); DLL_API int fko_decode_spa_data(fko_ctx_t ctx); -DLL_API int fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key); -DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key); -DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key); -DLL_API int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key); +DLL_API int fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key, + const int enc_key_len); +DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key, + const int dec_key_len); +DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key, + const int hmac_key_len); +DLL_API int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key, + const int hmac_key_len); DLL_API int fko_get_hmac_data(fko_ctx_t ctx, char **enc_data); DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data); @@ -295,18 +300,24 @@ DLL_API int fko_get_gpg_home_dir(fko_ctx_t ctx, char **gpg_home_dir); DLL_API const char* fko_gpg_errstr(fko_ctx_t ctx); -DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx, const unsigned char val); -DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char *val); -DLL_API int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, const unsigned char val); -DLL_API int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, unsigned char *val); +DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx, + const unsigned char val); +DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx, + unsigned char *val); +DLL_API int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, + const unsigned char val); +DLL_API int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, + unsigned char *val); DLL_API int fko_get_gpg_signature_id(fko_ctx_t ctx, char **sig_id); DLL_API int fko_get_gpg_signature_fpr(fko_ctx_t ctx, char **sig_fpr); DLL_API int fko_get_gpg_signature_summary(fko_ctx_t ctx, int *sigsum); DLL_API int fko_get_gpg_signature_status(fko_ctx_t ctx, int *sigstat); -DLL_API int fko_gpg_signature_id_match(fko_ctx_t ctx, const char *id, unsigned char *result); -DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char *fpr, unsigned char *result); +DLL_API int fko_gpg_signature_id_match(fko_ctx_t ctx, const char *id, + unsigned char *result); +DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char *fpr, + unsigned char *result); #ifdef __cplusplus } diff --git a/lib/fko_encryption.c b/lib/fko_encryption.c index 3b77f9c6..e3446217 100644 --- a/lib/fko_encryption.c +++ b/lib/fko_encryption.c @@ -43,7 +43,7 @@ /* Prep and encrypt using Rijndael */ static int -_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key) +_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) { char *plaintext; char *b64ciphertext; @@ -68,8 +68,9 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key) return(FKO_ERROR_MEMORY_ALLOCATION); cipher_len = rij_encrypt( - (unsigned char*)plaintext, strlen(plaintext), (char*)enc_key, ciphertext, - ctx->encryption_mode + (unsigned char*)plaintext, strlen(plaintext), + (char*)enc_key, enc_key_len, + ciphertext, ctx->encryption_mode ); /* Now make a bucket for the base64-encoded version and populate it. @@ -98,7 +99,8 @@ _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, int encryption_mode) +_rijndael_decrypt(fko_ctx_t ctx, + const char *dec_key, const int key_len, int encryption_mode) { char *tbuf; unsigned char *ndx; @@ -155,7 +157,7 @@ _rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int encryption_mode) if(ctx->encoded_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); - pt_len = rij_decrypt(cipher, cipher_len, dec_key, + pt_len = rij_decrypt(cipher, cipher_len, dec_key, key_len, (unsigned char*)ctx->encoded_msg, encryption_mode); /* Done with cipher... @@ -413,7 +415,7 @@ fko_get_spa_encryption_mode(fko_ctx_t ctx, int *enc_mode) /* Encrypt the encoded SPA data. */ int -fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key) +fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) { int res = 0; @@ -445,7 +447,7 @@ fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key) /* Encrypt according to type and return... */ if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL) - res = _rijndael_encrypt(ctx, enc_key); + res = _rijndael_encrypt(ctx, enc_key, enc_key_len); else if(ctx->encryption_type == FKO_ENCRYPTION_GPG) #if HAVE_LIBGPGME res = gpg_encrypt(ctx, enc_key); @@ -461,7 +463,7 @@ fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key) /* Decode, decrypt, and parse SPA data into the context. */ int -fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key) +fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key, const int key_len) { int enc_type, res; @@ -484,7 +486,8 @@ 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, ctx->encryption_mode); + res = _rijndael_decrypt(ctx, + dec_key, key_len, ctx->encryption_mode); } else return(FKO_ERROR_INVALID_DATA); diff --git a/lib/fko_funcs.c b/lib/fko_funcs.c index 04cc7145..4210276e 100644 --- a/lib/fko_funcs.c +++ b/lib/fko_funcs.c @@ -171,7 +171,9 @@ fko_new(fko_ctx_t *r_ctx) */ int fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg, - const char *dec_key, int encryption_mode, const char *hmac_key) + const char *dec_key, const int dec_key_len, + int encryption_mode, const char *hmac_key, + const int hmac_key_len) { fko_ctx_t ctx; int res = FKO_SUCCESS; /* Are we optimistic or what? */ @@ -204,7 +206,7 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg, */ ctx->initval = FKO_CTX_INITIALIZED; if(hmac_key != NULL) - res = fko_verify_hmac(ctx, hmac_key); + res = fko_verify_hmac(ctx, hmac_key, hmac_key_len); ctx->initval = 0; if(res != FKO_SUCCESS) { @@ -221,7 +223,7 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg, */ if(dec_key != NULL) { - res = fko_decrypt_spa_data(ctx, dec_key); + res = fko_decrypt_spa_data(ctx, dec_key, dec_key_len); if(res != FKO_SUCCESS) { @@ -330,7 +332,7 @@ fko_destroy(fko_ctx_t ctx) free(ctx); } -/* Generate Rijndael and HMAC keys from /dev/random and base-64 +/* Generate Rijndael and HMAC keys from /dev/random and base64 * encode them */ int @@ -353,15 +355,13 @@ fko_key_gen(char *key_base64, char *hmac_key_base64) int fko_base64_encode(unsigned char *in, char *out, int in_len) { - b64_encode(in, out, in_len); - return(FKO_SUCCESS); + return b64_encode(in, out, in_len); } int fko_base64_decode(const char *in, unsigned char *out) { - b64_decode(in, out); - return(FKO_SUCCESS); + return b64_decode(in, out); } /* Return the fko version @@ -384,7 +384,9 @@ fko_get_version(fko_ctx_t ctx, char **version) * set. */ int -fko_spa_data_final(fko_ctx_t ctx, const char *enc_key, const char *hmac_key) +fko_spa_data_final(fko_ctx_t ctx, + const char *enc_key, const int enc_key_len, + const char *hmac_key, const int hmac_key_len) { char *tbuf; int res = 0, data_with_hmac_len = 0; @@ -394,14 +396,14 @@ fko_spa_data_final(fko_ctx_t ctx, const char *enc_key, const char *hmac_key) if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); - res = fko_encrypt_spa_data(ctx, enc_key); + res = fko_encrypt_spa_data(ctx, enc_key, enc_key_len); /* Now calculate hmac if so configured */ if (res == FKO_SUCCESS && ctx->hmac_mode != FKO_HMAC_UNKNOWN && hmac_key != NULL) { - res = fko_calculate_hmac(ctx, hmac_key); + res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len); if (res == FKO_SUCCESS) { diff --git a/lib/fko_hmac.c b/lib/fko_hmac.c index 00d3dfd6..6337fb74 100644 --- a/lib/fko_hmac.c +++ b/lib/fko_hmac.c @@ -33,7 +33,8 @@ #include "hmac.h" #include "base64.h" -int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key) +int fko_verify_hmac(fko_ctx_t ctx, + const char *hmac_key, const int hmac_key_len) { /* Must be initialized */ @@ -80,7 +81,8 @@ fko_set_hmac_mode(fko_ctx_t ctx, const short hmac_mode) return(FKO_SUCCESS); } -int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key) +int fko_calculate_hmac(fko_ctx_t ctx, + const char *hmac_key, const int hmac_key_len) { unsigned char hmac[SHA256_DIGEST_STRING_LENGTH] = {0}; char *hmac_base64 = NULL; @@ -99,7 +101,8 @@ int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key) if (hmac_base64 == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); - hmac_sha256(ctx->encrypted_msg, strlen(ctx->encrypted_msg), hmac, hmac_key); + hmac_sha256(ctx->encrypted_msg, + strlen(ctx->encrypted_msg), hmac, hmac_key); b64_encode(hmac, hmac_base64, SHA256_DIGEST_LENGTH); strip_b64_eq(hmac_base64); diff --git a/lib/rijndael.c b/lib/rijndael.c index 2374fd48..2d6e450b 100644 --- a/lib/rijndael.c +++ b/lib/rijndael.c @@ -303,13 +303,13 @@ inv_mix_column(uint32_t *a, uint32_t *b) } void -rijndael_setup(RIJNDAEL_context *ctx, size_t keysize, const uint8_t *key) +rijndael_setup(RIJNDAEL_context *ctx, const size_t keysize, const uint8_t *key) { int nk, nr, i, lastkey; uint32_t temp, rcon; /* Truncate keysizes to the valid key sizes provided by Rijndael */ - if (keysize >= 32) { + if (keysize >= RIJNDAEL_MAX_KEYSIZE) { nk = 8; nr = 14; } else if (keysize >= 24) { diff --git a/lib/rijndael.h b/lib/rijndael.h index 9dc8a2e9..02e350a3 100644 --- a/lib/rijndael.h +++ b/lib/rijndael.h @@ -63,7 +63,7 @@ typedef struct { int nrounds; /* number of rounds to use for our key size */ int mode; /* encryption mode */ /* Added by DSS */ - uint8_t key[32]; + uint8_t key[RIJNDAEL_MAX_KEYSIZE]; uint8_t iv[16]; uint8_t salt[8]; } RIJNDAEL_context; @@ -77,7 +77,8 @@ typedef struct { * PASS A VALUE LESS THAN 16 TO KEYSIZE! */ void -rijndael_setup(RIJNDAEL_context *ctx, size_t keysize, const uint8_t *key); +rijndael_setup(RIJNDAEL_context *ctx, + const size_t keysize, const uint8_t *key); /* * rijndael_encrypt() diff --git a/server/access.c b/server/access.c index 43f18719..894706b5 100644 --- a/server/access.c +++ b/server/access.c @@ -49,7 +49,31 @@ add_acc_string(char **var, const char *val) if((*var = strdup(val)) == NULL) { log_msg(LOG_ERR, - "Fatal memory allocation error adding access list entry: %s", var + "Fatal memory allocation error adding access list entry: %s", *var + ); + exit(EXIT_FAILURE); + } +} + +/* Decode base64 encoded string into access entry +*/ +static void +add_acc_b64_string(char **var, int *len, const char *val) +{ + if((*var = strdup(val)) == NULL) + { + log_msg(LOG_ERR, + "Fatal memory allocation error adding access list entry: %s", *var + ); + exit(EXIT_FAILURE); + } + memset(*var, 0x0, strlen(val)); + *len = fko_base64_decode(val, (unsigned char *) *var); + + if (*len < 0) + { + log_msg(LOG_ERR, + "base64 decoding returned error for: %s", *var ); exit(EXIT_FAILURE); } @@ -752,9 +776,8 @@ set_acc_defaults(fko_srv_options_t *opts) static int acc_data_is_valid(const acc_stanza_t *acc) { - if((acc->key == NULL || !strlen(acc->key)) - && (acc->key_base64 == NULL || !strlen(acc->key_base64)) - && (acc->gpg_decrypt_pw == NULL || !strlen(acc->gpg_decrypt_pw))) + if(acc->key_len < 0 || ((acc->key == NULL && acc->key_base64 == NULL) + && (acc->gpg_decrypt_pw == NULL || !strlen(acc->gpg_decrypt_pw)))) { fprintf(stderr, "[*] No keys found for access stanza source: '%s'\n", acc->source @@ -904,6 +927,7 @@ parse_access_file(fko_srv_options_t *opts) clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } add_acc_string(&(curr_acc->key), val); + curr_acc->key_len = strlen(curr_acc->key); } else if(CONF_VAR_IS(var, "KEY_BASE64")) { @@ -922,6 +946,8 @@ parse_access_file(fko_srv_options_t *opts) clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } add_acc_string(&(curr_acc->key_base64), val); + add_acc_b64_string(&(curr_acc->key), + &(curr_acc->key_len), curr_acc->key_base64); } else if(CONF_VAR_IS(var, "HMAC_KEY_BASE64")) { @@ -940,6 +966,8 @@ parse_access_file(fko_srv_options_t *opts) clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } add_acc_string(&(curr_acc->hmac_key_base64), val); + add_acc_b64_string(&(curr_acc->hmac_key), + &curr_acc->hmac_key_len, curr_acc->hmac_key_base64); } else if(CONF_VAR_IS(var, "FW_ACCESS_TIMEOUT")) { diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index a10210cc..4ff4e5cb 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -267,8 +267,10 @@ typedef struct acc_stanza char *restrict_ports; acc_port_list_t *rport_list; char *key; + int key_len; char *key_base64; char *hmac_key; + int hmac_key_len; char *hmac_key_base64; int fw_access_timeout; unsigned char enable_cmd_exec; diff --git a/server/incoming_spa.c b/server/incoming_spa.c index 35a03419..59652ba8 100644 --- a/server/incoming_spa.c +++ b/server/incoming_spa.c @@ -241,19 +241,6 @@ incoming_spa(fko_srv_options_t *opts) if(enc_type == FKO_ENCRYPTION_RIJNDAEL) { - if (acc->key_base64 != NULL) - { - if ((acc->key = strdup(acc->key_base64)) == NULL) - { - log_msg(LOG_ERR, - "Fatal memory allocation error copying key_base64 -> key: %s", - acc->key_base64 - ); - exit(EXIT_FAILURE); - } - memset(acc->key, 0x0, strlen(acc->key_base64)); - fko_base64_decode(acc->key_base64, (unsigned char *) acc->key); - } if (acc->key == NULL) { log_msg(LOG_ERR, @@ -264,22 +251,9 @@ incoming_spa(fko_srv_options_t *opts) continue; } - if (acc->hmac_key_base64 != NULL) - { - if ((acc->hmac_key = strdup(acc->hmac_key_base64)) == NULL) - { - log_msg(LOG_ERR, - "Fatal memory allocation error copying hmac_key_base64 -> hmac_key: %s", - acc->hmac_key_base64 - ); - exit(EXIT_FAILURE); - } - memset(acc->hmac_key, 0x0, strlen(acc->hmac_key_base64)); - fko_base64_decode(acc->hmac_key_base64, (unsigned char *) acc->hmac_key); - } - res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, - acc->key, acc->encryption_mode, acc->hmac_key); + acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key, + acc->hmac_key_len); } else if(enc_type == FKO_ENCRYPTION_GPG) { @@ -289,7 +263,7 @@ 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, - acc->encryption_mode, NULL); + 0, acc->encryption_mode, NULL, 0); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, @@ -338,7 +312,7 @@ incoming_spa(fko_srv_options_t *opts) /* Now decrypt the data. */ - res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw); + res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw, 0); } else