=================================================================== RCS file: /cvs/palm/Palm-Keyring/lib/Palm/Keyring.pm,v retrieving revision 1.7 retrieving revision 1.10 diff -u -r1.7 -r1.10 --- palm/Palm-Keyring/lib/Palm/Keyring.pm 2006/11/10 16:45:42 1.7 +++ palm/Palm-Keyring/lib/Palm/Keyring.pm 2006/12/06 18:45:42 1.10 @@ -8,8 +8,8 @@ # # This started as Memo.pm, I just made it work for Keyring. # -# $Id: Keyring.pm,v 1.7 2006/11/10 16:45:42 andrew Exp $ -# $RedRiver: Keyring.pm,v 1.6 2006/11/10 16:18:59 andrew Exp $ +# $Id: Keyring.pm,v 1.10 2006/12/06 18:45:42 andrew Exp $ +# $RedRiver: Keyring.pm,v 1.9 2006/11/10 17:49:51 andrew Exp $ use strict; package Palm::Keyring; @@ -27,7 +27,7 @@ # One liner, to allow MakeMaker to work. -$VERSION = do { my @r = (q$Revision: 1.7 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 1.10 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; @ISA = qw( Palm::StdAppInfo Palm::Raw ); @@ -86,15 +86,7 @@ $self->{version} = 4; # Give the PDB the first record that will hold the encrypted password - $self->{records} = [ { - 'category' => 0, - 'attributes' => { - 'private' => 1, - 'Secret' => 1, - 'Dirty' => 1, - 'dirty' => 1, - }, - }, ]; + $self->{records} = [ $self->new_Record ]; if ($pass) { $self->Encrypt($pass); @@ -113,6 +105,8 @@ sub Load { my $self = shift; + $self->{'appinfo'} = {}; + $self->{'records'} = []; $self->SUPER::Load(@_); foreach my $record (@{ $self->{records} }) { @@ -129,7 +123,7 @@ { my $self = shift; $self->Encrypt() || return undef; - return $self->SUPER::Load(@_); + return $self->SUPER::Write(@_); } sub Encrypt @@ -255,7 +249,7 @@ # AFAIK the thing we use to test the password is # always in the first entry - my $data = $self->{records}->[1]->{data}; + my $data = $self->{records}->[0]->{data}; #die "No encrypted password in file!" unless defined $data; return undef unless defined $data; @@ -294,7 +288,7 @@ die "No password specified!" unless $pass; # if the database already has a password in it - if ($self->{records}->[1]->{data}) { + if ($self->{records}->[0]->{data}) { # Make sure everything is decrypted before we update the keyring $self->Decrypt() || return undef; } @@ -314,7 +308,7 @@ # AFAIK the thing we use to test the password is # always in the first entry - $self->{records}->[1]->{data} = $data; + $self->{records}->[0]->{data} = $data; $self->{password} = $pass; $self->{digest} = _calc_keys($self->{password}); @@ -323,47 +317,64 @@ } -# XXX Have to make this encrypt as well as decrypting, but w00 h00! -# do null padding on the end of a cleartext if we are going to encrypt it +# XXX It looks like they are using des_ecb2_encrypt so I dunno if that is different sub _crypt3des { my ( $plaintext, $passphrase, $flag ) = @_; + my $NULL = chr(0); $passphrase .= ' ' x (16*3); my $cyphertext = ""; - my $size = length ( $plaintext ); #print "STRING: '$plaintext' - Length: " . length($plaintext) . "\n"; - # This check should see if it is plaintext first, if it is, - # pad it with \000 - # if not, then die - die "record not 8 byte padded" if (length($plaintext) % 8) && ! $flag; - my @C; for ( 0..2 ) { $C[$_] = new Crypt::DES( pack( "H*", substr($passphrase, 16*$_, 16 ))); } - for ( 0 .. (($size)/8) - 1) { + +# XXX From Crypt::TripleDES +# http://search.cpan.org/src/VIPUL/Crypt-TripleDES-0.24/lib/Crypt/TripleDES.pm +# +# for ( 0 .. (($size)/8) -1 ) { +# my $pt = substr( $plaintext, $_*8, 8 ); +# $pt = Crypt::PPDES::des_ecb_encrypt( $flag ? $keyvecs{0} : $keyvecs{2}, $flag, $pt ); +# $pt = Crypt::PPDES::des_ecb_encrypt( $keyvecs{1}, (not $flag), $pt ); +# $pt = Crypt::PPDES::des_ecb_encrypt( $flag ? $keyvecs{2} : $keyvecs{0}, $flag, $pt ); +# $cyphertext .= $pt; +# } + + for ( 0 .. (($size)/8)) { my $pt = substr( $plaintext, $_*8, 8 ); #print "PT: '$pt' - Length: " . length($pt) . "\n"; + next unless length($pt); if (length($pt) < 8) { + die "record not 8 byte padded" if $flag == DECRYPT; my $len = 8 - length($pt); - print "LENGTH: $len\n"; - print "Binary: '" . unpack("b*", $pt) . "'\n"; - $pt .= (chr(0) x $len);# . $pt; - print "Binary: '" . unpack("b*", $pt) . "'\n"; + #print "LENGTH: $len\n"; + #print "Binary: '" . unpack("b*", $pt) . "'\n"; + $pt .= ($NULL x $len); #print "PT: '$pt' - Length: " . length($pt) . "\n"; + #print "Binary: '" . unpack("b*", $pt) . "'\n"; } - $pt = $C[0]->decrypt( $pt ); - $pt = $C[1]->encrypt( $pt ); - $pt = $C[2]->decrypt( $pt ); + if ($flag == ENCRYPT) { + $pt = $C[0]->encrypt( $pt ); + $pt = $C[1]->decrypt( $pt ); + $pt = $C[2]->encrypt( $pt ); + } else { + $pt = $C[0]->decrypt( $pt ); + $pt = $C[1]->encrypt( $pt ); + $pt = $C[2]->decrypt( $pt ); + } #print "PT: '$pt' - Length: " . length($pt) . "\n"; $cyphertext .= $pt; } - return substr ( $cyphertext, 0, $size ); + $cyphertext =~ s/$NULL+$//; + #print "CT: '$cyphertext' - Length: " . length($cyphertext) . "\n"; + + return $cyphertext; } 1;