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;