File Coverage

blib/lib/Net/DNS/SEC/RSA.pm
Criterion Covered Total %
statement 36 36 100.0
branch 8 8 100.0
condition n/a
subroutine 10 10 100.0
pod 2 2 100.0
total 56 56 100.0


line stmt bran cond sub pod time code
1             package Net::DNS::SEC::RSA;
2              
3 10     10   7969 use strict;
  10         22  
  10         432  
4 10     10   54 use warnings;
  10         22  
  10         1106  
5              
6             our $VERSION = (qw$Id: RSA.pm 2042 2025-12-24 10:23:11Z willem $)[2];
7              
8              
9             =head1 NAME
10              
11             Net::DNS::SEC::RSA - DNSSEC RSA digital signature algorithm
12              
13              
14             =head1 SYNOPSIS
15              
16             require Net::DNS::SEC::RSA;
17              
18             $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private );
19              
20             $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin );
21              
22              
23             =head1 DESCRIPTION
24              
25             Implementation of RSA digital signature
26             generation and verification procedures.
27              
28             =head2 sign
29              
30             $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private );
31              
32             Generates the wire-format signature from the sigdata octet string
33             and the appropriate private key object.
34              
35             =head2 verify
36              
37             $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin );
38              
39             Verifies the signature over the sigdata octet string using the specified
40             public key resource record.
41              
42             =cut
43              
44 10     10   133 use integer;
  10         73  
  10         72  
45 10     10   374 use MIME::Base64;
  10         20  
  10         1013  
46              
47 10     10   78 use constant RSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA');
  10         20  
  10         1043  
48              
49 10     10   5886 BEGIN { die 'RSA disabled or application has no "use Net::DNS::SEC"' unless RSA_configured }
50              
51              
52             my %parameters = (
53             1 => scalar eval { Net::DNS::SEC::libcrypto::EVP_md5() }, ## deprecate DNSSEC entirely
54             5 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, ## MUST NOT DNSSEC sign
55             7 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, ## MUST NOT DNSSEC sign
56             8 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha256() },
57             10 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha512() },
58             );
59              
60 11     11   4879 sub _index { return keys %parameters }
61              
62 11     11   911 sub _deprecate { return ( 1, -5, -7 ) }
63              
64              
65             sub sign {
66 10     10 1 25166 my ( $class, $sigdata, $private ) = @_;
67              
68 10         38 my $evpmd = $parameters{$private->algorithm};
69 10 100       38 die 'unsupported RSA algorithm ', $private->algorithm unless $evpmd;
70              
71 9         33 my @key = qw(Modulus PublicExponent PrivateExponent Prime1 Prime2 Exponent1 Exponent2 Coefficient);
72 9         21 my ( $n, $e, $d, $p1, $p2, $e1, $e2, $c ) = map { decode_base64( $private->$_ ) } @key;
  72         265  
73 9         1117 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $n, $e, $d, $p1, $p2, $e1, $e2, $c );
74              
75 9         28467 return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd );
76             }
77              
78              
79             sub verify {
80 30     30 1 18613 my ( $class, $sigdata, $keyrr, $sigbin ) = @_;
81              
82 30         97 my $evpmd = $parameters{$keyrr->algorithm};
83 30 100       262 die 'unsupported RSA algorithm ', $keyrr->algorithm unless $evpmd;
84              
85 29 100       70 return unless $sigbin;
86              
87 28         65 my $keybin = $keyrr->keybin; # public key
88 28         263 my ( $short, $long ) = unpack( 'Cn', $keybin ); # RFC3110, section 2
89 28 100       84 my $keyfmt = $short ? "x a$short a*" : "x3 a$long a*";
90 28         107 my ( $exponent, $modulus ) = unpack( $keyfmt, $keybin );
91              
92 28         1678 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $modulus, $exponent );
93              
94 28         4305 return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey, $evpmd );
95             }
96              
97              
98             1;
99              
100             __END__