=================================================================== RCS file: /cvs/palm/Palm-Keyring/lib/Palm/Keyring.pm,v retrieving revision 1.64 retrieving revision 1.65 diff -u -r1.64 -r1.65 --- palm/Palm-Keyring/lib/Palm/Keyring.pm 2011/09/19 04:05:11 1.64 +++ palm/Palm-Keyring/lib/Palm/Keyring.pm 2011/09/19 04:23:37 1.65 @@ -1,5 +1,5 @@ package Palm::Keyring; -# $RedRiver: Keyring.pm,v 1.61 2008/09/19 05:55:35 andrew Exp $ +# $RedRiver: Keyring.pm,v 1.62 2008/09/19 06:01:00 andrew Exp $ ######################################################################## # Keyring.pm *** Perl class for Keyring for Palm OS databases. # @@ -59,12 +59,12 @@ blocksize => 16, default_iter => 250, }, - { + { # Only for testing alias => 'TESTING', name => 'Testing', - keylen => 8, - blocksize => 1, - default_iter => 1, + keylen => 0, + blocksize => 0, + default_iter => 0, }, ); @@ -305,7 +305,8 @@ $rec->{data} = join $NULL, $name, $rec->{encrypted}; } - } elsif ($self->{version} == 5) { + } + elsif ($self->{version} == 5) { croak 'No encrypted data in record' if !defined $rec->{encrypted}; croak 'No ivec!' if !$rec->{ivec}; @@ -324,7 +325,8 @@ $rec->{data} = join $EMPTY, $packed, $rec->{ivec}, $rec->{encrypted}; - } else { + } + else { croak "Unsupported Version $self->{version}"; } # XXX Should I? @@ -463,13 +465,16 @@ lastchange => $data->{3}->{data}, notes => $data->{255}->{data}, }; - my $acctv4 = { - name => $acct->{0}->{data}, - account => $acct->{1}->{data}, - password => $acct->{2}->{data}, - lastchange => $acct->{3}->{data}, - notes => $acct->{255}->{data}, - }; + my $acctv4 = {}; + if ($acct) { + $acctv4 = { + name => $acct->{0}->{data}, + account => $acct->{1}->{data}, + password => $acct->{2}->{data}, + lastchange => $acct->{3}->{data}, + notes => $acct->{255}->{data}, + }; + } $encrypted = _encrypt_v4($datav4, $acctv4, $self->{digest}); } elsif ($self->{version} == 5) { @@ -485,7 +490,7 @@ croak "Unsupported Version $self->{version}"; } - $rec->{plaintext}->{0} = $data->{0}; + $rec->{plaintext} = $data; if ($encrypted ne '1') { $rec->{attributes}{Dirty} = 1; @@ -671,6 +676,7 @@ } $plaintext .= chr(0xff) x 2; + #print "CRYPT(e): $c->{name} [$cipher]\n"; my $encrypted; if ($c->{name} eq 'None') { # do nothing @@ -754,11 +760,8 @@ croak "Unsupported Version $self->{version}"; } - if ($plaintext) { - $rec->{plaintext} = $plaintext; - return $plaintext; - } - return; + $rec->{plaintext} = $plaintext; + return $plaintext; } sub _decrypt_v4 @@ -772,6 +775,7 @@ my $modified; if ($packed_date) { + #print _hexdump('DATE:', $packed_date); $modified = _parse_keyring_date($packed_date); } @@ -795,11 +799,13 @@ my $plaintext; + #print "CRYPT(d): $c->{name} [$cipher]\n"; if ($c->{name} eq 'None') { # do nothing $plaintext = $encrypted; - } elsif ($c->{name} eq 'DES_EDE3' or $c->{name} eq 'Rijndael') { + } + elsif ($c->{name} eq 'DES_EDE3' or $c->{name} eq 'Rijndael') { require Crypt::CBC; my $cbc = Crypt::CBC->new( -key => $key, @@ -810,23 +816,23 @@ -blocksize => $c->{blocksize}, -header => 'none', -padding => 'oneandzeroes', - ) || croak("Unable to set up encryption!"); + ) || croak("Unable to set up decryption!"); my $len = $c->{blocksize} - length($encrypted) % $c->{blocksize}; $encrypted .= $NULL x $len; + $plaintext = $cbc->decrypt($encrypted); - } else { - croak "Unsupported Crypt $c->{name}"; } + else { + croak "Unsupported Crypt $c->{name} in decrypt"; + } my %fields; while ($plaintext) { my $field; ($field, $plaintext) = _parse_field($plaintext); - if (! $field) { - last; - } + last if ! $field; $fields{ $field->{label_id} } = $field; } @@ -857,16 +863,12 @@ if ($new_pass) { my @accts = (); foreach my $rec (@{ $self->{records} }) { - my $acct = $self->Decrypt($rec, $pass); - if ( ! $acct ) { - croak("Couldn't decrypt $rec->{plaintext}->{0}->{data}"); - } + my $acct = $self->Decrypt($rec, $pass) + || croak("Couldn't decrypt $rec->{plaintext}->{0}->{data}"); push @accts, $acct; } - if ( ! $self->_password_update($new_pass)) { - croak("Couldn't set new password!"); - } + $self->_password_update($new_pass); $pass = $new_pass; foreach my $i (0..$#accts) { @@ -900,11 +902,12 @@ # May as well generate the keys we need now, # since we know the password is right - $self->{digest} = _calc_keys($pass); + $self->{digest} = _calc_keys($pass); $self->{password} = $pass; - return 1; - } elsif ($self->{version} == 5) { + return 1; + } + elsif ($self->{version} == 5) { _password_verify_v5($self->{appinfo}, $pass); $self->{password} = $pass; return 1; @@ -931,7 +934,7 @@ my $msg = $salt . $pass; $msg .= "\0" x ( $MD5_CBLOCK - length $msg ); - my $digest = md5($msg); + my $digest = md5($msg) || croak('MD5 Failed'); if ($data ne $salt . $digest ) { croak("Incorrect Password!"); @@ -961,10 +964,9 @@ #print "Hash: '". $hash . "'\n"; #print "Hash: '". $appinfo->{masterhash} . "'\n"; - if ($appinfo->{masterhash} ne $hash) { - croak("Incorrect Password!"); + if ($appinfo->{masterhash} && $appinfo->{masterhash} ne $hash) { + croak('Incorrect Password'); } - $appinfo->{key} = $key; return 1; } @@ -991,8 +993,8 @@ $self->{digest} = _calc_keys( $self->{password} ); return 1; - - } elsif ($self->{version} == 5) { + } + elsif ($self->{version} == 5) { my $cipher = shift || $self->{appinfo}->{cipher}; my $iter = shift || $self->{appinfo}->{iter}; my $salt = shift || 0; @@ -1018,7 +1020,7 @@ my $pass = shift; - if (! defined $pass) { croak('No password specified!'); }; + croak('No password specified!') if ! defined $pass; my $salt; for ( 1 .. $kSalt_Size ) { @@ -1029,7 +1031,7 @@ $msg .= "\0" x ( $MD5_CBLOCK - length $msg ); - my $digest = md5($msg); + my $digest = md5($msg) || croak('MD5 failed'); my $data = $salt . $digest; # . "\0"; @@ -1043,7 +1045,7 @@ my $cipher = shift; my $iter = shift; - # I thought this needed to be 'blocksize', but apparently not. + # I thought $length needed to be 'blocksize', but apparently not. #my $length = $CRYPTS[ $cipher ]{blocksize}; my $length = 8; my $salt = shift || pack("C*",map {rand(256)} 1..$length); @@ -1134,7 +1136,7 @@ import Digest::SHA1 qw(sha1); my $key = _pbkdf2( $pass, $salt, $iter, $keylen, \&hmac_sha1 ); - if ($dop) { $key = _DES_odd_parity($key); } + $key = _DES_odd_parity($key) if $dop; my $hash = unpack("H*", substr(sha1($key.$salt),0, 8));