summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm')
-rwxr-xr-xMaster/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm236
1 files changed, 236 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm b/Master/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm
new file mode 100755
index 00000000000..0fd5edc4a65
--- /dev/null
+++ b/Master/tlpkg/tlperl/lib/Crypt/OpenPGP/Key.pm
@@ -0,0 +1,236 @@
+package Crypt::OpenPGP::Key;
+use strict;
+
+use Carp qw( confess );
+use Crypt::OpenPGP::ErrorHandler;
+use base qw( Crypt::OpenPGP::ErrorHandler );
+
+use vars qw( %ALG %ALG_BY_NAME );
+%ALG = (
+ 1 => 'RSA',
+ 16 => 'ElGamal',
+ 17 => 'DSA',
+);
+%ALG_BY_NAME = map { $ALG{$_} => $_ } keys %ALG;
+
+sub new {
+ my $class = shift;
+ my $alg = shift;
+ $alg = $ALG{$alg} || $alg;
+ my $pkg = join '::', $class, $alg;
+ eval "use $pkg;";
+ return $class->error("Unsupported algorithm '$alg': $@") if $@;
+ my @valid = $pkg->all_props;
+ my %valid = map { $_ => 1 } @valid;
+ my $key = bless { __valid => \%valid, __alg => $alg,
+ __alg_id => $ALG_BY_NAME{$alg} }, $pkg;
+ $key->init(@_);
+}
+
+sub keygen {
+ my $class = shift;
+ my $alg = shift;
+ $alg = $ALG{$alg} || $alg;
+ my $pkg = join '::', __PACKAGE__, 'Public', $alg;
+ eval "use $pkg;";
+ return $class->error("Unsupported algorithm '$alg': $@") if $@;
+ my($pub_data, $sec_data) = $pkg->keygen(@_);
+ return $class->error("Key generation failed: " . $class->errstr)
+ unless $pub_data && $sec_data;
+ my $pub_pkg = join '::', __PACKAGE__, 'Public';
+ my $pub = $pub_pkg->new($alg, $pub_data);
+ my $sec_pkg = join '::', __PACKAGE__, 'Secret';
+ my $sec = $sec_pkg->new($alg, $sec_data);
+ ($pub, $sec);
+}
+
+sub init { $_[0] }
+
+sub check { 1 }
+
+sub alg { $_[0]->{__alg} }
+sub alg_id { $_[0]->{__alg_id} }
+
+sub size { 0 }
+sub bytesize { int(($_[0]->size + 7) / 8) }
+
+sub public_key { }
+sub is_secret { 0 }
+
+sub can_encrypt { 0 }
+sub can_sign { 0 }
+
+sub DESTROY { }
+
+use vars qw( $AUTOLOAD );
+sub AUTOLOAD {
+ my $key = shift;
+ (my $meth = $AUTOLOAD) =~ s/.*:://;
+ confess "Can't call method $meth on Key $key"
+ unless $key->{__valid}{$meth};
+ $key->{key_data}->$meth(@_);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Crypt::OpenPGP::Key - OpenPGP key factory
+
+=head1 SYNOPSIS
+
+ use Crypt::OpenPGP::Key;
+ my($pub, $sec) = Crypt::OpenPGP::Key->keygen('DSA', Size => 1024);
+
+ use Crypt::OpenPGP::Key::Public;
+ my $pubkey = Crypt::OpenPGP::Key::Public->new('DSA');
+
+ use Crypt::OpenPGP::Key::Secret;
+ my $seckey = Crypt::OpenPGP::Key::Secret->new('RSA');
+
+=head1 DESCRIPTION
+
+I<Crypt::OpenPGP::Key> provides base class functionality for all
+I<Crypt::OpenPGP> public and secret keys. It functions as a factory
+class for key generation and key instantiation.
+
+The only time you will ever use I<Crypt::OpenPGP::Key> directly is
+to generate a key-pair; in all other scenarios--for example, when
+instantiating a new key object--you should use either
+I<Crypt::OpenPGP::Key::Public> or I<Crypt::OpenPGP::Key::Secret>,
+depending on whether the key is public or secret, respectively.
+
+=head1 KEY GENERATION
+
+=head2 Crypt::OpenPGP::Key->keygen( $type, %arg )
+
+Generates a new key-pair of public key algorithm I<$type>. Returns
+a public and a secret key, each blessed into the appropriate
+implementation class. Returns an empty list on failure, in which case
+you should call the class method I<errstr> to determine the error.
+
+Valid values for type are C<DSA>, C<RSA>, and C<ElGamal>.
+
+I<%arg> can contain:
+
+=over 4
+
+=item * Size
+
+Bitsize of the key to be generated. This should be an even integer;
+there is no low end currently set, but for the sake of security
+I<Size> should be at least 1024 bits.
+
+This is a required argument.
+
+=item * Verbosity
+
+Set to a true value to enable a status display during key generation;
+since key generation is a relatively length process, it is helpful
+to have an indication that some action is occurring.
+
+I<Verbosity> is 0 by default.
+
+=back
+
+=head1 METHODS
+
+I<Crypt::OpenPGP::Key> is not meant to be used directly (unless you
+are generating keys; see I<KEY GENERATION>, above); instead you should
+use the subclasses of this module. There are, however, useful interface
+methods that are shared by all subclasses.
+
+=head2 Key Data Access
+
+Each public-key algorithm has different key data associated with it.
+For example, a public DSA key has 4 attributes: I<p>, I<q>, I<g>, and
+I<y>. A secret DSA key has the same attributes as a public key, and
+in addition it has an attribute I<x>.
+
+All of the key data attributes can be accessed by calling methods of
+the same name on the I<Key> object. For example:
+
+ my $q = $dsa_key->q;
+
+The attributes for each public-key algorithm are:
+
+=over 4
+
+=item * RSA
+
+Public key: I<n>, I<e>
+
+Secret key: I<n>, I<e>, I<d>, I<p>, I<q>, I<u>
+
+=item * DSA
+
+Public key: I<p>, I<q>, I<g>, I<y>
+
+Secret key: I<p>, I<q>, I<g>, I<y>, I<x>
+
+=item * ElGamal
+
+Public key: I<p>, I<g>, I<y>
+
+Secret key: I<p>, I<g>, I<y>, I<x>
+
+=back
+
+=head2 $key->check
+
+Check the key data to determine if it is valid. For example, an RSA
+secret key would multiply the values of I<p> and I<q> and verify that
+the product is equal to the value of I<n>. Returns true if the key
+is valid, false otherwise.
+
+Not all public key algorithm implementations implement a I<check>
+method; for those that don't, I<check> will always return true.
+
+=head2 $key->size
+
+Returns the "size" of the key. The definition of "size" depends on
+the public key algorithm; for example, DSA defines the size of a key
+as the bitsize of the value of I<p>.
+
+=head2 $key->bytesize
+
+Whereas I<size> will return a bitsize of the key, I<bytesize> returns
+the size in bytes. This value is defined as C<int((bitsize(key)+7)/8)>.
+
+=head2 $key->is_secret
+
+Returns true if the key I<$key> is a secret key, false otherwise.
+
+=head2 $key->public_key
+
+Returns the public part of the key I<$key>. If I<$key> is already a
+public key, I<$key> is returned; otherwise a new public key object
+(I<Crypt::OpenPGP::Key::Public>) is constructed, and the public values
+from the secret key are copied into the public key. The new public
+key is returned.
+
+=head2 $key->can_encrypt
+
+Returns true if the key algorithm has encryption/decryption
+capabilities, false otherwise.
+
+=head2 $key->can_sign
+
+Returns true if the key algorithm has signing/verification
+capabilities, false otherwise.
+
+=head2 $key->alg
+
+Returns the name of the public key algorithm.
+
+=head2 $key->alg_id
+
+Returns the number ID of the public key algorithm.
+
+=head1 AUTHOR & COPYRIGHTS
+
+Please see the Crypt::OpenPGP manpage for author, copyright, and
+license information.
+
+=cut