[BACK]Return to Keyring.pm CVS log [TXT][DIR] Up to [local] / palm / Palm-Keyring / lib / Palm

Diff for /palm/Palm-Keyring/lib/Palm/Keyring.pm between version 1.13 and 1.14

version 1.13, 2007/01/28 18:13:28 version 1.14, 2007/01/28 22:24:17
Line 1 
Line 1 
 # Palm::Keyring.pm  package Palm::Keyring;
   
   # $RedRiver: Keyring.pm,v 1.13 2007/01/28 18:13:28 andrew Exp $
 #  #
 # Perl class for dealing with Keyring for Palm OS databases.  # Perl class for dealing with Keyring for Palm OS databases.
 #  #
 #       Copyright (C) 2004, Andrew Fresh  
 #       You may distribute this file under the terms of the Artistic  
 #       License, as specified in the README file distributed with the p5-Palm distribution.  
 #  
 #   This started as Memo.pm, I just made it work for Keyring.  #   This started as Memo.pm, I just made it work for Keyring.
 #  
 # $RedRiver: Keyring.pm,v 1.12 2007/01/28 00:18:46 andrew Exp $  
   
 use strict;  use strict;
 package Palm::Keyring;  use warnings;
 use Palm::Raw();  use Carp;
 use Palm::StdAppInfo();  
 use vars qw( $VERSION @ISA );  
   
   use base qw/ Palm::StdAppInfo /;
   
 use Digest::MD5 qw(md5);  use Digest::MD5 qw(md5);
 use Crypt::DES;  use Crypt::DES;
   use Readonly;
   
 use constant ENCRYPT    =>  1;  Readonly my $ENCRYPT    => 1;
 use constant DECRYPT    =>  0;  Readonly my $DECRYPT    => 0;
 use constant MD5_CBLOCK => 64;  Readonly my $MD5_CBLOCK => 64;
 my $kSaltSize = 4;  Readonly my $kSalt_Size => 4;
   Readonly my $EMPTY      => q{};
   Readonly my $SPACE      => q{ };
   Readonly my $NULL       => chr 0;
   
   
 # One liner, to allow MakeMaker to work.  # One liner, to allow MakeMaker to work.
 $VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };  our ($VERSION) = q$Revision$ =~ m{ Revision: \s+ (\S+) }xm;
   
 @ISA = qw( Palm::StdAppInfo Palm::Raw );  #@ISA = qw( Palm::StdAppInfo Palm::Raw );
   
 =head1 NAME  sub new {
       my $classname = shift;
       my $pass      = shift;
   
 Palm::Keyring - Handler for Palm Keyring databases.      # Create a generic PDB. No need to rebless it, though.
       my $self = $classname->SUPER::new(@_);
   
 =head1 SYNOPSIS      $self->{'name'}    = 'Keys-Gtkr';    # Default
       $self->{'creator'} = 'Gtkr';
       $self->{'type'}    = 'Gkyr';
   
         use Palm::PDB;      # The PDB is not a resource database by
         use Palm::Keyring;      # default, but it's worth emphasizing,
         my $pdb = new Palm::PDB;      # since MemoDB is explicitly not a PRC.
         $pdb->Load($file);      $self->{'attributes'}{'resource'} = 0;
         foreach my $record (@{ $pdb->{'records'} }) {  
                 print "$record->{'plaintext'}->{'name'}\n";  
         }  
         $pdb->Decrypt($password);  
         # do something with the decrypted parts  
   
 =head1 DESCRIPTION      # Initialize the AppInfo block
       $self->{'appinfo'} = {};
   
 The Keyring PDB handler is a helper class for the Palm::PDB package. It      # Add the standard AppInfo block stuff
 parses Keyring for Palm OS databases.  See      Palm::StdAppInfo::seed_StdAppInfo( $self->{'appinfo'} );
 L<http://gnukeyring.sourceforge.net/>.  
   
 It has the standard Palm::PDB methods with 2 additional public methods.      # Set the version
 Decrypt and Encrypt.      $self->{'version'} = 4;
   
 It currently supports the v4 Keyring databases.  The v5 databases from the pre-release keyring-2.0 are not supported.      # Give the PDB the first record that will hold the encrypted password
       $self->{'records'} = [ $self->new_Record ];
   
 =cut      if ( defined $pass ) {
           $self->Encrypt($pass);
       }
   
 =head2 new      return $self;
   }
   
         $pdb = new Palm::Keyring([$password]);  sub import {
       Palm::PDB::RegisterPDBHandlers( __PACKAGE__, [ 'Gtkr', 'Gkyr' ], );
       return 1;
   }
   
 Create a new PDB, initialized with the various Palm::Keyring fields  sub Load {
 and an empty record list.      my $self     = shift;
       my $filename = shift;
       my $password = shift;
   
 Use this method if you're creating a Keyring PDB from scratch otherwise you      $self->{'appinfo'} = {};
 can just use Palm::PDB::new().      $self->{'records'} = [];
       $self->SUPER::Load($filename);
   
 =cut      foreach my $rec ( @{ $self->{'records'} } ) {
           if ( ! exists $rec->{'data'}) { next; };
           my ( $name, $encrypted ) = split /$NULL/xm, $rec->{'data'}, 2;
           if ( ! $encrypted ) { next };
           $rec->{'plaintext'}->{'name'} = $name;
           $rec->{'encrypted'} = $encrypted;
       }
   
 sub new      return $self->Decrypt($password) if defined $password;
 {  
         my $classname   = shift;  
         my $pass = shift;  
   
         # Create a generic PDB. No need to rebless it, though.      return 1;
         my $self        = $classname->SUPER::new(@_);  }
   
         $self->{name} = "Keys-Gtkr";    # Default  sub Write {
         $self->{creator} = "Gtkr";      my $self     = shift;
         $self->{type} = "Gkyr";      my $filename = shift;
         # The PDB is not a resource database by      my $password = shift;
         # default, but it's worth emphasizing,  
         # since MemoDB is explicitly not a PRC.  
         $self->{attributes}{resource} = 0;  
   
         # Initialize the AppInfo block      $self->Encrypt($password) || return;
         $self->{appinfo} = {};      return $self->SUPER::Write($filename);
   }
   
         # Add the standard AppInfo block stuff  sub Encrypt {
         &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo});      my $self = shift;
       my $pass = shift;
   
         # Set the version      if ($pass) {
         $self->{version} = 4;          if (
               !( exists $self->{'records'}->[0]->{'data'}
                   && $self->_keyring_verify($pass) )
             )
           {
   
         # Give the PDB the first record that will hold the encrypted password              # This would encrypt with a new password.
         $self->{records} = [ $self->new_Record ];              # First decrypting everything with the old password of course.
               $self->_keyring_update($pass) || return;
               $self->_keyring_verify($pass) || return;
           }
       }
   
         if (defined $pass) {      $self->{'digest'} ||= _calc_keys( $self->{'password'} );
                 $self->Encrypt($pass);  
         }  
   
         return $self;      foreach my $rec ( @{ $self->{'records'} } ) {
 }          if (!defined $rec->{'plaintext'}) { next; };
   
 sub import          my $name =
 {            defined $rec->{'plaintext'}->{'name'}
         &Palm::PDB::RegisterPDBHandlers(__PACKAGE__,            ? $rec->{'plaintext'}->{'name'}
                 [ "Gtkr", "Gkyr" ],            : $EMPTY;
                 );          my $account =
             defined $rec->{'plaintext'}->{'account'}
             ? $rec->{'plaintext'}->{'account'}
             : $EMPTY;
           my $password =
             defined $rec->{'plaintext'}->{'password'}
             ? $rec->{'plaintext'}->{'password'}
             : $EMPTY;
           my $description =
             defined $rec->{'plaintext'}->{'description'}
             ? $rec->{'plaintext'}->{'description'}
             : $EMPTY;
           my $extra = $EMPTY;
   
           my $plaintext = join "$NULL", $account, $password, $description, $extra;
   
           my $encrypted = _crypt3des( $plaintext, $self->{'digest'}, $ENCRYPT );
   
           $rec->{'data'} = join "$NULL", $name, $encrypted;
       }
   
       return 1;
 }  }
   
 =pod  sub Decrypt {
       my $self = shift;
       my $pass = shift;
   
 =head2 Load      if ($pass) {
           $self->_keyring_verify($pass) || return;
       }
   
         $pdb->Load($filename[, $password]);      $self->{'digest'} ||= _calc_keys( $self->{'password'} );
   
 Overrides the standard Palm::Raw Load() to add      my $reccount = 0;
 $record->{'plaintext'}->{'name'} and      foreach my $rec ( @{ $self->{'records'} } ) {
 $record->{'encrypted'} fields.          $reccount++;
 $record->{'plaintext'}->{'name'} holds the name of the record,  
 $record->{'encrypted'} is the encrypted information in the PDB.  
   
 It also takes an additional optional parameter, which is the password to use to          # always skip the first record that has the password in it.
 decrypt the database.          next if $reccount <= 1;
           if ( ! defined $rec->{'data'} ) {
               warn 'Invalid record ' . ( $reccount - 1 ) . "\n";
               next;
           }
   
 See Decrypt() for the additional fields that are available after decryption.          my ( $name, $encrypted ) = split /$NULL/xm, $rec->{'data'}, 2;
           if (! $encrypted) { next; };
   
 =cut          $rec->{'plaintext'}->{'name'} = $name;
   
 sub Load          my $decrypted = _crypt3des( $encrypted, $self->{'digest'}, $DECRYPT );
 {          my ( $account, $password, $description, $extra ) = split /$NULL/xm,
         my $self     = shift;            $decrypted, 4;
         my $filename = shift;  
         my $password = shift;  
   
         $self->{'appinfo'} = {};          $rec->{'plaintext'}->{'account'} = defined $account ? $account : $EMPTY;
         $self->{'records'} = [];          $rec->{'plaintext'}->{'password'} =
         $self->SUPER::Load($filename);            defined $password ? $password : $EMPTY;
           $rec->{'plaintext'}->{'description'} =
             defined $description ? $description : $EMPTY;
   
         foreach my $record (@{ $self->{records} }) {          #print "Name:      '$name'\n";
                 next unless exists $record->{data};          #print "Encrypted: '$encrypted' - Length: " . length($encrypted) . "\n";
                 my ($name, $encrypted) = split /\000/, $record->{data}, 2;          #print "    Hex:   '" . unpack("H*", $encrypted) . "'\n";
                 next unless $encrypted;          #print "    Binary:'" . unpack("b*", $encrypted) . "'\n";
                 $record->{plaintext}->{name} = $name;          #print "Decrypted: '$decrypted' - Length: " . length($decrypted) . "\n";
         $record->{encrypted} = $encrypted;          #print "    Hex:   '" . unpack("H*", $decrypted) . "'\n";
         }          #print "    Binary:'" . unpack("b*", $decrypted) . "'\n";
           #print "\n";
           #print "Extra: $extra\n";
           #exit;
           #--------------------------------------------------
           # print "Account:     $account\n";
           # print "Password:    $password\n";
           # print "Description: $description\n";
           #--------------------------------------------------
   
         return $self->Decrypt($password) if defined $password;      }
   
         1;      return 1;
 }  }
   
 =pod  sub _calc_keys {
       my $pass = shift;
       if (! defined $pass) { croak('No password defined!'); };
   
 =head2 Write      my $digest = md5($pass);
   
         $pdb->Write($filename[, $password]);      my ( $key1, $key2 ) = unpack 'a8a8', $digest;
   
 Just like the Palm::Raw::Write() but encrypts everything before saving.      #--------------------------------------------------
       # print "key1: $key1: ", length $key1, "\n";
       # print "key2: $key2: ", length $key2, "\n";
       #--------------------------------------------------
   
 Also takes an optional password to encrypt with a new password, not needed      $digest = unpack 'H*', $key1 . $key2 . $key1;
 unless you are changing the password.  
   
 =cut      #--------------------------------------------------
       # print "Digest: ", $digest, "\n";
       # print length $digest, "\n";
       #--------------------------------------------------
   
 sub Write      return $digest;
 {  
         my $self = shift;  
         my $filename = shift;  
         my $password = shift;  
   
         $self->Encrypt($password) || return undef;  
         return $self->SUPER::Write($filename);  
 }  }
   
 =pod  sub _keyring_verify {
       my $self = shift;
       my $pass = shift;
   
 =head2 Encrypt      if (! $pass) { croak('No password specified!'); };
   
         $pdb->Encrypt([$password]);      # AFAIK the thing we use to test the password is
       #     always in the first entry
       my $data = $self->{'records'}->[0]->{'data'};
   
 Encrypts the PDB, either with the password used to decrypt or create it, or      #die "No encrypted password in file!" unless defined $data;
 optionally with a password that is passed.      if (! defined $data) { return; };
   
 See Decrypt() for an what plaintext fields are available to be encrypted.      $data =~ s/$NULL$//xm;
   
 =cut      my $salt = substr $data, 0, $kSalt_Size;
   
 sub Encrypt      my $msg = $salt . $pass;
 {  
         my $self = shift;  
         my $pass = shift;  
   
         if ($pass) {      $msg .= "\0" x ( $MD5_CBLOCK - length $msg );
                 unless (exists $self->{'records'}->[0]->{'data'} &&  
                     $self->_keyring_verify($pass) ) {  
                         # This would encrypt with a new password.  
                         # First decrypting everything with the old password of course.  
                         $self->_keyring_update($pass) || return undef;  
                         $self->_keyring_verify($pass) || return undef;  
                 }  
         }  
   
         $self->{digest} ||= _calc_keys($self->{password});      my $digest = md5($msg);
   
         foreach my $record (@{ $self->{records} }) {      if ( $data eq $salt . $digest ) {
                 next unless defined $record->{plaintext};  
   
                 my $name        = defined $record->{plaintext}->{name}        ?  # May as well generate the keys we need now, since we know the password is right
                         $record->{plaintext}->{name}        : '';          $self->{'digest'} = _calc_keys($pass);
                 my $account     = defined $record->{plaintext}->{account}     ?          if ( $self->{'digest'} ) {
                         $record->{plaintext}->{account}     : '';              $self->{'password'} = $pass;
                 my $password    = defined $record->{plaintext}->{password}    ?              return 1;
                         $record->{plaintext}->{password}    : '';          }
                 my $description = defined $record->{plaintext}->{description} ?      }
                         $record->{plaintext}->{description} : '';      return;
                 my $extra       = '';  }
   
                 my $plaintext = join("\000", $account, $password, $description, $extra);  sub _keyring_update {
   
                 my $encrypted = _crypt3des($plaintext, $self->{digest}, ENCRYPT);      # It is very important to Encrypt after calling this
       #     (Although it is generally only called by Encrypt)
       # because otherwise the data will be out of sync with the
       # password, and that would suck!
       my $self = shift;
       my $pass = shift;
   
                 $record->{data} = join("\000", $name, $encrypted);      if (! $pass) { croak('No password specified!'); };
         }  
   
         1;      # if the database already has a password in it
 }      if ( $self->{'records'}->[0]->{'data'} ) {
   
 =head2 Decrypt          # Make sure everything is decrypted before we update the keyring
           $self->Decrypt() || return;
       }
   
         $pdb->Decrypt([$password]);      my $salt;
       for ( 1 .. $kSalt_Size ) {
           $salt .= chr int rand 255;
       }
   
 Decrypts the PDB and fills out the rest of the fields available in      my $msg = $salt . $pass;
 $record->{'plaintext'}.  
   
 The plaintext should now be this, before encryption or after decryption:      $msg .= "\0" x ( $MD5_CBLOCK - length $msg );
   
         $record->{'plaintext'} = {      my $digest = md5($msg);
                 name        => $name,  
                 account     => $account,  
                 password    => $account_password,  
                 description => $description,  
         };  
   
 =cut      my $data = $salt . $digest;    # . "\0";
   
 sub Decrypt      # AFAIK the thing we use to test the password is
 {      #     always in the first entry
         my $self = shift;      $self->{'records'}->[0]->{'data'} = $data;
         my $pass = shift;  
   
         if ($pass) {      $self->{'password'} = $pass;
                 $self->_keyring_verify($pass) || return undef;      $self->{'digest'}   = _calc_keys( $self->{'password'} );
         }  
   
         $self->{digest} ||= _calc_keys($self->{password});      return 1;
   }
   
         my $recordcount = 0;  sub _crypt3des {
         foreach my $record (@{ $self->{records} }) {      my ( $plaintext, $passphrase, $flag ) = @_;
                 $recordcount++;  
                 # always skip the first record that has the password in it.  
                 next if $recordcount <= 1;  
                 unless (defined $record->{data}) {  
                         warn "Invalid record " . ($recordcount - 1) . "\n";  
                         next;  
                 }  
   
                 my ($name, $encrypted) = split /\000/, $record->{data}, 2;      $passphrase   .= $SPACE x ( 16 * 3 );
                 next unless $encrypted;      my $cyphertext = $EMPTY;
   
                 $record->{plaintext}->{name} = $name;      my $size = length $plaintext;
   
                 my $decrypted = _crypt3des($encrypted, $self->{digest}, DECRYPT);      #print "STRING: '$plaintext' - Length: " . (length $plaintext) . "\n";
                 my ($account, $password, $description, $extra)  
                       = split /\000/, $decrypted, 4;  
   
                 $record->{plaintext}->{account}     = defined $account     ?      my @C;
                         $account     : '';      for ( 0 .. 2 ) {
                 $record->{plaintext}->{password}    = defined $password    ?          $C[$_] =
                         $password    : '';            new Crypt::DES( pack 'H*', ( substr $passphrase, 16 * $_, 16 ));
                 $record->{plaintext}->{description} = defined $description ?      }
                         $description : '';  
   
                 #print "Name:      '$name'\n";      for ( 0 .. ( ($size) / 8 ) ) {
                 #print "Encrypted: '$encrypted' - Length: " . length($encrypted) . "\n";          my $pt = substr $plaintext, $_ * 8, 8;
                 #print "    Hex:   '" . unpack("H*", $encrypted) . "'\n";  
                 #print "    Binary:'" . unpack("b*", $encrypted) . "'\n";  
                 #print "Decrypted: '$decrypted' - Length: " . length($decrypted) . "\n";  
                 #print "    Hex:   '" . unpack("H*", $decrypted) . "'\n";  
                 #print "    Binary:'" . unpack("b*", $decrypted) . "'\n";  
                 #print "\n";  
                 #print "Extra: $extra\n";  
                 #exit;  
                 #--------------------------------------------------  
                 # print "Account:     $account\n";  
                 # print "Password:    $password\n";  
                 # print "Description: $description\n";  
                 #--------------------------------------------------  
   
         }          #print "PT: '$pt' - Length: " . length($pt) . "\n";
           if (! length $pt) { next; };
           if ( (length $pt) < 8 ) {
                           if ($flag == $DECRYPT) { croak('record not 8 byte padded'); };
               my $len = 8 - (length $pt);
   
         1;              #print "LENGTH: $len\n";
 }              #print "Binary:    '" . unpack("b*", $pt) . "'\n";
               $pt .= ($NULL x $len);
   
 sub _calc_keys              #print "PT: '$pt' - Length: " . length($pt) . "\n";
 {              #print "Binary:    '" . unpack("b*", $pt) . "'\n";
         my $pass = shift;          }
         die "No password defined!" unless defined $pass;          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);
           }
   
         my $digest = md5($pass);          #print "PT: '$pt' - Length: " . length($pt) . "\n";
           $cyphertext .= $pt;
       }
   
         my ($key1, $key2) = unpack('a8a8', $digest);      $cyphertext =~ s/$NULL+$//xm;
         #--------------------------------------------------  
         # print "key1: $key1: ", length $key1, "\n";  
         # print "key2: $key2: ", length $key2, "\n";  
         #--------------------------------------------------  
   
         $digest = unpack('H*', $key1 . $key2 . $key1);      #print "CT: '$cyphertext' - Length: " . length($cyphertext) . "\n";
         #--------------------------------------------------  
         # print "Digest: ", $digest, "\n";  
         # print length $digest, "\n";  
         #--------------------------------------------------  
   
         return $digest;      return $cyphertext;
 }  }
   
 sub _keyring_verify  1;
 {  __END__
         my $self = shift;  
         my $pass = shift;  
   
         die "No password specified!" unless $pass;  =head1 NAME
   
         # AFAIK the thing we use to test the password is  Palm::Keyring - Handler for Palm Keyring databases.
         #     always in the first entry  
         my $data = $self->{records}->[0]->{data};  
         #die "No encrypted password in file!" unless defined $data;  
         return undef unless defined $data;  
   
         $data =~ s/\0$//;  =head1 DESCRIPTION
   
         my $salt = substr($data, 0, $kSaltSize);  The Keyring PDB handler is a helper class for the Palm::PDB package. It
   parses Keyring for Palm OS databases.  See
   L<http://gnukeyring.sourceforge.net/>.
   
         my $msg = $salt . $pass;  It has the standard Palm::PDB methods with 2 additional public methods.
   Decrypt and Encrypt.
   
         $msg .= "\0" x (MD5_CBLOCK - length($msg));  It currently supports the v4 Keyring databases.  The v5 databases from the pre-release keyring-2.0 are not supported.
   
         my $digest = md5($msg);  =head1 SYNOPSIS
   
         if ($data eq $salt . $digest) {          use Palm::PDB;
                 # May as well generate the keys we need now, since we know the password is right          use Palm::Keyring;
                 $self->{digest} = _calc_keys($pass);          my $pdb = new Palm::PDB;
                 if ($self->{digest}) {          $pdb->Load($file);
                         $self->{password} = $pass;          foreach my $rec (@{ $pdb->{'records'} }) {
                         return 1;                  print "$rec->{'plaintext'}->{'name'}\n";
                 } else {  
                         return undef;  
                 }  
         } else {  
                 return undef;  
         }          }
 }          $pdb->Decrypt($password);
           # do something with the decrypted parts
   
 sub _keyring_update  =head1 SUBROUTINES/METHODS
 {  
         # It is very important to Encrypt after calling this  
         #     (Although it is generally only called by Encrypt)  
         # because otherwise the data will be out of sync with the  
         # password, and that would suck!  
         my $self = shift;  
         my $pass = shift;  
   
         die "No password specified!" unless $pass;  =head2 new
   
         # if the database already has a password in it          $pdb = new Palm::Keyring([$password]);
         if ($self->{records}->[0]->{data}) {  
                 # Make sure everything is decrypted before we update the keyring  
                 $self->Decrypt() || return undef;  
         }  
   
         my $salt;  Create a new PDB, initialized with the various Palm::Keyring fields
         for (1..$kSaltSize) {  and an empty record list.
                 $salt .= chr(int(rand(255)));  
         }  
   
         my $msg = $salt . $pass;  Use this method if you're creating a Keyring PDB from scratch otherwise you
   can just use Palm::PDB::new().
   
         $msg .= "\0" x (MD5_CBLOCK - length($msg));  =head2 Load
   
         my $digest = md5($msg);          $pdb->Load($filename[, $password]);
   
         my $data = $salt . $digest;# . "\0";  Overrides the standard Palm::Raw Load() to add
   $rec->{'plaintext'}->{'name'} and
   $rec->{'encrypted'} fields.
   $rec->{'plaintext'}->{'name'} holds the name of the record,
   $rec->{'encrypted'} is the encrypted information in the PDB.
   
         # AFAIK the thing we use to test the password is  It also takes an additional optional parameter, which is the password to use to
         #     always in the first entry  decrypt the database.
         $self->{records}->[0]->{data} = $data;  
   
         $self->{password} = $pass;  See Decrypt() for the additional fields that are available after decryption.
         $self->{digest}   = _calc_keys($self->{password});  
   
         return 1;  =head2 Write
 }  
   
 sub _crypt3des {          $pdb->Write($filename[, $password]);
         my ( $plaintext, $passphrase, $flag ) = @_;  
         my $NULL = chr(0);  
   
         $passphrase .= ' ' x (16*3);  Just like the Palm::Raw::Write() but encrypts everything before saving.
         my $cyphertext = "";  
   
         my $size = length ( $plaintext );  Also takes an optional password to encrypt with a new password, not needed
         #print "STRING: '$plaintext' - Length: " . length($plaintext) . "\n";  unless you are changing the password.
   
         my @C;  =head2 Encrypt
         for ( 0..2 ) {  
                 $C[$_] = new Crypt::DES( pack( "H*", substr($passphrase, 16*$_, 16 )));  
         }  
   
         for ( 0 .. (($size)/8)) {          $pdb->Encrypt([$password]);
                 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 .= ($NULL x $len);  
                         #print "PT: '$pt' - Length: " . length($pt) . "\n";  
                         #print "Binary:    '" . unpack("b*", $pt) . "'\n";  
                 }  
                 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;  
         }  
   
         $cyphertext =~ s/$NULL+$//;  Encrypts the PDB, either with the password used to decrypt or create it, or
         #print "CT: '$cyphertext' - Length: " . length($cyphertext) . "\n";  optionally with a password that is passed.
   
         return $cyphertext;  See Decrypt() for an what plaintext fields are available to be encrypted.
 }  
   
 1;  =head2 Decrypt
 __END__  
   
           $pdb->Decrypt([$password]);
   
   Decrypts the PDB and fills out the rest of the fields available in
   $rec->{'plaintext'}.
   
   The plaintext should now be this, before encryption or after decryption:
   
           $rec->{'plaintext'} = {
                   name        => $name,
                   account     => $account,
                   password    => $account_password,
                   description => $description,
           };
   
   =head1 DEPENDENCIES
   
   Palm::StdAppInfo
   
   Digest::MD5
   
   Crypt::DES
   
   Readonly
   
   =head1 BUGS AND LIMITATIONS
   
   Once this module is uploaded, you can
   Please report any bugs or feature requests to
   C<bug-palm-keyring at rt.cpan.org>, or through the web interface at
   L<http://rt.cpan.org>.  I will be notified, and then you'll automatically be
   notified of progress on your bug as I make changes.
   
 =head1 AUTHOR  =head1 AUTHOR
   
 Andrew Fresh E<lt>andrew@mad-techies.orgE<gt>  Andrew Fresh E<lt>andrew@mad-techies.orgE<gt>
   
   =head1 LICENSE AND COPYRIGHT
   
   You may distribute this file under the terms of perl itself
   as specified in the LICENSE file.
   
   Copyright 2004, 2005, 2006, 2007 Andrew Fresh, All Rights Reserved.
   
   This program is free software; you can redistribute it and/or modify it
   under the same terms as Perl itself.
   
 =head1 SEE ALSO  =head1 SEE ALSO
   
 Palm::PDB(3)  Palm::PDB(3)
Line 468 
Line 492 
   
 The Keyring for Palm OS website:  The Keyring for Palm OS website:
 L<http://gnukeyring.sourceforge.net/>  L<http://gnukeyring.sourceforge.net/>
   
 =cut  

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>