File Coverage

blib/lib/Crypt/RSA/ES/PKCS1v15.pm
Criterion Covered Total %
statement 81 87 93.1
branch 11 24 45.8
condition 6 14 42.8
subroutine 15 16 93.7
pod 4 8 50.0
total 117 149 78.5


line stmt bran cond sub pod time code
1             package Crypt::RSA::ES::PKCS1v15;
2 1     1   14022 use strict;
  1         2  
  1         25  
3 1     1   4 use warnings;
  1         2  
  1         23  
4              
5             ## Crypt::RSA::ES::PKCS1v15
6             ##
7             ## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
8             ## This code is free software; you can redistribute it and/or modify
9             ## it under the same terms as Perl itself.
10              
11 1     1   4 use base 'Crypt::RSA::Errorhandler';
  1         1  
  1         344  
12 1     1   860 use Math::Prime::Util qw/random_bytes/;
  1         10079  
  1         4  
13 1     1   440 use Crypt::RSA::DataFormat qw(bitsize octet_len os2ip i2osp);
  1         3  
  1         64  
14 1     1   324 use Crypt::RSA::Primitives;
  1         3  
  1         26  
15 1     1   5 use Crypt::RSA::Debug qw(debug);
  1         2  
  1         33  
16 1     1   4 use Carp;
  1         9  
  1         666  
17              
18             $Crypt::RSA::ES::PKCS1v15::VERSION = '1.99';
19              
20             sub new {
21 1     1 1 269 my ($class, %params) = @_;
22 1         10 my $self = bless { primitives => new Crypt::RSA::Primitives,
23             VERSION => $Crypt::RSA::ES::PKCS1v15::VERSION,
24             }, $class;
25 1 50       7 if ($params{Version}) {
26             # do versioning here.
27             }
28 1         3 return $self;
29             }
30              
31              
32             sub encrypt {
33 2     2 1 912 my ($self, %params) = @_;
34 2   33     7 my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
  2         13  
35 2 50       7 return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
36 2 50       14 return $self->error ($key->errstr, \$M, $key, \%params) unless $key->check;
37 2         9 my $k = octet_len ($key->n); debug ("octet_len of modulus: $k");
  2         20  
38 2   50     13 my $em = $self->encode ($M, $k-1) ||
39             return $self->error ($self->errstr, \$M, $key, \%params);
40 2         11 debug ("encoded: $em");
41 2         9 my $m = os2ip ($em);
42 2         5318 my $c = $self->{primitives}->core_encrypt (Plaintext => $m, Key => $key);
43 2         16 my $ec = i2osp ($c, $k); debug ("cyphertext: $ec");
  2         11  
44 2         20 return $ec;
45             }
46              
47              
48             sub decrypt {
49 2     2 1 22 my ($self, %params) = @_;
50 2   33     7 my $key = $params{Key}; my $C = $params{Cyphertext} || $params{Ciphertext};
  2         8  
51 2 50       7 return $self->error ("No Cyphertext or Ciphertext parameter", \$key, \%params) unless $C;
52 2 50       16 return $self->error ($key->errstr, $key, \%params) unless $key->check;
53 2         18 my $k = octet_len ($key->n);
54 2         11 my $c = os2ip ($C);
55 2         5420 debug ("bitsize(c): " . bitsize($c));
56 2         19 debug ("bitsize(n): " . bitsize($key->n));
57 2 50       10 if (bitsize($c) > bitsize($key->n)) {
58 0         0 return $self->error ("Decryption error.", $key, \%params)
59             }
60 2   50     19 my $m = $self->{primitives}->core_decrypt (Cyphertext => $c, Key => $key) ||
61             return $self->error ("Decryption error.", $key, \%params);
62 2   50     90 my $em = i2osp ($m, $k-1) ||
63             return $self->error ("Decryption error.", $key, \%params);
64 2         6 my $M; $self->errstrrst; # reset the errstr
  2         47  
65 2 50       12 unless ($M = $self->decode ($em)) {
66 0 0       0 return $self->error ("Decryption error.", $key, \%params) if $self->errstr();
67 0         0 return $M;
68             }
69 2         19 return $M;
70             }
71              
72              
73             sub encode {
74 2     2 0 10 my ($self, $M, $emlen) = @_;
75 2   50     9 $M = $M || ""; my $mlen = length($M);
  2         8  
76 2 50       17 return $self->error ("Message too long.", \$M) if $mlen > $emlen-10;
77              
78 2         5 my $pslen = $emlen-$mlen-2;
79             # my $PS = join('', map { chr( 1+urandomm(255) ) } 1 .. $pslen);
80 2         8 my $PS = '';
81 2         21 while (length($PS) < $pslen) {
82 2         29 $PS .= random_bytes( $pslen - length($PS) );
83 2         11 $PS =~ s/\x00//g;
84             }
85 2         9 my $em = chr(2).$PS.chr(0).$M;
86 2         7 return $em;
87             }
88              
89              
90             sub decode {
91 2     2 0 6 my ($self, $em) = @_;
92              
93 2 50       10 return $self->error ("Decoding error.") if length($em) < 10;
94              
95 2         10 debug ("to decode: $em");
96 2         8 my ($chr0, $chr2) = (chr(0), chr(2));
97 2         4 my ($ps, $M);
98 2 50       53 unless ( ($ps, $M) = $em =~ /^$chr2(.*?)$chr0(.*)$/s ) {
99 0         0 return $self->error ("Decoding error.");
100             }
101 2 50       17 return $self->error ("Decoding error.") if length($ps) < 8;
102 2         10 return $M;
103             }
104              
105              
106             sub encryptblock {
107 1     1 0 14 my ($self, %params) = @_;
108 1         7 return octet_len ($params{Key}->n) - 11;
109             }
110              
111              
112             sub decryptblock {
113 1     1 0 5 my ($self, %params) = @_;
114 1         8 return octet_len ($params{Key}->n);
115             }
116              
117              
118             sub version {
119 0     0 1   my $self = shift;
120 0           return $self->{VERSION};
121             }
122              
123              
124             1;
125              
126             =head1 NAME
127              
128             Crypt::RSA::ES::PKCS1v15 - PKCS #1 v1.5 padded encryption scheme based on RSA.
129              
130             =head1 SYNOPSIS
131              
132             my $pkcs = new Crypt::RSA::ES::PKCS1v15;
133              
134             my $ct = $pkcs->encrypt( Key => $key, Message => $message ) ||
135             die $pkcs->errstr;
136              
137             my $pt = $pkcs->decrypt( Key => $key, Cyphertext => $ct ) ||
138             die $pkcs->errstr;
139              
140             =head1 DESCRIPTION
141              
142             This module implements PKCS #1 v1.5 padded encryption scheme based on RSA.
143             See [13] for details on the encryption scheme.
144              
145             =head1 METHODS
146              
147             =head2 B
148              
149             Constructor.
150              
151             =head2 B
152              
153             Returns the version number of the module.
154              
155             =head2 B
156              
157             Encrypts a string with a public key and returns the encrypted string
158             on success. encrypt() takes a hash argument with the following
159             mandatory keys:
160              
161             =over 4
162              
163             =item B
164              
165             A string to be encrypted. The length of this string should not exceed k-10
166             octets, where k is the octet length of the RSA modulus. If Message is
167             longer than k-10, the method will fail and set $self->errstr to "Message
168             too long."
169              
170             =item B
171              
172             Public key of the recipient, a Crypt::RSA::Key::Public object.
173              
174             =back
175              
176             =head2 B
177              
178             Decrypts cyphertext with a private key and returns plaintext on
179             success. $self->errstr is set to "Decryption Error." or appropriate
180             error on failure. decrypt() takes a hash argument with the following
181             mandatory keys:
182              
183             =over 4
184              
185             =item B
186              
187             A string encrypted with encrypt(). The length of the cyphertext must be k
188             octets, where k is the length of the RSA modulus.
189              
190             =item B
191              
192             Private key of the receiver, a Crypt::RSA::Key::Private object.
193              
194             =back
195              
196             =head1 ERROR HANDLING
197              
198             See ERROR HANDLING in Crypt::RSA(3) manpage.
199              
200             =head1 BIBLIOGRAPHY
201              
202             See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
203              
204             =head1 AUTHOR
205              
206             Vipul Ved Prakash, Email@vipul.netE
207              
208             =head1 SEE ALSO
209              
210             Crypt::RSA(3), Crypt::RSA::Primitives(3), Crypt::RSA::Keys(3),
211             Crypt::RSA::SSA::PSS(3)
212              
213             =cut
214              
215