File Coverage

blib/lib/Net/DNS/SEC/EdDSA.pm
Criterion Covered Total %
statement 35 35 100.0
branch 10 10 100.0
condition n/a
subroutine 9 9 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::EdDSA;
2              
3 10     10   8140 use strict;
  10         20  
  10         407  
4 10     10   81 use warnings;
  10         23  
  10         936  
5              
6             our $VERSION = (qw$Id: EdDSA.pm 2002 2025-01-07 09:57:46Z 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 10     10   184 use integer;
  10         59  
  10         161  
45 10     10   336 use MIME::Base64;
  10         20  
  10         964  
46              
47 10     10   116 use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA');
  10         20  
  10         1015  
48              
49 10     10   5159 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 11     11   456 sub _index { return keys %parameters }
58              
59              
60             sub sign {
61 3     3 1 19850 my ( $class, $sigdata, $private ) = @_;
62              
63 3         15 my $algorithm = $private->algorithm;
64 3 100       8 my ( $curve, $keylen ) = @{$parameters{$algorithm} || []};
  3         27  
65 3 100       21 die 'private key not EdDSA' unless $curve;
66              
67 2         23 my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey );
68 2         2223 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, '', $rawkey );
69              
70 2         1243 return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey );
71             }
72              
73              
74             sub verify {
75 6     6 1 3230 my ( $class, $sigdata, $keyrr, $signature ) = @_;
76              
77 6         41 my $algorithm = $keyrr->algorithm;
78 6 100       77 my ( $curve, $keylen, $siglen ) = @{$parameters{$algorithm} || []};
  6         35  
79 6 100       28 die 'public key not EdDSA' unless $curve;
80              
81 5 100       18 return unless $signature;
82              
83 4         34 my $rawkey = pack "a$keylen", $keyrr->keybin;
84 4         224 my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, $rawkey );
85              
86 4         24 my $sigbin = pack "a$siglen", $signature;
87 4         3004 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__