File Coverage

lib/Crypt/RSA/SS/PKCS1v15.pm
Criterion Covered Total %
statement 75 83 90.4
branch 11 26 42.3
condition 7 14 50.0
subroutine 16 18 88.9
pod 4 7 57.1
total 113 148 76.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -sw
2             ##
3             ## Crypt::RSA::SS:PKCS1v15
4             ##
5             ## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
6             ## This code is free software; you can redistribute it and/or modify
7             ## it under the same terms as Perl itself.
8             ##
9             ## $Id: PKCS1v15.pm,v 1.6 2001/06/22 23:27:38 vipul Exp $
10              
11             package Crypt::RSA::SS::PKCS1v15;
12 2     2   32 use lib qw(lib);
  2         27  
  2         33  
13 2     2   36 use strict;
  2         19  
  2         31  
14 2     2   28 use vars qw(@ISA $VERSION);
  2         18  
  2         102  
15 2     2   31 use Crypt::RSA::Errorhandler;
  2         19  
  2         36  
16 2     2   29 use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp h2osp);
  2         19  
  2         39  
17 2     2   50 use Crypt::RSA::Primitives;
  2         19  
  2         44  
18 2     2   68 use Crypt::RSA::Debug qw(debug);
  2         19  
  2         41  
19 2     2   37 use Digest::SHA1 qw(sha1);
  2         18  
  2         109  
20 2     2   35 use Digest::MD5 qw(md5);
  2         18  
  2         33  
21 2     2   148 use Digest::MD2 qw(md2);
  2         22  
  2         28  
22 2     2   39 use Math::Pari qw(floor);
  2         19  
  2         32  
23             @ISA = qw(Crypt::RSA::Errorhandler);
24             ($VERSION)  = '$Revision: 1.6 $' =~ /\s(\d+\.\d+)\s/;
25              
26              
27             sub new {
28              
29 4     4 1 208     my ($class, %params) = @_;
30 4   100     59     my $self = bless {
31                                    primitives => new Crypt::RSA::Primitives,
32                                    digest => $params{Digest} || 'SHA1',
33                                    encoding => {
34                                                     MD2 => "0x 30 20 30 0C 06 08 2A 86 48
35             86 F7 0D 02 02 05 00 04 10",
36                                                     MD5 => "0x 30 20 30 0C 06 08 2A 86 48
37             86 F7 0D 02 05 05 00 04 10",
38                                                    SHA1 => "0x 30 21 30 09 06 05 2B 0E 03
39             02 1A 05 00 04 14",
40                                                  },
41                                    VERSION => $VERSION,
42                                  }, $class;
43 4 50       96     if ($params{Version}) {
44             # do versioning here
45                 }
46 4         50     return $self;
47              
48             }
49              
50              
51             sub sign {
52              
53 204     204 1 2939     my ($self, %params) = @_;
54 204   33     2116     my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
  204         212141  
55 204         3287     my $k = octet_len ($key->n);
56              
57 204         3635     my $em;
58 204 50       2684     unless ($em = $self->encode ($M, $k-1)) {
59 0 0       0         return $self->error ($self->errstr, \$key, \%params, \$M)
60                         if $self->errstr eq "Message too long.";
61 0 0       0         return $self->error ("Modulus too short.", \$key, \%params, \$M)
62                         if $self->errstr eq "Intended encoded message length too short";
63                 }
64              
65 204         2760     my $m = os2ip ($em);
66 204         3415     my $sig = $self->{primitives}->core_sign (Key => $key, Message => $m);
67 204         9946     return i2osp ($sig, $k);
68              
69             }    
70              
71              
72             sub verify {
73              
74 203     203 1 3064     my ($self, %params) = @_;
75 203   33     2135     my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
  203         2366  
76 203         2154     my $S = $params{Signature};
77 203         3678     my $k = octet_len ($key->n);
78 203 50       10655     return $self->error ("Invalid signature.", \$key, \$M, \%params) if length($S) != $k;
79 203         2782     my $s = os2ip ($S);
80 203   33     3872     my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
81                     $self->error ("Invalid signature.", \$M, $key, \%params);
82 203   66     3123     my $em = i2osp ($m, $k-1) ||
83                     return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
84 103         1183     my $em1;
85 103 50       2256     unless ($em1 = $self->encode ($M, $k-1)) {
86 0 0       0         return $self->error ($self->errstr, \$key, \%params, \$M)
87                         if $self->errstr eq "Message too long.";
88 0 0       0         return $self->error ("Modulus too short.", \$key, \%params, \$M)
89                         if $self->errstr eq "Intended encoded message length too short.";
90                 }
91              
92 103         1388     debug ("em: $em"); debug ("em1: $em1");
  103         1066  
93              
94 103 50       3098     return 1 if $em eq $em1;
95 0         0     return $self->error ("Invalid signature.", \$M, \$key, \%params);
96              
97             }
98              
99              
100             sub encode {
101              
102 307     307 0 4131     my ($self, $M, $emlen) = @_;
103              
104 307         2956     my $H;
105 307 100       6695     if ($self->{digest} eq "SHA1") { $H = sha1 ($M) }
  303 100       210109  
    50          
106 2         99     elsif ($self->{digest} eq "MD5" ) { $H = md5 ($M) }
107 2         104     elsif ($self->{digest} eq "MD2" ) { $H = md2 ($M) }
108              
109 307         4494     my $alg = h2osp($self->{encoding}->{$self->{digest}});
110 307         4395     my $T = $alg . $H;
111 307 50       3658     $self->error ("Intended encoded message length too short.", \$M) if $emlen < length($T) + 10;
112 307         2864     my $pslen = $emlen - length($T) - 2;
113 307         3503     my $PS = chr(0xff) x $pslen;
114 307         4362     my $em = chr(1) . $PS . chr(0) . $T;
115 307         4257     return $em;
116              
117             }
118              
119              
120             sub version {
121 0     0 1 0     my $self = shift;
122 0         0     return $self->{VERSION};
123             }
124              
125              
126             sub signblock {
127 0     0 0 0     return -1;
128             }
129              
130              
131             sub verifyblock {
132 3     3 0 76     my ($self, %params) = @_;
133 3         53     return octet_len($params{Key}->n);
134             }
135              
136              
137             1;
138              
139             =head1 NAME
140            
141             Crypt::RSA::SS::PKCS1v15 - PKCS #1 v1.5 signatures.
142            
143             =head1 SYNOPSIS
144            
145             my $pkcs = new Crypt::RSA::SS::PKCS1v15 (
146             Digest => 'MD5'
147             );
148            
149             my $signature = $pkcs->sign (
150             Message => $message,
151             Key => $private,
152             ) || die $pss->errstr;
153            
154             my $verify = $pkcs->verify (
155             Message => $message,
156             Key => $key,
157             Signature => $signature,
158             ) || die $pss->errstr;
159            
160            
161             =head1 DESCRIPTION
162            
163             This module implements PKCS #1 v1.5 signatures based on RSA. See [13]
164             for details on the scheme.
165            
166             =head1 METHODS
167            
168             =head2 B<new()>
169            
170             Constructor. Takes a hash as argument with the following key:
171            
172             =over 4
173            
174             =item B<Digest>
175            
176             Name of the Message Digest algorithm. Three Digest algorithms are
177             supported: MD2, MD5 and SHA1. Digest defaults to SHA1.
178            
179             =back
180            
181            
182             =head2 B<version()>
183            
184             Returns the version number of the module.
185            
186             =head2 B<sign()>
187            
188             Computes a PKCS #1 v1.5 signature on a message with the private key of the
189             signer. sign() takes a hash argument with the following mandatory keys:
190            
191             =over 4
192            
193             =item B<Message>
194            
195             Message to be signed, a string of arbitrary length.
196            
197             =item B<Key>
198            
199             Private key of the signer, a Crypt::RSA::Key::Private object.
200            
201             =back
202            
203             =head2 B<verify()>
204            
205             Verifies a signature generated with sign(). Returns a true value on
206             success and false on failure. $self->errstr is set to "Invalid signature."
207             or appropriate error on failure. verify() takes a hash argument with the
208             following mandatory keys:
209            
210             =over 4
211            
212             =item B<Key>
213            
214             Public key of the signer, a Crypt::RSA::Key::Public object.
215            
216             =item B<Message>
217            
218             The original signed message, a string of arbitrary length.
219            
220             =item B<Signature>
221            
222             Signature computed with sign(), a string.
223            
224             =back
225            
226             =head1 ERROR HANDLING
227            
228             See ERROR HANDLING in Crypt::RSA(3) manpage.
229            
230             =head1 BIBLIOGRAPHY
231            
232             See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
233            
234             =head1 AUTHOR
235            
236             Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>
237            
238             =head1 SEE ALSO
239            
240             Crypt::RSA(3), Crypt::RSA::Primitives(3), Crypt::RSA::Keys(3),
241             Crypt::RSA::EME::OAEP(3)
242            
243             =cut
244              
245              
246