Merge branch 'hmac_support' of ssh://192.168.10.1/home/mbr/git/bare_repos/fwknop into hmac_support

This commit is contained in:
Michael Rash 2013-03-29 20:45:30 -04:00
commit 9ee21aae12
16 changed files with 219 additions and 32 deletions

View File

@ -254,6 +254,7 @@ EXTRA_DIST = \
test/hardening-check \
test/local_spa.key \
test/test-fwknop.pl \
test/fko-python.py \
test/run-test-suite.sh \
test/README \
VERSION \

View File

@ -1175,7 +1175,7 @@ display_ctx(fko_ctx_t ctx)
fko_get_spa_encryption_type(ctx, &encryption_type);
fko_get_spa_encryption_mode(ctx, &encryption_mode);
fko_get_encoded_data(ctx, &enc_data);
fko_get_hmac_data(ctx, &hmac_data);
fko_get_spa_hmac(ctx, &hmac_data);
fko_get_spa_digest(ctx, &spa_digest);
fko_get_spa_data(ctx, &spa_data);

View File

@ -132,6 +132,7 @@ typedef enum {
FKO_ERROR_FILESYSTEM_OPERATION,
FKO_ERROR_INVALID_DATA,
FKO_ERROR_DATA_TOO_LARGE,
FKO_ERROR_INVALID_KEY_LEN,
FKO_ERROR_USERNAME_UNKNOWN,
FKO_ERROR_INCOMPLETE_SPA_DATA,
FKO_ERROR_MISSING_ENCODED_DATA,
@ -145,6 +146,7 @@ typedef enum {
FKO_ERROR_DECRYPTION_SIZE,
FKO_ERROR_DECRYPTION_FAILURE,
FKO_ERROR_DIGEST_VERIFICATION_FAILED,
FKO_ERROR_INVALID_HMAC_KEY_LEN,
FKO_ERROR_UNSUPPORTED_HMAC_MODE,
FKO_ERROR_UNSUPPORTED_FEATURE,
FKO_ERROR_UNKNOWN,
@ -280,9 +282,9 @@ DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char * const dec_key,
const int dec_key_len);
DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char * const hmac_key,
const int hmac_key_len);
DLL_API int fko_calculate_hmac(fko_ctx_t ctx, const char * const hmac_key,
DLL_API int fko_set_spa_hmac(fko_ctx_t ctx, const char * const 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_spa_hmac(fko_ctx_t ctx, char **enc_data);
DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data);

View File

@ -52,6 +52,9 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len)
int cipher_len;
int pt_len;
if(enc_key_len > RIJNDAEL_MAX_KEYSIZE)
return(FKO_ERROR_INVALID_KEY_LEN);
if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
return(FKO_ERROR_INVALID_DATA);
@ -138,6 +141,9 @@ _rijndael_decrypt(fko_ctx_t ctx,
unsigned char *cipher;
int cipher_len, pt_len, i, err = 0;
if(key_len > RIJNDAEL_MAX_KEYSIZE)
return(FKO_ERROR_INVALID_KEY_LEN);
/* Now see if we need to add the "Salted__" string to the front of the
* encrypted data.
*/

View File

@ -60,6 +60,9 @@ fko_errstr(const int err_code)
case FKO_ERROR_DATA_TOO_LARGE:
return("Value or Size of the data exceeded the max allowed");
case FKO_ERROR_INVALID_KEY_LEN:
return("Invalid key length");
case FKO_ERROR_USERNAME_UNKNOWN:
return("Unable to determine username");
@ -99,6 +102,9 @@ fko_errstr(const int err_code)
case FKO_ERROR_DIGEST_VERIFICATION_FAILED:
return("The computed digest did not match the digest in the spa data");
case FKO_ERROR_INVALID_HMAC_KEY_LEN:
return("Invalid HMAC key length");
case FKO_ERROR_UNSUPPORTED_HMAC_MODE:
return("Unsupported HMAC mode (default: SHA256)");

View File

@ -458,7 +458,7 @@ fko_spa_data_final(fko_ctx_t ctx,
if (res == FKO_SUCCESS &&
ctx->hmac_type != FKO_HMAC_UNKNOWN && hmac_key != NULL)
{
res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
if (res == FKO_SUCCESS)
{

View File

@ -50,6 +50,9 @@ int fko_verify_hmac(fko_ctx_t ctx,
if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
return(FKO_ERROR_INVALID_DATA);
if(hmac_key_len > MAX_DIGEST_BLOCK_LEN)
return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
if(ctx->hmac_type == FKO_HMAC_MD5)
hmac_b64_digest_len = MD5_B64_LEN;
else if(ctx->hmac_type == FKO_HMAC_SHA1)
@ -109,7 +112,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
res = fko_set_spa_hmac_type(ctx, ctx->hmac_type);
if(res == FKO_SUCCESS)
{
res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
if(res == FKO_SUCCESS)
{
@ -128,7 +131,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
/* Return the fko HMAC data
*/
int
fko_get_hmac_data(fko_ctx_t ctx, char **hmac_data)
fko_get_spa_hmac(fko_ctx_t ctx, char **hmac_data)
{
/* Must be initialized
*/
@ -175,7 +178,7 @@ fko_get_spa_hmac_type(fko_ctx_t ctx, short *hmac_type)
return(FKO_SUCCESS);
}
int fko_calculate_hmac(fko_ctx_t ctx,
int fko_set_spa_hmac(fko_ctx_t ctx,
const char * const hmac_key, const int hmac_key_len)
{
unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0};
@ -188,6 +191,9 @@ int fko_calculate_hmac(fko_ctx_t ctx,
if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED);
if(hmac_key_len > MAX_DIGEST_BLOCK_LEN)
return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
memset(hmac, 0x00, SHA512_DIGEST_STR_LEN);
if(ctx->hmac_type == FKO_HMAC_MD5)

View File

@ -393,7 +393,7 @@ _get_spa_hmac(ctx, val)
fko_ctx_t ctx;
char *val;
CODE:
RETVAL = fko_get_hmac_data(ctx, &val);
RETVAL = fko_get_spa_hmac(ctx, &val);
OUTPUT:
val
RETVAL
@ -639,13 +639,13 @@ _verify_hmac(ctx, hmac_key, hmac_key_len)
RETVAL
int
_calculate_hmac(ctx, hmac_key, hmac_key_len)
_set_spa_hmac(ctx, hmac_key, hmac_key_len)
INPUT:
fko_ctx_t ctx;
char* hmac_key;
int hmac_key_len;
CODE:
RETVAL = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
RETVAL = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
OUTPUT:
RETVAL

View File

@ -323,7 +323,7 @@ sub spa_hmac {
my $val = '';
return FKO::_calculate_hmac($self->{_ctx})
return FKO::_set_spa_hmac($self->{_ctx})
if($recompute and $hmac_key and $hmac_key_len);
$self->{_err} = FKO::_get_spa_hmac($self->{_ctx}, $val);
@ -518,12 +518,12 @@ sub verify_hmac {
return FKO::_verify_hmac($self->{_ctx}, $hmac_key, $hmac_key_len)
}
sub calculate_hmac {
sub set_spa_hmac {
my $self = shift;
my $hmac_key = shift || '';
my $hmac_key_len = shift || 0;
return FKO::_calculate_hmac($self->{_ctx}, $hmac_key, $hmac_key_len)
return FKO::_set_spa_hmac($self->{_ctx}, $hmac_key, $hmac_key_len)
}
sub DESTROY {

View File

@ -591,15 +591,15 @@ class Fko:
"""
_fko.verify_hmac(self.ctx, hmac_key)
def calculate_hmac(self, hmac_key):
def set_spa_hmac(self, hmac_key):
"""Calculate the HMAC for the given data
"""
_fko.calculate_hmac(self.ctx, hmac_key)
_fko.set_spa_hmac(self.ctx, hmac_key)
def get_hmac_data(self):
def get_spa_hmac(self):
"""Return the HMAC for the data in the current context
"""
_fko.get_hmac_data(self.ctx)
_fko.get_spa_hmac(self.ctx)
# GPG-related functions.

View File

@ -76,8 +76,8 @@ static PyObject * key_gen(PyObject *self, PyObject *args);
static PyObject * base64_encode(PyObject *self, PyObject *args);
static PyObject * base64_decode(PyObject *self, PyObject *args);
static PyObject * verify_hmac(PyObject *self, PyObject *args);
static PyObject * calculate_hmac(PyObject *self, PyObject *args);
static PyObject * get_hmac_data(PyObject *self, PyObject *args);
static PyObject * set_spa_hmac(PyObject *self, PyObject *args);
static PyObject * get_spa_hmac(PyObject *self, PyObject *args);
/* FKO GPG-related Functions.
*/
@ -206,9 +206,9 @@ static PyMethodDef FKOMethods[] = {
"Base64 decode function"},
{"verify_hmac", verify_hmac, METH_VARARGS,
"Generate HMAC for the data and verify it against the HMAC included with the data"},
{"calculate_hmac", calculate_hmac, METH_VARARGS,
{"set_spa_hmac", set_spa_hmac, METH_VARARGS,
"Calculate the HMAC for the given data"},
{"get_hmac_data", get_hmac_data, METH_VARARGS,
{"get_spa_hmac", get_spa_hmac, METH_VARARGS,
"Return the HMAC for the data in the current context"},
{"get_gpg_recipient", get_gpg_recipient, METH_VARARGS,
@ -1330,7 +1330,7 @@ verify_hmac(PyObject *self, PyObject *args)
}
static PyObject *
calculate_hmac(PyObject *self, PyObject *args)
set_spa_hmac(PyObject *self, PyObject *args)
{
fko_ctx_t ctx;
char *hmac_key;
@ -1340,7 +1340,7 @@ calculate_hmac(PyObject *self, PyObject *args)
if(!PyArg_ParseTuple(args, "ks#", &ctx, &hmac_key, &hmac_key_len))
return NULL;
res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
if(res != FKO_SUCCESS)
{
@ -1352,7 +1352,7 @@ calculate_hmac(PyObject *self, PyObject *args)
}
static PyObject *
get_hmac_data(PyObject *self, PyObject *args)
get_spa_hmac(PyObject *self, PyObject *args)
{
fko_ctx_t ctx;
char *enc_data;
@ -1361,7 +1361,7 @@ get_hmac_data(PyObject *self, PyObject *args)
if(!PyArg_ParseTuple(args, "k", &ctx))
return NULL;
res = fko_get_hmac_data(ctx, &enc_data);
res = fko_get_spa_hmac(ctx, &enc_data);
if(res != FKO_SUCCESS)
{

View File

@ -115,7 +115,7 @@ dump_ctx(fko_ctx_t ctx)
fko_get_spa_encryption_type(ctx, &encryption_type);
fko_get_spa_encryption_mode(ctx, &encryption_mode);
fko_get_encoded_data(ctx, &enc_data);
fko_get_hmac_data(ctx, &hmac_data);
fko_get_spa_hmac(ctx, &hmac_data);
fko_get_spa_digest(ctx, &spa_digest);
fko_get_spa_data(ctx, &spa_data);

37
test/fko-python.py Executable file
View File

@ -0,0 +1,37 @@
#!/usr/bin/python
#
# Import the Fko class and all constants.
#
from fko import *
# Create an Fko instance with an empty context.
#
fko = Fko()
fko.hmac_type(FKO_HMAC_SHA512)
# Set the SPA message (Note: Access request is default if not specified).
#
fko.spa_message("0.0.0.0,tcp/22")
# Create the final SPA data message string.
#
fko.spa_data_final("testtest", "blah")
# print the spa message.
#
print fko.spa_data()
# Print some of the data:
#
print "Version:", fko.version()
print "Timestamp:", fko.timestamp()
print "Username:", fko.username()
print "Digest Type (value):", fko.digest_type()
print "Digest Type (string):", fko.digest_type_str()
print "Digest:", fko.spa_digest()
print "HMAC Type (value):", fko.hmac_type()
print "HMAC Type (string):", fko.hmac_type_str()
print "HMAC:", fko.get_spa_hmac()
print "SPA Message:", fko.spa_message()

View File

@ -166,7 +166,7 @@ display_ctx(fko_ctx_t ctx)
fko_get_spa_hmac_type(ctx, &hmac_type);
fko_get_spa_encryption_mode(ctx, &encryption_mode);
fko_get_encoded_data(ctx, &enc_data);
fko_get_hmac_data(ctx, &hmac_data);
fko_get_spa_hmac(ctx, &hmac_data);
fko_get_spa_digest(ctx, &spa_digest);
fko_get_spa_data(ctx, &spa_data);

View File

@ -1617,6 +1617,88 @@ sub perl_fko_module_msg_types() {
return $rv;
}
sub perl_fko_module_long_keys() {
my $test_hr = shift;
my $rv = 1;
for my $msg (@{valid_access_messages()}) {
for my $key (@{fuzzing_encryption_keys()}) {
$fko_obj = FKO->new();
unless ($fko_obj) {
&write_test_file("[-] error FKO->new(): " . FKO::error_str() . "\n",
$curr_test_file);
return 0;
}
### set message and then encrypt
my $status = $fko_obj->spa_message($msg);
$status = $fko_obj->spa_data_final($key, length($key), '', 0);
if ($status == FKO->FKO_SUCCESS) {
&write_test_file("[-] Accepted fuzzing key '$key' for $msg\n",
$curr_test_file);
$rv = 0;
$fko_obj->destroy();
last;
} else {
&write_test_file("[+] Rejected fuzzing key '$key' for $msg: " .
FKO::error_str() . "\n",
$curr_test_file);
}
$fko_obj->destroy();
}
}
return $rv;
}
sub perl_fko_module_long_hmac_keys() {
my $test_hr = shift;
my $rv = 1;
for my $msg (@{valid_access_messages()}) {
for my $hmac_type (@{valid_spa_hmac_types()}) {
for my $hmac_key (@{fuzzing_hmac_keys()}) {
$fko_obj = FKO->new();
unless ($fko_obj) {
&write_test_file("[-] error FKO->new(): " . FKO::error_str() . "\n",
$curr_test_file);
return 0;
}
### set message and then encrypt
my $status = $fko_obj->spa_message($msg);
$fko_obj->hmac_type($hmac_type);
my $enc_key = 'asdfasdf';
$status = $fko_obj->spa_data_final($enc_key, length($enc_key), $hmac_key, length($hmac_key));
if ($status == FKO->FKO_SUCCESS) {
&write_test_file("[-] Accepted fuzzing hmac key '$hmac_key' for $msg\n",
$curr_test_file);
$rv = 0;
$fko_obj->destroy();
last;
} else {
&write_test_file("[+] Rejected fuzzing hmac key '$hmac_key' for $msg: " .
FKO::error_str() . "\n",
$curr_test_file);
}
$fko_obj->destroy();
}
}
}
return $rv;
}
sub perl_fko_module_access_msgs() {
my $test_hr = shift;
@ -1830,14 +1912,32 @@ sub fuzzing_usernames() {
return \@users;
}
sub fuzzing_encryption_keys() {
my @keys = (
'A'x33,
'A'x34,
'A'x128,
'A'x1000,
'A'x2000,
'asdfasdfsafsdafasdfasdfsafsdaffdjskalfjdsklafjsldkafjdsajdkajsklfdafsklfjjdkljdsafjdjd' .
'sklfjsfdsafjdslfdkjdljsajdskjdskafjdldsljdkafdsljdslafdslaldldajdskajlddslajsl',
);
return \@keys;
}
sub fuzzing_hmac_keys() {
my @keys = (
'A'x129,
'A'x1000,
'A'x2000,
);
return \@keys;
}
sub valid_encryption_keys() {
my @keys = (
'!@#$%',
'asdfasdfsafsdafasdfasdfsafsdaf',
# 'asdfasdfsafsdafasdfasdfsafsdaffdjskalfjdskl' .
# 'afjsldkafjdsajdkajsklfdafsklfjjdkljdsafjdjd' .
# 'sklfjsfdsafjdslfdkjdljsajdskjdskafjdldsljdk' .
# afdsljdslafdslaldldajdskajlddslajsl',
'$',
'asdfasdfsafsdaf',
'testtest',
@ -1849,6 +1949,20 @@ sub valid_encryption_keys() {
return \@keys;
}
sub valid_hmac_keys() {
my @keys = (
'!@#$%',
'asdfasdfsafsdafasdfasdfsafsdaf',
'$',
'A'x33,
'A'x128,
'A'x120,
'asdfasdfsafsdaf',
'1234',
'a',
);
return \@keys;
}
sub valid_spa_digest_types() {
my @types = (
FKO->FKO_DIGEST_MD5,
@ -2170,7 +2284,7 @@ sub perl_fko_module_complete_cycle_hmac() {
}
my $hmac_key_ctr = 0;
HMAC_KEY: for my $hmac_key (@{valid_encryption_keys()}) {
HMAC_KEY: for my $hmac_key (@{valid_hmac_keys()}) {
$hmac_key_ctr++;
last HMAC_KEY if $hmac_key_ctr >= 4;

View File

@ -131,6 +131,21 @@
'function' => \&perl_fko_module_rijndael_truncated_keys,
'fatal' => $NO
},
{
'category' => 'perl FKO module',
'subcategory' => 'encrypt/decrypt',
'detail' => 'invalid (long) keys',
'function' => \&perl_fko_module_long_keys,
'fatal' => $NO
},
{
'category' => 'perl FKO module',
'subcategory' => 'HMAC encrypt/decrypt',
'detail' => 'invalid (long) keys',
'function' => \&perl_fko_module_long_hmac_keys,
'fatal' => $NO
},
{
'category' => 'perl FKO module',
'subcategory' => 'encrypt/decrypt',