File Coverage

blib/lib/Net/DNS/SEC/EdDSA.pm
Criterion Covered Total %
statement 16 16 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 22 100.0


line stmt bran cond sub pod time code
1             package Net::DNS::SEC::EdDSA;
2              
3 12     12   6326 use strict;
  12         33  
  12         358  
4 12     12   67 use warnings;
  12         26  
  12         597  
5              
6             our $VERSION = (qw$Id: EdDSA.pm 1937 2023-09-11 09:27:16Z willem $)[2];
7              
8              
9             =head1 NAME
10              
11             Net::DNS::SEC::EdDSA - DNSSEC EdDSA digital signature algorithm
12              
13              
14             =head1 SYNOPSIS
15              
16             require Net::DNS::SEC::EdDSA;
17              
18             $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private );
19              
20             $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $sigbin );
21              
22              
23             =head1 DESCRIPTION
24              
25             Implementation of EdDSA Edwards curve digital signature
26             generation and verification procedures.
27              
28             =head2 sign
29              
30             $signature = Net::DNS::SEC::EdDSA->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::EdDSA->verify( $sigdata, $keyrr, $signature );
38              
39             Verifies the signature over the sigdata octet string using the specified
40             public key resource record.
41              
42             =cut
43              
44 12     12   73 use integer;
  12         22  
  12         79  
45 12     12   299 use MIME::Base64;
  12         47  
  12         945  
46              
47 12     12   108 use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA');
  12         45  
  12         913  
48              
49 12     12   553 BEGIN { die 'EdDSA disabled or application has no "use Net::DNS::SEC"' unless EdDSA_configured }
50              
51              
52             my %parameters = (
53             15 => ['ED25519', 32, 64],
54             16 => ['ED448', 57, 114],
55             );
56              
57             sub _index { return keys %parameters }
58              
59              
60             sub sign {
61             my ( $class, $sigdata, $private ) = @_;
62              
63             my $algorithm = $private->algorithm;
64             my ( $curve, $keylen ) = @{$parameters{$algorithm} || []};
65             die 'private key not EdDSA' unless $curve;
66              
67             my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey );
68             my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, '', $rawkey );
69              
70             return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey );
71             }
72              
73              
74             sub verify {
75             my ( $class, $sigdata, $keyrr, $signature ) = @_;
76              
77             my $algorithm = $keyrr->algorithm;
78             my ( $curve, $keylen, $siglen ) = @{$parameters{$algorithm} || []};
79             die 'public key not EdDSA' unless $curve;
80              
81             return unless $signature;
82              
83             my $rawkey = pack "a$keylen", $keyrr->keybin;
84             my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, $rawkey );
85              
86             my $sigbin = pack "a$siglen", $signature;
87             return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey );
88             }
89              
90              
91             my $key448 = decode_base64 '69oJdWluramCzd28zK6E/LIZzL6MxVkQ0drFQ/dyeFQon2Tso03D0jCrP1NZ965ASnIC5N+sgwOA';
92             my $evpkey = eval { Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( 'ED448', $key448 ) };
93             delete $parameters{16} unless defined $evpkey; ## disallow ED448 if using BoringSSL|LibreSSL
94              
95              
96             1;
97              
98             __END__