Skip Menu |

This queue is for tickets about the Crypt-RSA CPAN distribution.

Report information
The Basics
Id: 69376
Status: open
Priority: 0/
Queue: Crypt-RSA

People
Owner: Nobody in particular
Requestors: Nicholas.Wallette [...] chenega.com
Cc:
AdminCc:

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



Subject: Bug in Crypt::RSA::Key::Private::SSH serialize function
Date: Sat, 9 Jul 2011 18:41:22 +0000
To: "bug-Crypt-RSA [...] rt.cpan.org" <bug-Crypt-RSA [...] rt.cpan.org>
From: "Wallette, Nicholas" <Nicholas.Wallette [...] chenega.com>
The serialize function does not interpret the Cipher parameter correctly. According to the documentation in Crypt::RSA::Key::Private.pm, in the new() function, the Cipher parameter is supposed to be: "Name of the symmetric cipher in which the private key is encrypted (or should be encrypted)." The code in Crypt::RSA::Key::Private::SSH serialize() seems to expect this to be a number serving as a key in the %CIPHERS hash. Line 113 in SSH.pm checks $passphrase to see if it's provided, and if so, then checks $params{Cipher} for contents, providing a default value of 3 if not. (Note: On my system, this is apparently mapped to Crypt::DES3, which is also not the documented default of "Blowfish".) Line 143, executed only if $cipher_type passes a Boolean truth test, then sets $cipher_name to be the value determined by $CIPHERS{$cipher_type). If used according to the documentation's convention for the Cipher parameter, this will cause Line 143 to set $cipher_name = $CIPHERS{NAME_of_chosen_cipher}, which is not a number, and thus not a valid key in the CIPHERS hash, causing Line 145 to try and require "Crypt::", which obviously fails. Here's a code snippet that will show this behavior: #!/usr/bin/perl use warnings; use strict; use Crypt::RSA::Key; use Crypt::RSA::Key::Private::SSH; my $obj = new Crypt::RSA::Key; # Create an unencrypted key my ($pub, $pri) = $obj->generate( Identity => 'Some User <someuser@example.com>', Size => 1024, KF => 'SSH' ); # Now try to encrypt this key my $crypted = $pri->serialize( Cipher => "Blowfish", Password => "Hunter2" ); This pertains to version 1.99 of the Crypt::RSA package. Perl version is v5.12.3, x86_64-linux. OS is Gentoo Linux, Kernel 2.6.38-gentoo-r6, built June 13th, 2011 using an up-to-date Portage snapshot. Exact error message is: Unsupported cipher '': Can't locate Crypt:: in @INC (@INC contains: lib /root/dev/pdb/../../../../../lib /etc/perl /usr/lib64/perl5/site_perl/5.12.3/x86_64-linux /usr/lib64/perl5/site_perl/5.12.3 /usr/lib64/perl5/vendor_perl/5.12.3/x86_64-linux /usr/lib64/perl5/vendor_perl/5.12.3 /usr/lib64/perl5/site_perl /usr/lib64/perl5/vendor_perl /usr/lib64/perl5/5.12.3/x86_64-linux /usr/lib64/perl5/5.12.3 /usr/local/lib/site_perl .) at /usr/lib64/perl5/site_perl/5.12.3/Crypt/RSA/Key/Private/SSH.pm line 145. at ./testcase.pl line 19 A couple possible fixes: 1) Change Line 113 to read: my $cipher_type = $passphrase eq '' ? '' : $params{Cipher} || 'Blowfish'; and Line 144 to read: my $class = 'Crypt::' . $cipher_type; 2) Map $params{Cipher} to $cipher_type by something like this: foreach my $type keys(%CIPHERS) { if $CIPHERS{$type} eq $params{Cipher} { $cipher_type = $type; } } 3) Change the documentation to suggest using the numerical index for Cipher, and a good way to find out what those are. Nick Wallette Systems Administrator Chenega Logistics, LLC 3000 C Street, Suite 301 Anchorage, AK 99503 (907) 677-4928 Direct (907) 903-1811 Cell (907) 277-5706 Main (907) 277-5700 Fax nick.wallette@chenega.com<mailto:nick.wallette@chenega.com> Email

Message body is not shown because it is too large.

I took the liberty of fixing this in Alt-Crypt-RSA-BigInt-0.03, and adding a test file for it as well as an extended one in the xt/ directory. I don't know if all the details are what Vipul wants however. The cipher used is none if both the serialize Password and the key Password are not provided. If there is a passphrase, then the Cipher is either the one provided (text name), the key's Cipher, or Blowfish (since it is the only cipher we have listed in the dependencies). The cipher is uppercased then compared against a list including: NONE, IDEA, DES, [DES_EDE3, DES3, 3DES, TRIPLEDES], BLOWFISH, [TWOFISH, TWOFISH2], [CAST5, CAST5_PP, CAST5PP, CAST-5, CAST-128, CAST128], [RIJNDAEL, AES, OPENSSL::AES], RC6, CAMELLIA. If we can't find a match then we croak indicating it is an unknown cipher. I skipped RC4 (ARCFOUR) because none of the current CPAN modules seem to be Crypt::CBC-compliant. There is a list of modules associated with each algorithm, so for instance for Twofish we use Crypt::Twofish2, while for Rijndael we first try Crypt::Rijndael and then Crypt::OpenSSL::AES if that failed. If we can't load one of the modules then we croak indicating the cipher is unsupported, which means you need to install the appropriate module. For deserialization, we do just the paragraph above: Once we have the number from the SSH1 key string this tells us the algorithm. Then we do the module lookup in the same way. The deserialization interface is a little funny to me -- instead of saying "I want a new key with this data" we have to generate a new key, then tell it to overwrite itself with the string. Also, I'm not sure what separation there is supposed to be between the serialize password and the key password. I chose to treat them as if they were not tied together, so if you deserialize with a password, that doesn't make the new key have that password.