summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm')
-rwxr-xr-xMaster/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm195
1 files changed, 195 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm b/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm
new file mode 100755
index 00000000000..ec1e61ac536
--- /dev/null
+++ b/Master/tlpkg/tlperl.straw/lib/Crypt/OpenPGP/SKSessionKey.pm
@@ -0,0 +1,195 @@
+package Crypt::OpenPGP::SKSessionKey;
+use strict;
+
+use Crypt::OpenPGP::Constants qw( DEFAULT_CIPHER );
+use Crypt::OpenPGP::Buffer;
+use Crypt::OpenPGP::S2k;
+use Crypt::OpenPGP::ErrorHandler;
+use base qw( Crypt::OpenPGP::ErrorHandler );
+
+sub new {
+ my $class = shift;
+ my $key = bless { }, $class;
+ $key->init(@_);
+}
+
+sub init {
+ my $key = shift;
+ my %param = @_;
+ $key->{version} = 4;
+ if ((my $sym_key = $param{SymKey}) && (my $pass = $param{Passphrase})) {
+ my $alg = $param{Cipher} || DEFAULT_CIPHER;
+ my $cipher = Crypt::OpenPGP::Cipher->new($alg);
+ my $keysize = $cipher->keysize;
+ $key->{s2k_ciph} = $cipher->alg_id;
+ $key->{s2k} = $param{S2k} || Crypt::OpenPGP::S2k->new('Salt_Iter');
+ $sym_key = substr $sym_key, 0, $keysize;
+ my $s2k_key = $key->{s2k}->generate($pass, $keysize);
+ $cipher->init($s2k_key);
+ }
+ $key;
+}
+
+sub parse {
+ my $class = shift;
+ my($buf) = @_;
+ my $key = $class->new;
+ $key->{version} = $buf->get_int8;
+ return $class->error("Unsupported version ($key->{version})")
+ unless $key->{version} == 4;
+ $key->{s2k_ciph} = $buf->get_int8;
+ $key->{s2k} = Crypt::OpenPGP::S2k->parse($buf);
+ if ($buf->offset < $buf->length) {
+ $key->{encrypted} = $buf->get_bytes( $buf->length - $buf->offset );
+ }
+ $key;
+}
+
+sub save {
+ my $key = shift;
+ my $buf = Crypt::OpenPGP::Buffer->new;
+ $buf->put_int8($key->{version});
+ $buf->put_int8($key->{s2k_ciph});
+ $buf->put_bytes( $key->{s2k}->save );
+ $buf->bytes;
+}
+
+sub decrypt {
+ my $key = shift;
+ my($passphrase) = @_;
+ my $cipher = Crypt::OpenPGP::Cipher->new($key->{s2k_ciph});
+ my $keysize = $cipher->keysize;
+ my $s2k_key = $key->{s2k}->generate($passphrase, $keysize);
+ my($sym_key, $alg);
+ if ($key->{encrypted}) {
+ $cipher->init($s2k_key);
+ $sym_key = $cipher->decrypt($key->{encrypted});
+ $alg = ord substr $sym_key, 0, 1, '';
+ } else {
+ $sym_key = $s2k_key;
+ $alg = $cipher->alg_id;
+ }
+ ($sym_key, $alg);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Crypt::OpenPGP::SKSessionKey - Symmetric-Key Encrypted Session Key
+
+=head1 SYNOPSIS
+
+ use Crypt::OpenPGP::SKSessionKey;
+
+ my $passphrase = 'foobar'; # Not a very good passphrase
+ my $key_data = 'f' x 64; # Not a very good key
+
+ my $skey = Crypt::OpenPGP::SKSessionKey->new(
+ Passphrase => $passphrase,
+ SymKey => $key_data,
+ );
+ my $serialized = $skey->save;
+
+=head1 DESCRIPTION
+
+I<Crypt::OpenPGP::SKSessionKey> implements symmetric-key encrypted
+session key packets; these packets store symmetric-key-encrypted key data
+that, when decrypted using the proper passphrase, can be used to decrypt a
+block of ciphertext--that is, a I<Crypt::OpenPGP::Ciphertext> object.
+
+Symmetric-key encrypted session key packets can work in two different
+ways: in one scenario the passphrase you provide is used to encrypt
+a randomly chosen string of key material; the key material is the key
+that is actually used to encrypt the data packet, and the passphrase
+just serves to encrypt the key material. This encrypted key material
+is then serialized into the symmetric-key encrypted session key packet.
+
+The other method of using this encryption form is to use the passphrase
+directly to encrypt the data packet. In this scenario the need for any
+additional key material goes away, because all the receiver needs is
+the same passphrase that you have entered to encrypt the data.
+
+At the moment I<Crypt::OpenPGP> really only supports the first
+scenario; note also that the interface to I<new> may change in the
+future when support for the second scenario is added.
+
+=head1 USAGE
+
+=head2 Crypt::OpenPGP::SKSessionKey->new( %arg )
+
+Creates a new encrypted session key packet object and returns that
+object. If there are no arguments in I<%arg>, the object is created
+empty; this is used, for example in I<parse> (below), to create an
+empty packet which is then filled from the data in the buffer.
+
+If you wish to initialize a non-empty object, I<%arg> can contain:
+
+=over 4
+
+=item * Passphrase
+
+An arbitrary-length passphrase; that is, a string of octets. The
+passphrase is used to encrypt the actual session key such that it can
+only be decrypted by supplying the correct passphrase.
+
+This argument is required (for a non-empty object).
+
+=item * SymKey
+
+The symmetric cipher key: a string of octets that make up the key data
+of the symmetric cipher key. This should be at least long enough for
+the key length of your chosen cipher (see I<Cipher>, below), or, if
+you have not specified a cipher, at least 64 bytes (to allow for long
+cipher key sizes).
+
+This argument is required (for a non-empty object).
+
+=item * S2k
+
+An object of type I<Crypt::OpenPGP::S2k> (or rather, of one of its
+subclasses). If you use the passphrase directly to encrypt the data
+packet (scenario one, above), you will probably be generating the
+key material outside of this class, meaning that you will need to pass
+in the I<S2k> object that was used to generate that key material from
+the passphrase. This is the way to do that.
+
+=item * Cipher
+
+The name (or ID) of a supported PGP cipher. See I<Crypt::OpenPGP::Cipher>
+for a list of valid cipher names.
+
+This argument is optional; by default I<Crypt::OpenPGP::Cipher> will
+use C<DES3>.
+
+=back
+
+=head2 $skey->save
+
+Serializes the session key packet and returns the string of octets.
+
+=head2 Crypt::OpenPGP::SKSessionKey->parse($buffer)
+
+Given I<$buffer>, a I<Crypt::OpenPGP::Buffer> object holding (or
+with offset pointing to) an encrypted session key packet, returns
+a new I<Crypt::OpenPGP::Ciphertext> object, initialized with the
+data in the buffer.
+
+=head2 $skey->decrypt($passphrase)
+
+Given a passphrase I<$passphrase>, decrypts the encrypted session key
+data. The key data includes the symmetric key itself, along with a
+one-octet ID of the symmetric cipher used to encrypt the message.
+
+Returns a list containing two items: the symmetric key and the cipher
+algorithm ID. These are suitable for passing off to the I<decrypt>
+method of a I<Crypt::OpenPGP::Ciphertext> object to decrypt a block
+of encrypted data.
+
+=head1 AUTHOR & COPYRIGHTS
+
+Please see the Crypt::OpenPGP manpage for author, copyright, and
+license information.
+
+=cut