summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2010-02-28 09:36:33 +0000
committerNorbert Preining <preining@logic.at>2010-02-28 09:36:33 +0000
commit5589232e99f0fa13868111280c5b64ce9dc25730 (patch)
tree28f2e6ff422108ac87934aff9c3fc5911963625c /Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm
parenta6f5de6eed80d66fbd23ceabda7edf22b8162236 (diff)
add a tlperl.straw directory for public inspection
git-svn-id: svn://tug.org/texlive/trunk@17235 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm')
-rwxr-xr-xMaster/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm245
1 files changed, 245 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm b/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm
new file mode 100755
index 00000000000..0ce398c24d1
--- /dev/null
+++ b/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/S2k.pm
@@ -0,0 +1,245 @@
+package Crypt::OpenPGP::S2k;
+use strict;
+
+use Crypt::OpenPGP::Buffer;
+use Crypt::OpenPGP::Digest;
+use Crypt::OpenPGP::ErrorHandler;
+use base qw( Crypt::OpenPGP::ErrorHandler );
+
+use vars qw( %TYPES );
+%TYPES = (
+ 0 => 'Simple',
+ 1 => 'Salted',
+ 3 => 'Salt_Iter',
+);
+
+sub new {
+ my $class = shift;
+ my $type = shift;
+ $type = $TYPES{ $type } || $type;
+ return $class->error("Invalid type of S2k") unless $type;
+ my $pkg = join '::', __PACKAGE__, $type;
+ my $s2k = bless { }, $pkg;
+ $s2k->init(@_);
+}
+
+sub parse {
+ my $class = shift;
+ my($buf) = @_;
+ my $id = $buf->get_int8;
+ my $type = $TYPES{$id};
+ $class->new($type, $buf);
+}
+
+sub init { $_[0] }
+sub generate {
+ my $s2k = shift;
+ my($passphrase, $keysize) = @_;
+ my($material, $pass) = ('', 0);
+ my $hash = $s2k->{hash};
+ while (length($material) < $keysize) {
+ my $pad = '' . chr(0) x $pass;
+ $material .= $s2k->s2k($passphrase, $pad);
+ $pass++;
+ }
+ substr($material, 0, $keysize);
+}
+sub set_hash {
+ my $s2k = shift;
+ my($hash_alg) = @_;
+ $s2k->{hash} = ref($hash_alg) ? $hash_alg :
+ Crypt::OpenPGP::Digest->new($hash_alg);
+}
+
+package Crypt::OpenPGP::S2k::Simple;
+use base qw( Crypt::OpenPGP::S2k );
+
+use Crypt::OpenPGP::Constants qw( DEFAULT_DIGEST );
+
+sub init {
+ my $s2k = shift;
+ my($buf) = @_;
+ if ($buf) {
+ $s2k->{hash_alg} = $buf->get_int8;
+ }
+ else {
+ $s2k->{hash_alg} = DEFAULT_DIGEST;
+ }
+ if ($s2k->{hash_alg}) {
+ $s2k->{hash} = Crypt::OpenPGP::Digest->new($s2k->{hash_alg});
+ }
+ $s2k;
+}
+
+sub s2k { $_[0]->{hash}->hash($_[2] . $_[1]) }
+
+sub save {
+ my $s2k = shift;
+ my $buf = Crypt::OpenPGP::Buffer->new;
+ $buf->put_int8(1);
+ $buf->put_int8($s2k->{hash_alg});
+ $buf->bytes;
+}
+
+package Crypt::OpenPGP::S2k::Salted;
+use base qw( Crypt::OpenPGP::S2k );
+
+use Crypt::OpenPGP::Constants qw( DEFAULT_DIGEST );
+
+sub init {
+ my $s2k = shift;
+ my($buf) = @_;
+ if ($buf) {
+ $s2k->{hash_alg} = $buf->get_int8;
+ $s2k->{salt} = $buf->get_bytes(8);
+ }
+ else {
+ $s2k->{hash_alg} = DEFAULT_DIGEST;
+ require Crypt::Random;
+ $s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
+ }
+ if ($s2k->{hash_alg}) {
+ $s2k->{hash} = Crypt::OpenPGP::Digest->new($s2k->{hash_alg});
+ }
+ $s2k;
+}
+
+sub s2k { $_[0]->{hash}->hash($_[0]->{salt} . $_[2] . $_[1]) }
+
+sub save {
+ my $s2k = shift;
+ my $buf = Crypt::OpenPGP::Buffer->new;
+ $buf->put_int8(2);
+ $buf->put_int8($s2k->{hash_alg});
+ $buf->put_bytes($s2k->{salt});
+ $buf->bytes;
+}
+
+package Crypt::OpenPGP::S2k::Salt_Iter;
+use base qw( Crypt::OpenPGP::S2k );
+
+use Crypt::OpenPGP::Constants qw( DEFAULT_DIGEST );
+
+sub init {
+ my $s2k = shift;
+ my($buf) = @_;
+ if ($buf) {
+ $s2k->{hash_alg} = $buf->get_int8;
+ $s2k->{salt} = $buf->get_bytes(8);
+ $s2k->{count} = $buf->get_int8;
+ }
+ else {
+ $s2k->{hash_alg} = DEFAULT_DIGEST;
+ require Crypt::Random;
+ $s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
+ $s2k->{count} = 96;
+ }
+ if ($s2k->{hash_alg}) {
+ $s2k->{hash} = Crypt::OpenPGP::Digest->new($s2k->{hash_alg});
+ }
+ $s2k;
+}
+
+sub s2k {
+ my $s2k = shift;
+ my($pass, $pad) = @_;
+ my $salt = $s2k->{salt};
+ my $count = (16 + ($s2k->{count} & 15)) << (($s2k->{count} >> 4) + 6);
+ my $len = length($pass) + 8;
+ if ($count < $len) {
+ $count = $len;
+ }
+ my $res = $pad;
+ while ($count > $len) {
+ $res .= $salt . $pass;
+ $count -= $len;
+ }
+ if ($count < 8) {
+ $res .= substr($salt, 0, $count);
+ } else {
+ $res .= $salt;
+ $count -= 8;
+ $res .= substr($pass, 0, $count);
+ }
+ $s2k->{hash}->hash($res);
+}
+
+sub save {
+ my $s2k = shift;
+ my $buf = Crypt::OpenPGP::Buffer->new;
+ $buf->put_int8(3);
+ $buf->put_int8($s2k->{hash_alg});
+ $buf->put_bytes($s2k->{salt});
+ $buf->put_int8($s2k->{count});
+ $buf->bytes;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Crypt::OpenPGP::S2k - String-to-key generation
+
+=head1 SYNOPSIS
+
+ use Crypt::OpenPGP::S2k;
+
+ # S2k generates an encryption key from a passphrase; in order to
+ # understand how large of a key to generate, we need to know which
+ # cipher we're using, and what the passphrase is.
+ my $cipher = Crypt::OpenPGP::Cipher->new( '...' );
+ my $passphrase = 'foo';
+
+ my $s2k = Crypt::OpenPGP::S2k->new( 'Salt_Iter' );
+ my $key = $s2k->generate( $passphrase, $cipher->keysize );
+
+ my $serialized = $s2k->save;
+
+=head1 DESCRIPTION
+
+I<Crypt::OpenPGP::S2k> implements string-to-key generation for use in
+generating symmetric cipher keys from standard, arbitrary-length
+passphrases (like those used to lock secret key files). Since a
+passphrase can be of any length, and key material must be a very
+specific length, a method is needed to translate the passphrase into
+the key. The OpenPGP RFC defines three such methods, each of which
+this class implements.
+
+=head1 USAGE
+
+=head2 Crypt::OpenPGP::S2k->new($type)
+
+Creates a new type of S2k-generator of type I<$type>; valid values for
+I<$type> are C<Simple>, C<Salted>, and C<Salt_Iter>. These generator
+types are described in the OpenPGP RFC section 3.6.
+
+Returns the new S2k-generator object.
+
+=head2 Crypt::OpenPGP::S2k->parse($buffer)
+
+Given a buffer I<$buffer> of type I<Crypt::OpenPGP::Buffer>, determines
+the type of S2k from the first octet in the buffer (one of the types
+listed above in I<new>), then creates a new object of that type and
+initializes the S2k state from the buffer I<$buffer>. Different
+initializations occur based on the type of S2k.
+
+Returns the new S2k-generator object.
+
+=head2 $s2k->save
+
+Serializes the S2k object and returns the serialized form; this form
+will differ based on the type of S2k.
+
+=head2 $s2k->generate($passphrase, $keysize)
+
+Given a passphrase I<$passphrase>, which should be a string of octets
+of arbitrary length, and a keysize I<$keysize>, generates enough key
+material to meet the size I<$keysize>, and returns that key material.
+
+=head1 AUTHOR & COPYRIGHTS
+
+Please see the Crypt::OpenPGP manpage for author, copyright, and
+license information.
+
+=cut