Initial Commit
This commit is contained in:
275
database/perl/vendor/lib/Crypt/RSA/SS/PKCS1v15.pm
vendored
Normal file
275
database/perl/vendor/lib/Crypt/RSA/SS/PKCS1v15.pm
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
package Crypt::RSA::SS::PKCS1v15;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
## Crypt::RSA::SS:PKCS1v15
|
||||
##
|
||||
## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
|
||||
## This code is free software; you can redistribute it and/or modify
|
||||
## it under the same terms as Perl itself.
|
||||
|
||||
use base 'Crypt::RSA::Errorhandler';
|
||||
use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp h2osp);
|
||||
use Crypt::RSA::Primitives;
|
||||
use Crypt::RSA::Debug qw(debug);
|
||||
use Digest::SHA qw(sha1 sha224 sha256 sha384 sha512);
|
||||
use Digest::MD5 qw(md5);
|
||||
use Digest::MD2 qw(md2);
|
||||
|
||||
$Crypt::RSA::SS::PKCS1v15::VERSION = '1.99';
|
||||
|
||||
# See if we have a bug-fixed RIPEMD-160.
|
||||
my $ripe_hash = undef;
|
||||
if (eval { require Crypt::RIPEMD160; $Crypt::RIPEMD160::VERSION >= 0.05; }) {
|
||||
$ripe_hash = sub { my $r=new Crypt::RIPEMD160; $r->add(shift); $r->digest();};
|
||||
}
|
||||
|
||||
sub new {
|
||||
|
||||
my ($class, %params) = @_;
|
||||
my $self = bless {
|
||||
primitives => new Crypt::RSA::Primitives,
|
||||
digest => $params{Digest} || 'SHA1',
|
||||
encoding => {
|
||||
# See http://rfc-ref.org/RFC-TEXTS/3447/chapter9.html
|
||||
MD2 =>[\&md2, "30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10"],
|
||||
MD5 =>[\&md5, "30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10"],
|
||||
SHA1 =>[\&sha1, "30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14"],
|
||||
SHA224=>[\&sha224,"30 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c"],
|
||||
SHA256=>[\&sha256,"30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20"],
|
||||
SHA384=>[\&sha384,"30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30"],
|
||||
SHA512=>[\&sha512,"30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40"],
|
||||
RIPEMD160=>[$ripe_hash,"30 21 30 09 06 05 2B 24 03 02 01 05 00 04 14"],
|
||||
},
|
||||
VERSION => $Crypt::RSA::SS::PKCS1v15::VERSION,
|
||||
}, $class;
|
||||
# Allow "sha256", "sha-256", "RipeMD-160", etc.
|
||||
$self->{digest} =~ tr/a-z/A-Z/;
|
||||
$self->{digest} =~ s/[^A-Z0-9]//g;
|
||||
if ($params{Version}) {
|
||||
# do versioning here
|
||||
}
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub sign {
|
||||
|
||||
my ($self, %params) = @_;
|
||||
my $key = $params{Key};
|
||||
my $M = $params{Message} || $params{Plaintext};
|
||||
return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
|
||||
return $self->error ("No Key parameter", \$M, \%params) unless $key;
|
||||
my $k = octet_len ($key->n);
|
||||
|
||||
my $em;
|
||||
unless ($em = $self->encode ($M, $k)) {
|
||||
return $self->error ($self->errstr, \$key, \%params, \$M)
|
||||
if $self->errstr eq "Message too long.";
|
||||
return $self->error ("Modulus too short.", \$key, \%params, \$M)
|
||||
if $self->errstr eq "Intended encoded message length too short";
|
||||
# Other error
|
||||
return $self->error ($self->errstr, \$key, \%params, \$M);
|
||||
}
|
||||
|
||||
my $m = os2ip ($em);
|
||||
my $sig = $self->{primitives}->core_sign (Key => $key, Message => $m);
|
||||
return i2osp ($sig, $k);
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub verify {
|
||||
|
||||
my ($self, %params) = @_;
|
||||
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
|
||||
my $S = $params{Signature};
|
||||
return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
|
||||
return $self->error ("No Key parameter", \$M, \$S, \%params) unless $key;
|
||||
return $self->error ("No Signature parameter", \$key, \$M, \%params) unless $S;
|
||||
my $k = octet_len ($key->n);
|
||||
return $self->error ("Invalid signature.", \$key, \$M, \%params) if length($S) != $k;
|
||||
my $s = os2ip ($S);
|
||||
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
|
||||
$self->error ("Invalid signature.", \$M, $key, \%params);
|
||||
my $em = i2osp ($m, $k) ||
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
my $em1;
|
||||
unless ($em1 = $self->encode ($M, $k)) {
|
||||
return $self->error ($self->errstr, \$key, \%params, \$M)
|
||||
if $self->errstr eq "Message too long.";
|
||||
return $self->error ("Modulus too short.", \$key, \%params, \$M)
|
||||
if $self->errstr eq "Intended encoded message length too short.";
|
||||
}
|
||||
|
||||
debug ("em: $em"); debug ("em1: $em1");
|
||||
|
||||
return 1 if $em eq $em1;
|
||||
return $self->error ("Invalid signature.", \$M, \$key, \%params);
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub encode {
|
||||
|
||||
my ($self, $M, $emlen) = @_;
|
||||
|
||||
my $encoding = $self->{encoding}->{$self->{digest}};
|
||||
return $self->error ("Invalid encoding: $self->{digest}") unless defined $encoding;
|
||||
my ($hashfunc, $digestinfo) = @$encoding;
|
||||
return $self->error ("encoding method $self->{digest} not supported") unless defined $hashfunc;
|
||||
|
||||
# Changed to match RFC 2313 (PKCS#1 v1.5) and 3447 (PKCS#1 v2.1).
|
||||
# There was apparently some confusion from XML documentation that
|
||||
# printed a different set of instructions here. See, for example:
|
||||
# http://osdir.com/ml/mozilla.crypto/2005-05/msg00300.htm
|
||||
# However, previously emlen was always k-1, so the result ended up
|
||||
# being identical anyway. One change is that we now return if there
|
||||
# is not enough padding. Previously the error string would be set
|
||||
# but processing would continue.
|
||||
#
|
||||
# Refs:
|
||||
# http://rfc-ref.org/RFC-TEXTS/3447/chapter9.html
|
||||
# https://tools.ietf.org/html/rfc2313
|
||||
my $H = $hashfunc->($M);
|
||||
my $alg = h2osp($digestinfo);
|
||||
return $self->error ("Invalid digest results: $self->{digest}") unless defined $H && length($H) > 0;
|
||||
|
||||
my $T = $alg . $H;
|
||||
return $self->error ("Intended encoded message length too short.", \$M) if $emlen < length($T) + 11;
|
||||
my $pslen = $emlen - length($T) - 3;
|
||||
my $PS = chr(0xff) x $pslen;
|
||||
my $em = chr(0) . chr(1) . $PS . chr(0) . $T;
|
||||
return $em;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub version {
|
||||
my $self = shift;
|
||||
return $self->{VERSION};
|
||||
}
|
||||
|
||||
|
||||
sub signblock {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
sub verifyblock {
|
||||
my ($self, %params) = @_;
|
||||
return octet_len($params{Key}->n);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Crypt::RSA::SS::PKCS1v15 - PKCS #1 v1.5 signatures.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $pkcs = new Crypt::RSA::SS::PKCS1v15 (
|
||||
Digest => 'MD5'
|
||||
);
|
||||
|
||||
my $signature = $pkcs->sign (
|
||||
Message => $message,
|
||||
Key => $private,
|
||||
) || die $pss->errstr;
|
||||
|
||||
my $verify = $pkcs->verify (
|
||||
Message => $message,
|
||||
Key => $key,
|
||||
Signature => $signature,
|
||||
) || die $pss->errstr;
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module implements PKCS #1 v1.5 signatures based on RSA. See [13]
|
||||
for details on the scheme.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 B<new()>
|
||||
|
||||
Constructor. Takes a hash as argument with the following key:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Digest>
|
||||
|
||||
Name of the Message Digest algorithm. Three Digest algorithms are
|
||||
supported: MD2, MD5, SHA1, SHA224, SHA256, SHA384, and SHA512.
|
||||
Digest defaults to SHA1.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 B<version()>
|
||||
|
||||
Returns the version number of the module.
|
||||
|
||||
=head2 B<sign()>
|
||||
|
||||
Computes a PKCS #1 v1.5 signature on a message with the private key of the
|
||||
signer. sign() takes a hash argument with the following mandatory keys:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Message>
|
||||
|
||||
Message to be signed, a string of arbitrary length.
|
||||
|
||||
=item B<Key>
|
||||
|
||||
Private key of the signer, a Crypt::RSA::Key::Private object.
|
||||
|
||||
=back
|
||||
|
||||
=head2 B<verify()>
|
||||
|
||||
Verifies a signature generated with sign(). Returns a true value on
|
||||
success and false on failure. $self->errstr is set to "Invalid signature."
|
||||
or appropriate error on failure. verify() takes a hash argument with the
|
||||
following mandatory keys:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Key>
|
||||
|
||||
Public key of the signer, a Crypt::RSA::Key::Public object.
|
||||
|
||||
=item B<Message>
|
||||
|
||||
The original signed message, a string of arbitrary length.
|
||||
|
||||
=item B<Signature>
|
||||
|
||||
Signature computed with sign(), a string.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ERROR HANDLING
|
||||
|
||||
See ERROR HANDLING in Crypt::RSA(3) manpage.
|
||||
|
||||
=head1 BIBLIOGRAPHY
|
||||
|
||||
See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Crypt::RSA(3), Crypt::RSA::Primitives(3), Crypt::RSA::Keys(3),
|
||||
Crypt::RSA::EME::OAEP(3)
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
271
database/perl/vendor/lib/Crypt/RSA/SS/PSS.pm
vendored
Normal file
271
database/perl/vendor/lib/Crypt/RSA/SS/PSS.pm
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
package Crypt::RSA::SS::PSS;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
## Crypt::RSA::SS:PSS
|
||||
##
|
||||
## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
|
||||
## This code is free software; you can redistribute it and/or modify
|
||||
## it under the same terms as Perl itself.
|
||||
|
||||
use base 'Crypt::RSA::Errorhandler';
|
||||
use Math::Prime::Util qw/random_bytes/;
|
||||
use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp octet_xor mgf1);
|
||||
use Crypt::RSA::Primitives;
|
||||
use Crypt::RSA::Debug qw(debug);
|
||||
use Digest::SHA qw(sha1);
|
||||
|
||||
$Crypt::RSA::SS::PSS::VERSION = '1.99';
|
||||
|
||||
sub new {
|
||||
my ($class, %params) = @_;
|
||||
my $self = bless { primitives => new Crypt::RSA::Primitives,
|
||||
hlen => 20,
|
||||
VERSION => $Crypt::RSA::SS::PSS::VERSION,
|
||||
}, $class;
|
||||
if ($params{Version}) {
|
||||
# do versioning here
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub sign {
|
||||
my ($self, %params) = @_;
|
||||
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
|
||||
return $self->error("No Key parameter", \$M, \%params) unless $key;
|
||||
return $self->error("No Message or Plaintext parameter", \$key, \%params) unless $M;
|
||||
my $k = octet_len ($key->n);
|
||||
my $salt = random_bytes($self->{hlen});
|
||||
my $em = $self->encode ($M, $salt, $k-1);
|
||||
my $m = os2ip ($em);
|
||||
my $sig = $self->{primitives}->core_sign (Key => $key, Message => $m);
|
||||
my $S = i2osp ($sig, $k);
|
||||
return ($S, $salt) if wantarray;
|
||||
return $S;
|
||||
}
|
||||
|
||||
|
||||
sub verify_with_salt {
|
||||
my ($self, %params) = @_;
|
||||
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
|
||||
my $S = $params{Signature}; my $salt = $params{Salt};
|
||||
return $self->error("No Key parameter", \$S, \%params) unless $key;
|
||||
return $self->error("No Signature parameter", \$key, \%params) unless $S;
|
||||
my $k = octet_len ($key->n);
|
||||
my $em;
|
||||
unless ($em = $self->encode ($M, $salt, $k-1)) {
|
||||
return if $self->errstr eq "Message too long.";
|
||||
return $self->error ("Modulus too short.", \$M, \$S, \$key, \%params) if
|
||||
$self->errstr eq "Intended encoded message length too short.";
|
||||
}
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params) if length($S) < $k;
|
||||
my $s = os2ip ($S);
|
||||
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
|
||||
$self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
my $em1 = i2osp ($m, $k-1) ||
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
return 1 if $em eq $em1;
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
}
|
||||
|
||||
|
||||
sub verify {
|
||||
my ($self, %params) = @_;
|
||||
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
|
||||
my $S = $params{Signature};
|
||||
return $self->error("No Key parameter", \$S, \$M, \%params) unless $key;
|
||||
return $self->error("No Signature parameter", \$key, \$M, \%params) unless $S;
|
||||
return $self->error("No Message or Plaintext parameter", \$key, \$S, \%params) unless $M;
|
||||
my $k = octet_len ($key->n);
|
||||
my $s = os2ip ($S);
|
||||
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
|
||||
$self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
my $em1 = i2osp ($m, $k-1) ||
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
return 1 if $self->verify_with_salt_recovery ($M, $em1);
|
||||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
|
||||
}
|
||||
|
||||
|
||||
sub encode {
|
||||
my ($self, $M, $salt, $emlen) = @_;
|
||||
return $self->error ("Intended encoded message length too short.", \$M, \$salt )
|
||||
if $emlen < 2 * $self->{hlen};
|
||||
my $H = $self->hash ("$salt$M");
|
||||
my $padlength = $emlen - (2*$$self{hlen});
|
||||
my $PS = chr(0)x$padlength;
|
||||
my $db = $salt . $PS;
|
||||
my $dbmask = $self->mgf ($H, $emlen - $self->{hlen});
|
||||
my $maskeddb = octet_xor ($db, $dbmask);
|
||||
my $em = $H . $maskeddb;
|
||||
return $em;
|
||||
}
|
||||
|
||||
|
||||
sub verify_with_salt_recovery {
|
||||
my ($self, $M, $EM) = @_;
|
||||
my $hlen = $$self{hlen};
|
||||
my $emlen = length ($EM);
|
||||
return $self->error ("Encoded message too short.", \$M, \$EM) if $emlen < (2*$hlen);
|
||||
my $H = substr $EM, 0, $hlen;
|
||||
my $maskeddb = substr $EM, $hlen;
|
||||
my $dbmask = $self->mgf ($H, $emlen-$hlen);
|
||||
my $db = octet_xor ($maskeddb, $dbmask);
|
||||
my $salt = substr $db, 0, $hlen;
|
||||
my $PS = substr $db, $hlen;
|
||||
my $check = chr(0) x ($emlen-(2*$hlen)); debug ("PS: $PS");
|
||||
return $self->error ("Inconsistent.") unless $check eq $PS;
|
||||
my $H1 = $self->hash ("$salt$M");
|
||||
return 1 if $H eq $H1;
|
||||
return $self->error ("Inconsistent.");
|
||||
}
|
||||
|
||||
|
||||
sub hash {
|
||||
my ($self, $data) = @_;
|
||||
return sha1 ($data);
|
||||
}
|
||||
|
||||
|
||||
sub mgf {
|
||||
my ($self, @data) = @_;
|
||||
return mgf1 (@data);
|
||||
}
|
||||
|
||||
|
||||
sub version {
|
||||
my $self = shift;
|
||||
return $self->{VERSION};
|
||||
}
|
||||
|
||||
|
||||
sub signblock {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
sub verifyblock {
|
||||
my ($self, %params) = @_;
|
||||
return octet_len($params{Key}->n);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Crypt::RSA::SS::PSS - Probabilistic Signature Scheme based on RSA.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $pss = new Crypt::RSA::SS::PSS;
|
||||
|
||||
my $signature = $pss->sign (
|
||||
Message => $message,
|
||||
Key => $private,
|
||||
) || die $pss->errstr;
|
||||
|
||||
my $verify = $pss->verify (
|
||||
Message => $message,
|
||||
Key => $key,
|
||||
Signature => $signature,
|
||||
) || die $pss->errstr;
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
PSS (Probabilistic Signature Scheme) is a provably secure method of
|
||||
creating digital signatures with RSA. "Provable" means that the
|
||||
difficulty of forging signatures can be directly related to inverting
|
||||
the RSA function. "Probabilistic" alludes to the randomly generated salt
|
||||
value included in the signature to enhance security. For more details
|
||||
on PSS, see [4] & [13].
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 B<new()>
|
||||
|
||||
Constructor.
|
||||
|
||||
=head2 B<version()>
|
||||
|
||||
Returns the version number of the module.
|
||||
|
||||
=head2 B<sign()>
|
||||
|
||||
Computes a PSS signature on a message with the private key of the signer.
|
||||
In scalar context, sign() returns the computed signature. In array
|
||||
context, it returns the signature and the random salt. The signature can
|
||||
verified with verify() or verify_with_salt(). sign() takes a hash argument
|
||||
with the following mandatory keys:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Message>
|
||||
|
||||
Message to be signed, a string of arbitrary length.
|
||||
|
||||
=item B<Key>
|
||||
|
||||
Private key of the signer, a Crypt::RSA::Key::Private object.
|
||||
|
||||
=back
|
||||
|
||||
=head2 B<verify()>
|
||||
|
||||
Verifies a signature generated with sign(). The salt is recovered from the
|
||||
signature and need not be passed. Returns a true value on success and
|
||||
false on failure. $self->errstr is set to "Invalid signature." or
|
||||
appropriate error on failure. verify() takes a hash argument with the
|
||||
following mandatory keys:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Key>
|
||||
|
||||
Public key of the signer, a Crypt::RSA::Key::Public object.
|
||||
|
||||
=item B<Message>
|
||||
|
||||
The original signed message, a string of arbitrary length.
|
||||
|
||||
=item B<Signature>
|
||||
|
||||
Signature computed with sign(), a string.
|
||||
|
||||
=item B<Version>
|
||||
|
||||
Version of the module that was used for creating the Signature. This is an
|
||||
optional argument. When present, verify() will ensure before proceeding
|
||||
that the installed version of the module can successfully verify the
|
||||
Signature.
|
||||
|
||||
=back
|
||||
|
||||
=head2 B<verify_with_salt()>
|
||||
|
||||
Verifies a signature given the salt. Takes the same arguments as verify()
|
||||
in addition to B<Salt>, which is a 20-byte string returned by sign() in
|
||||
array context.
|
||||
|
||||
=head1 ERROR HANDLING
|
||||
|
||||
See ERROR HANDLING in Crypt::RSA(3) manpage.
|
||||
|
||||
=head1 BIBLIOGRAPHY
|
||||
|
||||
See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Crypt::RSA(3), Crypt::RSA::Primitives(3), Crypt::RSA::Keys(3),
|
||||
Crypt::RSA::EME::OAEP(3)
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
Reference in New Issue
Block a user