version 1.58, 2008/09/19 03:50:05 |
version 1.63, 2011/09/18 00:45:33 |
|
|
package Palm::Keyring; |
package Palm::Keyring; |
# $RedRiver: Keyring.pm,v 1.57 2008/09/19 02:04:34 andrew Exp $ |
# $RedRiver: Keyring.pm,v 1.61 2008/09/19 05:55:35 andrew Exp $ |
######################################################################## |
######################################################################## |
# Keyring.pm *** Perl class for Keyring for Palm OS databases. |
# Keyring.pm *** Perl class for Keyring for Palm OS databases. |
# |
# |
|
|
# Nothing extra for version 4 |
# Nothing extra for version 4 |
|
|
} elsif ($self->{version} == 5) { |
} elsif ($self->{version} == 5) { |
_parse_appinfo_v5($appinfo) || return; |
_parse_appinfo_v5($appinfo); |
|
|
} else { |
} else { |
croak "Unsupported Version $self->{version}"; |
croak "Unsupported Version $self->{version}"; |
|
|
{ |
{ |
my $appinfo = shift; |
my $appinfo = shift; |
|
|
if (! exists $appinfo->{other}) { |
croak 'Corrupt appinfo? no {other}' if ! $appinfo->{other}; |
# XXX Corrupt appinfo? |
|
return; |
|
} |
|
|
|
my $unpackstr |
my $unpackstr |
= ("C1" x 8) # 8 uint8s in an array for the salt |
= ("C1" x 8) # 8 uint8s in an array for the salt |
|
|
my $self = shift; |
my $self = shift; |
my $rec = shift; |
my $rec = shift; |
my $pass = shift || $self->{password}; |
my $pass = shift || $self->{password}; |
|
|
|
if ( !$rec ) { |
|
croak('Needed parameter [record] not passed!'); |
|
} |
|
|
my $data = shift || $rec->{plaintext}; |
my $data = shift || $rec->{plaintext}; |
my $ivec = shift; |
my $ivec = shift; |
|
|
|
|
if ( ! $pass && ! $self->{appinfo}->{key}) { |
if ( ! $pass && ! $self->{appinfo}->{key}) { |
croak("password not set!\n"); |
croak('password not set!'); |
} |
} |
|
|
if ( ! $rec) { |
|
croak("Needed parameter 'record' not passed!\n"); |
|
} |
|
|
|
if ( ! $data) { |
if ( ! $data) { |
croak("Needed 'plaintext' not passed!\n"); |
croak('Needed parameter [plaintext] not passed!'); |
} |
} |
|
|
if ( $pass && ! $self->Password($pass)) { |
if ( $pass && ! $self->Password($pass)) { |
croak("Incorrect Password!\n"); |
croak('Incorrect Password!'); |
} |
} |
|
|
my $acct; |
my $acct; |
|
|
$encrypted = _encrypt_v4($datav4, $acctv4, $self->{digest}); |
$encrypted = _encrypt_v4($datav4, $acctv4, $self->{digest}); |
|
|
} elsif ($self->{version} == 5) { |
} elsif ($self->{version} == 5) { |
($encrypted, $ivec) = _encrypt_v5( |
($encrypted, $rec->{ivec}) = _encrypt_v5( |
$data, $acct, |
$data, $acct, |
$self->{appinfo}->{key}, |
$self->{appinfo}->{key}, |
$self->{appinfo}->{cipher}, |
$self->{appinfo}->{cipher}, |
$ivec, |
$ivec, |
); |
); |
if (defined $ivec) { |
|
$rec->{ivec} = $ivec; |
|
} |
|
|
|
} else { |
} else { |
croak "Unsupported Version $self->{version}"; |
croak "Unsupported version $self->{version}"; |
} |
} |
|
|
$rec->{plaintext}->{0} = $data->{0}; |
$rec->{plaintext}->{0} = $data->{0}; |
|
|
if ($encrypted) { |
if ($encrypted ne '1') { |
if ($encrypted eq '1') { |
|
return 1; |
|
} |
|
|
|
$rec->{attributes}{Dirty} = 1; |
$rec->{attributes}{Dirty} = 1; |
$rec->{attributes}{dirty} = 1; |
$rec->{attributes}{dirty} = 1; |
$rec->{encrypted} = $encrypted; |
$rec->{encrypted} = $encrypted; |
|
|
return 1; |
|
} else { |
|
return; |
|
} |
} |
|
|
|
return 1; |
} |
} |
|
|
sub _encrypt_v4 |
sub _encrypt_v4 |
|
|
my $c = crypts($cipher) or croak('Unknown cipher ' . $cipher); |
my $c = crypts($cipher) or croak('Unknown cipher ' . $cipher); |
|
|
if (! defined $ivec) { |
if (! defined $ivec) { |
$ivec = pack("C*",map {rand(256)} 1..$c->{blocksize}); |
while (! $ivec) { |
|
$ivec = pack("C*",map {rand(256)} 1..$c->{blocksize}); |
|
} |
} |
} |
|
|
my $changed = 0; |
my $changed = 0; |
|
|
} |
} |
} |
} |
|
|
return 1, 0 if $changed == 0; |
return (1, $ivec) if $changed == 0; |
|
|
if ($need_newdate) { |
if ($need_newdate) { |
my ($day, $month, $year) = (localtime)[3,4,5]; |
my ($day, $month, $year) = (localtime)[3,4,5]; |
|
|
my $pass = shift; |
my $pass = shift; |
my $data = shift; |
my $data = shift; |
|
|
if (! $pass) { croak('No password specified!'); }; |
if (! $pass) { croak('No password specified!'); } |
|
if (! $data) { croak("No encrypted password in file!"); } |
|
|
# XXX die "No encrypted password in file!" unless defined $data; |
|
if ( ! defined $data) { return; }; |
|
|
|
$data =~ s/$NULL$//xm; |
$data =~ s/$NULL$//xm; |
|
|
my $salt = substr $data, 0, $kSalt_Size; |
my $salt = substr $data, 0, $kSalt_Size; |
|
|
|
|
sub _calc_keys |
sub _calc_keys |
{ |
{ |
|
require Digest::MD5; |
|
import Digest::MD5 qw(md5); |
|
|
my $pass = shift; |
my $pass = shift; |
if (! defined $pass) { croak('No password defined!'); }; |
if (! defined $pass) { croak('No password defined!'); }; |
|
|