Skip Menu |

This queue is for tickets about the Authen-Passphrase CPAN distribution.

Report information
The Basics
Id: 102133
Status: new
Priority: 0/
Queue: Authen-Passphrase

People
Owner: Nobody in particular
Requestors: mstock [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Add support for the SHA-2 family of cryptographic hash functions
Hi, I noticed that Authen-Passphrase currently lacks support for the SHA-2 family of cryptographic hash functions when I wanted to use salted SHA-512 with DBIx::Class::PassphraseColumn. The attached patch would change this by adding support for SHA-{224,256,384,512} in unsalted and salted variants. Unfortunately, RFC 2307 does not define the scheme for these functions, so I used eg. SSHA512 for salted SHA-512, which is also done by Crypt::SaltedHash and the OpenLDAP module which provides support for SHA-2 [1]. Best regards Manfred [1] http://www.openldap.org/devel/gitweb.cgi?p=openldap.git;a=blob;f=contrib/slapd-modules/passwd/sha2/README;hb=HEAD
Subject: sha-2-support.patch
diff --git a/Build.PL b/Build.PL index b39ab56..686757f 100644 --- a/Build.PL +++ b/Build.PL @@ -31,10 +31,10 @@ Module::Build->new( "Crypt::PasswdMD5" => "1.0", "Crypt::UnixCrypt_XS" => "0.08", "Data::Entropy::Algorithms" => 0, - "Digest" => "1.00", + "Digest" => "1.11", "Digest::MD4" => "1.2", "Digest::MD5" => "1.9953", - "Digest::SHA" => 0, + "Digest::SHA" => "5.60", "MIME::Base64" => "2.21", "Module::Runtime" => "0.011", "Params::Classify" => 0, diff --git a/lib/Authen/Passphrase.pm b/lib/Authen/Passphrase.pm index 2fb3550..6445a31 100644 --- a/lib/Authen/Passphrase.pm +++ b/lib/Authen/Passphrase.pm @@ -401,6 +401,11 @@ identifier is followed by the user's username. The SHA-1 digest of the passphrase is stored. See L<Authen::Passphrase::SaltedDigest>. +=item B<{SHA{224,256,384,512}}> + +The SHA-2, {224,256,384,512} bit digest of the passphrase is stored. See +L<Authen::Passphrase::SaltedDigest>. + =item B<{SMD5}> The MD5 digest of the passphrase plus a salt is stored. See @@ -411,6 +416,11 @@ L<Authen::Passphrase::SaltedDigest>. The SHA-1 digest of the passphrase plus a salt is stored. See L<Authen::Passphrase::SaltedDigest>. +=item B<{SSHA{224,256,384,512}}> + +The SHA-2, {224,256,384,512} bit digest of the passphrase plus a salt is stored. +See L<Authen::Passphrase::SaltedDigest>. + =item B<{UNIX}> Not a real passphrase scheme, but a placeholder to indicate that Unix @@ -440,8 +450,16 @@ my %rfc2307_scheme_handler = ( "RMD160" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], "SASL" => sub($) { croak "{SASL} is a placeholder" }, "SHA" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], + "SHA224" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SHA256" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SHA384" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SHA512" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], "SMD5" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], "SSHA" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], + "SSHA224" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SSHA256" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SSHA384" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], + "SSHA512" => [ "Authen::Passphrase::SaltedDigest", 0.009 ], "UNIX" => sub($) { croak "{UNIX} is a placeholder" }, # "WM-CRY" is handled specially ); diff --git a/lib/Authen/Passphrase/SaltedDigest.pm b/lib/Authen/Passphrase/SaltedDigest.pm index cc86ae4..e20dc5a 100644 --- a/lib/Authen/Passphrase/SaltedDigest.pm +++ b/lib/Authen/Passphrase/SaltedDigest.pm @@ -81,7 +81,7 @@ use MIME::Base64 2.21 qw(encode_base64 decode_base64); use Module::Runtime 0.011 qw(is_valid_module_name use_module); use Params::Classify 0.000 qw(is_string is_blessed); -our $VERSION = "0.008"; +our $VERSION = "0.009"; use parent "Authen::Passphrase"; @@ -234,8 +234,12 @@ and salt. The scheme identifiers accepted are "B<{MD4}>" (unsalted MD4), "B<{MD5}>" (unsalted MD5), "B<{RMD160}>" (unsalted RIPEMD-160), "B<{SHA}>" (unsalted -SHA-1), "B<{SMD5}>" (salted MD5), and "B<{SSHA}>" (salted SHA-1). -All scheme identifiers are recognised case-insensitively. +SHA-1), "B<{SHA224}>" (unsalted SHA-224), "B<{SHA256}>" (unsalted SHA-256), +"B<{SHA384}>" (unsalted SHA-384), "B<{SHA512}>" (unsalted SHA-512), "B<{SMD5}>" +(salted MD5), "B<{SSHA}>" (salted SHA-1), "B<{SSHA224}>" (salted SHA-224), +"B<{SSHA256}>" (salted SHA-256), "B<{SSHA384}>" (salted SHA-384) and +"B<{SSHA512}>" (salted SHA-512). All scheme identifiers are recognised +case-insensitively. =cut @@ -244,8 +248,16 @@ my %rfc2307_scheme_meaning = ( "MD5" => ["MD5", 16, 0], "RMD160" => ["Crypt::RIPEMD160-", 20, 0], "SHA" => ["SHA-1", 20, 0], + "SHA224" => ["SHA-224", 28, 0], + "SHA256" => ["SHA-256", 32, 0], + "SHA384" => ["SHA-384", 48, 0], + "SHA512" => ["SHA-512", 64, 0], "SMD5" => ["MD5", 16, 1], "SSHA" => ["SHA-1", 20, 1], + "SSHA224" => ["SHA-224", 28, 1], + "SSHA256" => ["SHA-256", 32, 1], + "SSHA384" => ["SHA-384", 48, 1], + "SSHA512" => ["SHA-512", 64, 1], ); sub from_rfc2307 { @@ -390,6 +402,14 @@ my %rfc2307_scheme_for_digest_name = ( "MD5" => "MD5", "SHA-1" => "SHA", "SHA1" => "SHA", + "SHA-224" => "SHA224", + "SHA224" => "SHA224", + "SHA-256" => "SHA256", + "SHA256" => "SHA256", + "SHA-384" => "SHA384", + "SHA384" => "SHA384", + "SHA-512" => "SHA512", + "SHA512" => "SHA512", ); my %rfc2307_scheme_for_package_name = ( diff --git a/t/sha.t b/t/sha.t new file mode 100644 index 0000000..54cc149 --- /dev/null +++ b/t/sha.t @@ -0,0 +1,72 @@ +use warnings; +use strict; + +use Test::More tests => 248; + +use MIME::Base64 2.21 qw(encode_base64); + +BEGIN { use_ok "Authen::Passphrase::SaltedDigest"; } + +my $ppr = Authen::Passphrase::SaltedDigest + ->from_rfc2307("{SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M="); +ok $ppr; +is $ppr->algorithm, "SHA-1"; +is $ppr->salt_hex, ''; +is $ppr->hash_hex, "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"; + +my %pprs; +my $i = 0; +while(<DATA>) { + chomp; + s/([^ \n]+) ([^ \n]+) ([^ \n]+) *//; + my($algorithm, $scheme, $hash_hex) = ($1, $2, $3, $4); + my $hash = pack("H*", $hash_hex); + my $ppr = Authen::Passphrase::SaltedDigest + ->new(algorithm => $algorithm, + ($i & 1) ? (hash => $hash) : + (hash_hex => $hash_hex)); + $i++; + ok $ppr; + is $ppr->salt_hex, ''; + is $ppr->salt, ''; + is $ppr->hash_hex, $hash_hex; + is $ppr->hash, $hash; + eval { $ppr->passphrase }; isnt $@, ""; + eval { $ppr->as_crypt }; isnt $@, ""; + is $ppr->as_rfc2307, "{".$scheme."}".encode_base64($hash, ""); + $pprs{$_} = $ppr; + + $ppr = Authen::Passphrase::SaltedDigest->from_rfc2307($ppr->as_rfc2307); + ok $ppr; + is $ppr->salt_hex, ''; + is $ppr->salt, ''; + is $ppr->hash_hex, $hash_hex; + is $ppr->hash, $hash; + + $ppr = Authen::Passphrase->from_rfc2307($ppr->as_rfc2307); + ok $ppr; + is $ppr->salt_hex, ''; + is $ppr->salt, ''; + is $ppr->hash_hex, $hash_hex; + is $ppr->hash, $hash; +} + +foreach my $rightphrase (sort keys %pprs) { + my $ppr = $pprs{$rightphrase}; + foreach my $passphrase (sort keys %pprs) { + ok ($ppr->match($passphrase) xor $passphrase ne $rightphrase); + } +} + +1; + +__DATA__ +SHA-1 SHA da39a3ee5e6b4b0d3255bfef95601890afd80709 +SHA-1 SHA b6589fc6ab0dc82cf12099d1c2d40ab994e8410c 0 +SHA-1 SHA 356a192b7913b04c54574d18c28d46e6395428ab 1 +SHA-1 SHA 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 foo +SHA-1 SHA 98389f5ae1dfdbad80426cb2cf498dbdd56b70c6 supercalifragilisticexpialidocious +SHA-224 SHA224 07daf010de7f7f0d8d76a76eb8d1eb40182c8d1e7a3877a6686c9bf0 bar +SHA-256 SHA256 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 test +SHA-384 SHA384 967004d25de4abc1bd6a7c9a216254a5ac0733e8ad96dc9f1ea0fad9619da7c32d654ec8ad8ba2f9b5728fed6633bd91 baz +SHA-512 SHA512 0a50261ebd1a390fed2bf326f2673c145582a6342d523204973d0219337f81616a8069b012587cf5635f6925f1b56c360230c19b273500ee013e030601bf2425 foobar diff --git a/t/ssha.t b/t/ssha.t index 6d86237..bf963a0 100644 --- a/t/ssha.t +++ b/t/ssha.t @@ -1,7 +1,7 @@ use warnings; use strict; -use Test::More tests => 70; +use Test::More tests => 248; use MIME::Base64 2.21 qw(encode_base64); @@ -18,12 +18,12 @@ my %pprs; my $i = 0; while(<DATA>) { chomp; - s/([^ \n]+) ([^ \n]+) *//; - my($salt_hex, $hash_hex) = ($1, $2); + s/([^ \n]+) ([^ \n]+) ([^ \n]+) ([^ \n]+) *//; + my($algorithm, $scheme, $salt_hex, $hash_hex) = ($1, $2, $3, $4); my $salt = pack("H*", $salt_hex); my $hash = pack("H*", $hash_hex); my $ppr = Authen::Passphrase::SaltedDigest - ->new(algorithm => "SHA-1", + ->new(algorithm => $algorithm, ($i & 1) ? (salt => $salt) : (salt_hex => $salt_hex), ($i & 2) ? (hash => $hash) : @@ -36,8 +36,22 @@ while(<DATA>) { is $ppr->hash, $hash; eval { $ppr->passphrase }; isnt $@, ""; eval { $ppr->as_crypt }; isnt $@, ""; - is $ppr->as_rfc2307, "{SSHA}".encode_base64($hash.$salt, ""); + is $ppr->as_rfc2307, "{".$scheme."}".encode_base64($hash.$salt, ""); $pprs{$_} = $ppr; + + $ppr = Authen::Passphrase::SaltedDigest->from_rfc2307($ppr->as_rfc2307); + ok $ppr; + is $ppr->salt_hex, $salt_hex; + is $ppr->salt, $salt; + is $ppr->hash_hex, $hash_hex; + is $ppr->hash, $hash; + + $ppr = Authen::Passphrase->from_rfc2307($ppr->as_rfc2307); + ok $ppr; + is $ppr->salt_hex, $salt_hex; + is $ppr->salt, $salt; + is $ppr->hash_hex, $hash_hex; + is $ppr->hash, $hash; } foreach my $rightphrase (sort keys %pprs) { @@ -50,8 +64,12 @@ foreach my $rightphrase (sort keys %pprs) { 1; __DATA__ -616263 a9993e364706816aba3e25717850c26c9cd0d89d -717765 7cd928d1e6457c57c01f3c9442177fc62cafa56f 0 -212121 2fee6a4e9b98f3bd6de8b1960cfb37f8b44d8bb1 1 -787878 76cdd1408a02a44687fe87c98f8dc43678c4ef5f foo -707966 b264504de2719cebf898608cf950e1da5f3ae28f supercalifragilisticexpialidocious +SHA-1 SSHA 616263 a9993e364706816aba3e25717850c26c9cd0d89d +SHA-1 SSHA 717765 7cd928d1e6457c57c01f3c9442177fc62cafa56f 0 +SHA-1 SSHA 212121 2fee6a4e9b98f3bd6de8b1960cfb37f8b44d8bb1 1 +SHA-1 SSHA 787878 76cdd1408a02a44687fe87c98f8dc43678c4ef5f foo +SHA-1 SSHA 707966 b264504de2719cebf898608cf950e1da5f3ae28f supercalifragilisticexpialidocious +SHA-224 SSHA224 482939 1186253382c5b15e694b4351a6d525316b945a2fef6db7f7d6ca1d1c bar +SHA-256 SSHA256 742935 f0851d4e2f92e8320be35e958545ea686ba9cbc6db53f43d8e5f9e005941fbcf test +SHA-384 SSHA384 395425 501922945b68430fedb3cff4001db4a6a8e19933596cb503ea0db151b92bbe90be0e69fd781f5683780e1579ce752252 baz +SHA-512 SSHA512 243722 8c692b969c27e9c50a0a9a779929c99bcaf25cfbfaf62c07a2c8eba9d38f5e6affd9ef2bfe7cf49222e7372a21c2fdcc2643823cd4aaf629aa70999525ab5002 foobar