/ tests / parsers.pm
parsers.pm
 1  package parsers;
 2  
 3  use Exporter qw(import);
 4  our @EXPORT_OK = qw(parse_pkcs1_vectors);
 5  
 6  sub parse_pkcs1_vectors {
 7      my $file = shift;
 8      my $data;
 9  
10      my %privkey_injectors = (
11          '# Modulus:'            => sub { $data->[$#$data]->{key}->{N} .= $_[0] },
12          '# Public exponent:'    => sub { $data->[$#$data]->{key}->{e} .= $_[0] },
13          '# Exponent:'           => sub { $data->[$#$data]->{key}->{d} .= $_[0] },
14          '# Prime 1:'            => sub { $data->[$#$data]->{key}->{factors}->[0] .= $_[0] },
15          '# Prime 2:'            => sub { $data->[$#$data]->{key}->{factors}->[1] .= $_[0] },
16          '# Prime exponent 1:'   => sub { $data->[$#$data]->{key}->{exponents}->[0] .= $_[0] },
17          '# Prime exponent 2:'   => sub { $data->[$#$data]->{key}->{exponents}->[1] .= $_[0] },
18          '# Coefficient:'        => sub { $data->[$#$data]->{key}->{coefficients}->[0] .= $_[0] },
19          );
20  
21      my %test_injectors = (
22          # Used for PKCS1 signature and verification
23          '# Message to be signed:'
24          => sub { $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{message} .= $_[0] },
25          '# Signature:'
26          => sub { $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{signature} .= $_[0] },
27  
28          # Used for PKCS1 encryption and decryption
29          '# Message:'
30          => sub { $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{message} .= $_[0] },
31          '# Seed:'
32          => sub { $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{seed} .= $_[0] },
33          '# Encryption:'
34          => sub { $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{encryption} .= $_[0] },
35          );
36  
37      my $injectors;
38      my $current_injector;
39  
40      my $fh;
41  
42      open $fh, $file or die "Trying to read $file\n";
43      while (<$fh>) {
44          s|\R$||; # Better chomp
45          s| *$||; # Remove ending whitespace
46  
47          if (m|# (Example \d+: A \d+-bit RSA key pair)|) {
48              push @$data, {};
49              $data->[$#$data]->{title} = $1;
50              $data->[$#$data]->{tests} = [];
51              $injectors = undef;
52              $current_injector = undef;
53              next;
54          }
55  
56          if (m|# Private key|) {
57              $injectors = \%privkey_injectors;
58              $current_injector = undef;
59          }
60  
61          if (m/# PKCS#1 v1\.5 (?:Signature|Encryption) (Example \d+\.\d+)/) {
62              push @{$data->[$#$data]->{tests}}, {};
63              $data->[$#$data]->{tests}->[$#{$data->[$#$data]->{tests}}]->{title} = $1;
64              $injectors = \%test_injectors;
65              $current_injector = undef;
66          }
67  
68          if (defined $injectors && defined $injectors->{$_}) {
69              $current_injector = $injectors->{$_};
70          }
71  
72          if (m|^[[:xdigit:]]{2}(?:\s[[:xdigit:]]{2})*$|) {
73              my $hex = $_;
74              $hex =~ s| ||g;
75              if ($current_injector) {
76                  $current_injector->($hex);
77              }
78          }
79      }
80      close $fh;
81  
82      return $data;
83  }
84  
85  1;