From 1049cc8016d3130a256ee0279224443b5ec25a7d Mon Sep 17 00:00:00 2001 From: mhasbini Date: Sun, 17 Feb 2019 22:48:19 +0200 Subject: [PATCH] Add unit tests for multiple modules: 10900, 11000, 11100, 11200, 11300 & 11400 --- tools/test_modules/m10900.pm | 70 +++++++++++++++ tools/test_modules/m11000.pm | 44 ++++++++++ tools/test_modules/m11100.pm | 50 +++++++++++ tools/test_modules/m11200.pm | 68 +++++++++++++++ tools/test_modules/m11300.pm | 66 ++++++++++++++ tools/test_modules/m11400.pm | 164 +++++++++++++++++++++++++++++++++++ 6 files changed, 462 insertions(+) create mode 100644 tools/test_modules/m10900.pm create mode 100644 tools/test_modules/m11000.pm create mode 100644 tools/test_modules/m11100.pm create mode 100644 tools/test_modules/m11200.pm create mode 100644 tools/test_modules/m11300.pm create mode 100644 tools/test_modules/m11400.pm diff --git a/tools/test_modules/m10900.pm b/tools/test_modules/m10900.pm new file mode 100644 index 000000000..29e04cefb --- /dev/null +++ b/tools/test_modules/m10900.pm @@ -0,0 +1,70 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; +use MIME::Base64 qw (encode_base64 decode_base64); + +sub module_constraints { [[0, 255], [1, 15], [0, 55], [1, 15], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $iterations = shift // 1000; + my $out_len = shift // 24; + + my $pbkdf2 = Crypt::PBKDF2->new + ( + hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256), + iterations => $iterations, + output_len => $out_len + ); + + my $digest = encode_base64 ($pbkdf2->PBKDF2 ($salt, $word), ""); + + my $base64_salt = encode_base64 ($salt, ""); + + my $hash = sprintf ("sha256:%i:%s:%s", $iterations, $base64_salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($digest, $word) = split (/:([^:]+)$/, $line); + + return unless defined $digest; + return unless defined $word; + + my @data = split (':', $digest); + + return unless scalar(@data) == 4; + + my $signature = shift @data; + + return unless ($signature eq 'sha256'); + + my $iterations = int (shift @data); + + my $salt = decode_base64 (shift @data); + my $hash = decode_base64 (shift @data); + + my $out_len = length ($hash); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $iterations, $out_len); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m11000.pm b/tools/test_modules/m11000.pm new file mode 100644 index 000000000..ef1c09b38 --- /dev/null +++ b/tools/test_modules/m11000.pm @@ -0,0 +1,44 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5 qw (md5_hex); + +sub module_constraints { [[0, 255], [56, 56], [0, 55], [56, 56], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $digest = md5_hex ($salt . $word); + + my $hash = sprintf ("%s:%s", $digest, $salt); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $salt, $word) = split (/:/, $line); + + return unless defined $hash; + return unless defined $salt; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m11100.pm b/tools/test_modules/m11100.pm new file mode 100644 index 000000000..6d29f05c7 --- /dev/null +++ b/tools/test_modules/m11100.pm @@ -0,0 +1,50 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5 qw (md5_hex); + +sub module_constraints { [[0, 255], [8, 8], [0, 55], [8, 8], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $user = shift // "postgres"; + + my $digest = md5_hex (md5_hex ($word . $user) . pack ("H*", $salt)); + + my $hash = sprintf ("\$postgres\$%s*%s*%s", $user, $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash_in, $word) = split (/:/, $line); + + return unless defined $hash_in; + return unless defined $word; + + my (undef, $signature, $digest) = split ('\$', $hash_in); + + return unless ($signature eq 'postgres'); + + my ($user, $salt, $hash) = split ('\*', $digest); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $user); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m11200.pm b/tools/test_modules/m11200.pm new file mode 100644 index 000000000..ad1813c2a --- /dev/null +++ b/tools/test_modules/m11200.pm @@ -0,0 +1,68 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5 qw (md5_hex); +use Digest::SHA qw (sha1); + +sub module_constraints { [[0, 255], [40, 40], [0, 55], [40, 40], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $sha1_pass = sha1 ($word); + my $double_sha1 = sha1 ($sha1_pass); + + my $xor_part1 = $sha1_pass; + my $xor_part2 = sha1 (pack ("H*", $salt) . $double_sha1); + + my $digest = ""; + + for (my $i = 0; $i < 20; $i++) + { + my $first_byte = substr ($xor_part1, $i, 1); + my $second_byte = substr ($xor_part2, $i, 1); + + my $xor_result = $first_byte ^ $second_byte; + + $digest .= unpack ("H*", $xor_result); + } + + my $hash = sprintf ("\$mysqlna\$%s*%s", $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash_in, $word) = split (/:/, $line); + + return unless defined $hash_in; + return unless defined $word; + + my (undef, $signature, $digest) = split ('\$', $hash_in); + + my ($salt, $hash) = split ('\*', $digest); + + return unless ($signature eq 'mysqlna'); + return unless defined $salt; + return unless defined $hash; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m11300.pm b/tools/test_modules/m11300.pm new file mode 100644 index 000000000..e4e8d5724 --- /dev/null +++ b/tools/test_modules/m11300.pm @@ -0,0 +1,66 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA qw (sha512); +use Crypt::CBC; + +sub module_constraints { [[0, 255], [16, 16], [0, 55], [16, 16], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $ckey = shift // random_hex_string (96); + my $public_key = shift // random_hex_string (66); + my $salt_iter = shift // random_number (150000, 250000); + + my $digest = sha512 ($word . pack ("H*", $salt)); + + for (my $i = 1; $i < $salt_iter; $i++) + { + $digest = sha512 ($digest); + } + + my $data = random_hex_string (32); + + my $aes = Crypt::CBC->new ({ + key => substr ($digest, 0, 32), + cipher => "Crypt::Rijndael", + iv => substr ($digest, 32, 16), + literal_key => 1, + header => "none", + keysize => 32, + padding => "standard", + }); + + my $cry_master = (unpack ("H*", $aes->encrypt ($data))); + + my $hash = sprintf ('$bitcoin$%d$%s$%d$%s$%d$%d$%s$%d$%s', + length ($cry_master), + $cry_master, + length ($salt), + $salt, + $salt_iter, + length ($ckey), + $ckey, + length ($public_key), + $public_key); + + return $hash; +} + +sub module_verify_hash +{ + print "ERROR: verify currently not supported for Bitcoin/Litecoin wallet.dat because of unknown crypt data\n"; + + exit (1); +} + +1; diff --git a/tools/test_modules/m11400.pm b/tools/test_modules/m11400.pm new file mode 100644 index 000000000..a3dd73b98 --- /dev/null +++ b/tools/test_modules/m11400.pm @@ -0,0 +1,164 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5 qw (md5_hex); + +sub module_constraints { [[0, 24], [1, 15], [0, 24], [1, 15], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $nonce = shift; + my $user = shift // random_string (random_number (1, 12 + 1)); + my $realm = shift; + my $nonce_count = shift; + my $nonce_client = shift; + my $qop = shift; + my $method = shift // random_string (random_number (1, 24 + 1)); + my $URI_prefix = shift // random_string (random_number (1, 10 + 1)); + my $URI_resource = shift // random_string (random_number (1, 32 + 1)); + my $URI_suffix = shift // random_string (random_number (1, 32 + 1)); + my $directive = shift // "MD5"; + + # not needed information + my $URI_server = shift // random_string (random_number (1, 32 + 1)); + my $URI_client = $URI_resource; + + return unless ($directive eq "MD5"); # only MD5 directive currently supported + + unless (defined $realm) + { + # special limit: (user_len + 1 + realm_len + 1 + word_len) < 56 + my $realm_max_len = 55 - length ($user) - 1 - length ($word) - 1; + + if ($realm_max_len < 1) # should never happen + { + $realm_max_len = 1; + } + + $realm_max_len = min (20, $realm_max_len); + + $realm = random_string (random_number (1, $realm_max_len + 1)); + } + + unless ((defined $nonce_count) && (defined $nonce_client) && (defined $qop)) + { + if (random_number (0, 1 + 1) == 1) + { + $qop = "auth"; + + $nonce_count = random_string (random_number (1, 10 + 1)); + $nonce_client = random_string (random_number (1, 12 + 1)); + } + else + { + $qop = ""; + + $nonce_count = ""; + $nonce_client = ""; + } + } + + # start + + my $URI = ""; + + if (length ($URI_prefix) > 0) + { + $URI = $URI_prefix . ":"; + } + + $URI .= $URI_resource; + + if (length ($URI_suffix) > 0) + { + $URI .= ":" . $URI_suffix; + } + + my $HA2 = md5_hex ($method . ":" . $URI); + + my $HA1 = md5_hex ($user . ":" . $realm . ":" . $word); + + my $tmp; + + if (($qop eq "auth") || ($qop eq "auth-int")) + { + $tmp = $nonce . ":" . $nonce_count . ":" . $nonce_client . ":" . $qop; + } + else + { + $tmp = $nonce; + } + + my $digest = md5_hex ($HA1 . ":" . $tmp . ":" . $HA2); + + my $hash = sprintf ("\$sip\$*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s", $URI_server, $URI_resource, $user, $realm, $method, $URI_prefix, $URI_resource, $URI_suffix, $nonce, $nonce_client, $nonce_count, $qop, $directive, $digest); + + return $hash; +} + +sub module_verify_hash +{ + + my $line = shift; + + my ($digest, $word) = split (/:/, $line); + + return unless defined $digest; + return unless defined $word; + + my @data = split ('\*', $digest); + + return unless scalar @data == 15; + + my $signature = shift @data; + my $URI_server = shift @data; + my $URI_client = shift @data; + my $user = shift @data; + my $realm = shift @data; + my $method = shift @data; + my $URI_prefix = shift @data; + my $URI_resource = shift @data; + my $URI_suffix = shift @data; + my $nonce = shift @data; + my $nonce_client = shift @data; + my $nonce_count = shift @data; + my $qop = shift @data; + my $directive = shift @data; + my $hash = shift @data; + + return unless ($signature eq '$sip$'); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ( + $word_packed, + $nonce, + $user, + $realm, + $nonce_count, + $nonce_client, + $qop, + $method, + $URI_prefix, + $URI_resource, + $URI_suffix, + $directive, + $URI_server); + + return ($new_hash, $word); +} + +sub min +{ + $_[$_[0] > $_[1]]; +} + +1;