Palm-Keyring
view release on metacpan or search on metacpan
lib/Palm/Keyring.pm view on Meta::CPAN
my ($key, $hash) = _calc_key_v5(
$pass, $salt, $iter,
$c->{keylen},
$c->{DES_odd_parity},
);
$appinfo->{salt} = unpack "H*", $salt;
$appinfo->{iter} = $iter;
$appinfo->{cipher} = $cipher;
$appinfo->{masterhash} = $hash;
$appinfo->{key} = $key;
return $key;
}
# Helpers
sub _calc_keys
{
my $pass = shift;
if (! defined $pass) { croak('No password defined!'); };
my $digest = md5($pass);
my ( $key1, $key2 ) = unpack 'a8a8', $digest;
#--------------------------------------------------
# print "key1: $key1: ", length $key1, "\n";
# print "key2: $key2: ", length $key2, "\n";
#--------------------------------------------------
$digest = unpack 'H*', $key1 . $key2 . $key1;
#--------------------------------------------------
# print "Digest: ", $digest, "\n";
# print length $digest, "\n";
#--------------------------------------------------
return $digest;
}
sub _calc_key_v5
{
my ($pass, $salt, $iter, $keylen, $dop) = @_;
require Digest::HMAC_SHA1;
import Digest::HMAC_SHA1 qw(hmac_sha1);
require Digest::SHA1;
import Digest::SHA1 qw(sha1);
my $key = _pbkdf2( $pass, $salt, $iter, $keylen, \&hmac_sha1 );
if ($dop) { $key = _DES_odd_parity($key); }
my $hash = unpack("H*", substr(sha1($key.$salt),0, 8));
return $key, $hash;
}
sub _crypt3des
{
require Crypt::DES;
my ( $plaintext, $passphrase, $flag ) = @_;
$passphrase .= $SPACE x ( 16 * 3 );
my $cyphertext = $EMPTY;
my $size = length $plaintext;
#print "STRING: '$plaintext' - Length: " . (length $plaintext) . "\n";
my @C;
for ( 0 .. 2 ) {
$C[$_] =
new Crypt::DES( pack 'H*', ( substr $passphrase, 16 * $_, 16 ));
}
for ( 0 .. ( ($size) / 8 ) ) {
my $pt = substr $plaintext, $_ * 8, 8;
#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);
$pt .= ($NULL x $len);
}
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+$//xm;
#print "CT: '$cyphertext' - Length: " . length($cyphertext) . "\n";
return $cyphertext;
}
sub _parse_field
{
my $field = shift;
my @labels;
$labels[0] = 'name';
$labels[1] = 'account';
$labels[2] = 'password';
$labels[3] = 'lastchange';
$labels[255] = 'notes';
my ($len) = unpack "n1", $field;
if ($len + 4 > length $field) {
return undef, $field;
}
my $unpackstr = "x2 C1 C1 A$len";
my $offset = 2 +1 +1 +$len;
if ($len % 2) { # && $len + 4 < length $field) {
# trim the 0/1 byte padding for next even address.
$offset++;
$unpackstr .= ' x'
}
my ($label, $font, $data) = unpack $unpackstr, $field;
my $leftover = substr $field, $offset;
lib/Palm/Keyring.pm view on Meta::CPAN
$pdb->{password} = the password that was passed in;
For v5
$pdb->{appinfo} = {
# As described under new() with these additional fields
cipher => The index number of the cipher being used
iter => Number of iterations for the cipher
key => The key that is calculated from the password
and salt and is used to decrypt the records.
masterhash => the hash of the key that is stored in the
database. Either set when Loading the database
or when setting a new password.
salt => the salt that is either read out of the database
or calculated when setting a new password.
};
=head2 Other overridden subroutines/methods
=over
=item ParseAppInfoBlock
Converts the extra returned by Palm::StdAppInfo::ParseAppInfoBlock() into
the following additions to $pdb->{appinfo}
$pdb->{appinfo} = {
cipher => The index number of the cipher being used (Not v4)
iter => Number of iterations for the cipher (Not v4)
};
=item PackAppInfoBlock
Reverses ParseAppInfoBlock before
sending it on to Palm::StdAppInfo::PackAppInfoBlock()
=item ParseRecord
Adds some fields to a record from Palm::StdAppInfo::ParseRecord()
$rec = {
name => Account name
ivec => The IV for the encrypted record. (Not v4)
encrypted => the encrypted information
};
=item PackRecord
Reverses ParseRecord and then sends it through Palm::StdAppInfo::PackRecord()
=back
=head1 DEPENDENCIES
Palm::StdAppInfo
B<For v4 databases>
Digest::MD5
Crypt::DES
B<For v5 databases>
Digest::HMAC_SHA1
Digest::SHA1
Depending on how the database is encrypted
Crypt::CBC - For any encryption but None
Crypt::DES_EDE3 - DES_EDE3 encryption
Crytp::Rijndael - AES encryption schemes
=head1 THANKS
I would like to thank the helpful Perlmonk shigetsu who gave me some great advice
and helped me get my first module posted. L<http://perlmonks.org/?node_id=596998>
I would also like to thank
Johan Vromans
E<lt>jvromans@squirrel.nlE<gt> --
L<http://www.squirrel.nl/people/jvromans>.
He had his own Palm::KeyRing module that he posted a couple of days before
mine was ready and he was kind enough to let me have the namespace as well
as giving me some very helpful hints about doing a few things that I was
unsure of. He is really great.
And finally,
thanks to Jochen Hoenicke E<lt>hoenicke@gmail.comE<gt>
(one of the authors of Palm Keyring)
for getting me started on the v5 support as well as providing help
and some subroutines.
=head1 BUGS AND LIMITATIONS
I am sure there are problems with this module. For example, I have
not done very extensive testing of the v5 databases.
I am not sure I am 'require module' the best way, but I don't want to
depend on modules that you don't need to use.
I am not very happy with the data structures used by Encrypt() and
Decrypt() for v5 databases, but I am not sure of a better way.
The v4 compatibility mode does not insert a fake record 0 where
normally the encrypted password is stored.
The date validation for packing new dates is very poor.
I have not gone through and standardized on how the module fails. Some
things fail with croak, some return undef, some may even fail silently.
Nothing initializes a lasterr method or anything like that. I need
to fix all that before it is a 1.0 candidate.
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
Andrew Fresh E<lt>andrew@cpan.orgE<gt>
=head1 LICENSE AND COPYRIGHT
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.
( run in 0.781 second using v1.01-cache-2.11-cpan-39bf76dae61 )