1package Net::DNS::SEC::RSA; 2 3use strict; 4use warnings; 5 6our $VERSION = (qw$Id: RSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; 7 8 9=head1 NAME 10 11Net::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 25Implementation of RSA digital signature 26generation and verification procedures. 27 28=head2 sign 29 30 $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); 31 32Generates the wire-format signature from the sigdata octet string 33and the appropriate private key object. 34 35=head2 verify 36 37 $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); 38 39Verifies the signature over the sigdata octet string using the specified 40public key resource record. 41 42=cut 43 44use integer; 45use MIME::Base64; 46 47use constant RSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA'); 48 49BEGIN { die 'RSA disabled or application has no "use Net::DNS::SEC"' unless RSA_configured } 50 51 52my %parameters = ( 53 1 => Net::DNS::SEC::libcrypto::EVP_md5(), 54 5 => Net::DNS::SEC::libcrypto::EVP_sha1(), 55 7 => Net::DNS::SEC::libcrypto::EVP_sha1(), 56 8 => Net::DNS::SEC::libcrypto::EVP_sha256(), 57 10 => Net::DNS::SEC::libcrypto::EVP_sha512(), 58 ); 59 60sub _index { return keys %parameters } 61 62 63sub sign { 64 my ( $class, $sigdata, $private ) = @_; 65 66 my $index = $private->algorithm; 67 my $evpmd = $parameters{$index} || die 'private key not RSA'; 68 69 my ( $n, $e, $d, $p, $q ) = 70 map { decode_base64( $private->$_ ) } qw(Modulus PublicExponent PrivateExponent Prime1 Prime2); 71 72 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $n, $e, $d, $p, $q ); 73 74 return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); 75} 76 77 78sub verify { 79 my ( $class, $sigdata, $keyrr, $sigbin ) = @_; 80 81 my $index = $keyrr->algorithm; 82 my $evpmd = $parameters{$index} || die 'public key not RSA'; 83 84 return unless $sigbin; 85 86 my $keybin = $keyrr->keybin; # public key 87 my ( $short, $long ) = unpack( 'Cn', $keybin ); # RFC3110, section 2 88 my $keyfmt = $short ? "x a$short a*" : "x3 a$long a*"; 89 my ( $exponent, $modulus ) = unpack( $keyfmt, $keybin ); 90 91 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $modulus, $exponent, '', '', '' ); 92 93 return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey, $evpmd ); 94} 95 96 971; 98 99__END__ 100 101######################################## 102 103=head1 ACKNOWLEDGMENT 104 105Thanks are due to Eric Young and the many developers and 106contributors to the OpenSSL cryptographic library. 107 108 109=head1 COPYRIGHT 110 111Copyright (c)2014,2018 Dick Franks. 112 113All rights reserved. 114 115 116=head1 LICENSE 117 118Permission to use, copy, modify, and distribute this software and its 119documentation for any purpose and without fee is hereby granted, provided 120that the original copyright notices appear in all copies and that both 121copyright notice and this permission notice appear in supporting 122documentation, and that the name of the author not be used in advertising 123or publicity pertaining to distribution of the software without specific 124prior written permission. 125 126THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 127IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 128FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 129THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 130LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 131FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 132DEALINGS IN THE SOFTWARE. 133 134 135=head1 SEE ALSO 136 137L<Net::DNS>, L<Net::DNS::SEC>, 138RFC8017, RFC3110, 139L<OpenSSL|http://www.openssl.org/docs> 140 141=cut 142 143