1package Net::DNS::SEC::ECDSA; 2 3use strict; 4use warnings; 5 6our $VERSION = (qw$Id: ECDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; 7 8 9=head1 NAME 10 11Net::DNS::SEC::ECDSA - DNSSEC ECDSA digital signature algorithm 12 13 14=head1 SYNOPSIS 15 16 require Net::DNS::SEC::ECDSA; 17 18 $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); 19 20 $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); 21 22 23=head1 DESCRIPTION 24 25Implementation of ECDSA elliptic curve digital signature 26generation and verification procedures. 27 28=head2 sign 29 30 $signature = Net::DNS::SEC::ECDSA->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::ECDSA->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 ECDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA'); 48 49BEGIN { die 'ECDSA disabled or application has no "use Net::DNS::SEC"' unless ECDSA_configured } 50 51 52my %parameters = ( 53 13 => [415, 32, Net::DNS::SEC::libcrypto::EVP_sha256()], 54 14 => [715, 48, Net::DNS::SEC::libcrypto::EVP_sha384()], 55 ); 56 57sub _index { return keys %parameters } 58 59 60sub sign { 61 my ( $class, $sigdata, $private ) = @_; 62 63 my $algorithm = $private->algorithm; 64 my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; 65 die 'private key not ECDSA' unless $nid; 66 67 my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); 68 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $nid, $rawkey, '' ); 69 70 my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); 71 return _ASN1decode( $asn1, $keylen ); 72} 73 74 75sub verify { 76 my ( $class, $sigdata, $keyrr, $sigbin ) = @_; 77 78 my $algorithm = $keyrr->algorithm; 79 my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; 80 die 'public key not ECDSA' unless $nid; 81 82 return unless $sigbin; 83 84 my ( $x, $y ) = unpack "a$keylen a$keylen", $keyrr->keybin; 85 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $nid, $x, $y ); 86 87 my $asn1 = _ASN1encode( $sigbin, $keylen ); 88 return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $asn1, $evpkey, $evpmd ); 89} 90 91 92######################################## 93 94sub _ASN1encode { 95 my ( $sig, $size ) = @_; 96 my @part = unpack "a$size a$size", $sig; 97 my $length; 98 foreach (@part) { 99 s/^[\000]+//; 100 s/^$/\000/; 101 s/^(?=[\200-\377])/\000/; 102 $_ = pack 'C2 a*', 2, length, $_; 103 $length += length; 104 } 105 return pack 'C2 a* a*', 0x30, $length, @part; 106} 107 108sub _ASN1decode { 109 my ( $asn1, $size ) = @_; 110 my $n = unpack 'x3 C', $asn1; 111 my $m = unpack "x5 x$n C", $asn1; 112 my @part = unpack "x4 a$n x2 a$m", $asn1; 113 return pack 'a* a*', map { substr( pack( "x$size a*", $_ ), -$size ) } @part; 114} 115 116 1171; 118 119__END__ 120 121######################################## 122 123=head1 ACKNOWLEDGMENT 124 125Thanks are due to Eric Young and the many developers and 126contributors to the OpenSSL cryptographic library. 127 128 129=head1 COPYRIGHT 130 131Copyright (c)2014,2018 Dick Franks. 132 133All rights reserved. 134 135 136=head1 LICENSE 137 138Permission to use, copy, modify, and distribute this software and its 139documentation for any purpose and without fee is hereby granted, provided 140that the original copyright notices appear in all copies and that both 141copyright notice and this permission notice appear in supporting 142documentation, and that the name of the author not be used in advertising 143or publicity pertaining to distribution of the software without specific 144prior written permission. 145 146THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 147IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 148FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 149THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 150LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 151FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 152DEALINGS IN THE SOFTWARE. 153 154 155=head1 SEE ALSO 156 157L<Net::DNS>, L<Net::DNS::SEC>, 158RFC6090, RFC6605, 159L<OpenSSL|http://www.openssl.org/docs> 160 161=cut 162 163