Net-DNS-SEC-1.15/0000755000175000017500000000000013616025777012602 5ustar willemwillemNet-DNS-SEC-1.15/META.json0000644000175000017500000000226013616025777014223 0ustar willemwillem{ "abstract" : "DNSSEC extensions to Net::DNS", "author" : [ "Dick Franks", "Olaf Kolkman" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010", "license" : [ "mit" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-DNS-SEC", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "recommends" : {}, "requires" : { "DynaLoader" : "1.04", "File::Find" : "1.05", "File::Spec" : "0.86", "IO::File" : "1.08", "MIME::Base64" : "2.13", "Net::DNS" : "1.08", "Test::More" : "0.47", "perl" : "5.006" } } }, "release_status" : "stable", "version" : "1.15", "x_serialization_backend" : "JSON::PP version 2.97001" } Net-DNS-SEC-1.15/lib/0000755000175000017500000000000013616025777013350 5ustar willemwillemNet-DNS-SEC-1.15/lib/Net/0000755000175000017500000000000013616025777014076 5ustar willemwillemNet-DNS-SEC-1.15/lib/Net/DNS/0000755000175000017500000000000013616025777014522 5ustar willemwillemNet-DNS-SEC-1.15/lib/Net/DNS/SEC.pm0000644000175000017500000000720413616025670015465 0ustar willemwillempackage Net::DNS::SEC; # # $Id: SEC.pm 1766 2020-02-03 14:17:59Z willem $ # our $VERSION; $VERSION = '1.15'; our $SVNVERSION = (qw$LastChangedRevision: 1766 $)[1]; our $XS_VERSION = $VERSION; $VERSION = eval $VERSION; =head1 NAME Net::DNS::SEC - DNSSEC extensions to Net::DNS =head1 SYNOPSIS use Net::DNS::SEC; =head1 DESCRIPTION Net::DNS::SEC is installed as an extension to an existing Net::DNS installation providing packages to support DNSSEC as specified in RFC4033, RFC4034, RFC4035 and related documents. It also provides support for SIG0 which is useful for dynamic updates. Implements cryptographic signature generation and verification functions using RSA, DSA, ECDSA, and Edwards curve algorithms. The extended features are made available by replacing Net::DNS by Net::DNS::SEC in the use declaration. =cut use strict; use base qw(Exporter DynaLoader); use Net::DNS 1.01 qw(:DEFAULT); our @EXPORT = ( @Net::DNS::EXPORT, qw(algorithm digtype key_difference) ); use integer; use warnings; use Carp; =head1 UTILITY FUNCTIONS =head2 algorithm $mnemonic = algorithm( 5 ); $numeric = algorithm( 'RSA-SHA1' ); print "algorithm mnemonic\t", $mnemonic, "\n"; print "algorithm number:\t", $numeric, "\n"; algorithm() provides conversions between an algorithm code number and the corresponding mnemonic. =cut sub algorithm { &Net::DNS::RR::DS::algorithm; } =head2 digtype $mnemonic = digtype( 2 ); $numeric = digtype( 'SHA-256' ); print "digest type mnemonic\t", $mnemonic, "\n"; print "digest type number:\t", $numeric, "\n"; digtype() provides conversions between a digest type number and the corresponding mnemonic. =cut sub digtype { &Net::DNS::RR::DS::digtype; } =head2 key_difference @result = key_difference( \@a, \@b ); Fills @result with all keys in array @a that are not in array @b. =cut sub key_difference { my $a = shift; my $b = shift; my $r = shift || []; ## 0.17 interface eval { local $SIG{__DIE__}; my ($x) = grep !$_->isa('Net::DNS::RR::DNSKEY'), @$a, @$b; die sprintf 'unexpected %s object in key list', ref($x) if $x; my %index = map { ( $_->privatekeyname => 1 ) } @$b; @$r = grep !$index{$_->privatekeyname}, @$a; 1; } || do { croak($@) if wantarray; }; return wantarray ? (@$r) : $@; } ######################################## eval { Net::DNS::SEC->bootstrap($XS_VERSION) } || warn; foreach (qw(DS CDS RRSIG)) { new Net::DNS::RR( type => $_ ); # pre-load to access class methods } 1; __END__ =head1 COPYRIGHT Copyright (c)2014-2018 Dick Franks Copyright (c)2001-2005 RIPE NCC. Author Olaf M. Kolkman All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC4033, RFC4034, RFC4035, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/0000755000175000017500000000000013616025777015134 5ustar willemwillemNet-DNS-SEC-1.15/lib/Net/DNS/SEC/libcrypto.pod0000644000175000017500000000305713616025670017644 0ustar willemwillempackage Net::DNS::SEC::libcrypto; # # $Id: libcrypto.pod 1616 2018-01-22 08:54:52Z willem $ # =head1 NAME Net::DNS::SEC::libcrypto - Perl interface to OpenSSL libcrypto =head1 DESCRIPTION Perl XS extension providing access to the OpenSSL libcrypto library upon which the Net::DNS::SEC cryptographic components are built. =cut 1; __END__ =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/Private.pm0000644000175000017500000001167113616025670017102 0ustar willemwillempackage Net::DNS::SEC::Private; # # $Id: Private.pm 1705 2018-08-23 10:24:02Z willem $ # our $VERSION = (qw$LastChangedRevision: 1705 $)[1]; =head1 NAME Net::DNS::SEC::Private - DNSSEC Private key object =head1 SYNOPSIS use Net::DNS::SEC::Private; $private = new Net::DNS::SEC::Private( $keypath ); $private = new Net::DNS::SEC::Private( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); =head1 DESCRIPTION Class representing private keys as read from a keyfile generated by BIND dnssec-keygen. The class is written to be used only in the context of the Net::DNS::RR::RRSIG create method. This class is not designed to interact with any other system. =cut use strict; use integer; use warnings; use File::Spec; use IO::File; sub new { scalar(@_) > 2 ? &_new_params : &_new_keyfile } sub _new_keyfile { my ( $class, $file ) = @_; my ( $vol, $dir, $keyname ) = File::Spec->splitpath($file); # Format something like: /Kbla.foo.+001+12345.private' # as created by BIND keygen. # We determine the algorithm from the filename. die "$keyname does not appear to be a BIND private key" unless $keyname =~ /^K(.*\.)\+(\d+)\+(\d+)\.private$/; my @identifier = ( signame => $1, algorithm => 0 + $2, keytag => 0 + $3 ); my $handle = new IO::File($file) or die qq(open: "$file" $!); my @content; local $_; while (<$handle>) { chomp; next if /^$/; next if /^\s*[;]/; s/\(.+\)//; my ( $name, $value ) = split; push @content, $name, $value; } return $class->_new_params( @content, @identifier ); } sub _new_params { my $class = shift; my $param = {}; while (@_) { my $name = shift @_; $name =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; $param->{$name} = shift @_; } my $self = bless sub { $param->{shift()} }, $class; die 'no algorithm specified' unless $self->algorithm; die 'no signame specified' unless $self->signame; return $self; } our $AUTOLOAD; sub AUTOLOAD { ## Default method my ($self) = @_; no strict q/refs/; my ($attribute) = $AUTOLOAD =~ m/::([^:]*)$/; $attribute =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; # Build a method in the class *{$AUTOLOAD} = sub { &{shift()}($attribute) }; # and jump to it goto &{$AUTOLOAD}; } 1; __END__ =head1 METHODS =head2 new (from private keyfile) $keypath = '/home/foo/Kexample.com.+013+26512.private'; $private = new Net::DNS::SEC::Private( $keypath ); The argument is the full path to a private key file generated by the BIND dnssec-keygen tool. Note that the filename contains information about the algorithm and keytag. =head2 new (from private key parameters) $private = new Net::DNS::SEC::Private( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); The arguments define the private key parameters as (name,value) pairs. The name and data representation are identical to that used in a BIND private keyfile. =head2 private_key_format $format = $private->private_key_format; Returns a string which identifies the format of the private key file. =head2 algorithm, keytag, signame $algorithm = $private->algorithm; $keytag = $private->keytag; $signame = $private->signame; Returns the corresponding attribute determined from the filename. =head2 Private key attributes $attribute = $private->attribute; Returns the value as it appears in the private key file. The attribute names correspond to the tag in the key file, modified to form an acceptable Perl subroutine name. =head2 created, publish, activate $created = $private->created; $publish = $private->publish; $activate = $private->activate; Returns a string which represents a date in the form 20141212123456. Returns undefined value for key formats older than v1.3. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/DSA.pm0000644000175000017500000001076213616025670016077 0ustar willemwillempackage Net::DNS::SEC::DSA; # # $Id: DSA.pm 1763 2020-02-02 21:48:03Z willem $ # our $VERSION = (qw$LastChangedRevision: 1763 $)[1]; =head1 NAME Net::DNS::SEC::DSA - DNSSEC DSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::DSA; $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of DSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use strict; use integer; use warnings; use MIME::Base64; use constant DSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_DSA'); BEGIN { die 'DSA disabled or application has no "use Net::DNS::SEC"' unless DSA_configured } my %parameters = ( 3 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, 6 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, ); sub _index { keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $index = $private->algorithm; my $evpmd = $parameters{$index} || die 'private key not DSA'; my ( $p, $q, $g, $x, $y ) = map decode_base64( $private->$_ ), qw(prime subprime base private_value public_value); my $t = ( length($g) - 64 ) / 8; my $dsa = Net::DNS::SEC::libcrypto::DSA_new(); Net::DNS::SEC::libcrypto::DSA_set0_pqg( $dsa, $p, $q, $g ); Net::DNS::SEC::libcrypto::DSA_set0_key( $dsa, $y, $x ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_DSA( $evpkey, $dsa ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, &$evpmd ); _ASN1decode( $asn1, $t ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $index = $keyrr->algorithm; my $evpmd = $parameters{$index} || die 'public key not DSA'; return unless $sigbin; my $key = $keyrr->keybin; # public key my $len = 64 + 8 * unpack( 'C', $key ); # RFC2536, section 2 my ( $q, $p, $g, $y ) = unpack "x a20 a$len a$len a$len", $key; my $dsa = Net::DNS::SEC::libcrypto::DSA_new(); Net::DNS::SEC::libcrypto::DSA_set0_pqg( $dsa, $p, $q, $g ); Net::DNS::SEC::libcrypto::DSA_set0_key( $dsa, $y, '' ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_DSA( $evpkey, $dsa ); my $asn1 = _ASN1encode($sigbin); Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $asn1, $evpkey, &$evpmd ); } ######################################## sub _ASN1encode { my @part = unpack 'x a20 a20', shift; # discard "t" my $length; foreach (@part) { s/^[\000]+//; s/^$/\000/; s/^(?=[\200-\377])/\000/; $_ = pack 'C2 a*', 2, length, $_; $length += length; } pack 'C2 a* a*', 0x30, $length, @part; } sub _ASN1decode { my ( $asn1, $t ) = @_; my $n = unpack 'x3 C', $asn1; my $m = unpack "x5 x$n C", $asn1; my @part = unpack "x4 a$n x2 a$m", $asn1; pack 'C a* a*', $t, map substr( pack( 'x20 a*', $_ ), -20 ), @part; } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC2536, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/Digest.pm0000644000175000017500000001004513616025670016701 0ustar willemwillempackage Net::DNS::SEC::Digest; # # $Id: Digest.pm 1763 2020-02-02 21:48:03Z willem $ # our $VERSION = (qw$LastChangedRevision: 1763 $)[1]; =head1 NAME Net::DNS::SEC::Digest - Message Digest Algorithms =head1 SYNOPSIS require Net::DNS::SEC::Digest; $object = new Net::DNS::SEC::Digest::SHA(256); $object->add($text); $object->add($more); $digest = $object->digest; =head1 DESCRIPTION Interface package providing access to the message digest algorithm implementations within the OpenSSL libcrypto library. =cut use strict; use integer; use warnings; use constant libcrypto_available => Net::DNS::SEC::libcrypto->can('EVP_MD_CTX_new'); BEGIN { die 'Net::DNS::SEC not available' unless libcrypto_available } my %sha = ( 1 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, 224 => sub { Net::DNS::SEC::libcrypto::EVP_sha224() }, 256 => sub { Net::DNS::SEC::libcrypto::EVP_sha256() }, 384 => sub { Net::DNS::SEC::libcrypto::EVP_sha384() }, 512 => sub { Net::DNS::SEC::libcrypto::EVP_sha512() }, ); my %sha3 = ( 224 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_224() }, 256 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_256() }, 384 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_384() }, 512 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_512() }, ); package Net::DNS::SEC::Digest::SHA; sub new { my ( $class, $alg ) = @_; my $mdobj = Net::DNS::SEC::libcrypto::EVP_MD_CTX_new(); my $evpmd = $sha{$alg}; Net::DNS::SEC::libcrypto::EVP_DigestInit( $mdobj, &$evpmd ); bless( \$mdobj, $class ); } sub add { my $object = shift; Net::DNS::SEC::libcrypto::EVP_DigestUpdate( $$object, shift ); } sub digest { my $object = shift; Net::DNS::SEC::libcrypto::EVP_DigestFinal($$object); } DESTROY { my $object = shift; Net::DNS::SEC::libcrypto::EVP_MD_CTX_free($$object); } package Net::DNS::SEC::Digest::SHA3; our @ISA = qw(Net::DNS::SEC::Digest::SHA); sub new { my ( $class, $alg ) = @_; my $mdobj = Net::DNS::SEC::libcrypto::EVP_MD_CTX_new(); my $evpmd = $sha3{$alg}; Net::DNS::SEC::libcrypto::EVP_DigestInit( $mdobj, &$evpmd ); bless( \$mdobj, $class ); } package Net::DNS::SEC::Digest::MD5; our @ISA = qw(Net::DNS::SEC::Digest::SHA); sub new { my ( $class, $alg ) = @_; my $mdobj = Net::DNS::SEC::libcrypto::EVP_MD_CTX_new(); my $evpmd = sub { Net::DNS::SEC::libcrypto::EVP_md5() }; Net::DNS::SEC::libcrypto::EVP_DigestInit( $mdobj, &$evpmd ); bless( \$mdobj, $class ); } 1; __END__ ######################################## =head1 METHODS =head2 new require Net::DNS::SEC::Digest; $object = new Net::DNS::SEC::Digest::SHA( $algorithm ); Creates and initialises a new digest object instance for the specified algorithm. =head2 add $object->add($text); $object->add($more); Append specified text to digest stream. =head2 digest $digest = $object->digest; Returns the digest encoded as a binary string. =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2020 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/EdDSA.pm0000644000175000017500000000665513616025670016356 0ustar willemwillempackage Net::DNS::SEC::EdDSA; # # $Id: EdDSA.pm 1758 2019-10-14 13:17:11Z willem $ # our $VERSION = (qw$LastChangedRevision: 1758 $)[1]; =head1 NAME Net::DNS::SEC::EdDSA - DNSSEC EdDSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::EdDSA; $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of EdDSA Edwards curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $signature ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use strict; use integer; use warnings; use MIME::Base64; use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_public_key'); BEGIN { die 'EdDSA disabled or application has no "use Net::DNS::SEC"' unless EdDSA_configured } my %parameters = ( 15 => [1087, 32, 64], 16 => [1088, 57, 114], ); sub _index { keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; my ( $nid, $keylen ) = @{$parameters{$algorithm} || []}; die 'private key not EdDSA' unless $keylen; my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_raw_private_key( $nid, $rawkey ); Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey ); } sub verify { my ( $class, $sigdata, $keyrr, $signature ) = @_; my $algorithm = $keyrr->algorithm; my ( $nid, $keylen, $siglen ) = @{$parameters{$algorithm} || []}; die 'public key not EdDSA' unless $keylen; return unless $signature; my $rawkey = pack "a$keylen", $keyrr->keybin; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_raw_public_key( $nid, $rawkey ); my $sigbin = pack "a$siglen", $signature; Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey ); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC8032, RFC8080, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/Keyset.pm0000644000175000017500000002132613616025670016732 0ustar willemwillempackage Net::DNS::SEC::Keyset; # # $Id: Keyset.pm 1705 2018-08-23 10:24:02Z willem $ # our $VERSION = (qw$LastChangedRevision: 1705 $)[1]; =head1 NAME Net::DNS::SEC::Keyset - DNSSEC Keyset object class =head1 SYNOPSIS use Net::DNS::SEC::Keyset; =head1 DESCRIPTION A keyset is an "administrative" unit used for DNSSEC maintenance. This class provides interfaces for creating, reading and writing keysets. Object methods are provided to extract DNSKEY, RRSIG and DS records. Note that this class is still being developed. Attributes and methods are subject to change. =cut use strict; use integer; use warnings; use Carp; use File::Spec::Functions; use Net::DNS::ZoneFile; our $keyset_err; sub new { my ( $class, $arg1, $arg2 ) = @_; my $ref1 = ref($arg1); return &_new_from_file unless $ref1; return &_new_from_packet if $ref1 eq 'Net::DNS::Packet'; return &_new_from_keys unless ref($arg2); return &_new_from_keys_sigs; } =head2 new (from file) $keyset = Net::DNS::SEC::Keyset->new( $filename ); $keyset = Net::DNS::SEC::Keyset->new( $filename, $directory ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Constructor method which reads the specified keyset file and returns a keyset object. The optional second argument specifies the filename base directory. Sets keyset_err and returns undef on failure. =cut sub _new_from_file { my ( $class, $name, @path ) = @_; my $file = catfile( @path, $name ); my @rr = new Net::DNS::ZoneFile($file)->read; return $class->_new_from_keys_sigs( \@rr, \@rr ); } =head2 new (by signing keys) $keyset = Net::DNS::SEC::Keyset->new( [@keyrr], $privatekeypath ); Creates a keyset object from the keys provided through the reference to an array of Net::DNS::RR::DNSKEY objects. The method will create and self-sign the whole keyset. The private keys as generated by the BIND dnssec-keygen tool are assumed to be in the current directory or, if specified, the directory indicated by $privatekeypath. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys { my ( $class, $keylist, @keypath ) = @_; my @sigrr; foreach my $key ( grep $_->type eq 'DNSKEY', @$keylist ) { my $keyname = $key->privatekeyname; my $keyfile = catfile( @keypath, $keyname ); my @rrsig = Net::DNS::RR::RRSIG->create( $keylist, $keyfile ); push @sigrr, grep defined, @rrsig; } return $class->_new_from_keys_sigs( $keylist, \@sigrr ); } =head2 new (from key and sig RRsets) $keyset = Net::DNS::Keyset->new( [@keyrr], [@sigrr] ); Creates a keyset object from the keys provided through the references to arrays of Net::DNS::RR::DNSKEY and Net::DNS::RR::RRSIG objects. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys_sigs { my ( $class, $key_ref, $sig_ref ) = @_; my @keyrr = grep $_->type eq 'DNSKEY', @$key_ref; my @sigrr = grep $_->type eq 'RRSIG', @$sig_ref; my $keyset = bless {keys => \@keyrr, sigs => \@sigrr}, $class; return scalar( $keyset->verify ) ? $keyset : undef; } =head2 new (from Packet) $res = Net::DNS::Resolver->new; $res->dnssec(1); $packet = $res->query ( "example.com", "DNSKEY", "IN" ); $keyset = Net::DNS::SEC::Keyset->new( $packet ) Creates a keyset object from a Net::DNS::Packet that contains the answer to a query for the apex key records. This is the method you should use for automatically fetching keys. Sets keyset_err and returns undef on failure. =cut sub _new_from_packet { my ( $class, $packet ) = @_; my @rrset = $packet->answer; return $class->_new_from_keys_sigs( \@rrset, \@rrset ); } =head2 keys @keyrr = $keyset->keys; Returns an array of Net::DNS::RR::DNSKEY objects. =cut sub keys { my $self = shift; my @keys = @{$self->{keys}}; } =head2 sigs @sigrr = $keyset->sigs; Returns an array of Net::DNS::RR::RRSIG objects. =cut sub sigs { my $self = shift; my @sigs = @{$self->{sigs}}; } =head2 extract_ds @ds = $keyset->extract_ds; die $keyset->keyset_err unless @ds; Extracts DS records from the keyset. Note that the keyset will be verified during extraction. All keys will need to have a valid self-signature. The method sets keyset_err if verification fails. =cut sub extract_ds { my $self = shift; my @ds; @ds = map Net::DNS::RR::DS->create($_), $self->keys if $self->verify; return @ds; } =head2 verify @keytags = $keyset->verify(); die $keyset->keyset_err unless @keytags; $keyset->verify( $keytag ) || die $keyset->keyset_err; If no arguments are given: =over 2 =item Verifies if all signatures present verify the keyset. =item Verifies if there are DNSKEYs with the SEP flag set, there is at least one RRSIG made using that key. =item Verifies that if there are no DNSKEYs with the SEP flag set there is at least one RRSIG made with one of the keys from the keyset. =back If an argument is given, it is should be the numeric keytag of the key in the keyset which will be verified using the corresponding RRSIG. The method returns a list of keytags of verified keys in the keyset. The method sets keyset_err and returns empty list if verification fails. =cut sub verify { my ( $self, $keyid ) = @_; my @keys = $self->keys; my %keysbytag; push( @{$keysbytag{$_->keytag}}, $_ ) foreach @keys; my @sigs = $self->sigs; my @keyset_err; my %names = map { ( $_->name => $_ ) } @keys, @sigs; my @names = CORE::keys %names; push @keyset_err, "Multiple names in keyset: @names" if scalar(@names) > 1; if ($keyid) { @sigs = grep $_->keytag == $keyid, @sigs; push @keyset_err, "No signature made with $keyid found" unless @sigs; } elsif ( my @sepkeys = grep $_->sep, @keys ) { my %sepkey = map { ( $_->keytag => $_ ) } @sepkeys; push @keyset_err, 'No signature found for key with SEP flag' unless grep $sepkey{$_->keytag}, @sigs; } foreach my $sig (@sigs) { my $keytag = $sig->keytag; next if $sig->verify( \@keys, $keysbytag{$keytag} || [] ); my $vrfyerr = $sig->vrfyerrstr; my $signame = $sig->signame; push @keyset_err, "$vrfyerr on key $signame $keytag "; } $keyset_err = join "\n", @keyset_err; my @tags_verified; @tags_verified = map $_->keytag, @sigs unless $keyset_err; return @tags_verified; } =head2 keyset_err $keyset_err = Net::DNS::SEC::Keyset->keyset_err; $keyset_err = $keyset->keyset_err; Returns the keyset error string. =cut sub keyset_err { return $keyset_err; } =head2 string $string = $keyset->string; Returns a string representation of the keyset. =cut sub string { my $self = shift; return join "\n", map $_->string, ( $self->keys, $self->sigs ); } =head2 print $keyset->print; # similar to print( $keyset->string ) Prints the keyset. =cut sub print { my $self = shift; foreach ( $self->keys, $self->sigs ) { $_->print } } =head2 writekeyset $keyset->writekeyset; $keyset->writekeyset( $path ); $keyset->writekeyset( $prefix ); $keyset->writekeyset( $prefix, $path ); Writes the keyset to a file named "keyset-." in the current working directory or directory defined by the optional $path argument. The optional $prefix argument specifies the prefix that will be prepended to the domain name to form the keyset filename. =cut sub writekeyset { my $self = shift; my ( $arg1, @path ) = @_; @path = shift() if $arg1 && file_name_is_absolute($arg1); my $prefix = shift || 'keyset-'; my @keysetrr = ( $self->keys, $self->sigs ); my $domainname = $keysetrr[0]->name; my $keysetname = "$prefix$domainname."; my $filename = catfile( @path, $keysetname ); $filename =~ s/[.]+/\./; ## avoid antisocial consequences of $path with .. open( KEYSET, ">$filename" ) or croak qq(open: "$filename" $!); select( ( select(KEYSET), $self->print )[0] ); close(KEYSET); return $filename; } 1; __END__ =head1 COPYRIGHT Copyright (c)2002 RIPE NCC. Author Olaf M. Kolkman Portions Copyright (c)2014 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/ECCGOST.pm0000644000175000017500000000600313616025670016550 0ustar willemwillempackage Net::DNS::SEC::ECCGOST; # # $Id: ECCGOST.pm 1758 2019-10-14 13:17:11Z willem $ # our $VERSION = (qw$LastChangedRevision: 1758 $)[1]; =head1 NAME Net::DNS::SEC::ECCGOST - DNSSEC ECC-GOST digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::ECCGOST; $validated = Net::DNS::SEC::ECCGOST->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of GOST R 34.10-2001 elliptic curve digital signature verification procedure. =head2 sign Signature generation is not implemented. =head2 verify $validated = Net::DNS::SEC::ECCGOST->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the binary sigdata using the specified public key resource record. =cut use strict; use integer; use warnings; use constant Digest_GOST => defined( eval 'require Digest::GOST::CryptoPro' ); use constant ECCGOST_configured => Digest_GOST && Net::DNS::SEC::libcrypto->can('ECCGOST_verify'); BEGIN { die 'ECCGOST disabled or application has no "use Net::DNS::SEC"' unless ECCGOST_configured } my %parameters = ( 12 => [840, 'Digest::GOST::CryptoPro'] ); sub _index { keys %parameters } sub sign { die 'Russian Federation standard GOST R 34.10-2001 is obsolete'; } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; my ( $nid, $object ) = @{$parameters{$algorithm} || []}; die 'public key not ECC-GOST' unless $nid; my $hash = $object->new(); $hash->add($sigdata); my $H = reverse $hash->digest; return unless $sigbin; my $eckey = Net::DNS::SEC::libcrypto::EC_KEY_new_ECCGOST(); my ( $y, $x ) = unpack 'a32 a32', reverse $keyrr->keybin; # public key Net::DNS::SEC::libcrypto::EC_KEY_set_public_key_affine_coordinates( $eckey, $x, $y ); my ( $s, $r ) = unpack 'a32 a32', $sigbin; # RFC5933, RFC4490 Net::DNS::SEC::libcrypto::ECCGOST_verify( $H, $r, $s, $eckey ); } 1; __END__ ######################################## =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, RFC4357, RFC4490, RFC5832, RFC5933, RFC7091 =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/ECDSA.pm0000644000175000017500000001075313616025670016307 0ustar willemwillempackage Net::DNS::SEC::ECDSA; # # $Id: ECDSA.pm 1758 2019-10-14 13:17:11Z willem $ # our $VERSION = (qw$LastChangedRevision: 1758 $)[1]; =head1 NAME Net::DNS::SEC::ECDSA - DNSSEC ECDSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::ECDSA; $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of ECDSA elliptic curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use strict; use integer; use warnings; use MIME::Base64; use constant ECDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_EC_KEY'); BEGIN { die 'ECDSA disabled or application has no "use Net::DNS::SEC"' unless ECDSA_configured } my %parameters = ( 13 => [415, 32, sub { Net::DNS::SEC::libcrypto::EVP_sha256() }], 14 => [715, 48, sub { Net::DNS::SEC::libcrypto::EVP_sha384() }], ); sub _index { keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; die 'private key not ECDSA' unless $nid; my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); my $eckey = Net::DNS::SEC::libcrypto::EC_KEY_new_by_curve_name($nid); Net::DNS::SEC::libcrypto::EC_KEY_set_private_key( $eckey, $rawkey ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_EC_KEY( $evpkey, $eckey ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, &$evpmd ); _ASN1decode( $asn1, $keylen ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; die 'private key not ECDSA' unless $nid; return unless $sigbin; my $eckey = Net::DNS::SEC::libcrypto::EC_KEY_new_by_curve_name($nid); my ( $x, $y ) = unpack "a$keylen a$keylen", $keyrr->keybin; Net::DNS::SEC::libcrypto::EC_KEY_set_public_key_affine_coordinates( $eckey, $x, $y ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_EC_KEY( $evpkey, $eckey ); my $asn1 = _ASN1encode( $sigbin, $keylen ); Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $asn1, $evpkey, &$evpmd ); } ######################################## sub _ASN1encode { my ( $sig, $size ) = @_; my @part = unpack "a$size a$size", $sig; my $length; foreach (@part) { s/^[\000]+//; s/^$/\000/; s/^(?=[\200-\377])/\000/; $_ = pack 'C2 a*', 2, length, $_; $length += length; } pack 'C2 a* a*', 0x30, $length, @part; } sub _ASN1decode { my ( $asn1, $size ) = @_; my $n = unpack 'x3 C', $asn1; my $m = unpack "x5 x$n C", $asn1; my @part = unpack "x4 a$n x2 a$m", $asn1; pack 'a* a*', map substr( pack( "x$size a*", $_ ), -$size ), @part; } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC6090, RFC6605, L =cut Net-DNS-SEC-1.15/lib/Net/DNS/SEC/RSA.pm0000644000175000017500000001006413616025670016110 0ustar willemwillempackage Net::DNS::SEC::RSA; # # $Id: RSA.pm 1763 2020-02-02 21:48:03Z willem $ # our $VERSION = (qw$LastChangedRevision: 1763 $)[1]; =head1 NAME Net::DNS::SEC::RSA - DNSSEC RSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::RSA; $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of RSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use strict; use integer; use warnings; use MIME::Base64; use constant RSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA'); BEGIN { die 'RSA disabled or application has no "use Net::DNS::SEC"' unless RSA_configured } my %parameters = ( 1 => sub { Net::DNS::SEC::libcrypto::EVP_md5() }, 5 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, 7 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, 8 => sub { Net::DNS::SEC::libcrypto::EVP_sha256() }, 10 => sub { Net::DNS::SEC::libcrypto::EVP_sha512() }, ); sub _index { keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $index = $private->algorithm; my $evpmd = $parameters{$index} || die 'private key not RSA'; my ( $n, $e, $d, $p, $q ) = map decode_base64( $private->$_ ), qw(Modulus PublicExponent PrivateExponent Prime1 Prime2); my $rsa = Net::DNS::SEC::libcrypto::RSA_new(); Net::DNS::SEC::libcrypto::RSA_set0_factors( $rsa, $p, $q ); Net::DNS::SEC::libcrypto::RSA_set0_key( $rsa, $n, $e, $d ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_RSA( $evpkey, $rsa ); Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, &$evpmd ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $index = $keyrr->algorithm; my $evpmd = $parameters{$index} || die 'public key not RSA'; return unless $sigbin; my $keybin = $keyrr->keybin; # public key my ( $short, $long ) = unpack( 'Cn', $keybin ); # RFC3110, section 2 my $keyfmt = $short ? "x a$short a*" : "x3 a$long a*"; my ( $exponent, $modulus ) = unpack( $keyfmt, $keybin ); my $rsa = Net::DNS::SEC::libcrypto::RSA_new(); Net::DNS::SEC::libcrypto::RSA_set0_key( $rsa, $modulus, $exponent, '' ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new(); Net::DNS::SEC::libcrypto::EVP_PKEY_assign_RSA( $evpkey, $rsa ); Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey, &$evpmd ); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC8017, RFC3110, L =cut Net-DNS-SEC-1.15/README0000644000175000017500000001223413616025670013454 0ustar willemwillemNet::DNS::SEC - DNSSEC extensions to Net::DNS ============================================= 1. DESCRIPTION ----------- This module is designed as an extension the Net::DNS package (https://metacpan.org/release/Net-DNS). The module implements the cryptographic signature generation and verification functions that are relevant for DNSSEC operations. ** ** *************** ** ** WARNING ** ** *************** ** THE USE AND/OR HANDLING OF STRONG ENCRYPTION TECHNOLOGIES IS ** PROHIBITED OR SEVERELY RESTRICTED IN MANY TERRITORIES. ** PLEASE BE SURE THAT YOU FULLY UNDERSTAND THE LEGAL POSITION ** IN YOUR COUNTRY BEFORE ATTEMPTING TO INSTALL THIS MODULE OR ** ANY OF THE PREREQUISITE CRYPTOGRAPHY PACKAGES. ** Net::DNS::SEC also provides a class for handling keysets. Keysets are administrative files used by the BIND tools for key maintenance tasks. Net::DNS::SEC::Keyset provides an abstract interface for doing fun things with them. See also the 'pod' documentation in: Net::DNS::RR::DNSKEY Net::DNS::RR::DS Net::DNS::RR::NSEC Net::DNS::RR::NSEC3 Net::DNS::RR::RRSIG Net::DNS::SEC::Private and for the use of SIG0 see: Net::DNS::Packet (sign_sig0) Net::DNS::RR::SIG 2. AVAILABILITY ------------ You can get the latest version of Net::DNS::SEC from the Comprehensive Perl Archive Network (CPAN): https://metacpan.org/release/Net-DNS-SEC or through http://www.net-dns.org/ Additionally a subversion repository is made available through http://www.net-dns.org/svn/net-dns-sec/ The version on the "trunk" (http://www.net-dns.org/svn/net-dns-sec/trunk) is the version that is targeted for next release. Please note that the SVN version at any given moment may be broken. 3. PREREQUISITES ------------- This package relies on Net-DNS version 1.01 or later which has features specifically designed to support Net::DNS::SEC. The availability of prerequisites for Net::DNS::SEC is tested at installation time. These are the packages that need to be available: File::Find File::Spec MIME::Base64 Test::More The cryptographic heavy lifting is performed using the OpenSSL libcrypto library distributed under separate license. You will also require a C compiler. 4. INSTALLATION ------------ Please install any modules mentioned in the PREREQUISITES section above. When you run "perl Makefile.PL", Perl should complain if any of the required modules is missing. To build this module, run the following commands: tar xvzf Net-DNS-SEC-1.??.tar.gz cd Net-DNS-SEC-1.?? perl Makefile.PL make make test make install 'make test' will do some tests that should all succeed once all dependencies are satisfied. Please report any failure during the test phase. Alternatively, install the package using CPAN: perl -MCPAN -e shell; cpan> install Net::DNS::SEC To build the libcrypto.so library, run the following: tar xvzf openssl-1.1.*.tar.gz cd openssl-1.1.* ./config shared make # require only libcrypto.so.1.1 and include/openssl/*.h 5. MAINTENANCE ----------- Please use the CPAN request tracker to report bugs in the extensions. The request tracker is available through: https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-DNS-SEC 6. STAYING UP TO DATE ------------------ Announcements about Net::DNS::SEC will be published on http://www.net-dns.org/blog/. An RSS feed is available. 7. DEMOS ----- demo/getkeyset.pl A small demonstration program that will fetch the keyset for a specified domain, store the keys and print DS RRs to STDOUT. demo/key2ds Reads the key data from STDIN and prints the corresponding DS record on STDOUT. Contributed by Miek Gieben demo/make-signed-keyset Creates a self-signed keyset from a BIND public key specified on the command line. Contributed by Wes Griffin 8. ACKNOWLEDGEMENTS ---------------- Thanks are due to Eric Young and the many developers and contributors to the OpenSSL project and cryptographic library. 9. COPYRIGHT --------- Authorship of individual components and significant contributions is shown in the copyright notice attached to the relevant documentation. Copyright in all components is retained by their respective authors. 10. LICENSE ------- Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ $Id: README 1677 2018-05-22 11:59:10Z willem $ Net-DNS-SEC-1.15/Changes0000644000175000017500000004430113616025670014067 0ustar willemwillemRevision history for Perl extension Net::DNS::SEC. **** 1.15 February 3, 2020 Provide access to OpenSSL message digest implementations. **** 1.14 October 14, 2019 Improve exception capture in test scripts. Support more efficient algorithm mapping in Net::DNS. SEC.xs code reduction. **** 1.13 May 6, 2019 Tweaks to resolve compilation errors with BoringSSL. **** 1.12 Mar 19, 2019 Avoid use of EC_POINT_set_affine_coordinates_GFp which is deprecated in OpenSSL 3.0.0 Reduce level of support for OpenSSL non-LTS releases. **** 1.11 Dec 11, 2018 Explain why compilation aborted in Net::DNS::SEC::DSA et al. Fix Makefile.PL to suppress parallel test execution. **** 1.10 Aug 31, 2018 make test_cover now collects SEC.xs test coverage metrics using gcc and gcov. **** 1.09 Jun 4, 2018 Avoid use of EC_GROUP_new, EC_GROUP_set_curve_GFp, and EC_GFp_mont_method which are expected to disappear. Fix filename conflict when tests run in parallel. **** 1.08 May 11, 2018 Internal reorganisation to use OpenSSL EVP interface **** 1.07 April 5, 2018 Fix: rt.cpan.org #124880 1.06 will not install on macOS Feature Support for Ed25519 and Ed448 algorithms **** 1.06 March 22, 2018 Functionally identical to 1.05 All changes address build/test issues on some platforms **** 1.05 March 20, 2018 Feature Interim support for Ed25519 and Ed448 algorithms Fix: rt.cpan.org #124650 Net::DNS::SEC::Private must not die if attribute is not present **** 1.04 February 15, 2018 Feature Cryptographic library access re-engineered using PerlXS directly instead of CPAN Crypt::OpenSSL::(DSA|EDSA|RSA) distributions which have fallen into disrepair. **** 1.03 August 26, 2016 Fix: rt.cpan.org #108908 Tests break when Net::DNS gets shadowed by existing pre-1.01 version. **** 1.02 September 16, 2015 Fix: Bug in t/10-keyset.t raises exception in Net::DNS **** 1.01 August 3, 2015 Feature The RRs previously implemented in Net::DNS::SEC are now integrated with Net::DNS. Fix: rt.cpan.org #105808 Version test for Pod::Test is broken Fix: rt.cpan.org #105698 Net-DNS 1.01 conflicts with Net-DNS-SEC 0.22 **** 0.22 February 11, 2015 Fix: rt.cpan.org #101184 make siginception and sigexpiration available as time() values Fix: rt.cpan.org #101183 wrong URL for blog in README Fix: rt.cpan.org #83031 [RRSIG] lack of ECDSA support ***0.21 October 24, 2014 Fix: rt.cpan.org #99250 [RRSIG] validation fails when Signer's Name is upper case Fix: rt.cpan.org #99106 Premature end of base64 data (in 14-misc.t test script) ***0.20 August 15, 2014 Fix: rt.cpan.org #97457 !hex! error when parsing NSEC3 with empty salt ***0.19 Jun 6, 2014 Remove inappropriate deprecation warning in DNSKEY.pm ***0.18 May 8, 2014 Recode RR implementations to provide Net::DNS 0.69+ interface. Fix: rt.cpan.org #95034 Failure to parse NSEC3PARAM record with null salt Fix: rt.cpan.org #81289 Failure to handle GOST DS records ***0.17 November 29, 2013 Fix: rt.cpan.org #90270 NSEC3->covered() should use case-insensitive comparisons Fix: rt.cpan.org #79606 Lower case zone-name part with DNSKEY::privatename Allow to specify algorithms with ::Private->new_rsa_private and ::Private->generate_rsa instead of assuming RSASHA1. Fix: rt.cpan.org #55621 Specify license type (mit) in META.yml Fix: rt.cpan.org #60269 Remove Digest::SHA1 prerequirement Fix: rt.cpan.org #62387 & #63273 Typo fixes Fix: rt.cpan.org #62386 Make Net::DNS::RR::DS::digtype method work Fix: rt.cpan.org #62385 Do not compress Next Domain Name in NSEC rdata. Fix: rt.cpan.org #61104 Spelling correction in DS.pm and fix of key2ds demo program Fix: rt.cpan.org #60185 Make sure %main::SIG hash keeps its values when compiling Net::DNS::RR::SIG in perl versions before 5.14. See also: rt.perl.org #76138 Fix: rt.cpan.org #64552 and rt.cpan.org #79606 Support for private-key-format v1.3 Fix: rt.cpan.org #75892 Do not canonicalize the "Next Domain Name" rdata field of a NSEC RR for draft-ietf-dnsext-dnssec-bis-updates-17 compliance. BUG FIX/FEATURE: validation of wildcard RRs now available. Duane Wessels is acknowledged for submitting the initial code on which this fix is based. FIX: case sensitivity of ownername during DS generation (Acknowledgements Jens Wagner) ***0.16 March 12, 2010 Feature: KEY inherits DNSKEY This helps maintenance in one part of the code. Feature: keylength method (rt.cpan.org #53468) Added keylength method for RSA and DSA Acknowledgements Hugo Salgado Fix: rt.cpan.org #51778 Empty bitmap would cause error about undefined ARRAY in NSEC/NSEC3. Now the code will allow empty bitmaps gracefully Feature: New Algorithm Support (rt.cpan.org #51092) SHA2 algorithm support, including NSEC3 algorithm parameters updated Acknowledgement Jakob Shlyter Fix: rt.cpan.org #42089 NSEC3 Algorithm support in NSEC3 broken patch by Wes Hardaker ***0.15 December 31, 2008 Fix: digestbin not set when an empty value passed to hash. Feature: Added DLV (rfcc 4431). The RR object is simply a clone of the DS RR and inherits ... everything Feature: Added NSEC3 and NSEC3PARAM support (RFC5155). This adds Mime::Base32 to the module dependency list. The RR type was still experimental at that time and is maintained in Net::DNS::RR. Fix: Test script recognizes change in Time::Local. Note that Time::Local does not deal with dates beyond 03:14:07 UTC on Tuesday, 19 January 2038. Therefore this code has a year 2038 problem. Fix: DS create_from_hash now produces objects that can create wireformat. Other: minor changes to the debug statements added t/05-rr.t (and identified a couple of bugs using it) Fix: a few inconsistencies with respect to parsing of trailing dots. During development the test signatures generated with the BIND tools were re-generated in order to troubleshoot a bug that (most probably) was caused by a version incompatibility between Net::DNS and Net::DNS::SEC. Before release the original test from the 0.14 release were ran against this version too. 0.14 February 14, 2005 FIX: The introducion of the keytag warning triggered a bug with RSAMD5 keys, causing RSAMD5 keys not to be loaded. 0.13 December 9, 2005 FEAT: rt.cpan.org 14588 Added support for passing (a reference to) an array of keys to the RRSIG verify function. FIX/FEAT: The Net::DNS::SEC::Private function will for RSA based keys verify if the keytag in the filename is actually correct. Since at parsing the value of the DNSKEY RR flags is not known we test against the currently defined flag values 256 and 257. If we cannot find a keytag match a warning is printed and Private key generation fails This inconsistency was spotted by Jakob Shlyter. FEAT: Added support for SHA256 to the DS RR. Assigned the expected digest type2 for SHA256 type hashes. Note that this makes the Net::DNS::SEC depend on Digest::SHA instead of Digest::SHA1. The default digest type is still set to 1. NB. The code makes assumptions about the IANA assignment of the digest type. The assignment may change. Do not use SHA256 in production zones!! FIX: rt.cpan.org #15662 Roy Arends noticed and patched the label counting did not ignore an initial asterisk label. FIX: Wes Hardaker noticed the default TTL values for created signatures to be different from the TTLs from the data that is being signed. FIX: Wes Hardaker reported there was a problem with validating RRsets that had ownernames with capitals. The fix depends on a fix in Net::DNS::RR that is available in version 0.53_03 or later of the Net::DNS distribution. FEAT: Propper dealing with mnemonics for algorithm and digest type added to DS FIX/FEAT: Mnemonics were written as RSA/MD5 and RSA/SHA1. This has been corrected tp RSASHA1 and RSAMD5, as in the IANA registry. 0.12_02 June 6, 2005 (beta 2 release for 0.13) Bug: new_from_hash would not correctly create the RR since internally typebm is used to store the data this has been fixed so that the following works Net::DNS::RR->new(name=>$name, ttl=>$ttl, type=>"NSEC", nxtdname=>$nxtdname, typelist=>join(" ",@types) ); FEAT: Introduced the "use bytes" pragma to force character interpretation of all the scalars. Any utf processing by perl makes the code behave unpredictable. 0.12_01 April 18, 2005. (beta release for version 0.13) FEAT (!!!): Changed the symantics of the Net::DNS::Keyset::verify method. Read the perldoc for details. The requirement that each key in a keyset has to be selfsigned has been loosened. FEAT: Added a "carp" to the new methods of the NXT RR. Warning that that record is deprecated. FEAT: Cleaned the tests so that RRSIG and DNSKEY are used except for SIG0 based tests. FEAT: Changed the name of the siginceptation[SIC] to siginception. Thanks Jakob Schlyter for notifying me of this mistyping. An alias for the method remains available. FEAT: Renamed unset_sep() to clear_sep(). NOTE: To avoid confusion the Net::DNS::SIG::Private class has been removed. Use Net::DNS::SEC::Private! DOC: Added references to RFC 4033, RFC 4034 and RFC 4035. Rewrote parts of the perlpod. 0.12 June 2004 "DNSSEC-bis Release" FEAT: Added utility function key_difference() to Net::DNS::SEC. See perlpod for details. I needed this in other software and figured they are generic enough to make them available through this module. FEAT: Modified some functions to use DNSKEY and RRSIG instead off KEY and SIG. - Net::DNS::Keyset now uses DNSKEY and RRSIG. - the demo function getkeyset.pl now uses DNSKEY too. FEAT: Added the possibility to create a keyset out of two arrays of dnskey and rrsig object. FEAT: Added some helperfunctions to Net::DNS::SEC::Private to read X509 formated private keys and dump them into bind format. This functionality has not been tested well. BUG : When reading a RRSIG from a packet the signame would not have a trailing dot. 0.11_4 Apr 24 2004 Development snapshot. BUG: - Fixed MANIFEST. FEAT: Removed critical dependency on bubblebabble. It is available to DS if installed but not critically dependend. 0.11_3 Mar 4 2004 Development snapshot. BUG: - Fixed minor in signing unknown RR types. 0.11_2 Jan 27 2004 Development snapshot. FEAT: - Prelimanary support for draft-ietf-dnssec-nsec-rdata-02. This depends on support for unknown RR types (Net::DNS version 0.44) 0.11_1 Sep 23 2003 Development snapshot. FEAT: - To be able to deal with argument supplied as either mnemonics or by value the Net::DNS::SEC::argument method was created. It can be used as a class method but it is also inherited by Net::DNS::RR::RRSIG and Net::DNS::RR::DNSKEY. 0.11 August 28 2003 FEAT: - Implemented draft-ietf-dnsext-dnssec-2535typcode-change-04.txt This document has been through review and will be published as standard track RFCs shortly. (Publsished as RFC3755). IMPORTANT: the implementation of the typecode roll deprecated the use of SIG->create for any other reason than SIG0. If you try to create SIGs over RRsets you will be warned. FEAT: - Modified the namespace for the module that holds the name of the private key from Net::DNS::RR::SIG::Private to Net::DNS::SEC::Private. !!!!! Net::DNS::RR::SIG::Private will be deprecated in a next release. !!!!! CLEAN:- Crypt::OpenSSL::RSA v 0.19 introduced the possibility to create keys directly from parameters, although this introduced a dependency on Crypt::OpenSSL::Bignum it allowed to get rid from converting all parameters to DER/ANS1 encoding. Got rid of a number of lines of code. 0.10 January 8 2003 BUG: - Crypt::OpenSSL::RSA::new method has been deprecated. Code has been modified to deal with the new constructors 0.09 January 6 2003 FEAT: - Added Net::DNS::RR::SIG::Private. The class provides an abstraction to the private key material. The SIG create method now either takes a filename, like previously, or a Private key object as an argument. If you have to create many signatures the latter is preferred because you only have to read the file with the private key material once. Note that by adding this feature a modification to Net::DNS::Resolver was needed to properly do SIG0. Use Net::DNS version 0.32 or later in combination with this version FEAT: - Wes Griffen added a parameter change to keyset: 'Attached is a diff for Net::DNS::SEC v0.8 that adds a parameter changes keyset->writekeyset($path) to keyset->writekeyset($prefix,$path) where prefix is an optional string that is prepended to the filename of the keyset. That way I can keep my unsigned keyset in keyset-. and have the signed keyset in signed-keyset-.' FEAT: - Babblebubble, handy for telephone confirmation of hashes. Added babblebubble string as comment to DS RR. DS->babble returns the babble bubble string FEAT: - Miek Gieben contributed demo/key2ds 0.08 November 4 2002 BUG: - DSA signature verification failed at random about 1 per 10 sigatures. Corrected allignment problem that lead to this. Added 'stresstest' that loops over creation and verification of signatures to spot these kind of seldomly occuring errors. On my VAIO PII 500Mhz the take about a minute: Files=3, Tests=3056, 69 wallclock secs (63.30 cusr + 0.70 csys = 63.99 CPU) FEAT: - Added Test::More as dependency as on some systems diag was failing. 0.07 October 2 2002 FEAT: - Added demo/make-signed-keyset, a contribution by Wes Griffin. FEAT: - Removed dependency on Math::Pari by porting away from Crypt::DSA to Crypt::OpenSSL::DSA (version 0.10). This should increase portability over platform. T.J. Mather, the Crypt::OpenSSL::DSA maintainer has been particularly helpfull and responsive by adding a few methods to the DSA modules. 0.06 August 16 2002 NOTE: In one of ther versions prior to Net::DNS 0.26 a bug got introduced that made Net::DNS::SEC break. The bug was fixed in version 0.27. BUG: - Check on the existence of the private file improved in SIG.pm - signame got trailing dot with the create methods and not with others. FEAT: - Added privatekeyname method to KEY.pm - Started work on Net::DNS::Keyset. - Added RSA/SHA1 (algorithm ID 5) to SIG.pm. Patch supplied by Andy Vaskys, Network Associates Laboratories. - Rewrote regexp's to not use $' (Postmatch). 0.05 and 0.04 June 17, 2002 BUG: Makefile.PL needed a fix for unused dependency. This failed made the installation fail :-(. 0.04 introduced another failing dependency. DOC: Clarified the documentation at points. 0.03 June 14, 2002 DOC: Few Clarifications 0.02 June 4, 2002 First CPAN Release. Some modifications to the packaging. 0.01 May 25, 2002 Version 0.01 of the package is an alpha for CPAN release. --------------------------------------------------------------------------- The extensions used to be published as a modified version of Net::DNS. The history of those is documented below. 0.20-DNSSEC-0.2: Branched off Net::DNS version 0.20 release (CPAN May 15, 2002) 0.20-DNSSEC-0.1: This version had limited distribution First patch against a version 0.20 snapshot (2002-03-27). http://www.dyndns.org/~ctriv/net-dns-snaps/2002/03/ Modified t/09-dnssec.t; uses Test::More now and includes a number of self consistency checks. DOC Cleaned up the documentation and removed some references to functions and libraries that where not used anyway. FIX 'aesthetic' patch supplied by Simon Josefsson reordering the NXT RR map for the print method. FEAT Added checks on keytype and updated to latest specs for DS Added SIG0 support. See Net::DNS::Packet for details. The verify and create methods of SIG.pm where modified somewhat to cope with the difference. Changed RSA backend from Crypt::RSA to Crypt::OpenSSL::RSA because Crypt::RSA failed during a 'loss of Math::Pari precision in Crypt::Primes'. 0.19-DNSSEC-0.5: BUG DS create method: Hash calculation was done over concatenation of name and key material while the hash should be taken over concatenation of canonical name and key rdata. (Fix by Mike Schiraldi) 0.19-DNSSEC-0.4: Added CERT support: Courtesy of Mike Schiraldi for VeriSign BUG Fixed MANIFEST file. make dist will result in proper module tar ball 0.19-DNSSEC-0.3: Solved patch problems that where due to the $ Id $ in headers not being from the original distribution. Added DSA signature creation Added DS support You have to uncomment line 77 in Net/DNS.pm to fully enable DS This will assign QTYPE 93 to the DS RR. That value is not assigned by IANA. Added this README.DNSSEC file Added t/09-dnssec.t to the test script with a number of consistency checks. after patching the original distribution direction perl Makefile.PL make test will call this function among other things. BUG KeyID set to 0 for null keys. BUG Sorting of canonical RDATA; Data over which SIG was created was not sorted properly (RFC2535 sect 8.3) causing signature verification errors for RDATA within a RRset having different length (e.g. some NS RRsets would not verify.) 0.19-DNSSEC-0.2: First somewhat public release. --------------------------------------------------------------------------- $Id: Changes 1766 2020-02-03 14:17:59Z willem $ Net-DNS-SEC-1.15/META.yml0000644000175000017500000000130713616025777014054 0ustar willemwillem--- abstract: 'DNSSEC extensions to Net::DNS' author: - 'Dick Franks' - 'Olaf Kolkman' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010' license: mit meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-DNS-SEC no_index: directory: - t - inc recommends: {} requires: DynaLoader: '1.04' File::Find: '1.05' File::Spec: '0.86' IO::File: '1.08' MIME::Base64: '2.13' Net::DNS: '1.08' Test::More: '0.47' perl: '5.006' version: '1.15' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Net-DNS-SEC-1.15/typemap0000644000175000017500000000025713616025670014200 0ustar willemwillem# # $Id: typemap 1763 2020-02-02 21:48:03Z willem $ # TYPEMAP DSA* T_PTROBJ EC_KEY* T_PTROBJ EVP_MD_CTX* T_PTROBJ EVP_PKEY* T_PTROBJ const EVP_MD* T_PTROBJ RSA* T_PTROBJ # Net-DNS-SEC-1.15/demo/0000755000175000017500000000000013616025777013526 5ustar willemwillemNet-DNS-SEC-1.15/demo/make-signed-keyset0000644000175000017500000000525313616025670017134 0ustar willemwillem#!/usr/bin/perl #$Id: make-signed-keyset 1661 2018-04-04 09:51:45Z willem $ # # takes a bind public key file and creates a self-signed keyset # use Getopt::Std; use Net::DNS::SEC; use Net::DNS::SEC::Keyset; use Net::DNS::ZoneFile; use File::Basename; # global variables $VERSION = "0.2"; $verbose = 0; $printds = 0; $progname = basename($0); chomp($progname); # main program getopts('dvhVf:n:'); if ( defined($opt_d) ) { $printds = 1; } if ( defined($opt_v) ) { $verbose = 1; } if ( defined($opt_h) ) { &usage(); } if ( defined($opt_V) ) { &version(); } if ( $#ARGV < 0 ) { &usage(); } # silent some compiler warnings until i figure them out $opt_d = 0; $opt_v = 0; $opt_h = 0; $opt_V = 0; &make_keyset(@ARGV); exit(0); # print the usage and exit sub usage { print("usage: $progname [-vhV] file\n"); print("Options:\n"); print(" -d Print the DS record for each key in the keyset.\n"); print(" -v Be verbose.\n"); print(" -h Print this usage message.\n"); print(" -V Print version information.\n"); print(" file BIND public key file.\n"); exit(0); } # print version information sub version { print( "$progname v$VERSION using Net::DNS v", Net::DNS->version, "\n" ); exit(0); } sub make_keyset { my $source = new Net::DNS::ZoneFile(shift); my $file = $source->name; my $directory = dirname($file); print("Processing file: $file\n"); my @keys; while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); print("Read DNSKEY RR\n") if $verbose; push @keys, $keyrr; } print("Creating keyset\n") if $verbose; my $keyset = Net::DNS::SEC::Keyset->new( \@keys, "$directory" ) or die("$progname: unable to create keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); print("Verifying keyset\n") if $verbose; $keyset->verify() or die("$progname: unable to verify keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); if ($verbose) { print("Keyset:\n"); $keyset->print(); print("Writing keyset\n"); } $keyset->writekeyset("signed-") or die("$progname: unable to write keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); if ($printds) { print("Extracting DS RR\n") if $verbose; my @ds = $keyset->extract_ds(); foreach $ds (@ds) { $ds->print(); } } } =head1 NAME make-signed-keyset - create a self-signed keyset =head1 SYNOPSIS make-signed-keyset [-v] file =head1 DESCRIPTION make-signed-keyset is a program that creates a self-signed keyset from a BIND public key file specified on the command line. The options are as follows: =over =item -v Be verbose. =item -d Print the DS record for each key in the keyset. =back =head1 AUTHOR Contributed by Wes Griffin =cut Net-DNS-SEC-1.15/demo/getkeyset0000644000175000017500000000411513616025670015446 0ustar willemwillem#!/usr/bin/perl #$Id: getkeyset 1705 2018-08-23 10:24:02Z willem $ use strict; use Net::DNS::SEC; use Net::DNS::SEC::Keyset; my $domain = shift || die "At least one argument needed"; my $nameserver = shift; my $res = Net::DNS::Resolver->new; $res->dnssec(1); $res->nameservers($nameserver) if defined $nameserver; my $packet = $res->query( $domain, 'DNSKEY', 'IN' ) || die "No results for query $domain DNSKEY"; my $keyset = Net::DNS::SEC::Keyset->new($packet) || die $Net::DNS::SEC::Keyset::keyset_err; # Print DS records to STD out # my @ds = $keyset->extract_ds; foreach my $ds (@ds) { $ds->print; } # write keyset in current dir. # $keyset->writekeyset; 1; __END__ =head1 NAME getkeyset.pl - DS extraction demo =head1 SYNOPSIS getkeyset.pl [auth_nameserver] =head1 DESCRIPTION The program queries for the key-set of 'domain'. Spits out the DS records and writes the keyset to the current directory. If the second argument is specified the query is performed to that nameserver. =head1 TODO This is only a demonstration program to show how the interface can be used. =head1 COPYRIGHT Copyright (c) 2002 RIPE NCC. Author Olaf M. Kolkman All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. =cut Net-DNS-SEC-1.15/demo/key2ds0000644000175000017500000000161613616025670014646 0ustar willemwillem#!/usr/bin/perl #$Id: key2ds 1295 2015-01-08 13:14:03Z willem $ # A little util to convert DNSKEY records to DS records # from stdin to stdout # # Author: Miek Gieben, NLnetLabs use strict; use Net::DNS::SEC; use Net::DNS::ZoneFile; my $handle = \*STDIN; my $source = new Net::DNS::ZoneFile($handle); while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); foreach my $digtype (qw(SHA256 SHA1)) { my $ds = create Net::DNS::RR::DS( $keyrr, digtype => $digtype ); $ds->print; } } exit 0; =head1 NAME key2ds - Utility to create DS records from DNSKEY RRs read from stdin. =head1 SYNOPSIS key2ds ds.txt =head1 DESCRIPTION C reads the key data from STDIN and prints the corresponding DS record on STDOUT. =head1 COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 0; Net-DNS-SEC-1.15/t/0000755000175000017500000000000013616025777013045 5ustar willemwillemNet-DNS-SEC-1.15/t/21-RSA-MD5.t0000644000175000017500000000513113616025670014452 0ustar willemwillem# $Id: 21-RSA-MD5.t 1758 2019-10-14 13:17:11Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSAMD5.example. IN KEY 512 3 1 ( AwEAAc6K704XNTQYlCPw1R5qBNdPg3SxOdhEWdDFlPdCeeBL1UDSdUG1ijcNkoGCKpFXLaTqeJAH +VkXhOGUSvFxIOOmtxb3ubwFf80Up1iKwACNmfCgDlGm8EzGKVoPGcuXkwcxFsQtBoKqT6lWR3at 6MT/bnuwIIVaD91u1L+/tVw7 ; Key ID = 46428 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: zorvThc1NBiUI/DVHmoE10+DdLE52ERZ0MWU90J54EvVQNJ1QbWKNw2SgYIqkVctpOp4kAf5WReE4ZRK8XEg46a3Fve5vAV/zRSnWIrAAI2Z8KAOUabwTMYpWg8Zy5eTBzEWxC0GgqpPqVZHdq3oxP9ue7AghVoP3W7Uv7+1XDs= PublicExponent: AQAB PrivateExponent: hMPcJddXNMCj4SJ67Az8Rabv+j+9zh3JmiCXrAUIMLyuPPfLtcxLJy5LQYJ5eGmQhpTNoM/vYWxz10kqj17H40ZpAbrfD8/TZtQDnEA2Nzlp3F+qswpmMRih82LzqzpBm0l8lbqnyIRthHfytisG52YWW8pZ0jlBuQb7whO+ajk= Prime1: 6hj6OPHOP/1AuLiiQo8FcxFyES6WAKvJlcqKX2wb7Gxz6yPfTQlR7WcueEn60r75rF9VAS46qxa3XIsvBuETJw== Prime2: 4d35IrQ/bVCtdQ7A9DyUNmOVtS6bPCJBEVLI+M6dmj1icGJiiwNdCXbX3uaOG0SEh2/oXGBbw9wX8D1xDWqKzQ== Exponent1: FvM17Mk/+CQC6Vkohy/wT9ShAzA3An/U9ntxz2MQ5b/IKYBNzwaf4o9gDejqzyhr38tE0SXQGJ/UgB0hEiKUtw== Exponent2: KEOs3Q3q3K7sLRjzNtbxyPxZvNHRJJgqp07tusUCfXOB7+zqCkQQOtavxvGs1ZmSUp6VeppG4ZSDw/UACVc75Q== Coefficient: QIVRcEFrFbmhJntBjCZOgJ4tKaiJJ3s4J97RMR6xQ1pLVwlOKKozJbjVx2tZyb11/UQliVTHlgrqYGL/oWBMKw== END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::RSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.15/t/00-load.t0000644000175000017500000000443513616025670014364 0ustar willemwillem# $Id: 00-load.t 1763 2020-02-02 21:48:03Z willem $ # use strict; use Test::More tests => 4; my @module = qw( Net::DNS::SEC Net::DNS::SEC::DSA Net::DNS::SEC::ECDSA Net::DNS::SEC::ECCGOST Net::DNS::SEC::EdDSA Net::DNS::SEC::RSA Net::DNS::SEC::Digest Net::DNS::SEC::Keyset Net::DNS::SEC::Private Net::DNS::SEC::libcrypto File::Find File::Spec IO::File MIME::Base64 Net::DNS Test::More ); my @diag = "\nThese tests were run using:"; foreach my $module ( sort @module ) { eval "use $module"; for ( grep $_, eval { $module->VERSION } ) { s/^(\d+\.\d)$/${1}0/; push @diag, sprintf "%-25s %s", $module, $_; } } diag join "\n\t", @diag; ok( eval { Net::DNS::SEC::libcrypto->VERSION }, 'XS component SEC.xs loaded' ) || BAIL_OUT("Unable to access OpenSSL libcrypto library"); use_ok('Net::DNS::SEC'); my @index; foreach my $class ( map "Net::DNS::SEC::$_", qw(RSA DSA ECCGOST ECDSA EdDSA) ) { my @algorithms = eval join '', qw(r e q u i r e), " $class; $class->_index"; push @index, map( ( $_ => $class ), @algorithms ); } ok( scalar(@index), 'create consolidated algorithm index' ); eval { # Exercise checkerr() response to failed OpenSSL operation Net::DNS::SEC::libcrypto::checkerr(0) }; my ($exception) = split /\n/, "$@\n"; ok( $exception, "XS libcrypto error\t[$exception]" ); eval { # Exercise residual XS support for deprecated ECCGOST algorithm my $d = pack 'H*', '9df69fc32cd2d369a42ecb63512bc7e25d71b1af7a303ec38a8326809cdef349'; my $q = pack 'H*', 'ffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893'; my $r = pack 'H*', '36b98722d79b1cce42cdb9a6503d2fa16ce85969eae711b758aabfe3a39f5d0c'; my $s = pack 'H*', '22c1d462f790afab1624e211531d1d455d285978bb0d4875c428811d7028fc33'; my $x = pack 'H*', 'cadb74b9950fcf3728ad232626b0dc63f350c25dd09456cd155f413d35205ce9'; my $y = pack 'H*', '050fd637ab18f8f443eac48c26c12566e655e4d3b15046e0fef296a8835ebeee'; foreach my $H ( $d, $q ) { ## including specific case (alpha mod q) = 0 my $eckey = Net::DNS::SEC::libcrypto::EC_KEY_new_ECCGOST(); Net::DNS::SEC::libcrypto::EC_KEY_set_public_key_affine_coordinates( $eckey, $x, $y ); Net::DNS::SEC::libcrypto::ECCGOST_verify( $H, $r, $s, $eckey ); } }; exit; END { eval { Net::DNS::SEC::libcrypto::croak_memory_wrap() } # paper over crack in Devel::Cover } __END__ Net-DNS-SEC-1.15/t/62-Ed448.t0000644000175000017500000000420313616025670014236 0ustar willemwillem# $Id: 62-Ed448.t 1668 2018-04-23 13:36:44Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.05, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_private_key') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::EdDSA'); # Specimen private and public keys taken from RFC8080 my $key = new Net::DNS::RR <<'END'; ED448.example.com. IN DNSKEY ( 257 3 16 3kgROaDjrh0H2iuixWBrc8g2EpBBLCdGzHmn+G2MpTPhpj/OiBVHHSfPodx1FYYUcJKm1MDpJtIA ) ; Key ID = 9713 END ok( $key, 'set up EdDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 16 (ED448) PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up EdDSA private key' ); my $sigdata = 'arbitrary data'; ## Note: ED448 signing is deterministic my $signature = pack 'H*', join '', qw( 01f546bfe2fd040170133b3797c1c95a31dbb2f216d95f44ced76998f7dc8e16 8f7082550a83eea4ebeb66e34696249d790db5ba76047ca9002a3dedc10e6d26 bddc8378ff1a81815aa146e72a0d9672553b2aa5cc38354cbdf2b9c4b8e36a1c f7651f828fb64c200e2ee5d0686490910c00 ); my $signed = eval { Net::DNS::SEC::EdDSA->sign( $sigdata, $private ) } || ''; ok( $signed eq $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::EdDSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::EdDSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.15/t/31-DSA-SHA1.t0000644000175000017500000001107613616025670014551 0ustar willemwillem# $Id: 31-DSA-SHA1.t 1677 2018-05-22 11:59:10Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled DSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_DSA') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::DSA'); my $key = new Net::DNS::RR <<'END'; DSA.example. IN DNSKEY ( 257 3 3 CKrKbLrir4slVXYFrA4Y8Rik/UxzkCo1Rp0Spz907VrJL8u3I/YKTTvoMh/GL2n3/NL/KgzNRWb8 pLB3FIWHjXXhn3r3sbld180DI4tv98CZKr86UDP0UUHVE/DkkEZw5PAy2nyhhKTJRvbR4ZT0OSZY +GZA2hIzmMYk4gR2mwa3jCmAGqw2i0OtAYzSOe06uoELZLl96kRsFk69OcQxzrDKz5BEZZpNBpfZ UBk/CRPDxBE2xjJkq3VpehAUCMOFpPQlEuW2D6CNuIbJY5pNpOF3RF17vkvxQx6678ZLIN3PdeG/ nGwoJJArbt7Y/q+b/NxnIu6RwApE40p/7pOq6qKcqPVU2oHR/N7oNiyHnh68gSonUFfy5lETiyw8 vDaJS/JhC2WQKzxxBo4oa/KFXFAd6NR6bE5h5XRWWqZvm2sBgcy+sKTbKcR4PDvaAoMguBjDeigm /NV6phNbARV926NyQZOi5uUeBYA16v1KnUll7A3I9wt3ykVIbx0WqB4Ozzk2PF/3vH3wudO5bL72 zK1Yox60 ) ; Key ID = 53264 END ok( $key, 'set up DSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 3 (DSA) Prime(p): kCo1Rp0Spz907VrJL8u3I/YKTTvoMh/GL2n3/NL/KgzNRWb8pLB3FIWHjXXhn3r3sbld180DI4tv98CZKr86UDP0UUHVE/DkkEZw5PAy2nyhhKTJRvbR4ZT0OSZY+GZA2hIzmMYk4gR2mwa3jCmAGqw2i0OtAYzSOe06uoELZLk= Subprime(q): qspsuuKviyVVdgWsDhjxGKT9THM= Base(g): fepEbBZOvTnEMc6wys+QRGWaTQaX2VAZPwkTw8QRNsYyZKt1aXoQFAjDhaT0JRLltg+gjbiGyWOaTaThd0Rde75L8UMeuu/GSyDdz3Xhv5xsKCSQK27e2P6vm/zcZyLukcAKRONKf+6TquqinKj1VNqB0fze6DYsh54evIEqJ1A= Private_value(x): drOKJBTwCM0O9U6tpIgymGyBrao= Public_value(y): V/LmUROLLDy8NolL8mELZZArPHEGjihr8oVcUB3o1HpsTmHldFZapm+bawGBzL6wpNspxHg8O9oCgyC4GMN6KCb81XqmE1sBFX3bo3JBk6Lm5R4FgDXq/UqdSWXsDcj3C3fKRUhvHRaoHg7POTY8X/e8ffC507lsvvbMrVijHrQ= END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up DSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; RSAMD5.example. IN KEY ( 512 3 1 AwEAAcUHtdNvhdBKMkUle+MJ+ntJ148yfsITtZC0g93EguURfU113BQVk6tzgXP/aXs4OptkCgrL sTapAZr5+vQ8jNbLp/uUTqEUzBRMBqi0W78B3aEb7vEsC0FB6VLoCcjylDcKzzWHm4rj1ACN2Zbu 6eT88lDYHTPiGQskw5LGCze7 ) ; Key ID = 2871 END ok( $wrongkey, 'set up non-DSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: xQe102+F0EoyRSV74wn6e0nXjzJ+whO1kLSD3cSC5RF9TXXcFBWTq3OBc/9pezg6m2QKCsuxNqkBmvn69DyM1sun+5ROoRTMFEwGqLRbvwHdoRvu8SwLQUHpUugJyPKUNwrPNYebiuPUAI3Zlu7p5PzyUNgdM+IZCyTDksYLN7s= PublicExponent: AQAB PrivateExponent: yOATgH0y8Ci1F8ofhFmoBgpCurvAgB2X/vALgQ3YZbJvDYob1l4pL6OTV7AO2pF5LvPPSTJielfUSyyRrnANJSST/Dr19DgpSpnY2GWE7xmJ6/QqnIaJ2+10pFzVRXShijJZjt9dY7JXmNIoQ+JseE08aquKHFEGVfsvkThk8Q== Prime1: 9lyWnGhbZZwVQo/qNHjVeWEDyc0hsc/ynT4Qp/AjVhROY+eJnBEvhtmqj3sq2gDQm2ZfT8uubSH5ZkNrnJjL2Q== Prime2: zL0L5kwZXqUyRiPqZgbhFEib210WZne+AI88iyi39tU/Iplx1Q6DhHmOuPhUgCCj2nqQhWs9BAkQwemLylfHsw== Exponent1: rcETgHChtYJmBDIYTrXCaf8get2wnAY76ObzPF7DrVxZBWExzt7YFFXEU7ncuTDF8DQ9mLvg45uImLWIWkPx0Q== Exponent2: qtb8vPi3GrDCGKETkHshCank09EDRhGY7CKZpI0fpMogWqCrydrIh5xfKZ2d9SRHVaF8QrhPO7TM1OIqkXdZ3Q== Coefficient: IUxSSCxp+TotMTbloOt/aTtxlaz0b5tSS7dBoLa7//tmHZvHQjftEw8KbXC89QhHd537YZX4VcK/uYbU6SesRA== END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-DSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::DSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::DSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupted' ); ok( !eval { Net::DNS::SEC::DSA->sign( $sigdata, $wrongprivate ) }, 'signature not created using wrong private key' ); ok( !eval { Net::DNS::SEC::DSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not verifiable using wrong public key' ); ok( !eval { Net::DNS::SEC::DSA->verify( $sigdata, $key, undef ) }, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.15/t/24-RSA-SHA512.t0000644000175000017500000000526313616025670014741 0ustar willemwillem# $Id: 24-RSA-SHA512.t 1758 2019-10-14 13:17:11Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA512.example. IN DNSKEY 256 3 10 ( AwEAAdLaxcxvgdQKF3zSOuXQgwWPQ+dKzJ3Ob4w3r+o73i2MnhE0HBHuTzUZGVjGR05VGqZaJx64 LNt0Wlxxoxt3Uwaq55t5MzN3LYYYEcMQ1XPhPG1nNuD0LiqlqL+KmQqlAo3cm4F71gr/GXQiPG3O WM11ulruDKZpyfYg1NWryu3F ; Key ID = 35741 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 10 (RSASHA512) Modulus: 0trFzG+B1AoXfNI65dCDBY9D50rMnc5vjDev6jveLYyeETQcEe5PNRkZWMZHTlUaplonHrgs23RaXHGjG3dTBqrnm3kzM3cthhgRwxDVc+E8bWc24PQuKqWov4qZCqUCjdybgXvWCv8ZdCI8bc5YzXW6Wu4MpmnJ9iDU1avK7cU= PublicExponent: AQAB PrivateExponent: hTutzo8LBzPVQY8JnluR3rp3Grgd8P0XaQ9q/eQUcM2wt4go0H+31wJkDL9FIU8PRtwiafvQhF7SFiXL/bf5YlCBhCNnYmz8fZuIsZr9OC5tYDFU43AziHYrwhE0myYMJF16nrJTe8RfGnvkvsBUJovu92L86lUOexTQCeIJPeE= Prime1: 7Pq9K1h4B8UfhEH1+zh+LW4BS6OHPVt7WGPSob/8EqirMqsv1xNxfp/La9abLEJemyXJUZ7SjTN6MbNMHfH1rQ== Prime2: 48c9vC+ynHyq5mNbVr2pQKoWVdCoeK6wgMHXnoSyMnxwmnP+NNXM1NKDSX7TIJOmGerRL7MGsiTSf3W39IjreQ== Exponent1: I9lCaJ43eiVtwRohVeGT5NdxRrn0KWn/XL2tDV73iPMPAtk2oXiFgLw3j5alXqqjmSC8Naaq/0U8ROx0pUsG+Q== Exponent2: ulbOrFsg9WAPt3ZkzKtQATSkHQQcLs5KWqs5p9bKqP6gZ9qohbS6Ywjsmn2EXswrQFyXUTxWJ/pzsg4ttYElkQ== Coefficient: kZkMqvGGOYegRIujd89qRGgHR/A8RN/BUXiuS3GbUemX9RtFRwtf12BfTAf5glTBL+7kOojarbt+CD+qkFbd6A== Created: 20141208233433 Publish: 20141208233433 Activate: 20141208233433 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::RSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.15/t/22-RSA-SHA1.t0000644000175000017500000001475313616025670014574 0ustar willemwillem# $Id: 22-RSA-SHA1.t 1758 2019-10-14 13:17:11Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA') }; plan tests => 17; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA1.example. IN DNSKEY ( 257 3 5 AwEAAefP0RzK3K39a5wznjeWA1PssI2dxqPb9SL+ppY8wcimOuEBmSJP5n6/bwg923VFlRiYJHe5 if4saxWCYenQ46hWz44sK943K03tfHkxo54ayAk/7dMj1wQ7Dby5FJ1AAMGZZO65BlKSD+2BTcwp IL9mAYuhHYfkG6FTEEKgHVmOVmtyKWA3gl3RrSSgXzTWnUS5b/jEeh2SflXG9eXabaoVXEHQN+oJ dTiAiErZW4+Zlx5pIrSycZBpIdWvn4t71L3ik6GctQqG9ln12j2ngji3blVI3ENMnUc237jUeYsy k7E5TughQctLYOFXHaeTMgJt0LUTyv3gIgDTRmvgQDU= ) ; Key ID = 4501 END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 ; comment discarded ; empty line discarded Algorithm: 5 (RSASHA1) Modulus: 58/RHMrcrf1rnDOeN5YDU+ywjZ3Go9v1Iv6mljzByKY64QGZIk/mfr9vCD3bdUWVGJgkd7mJ/ixrFYJh6dDjqFbPjiwr3jcrTe18eTGjnhrICT/t0yPXBDsNvLkUnUAAwZlk7rkGUpIP7YFNzCkgv2YBi6Edh+QboVMQQqAdWY5Wa3IpYDeCXdGtJKBfNNadRLlv+MR6HZJ+Vcb15dptqhVcQdA36gl1OICIStlbj5mXHmkitLJxkGkh1a+fi3vUveKToZy1Cob2WfXaPaeCOLduVUjcQ0ydRzbfuNR5izKTsTlO6CFBy0tg4Vcdp5MyAm3QtRPK/eAiANNGa+BANQ== PublicExponent: AQAB PrivateExponent: qVfDp4j61ZAAAMgkmO7Z14FdKNdNuX6CAeKNx8rytaXZ9W25dLtx4r3uWtL1cyI13RWn7l54VFoWkEwDQ0/6P4vLbE0QbvFWjUMkX1TH9kQSRc+R6WCRPuH1Ex0R1h5fbw6kEVDRMZjKUfLX5oFVDv1xu5Mjg5Y8KQoJIuLdDgHtRRV7ZETcGcSXBQ1eY2rNxui2YzM0mtqzApgGq7pLb3GfiM5aqW5fSdRaFajGC2VIXkN3jZYxAryT8EYJ6uRFJk0X3VegEwj6keHOem/tBV2DaNlv1JWidauPeU67evKNTQVW3h3AbQxnOtegdWrRKoa9Ksf27bgoKAlveHIfsQ== Prime1: +s1y+iP+AoB4UVS4S5njIZD21AWm36JTaqEvRPdevjuzc9q7yJATROdRdcAitdSPHeRC8xtQw/C9zGhJRdynlxfmUTeyYgM0EYHYiG7PLwkW5Wu9EeXJ7/Fpct51L+ednloQ0d7tYP/5QUd6cqbFGGKH0yF5zZMO0k+ZZ/saeCs= Prime2: 7J2eVZ5Psue4BTNya8PMA89cC0Gf51zFeQ8dPBZIOpN28DJN2EN6C6fwGtnr6BO+M/6loXzcekPGgRkpNcQ6MzJup8hZQmU8RxESAMlmQzOtaBbtmMwPa0p6IcZBUWpbRaKwQ4ZjAUS9R13PFwgEU+a855o0XRRTupdmyZ6OmR8= Exponent1: nGakbdMmIx9EaMuhRhwIJTWGhz+jCdDrnhI4LRTqM019oiDke7VFHvH1va18t9F/Ek/3ZC1Dl304jxD1qKhqpnGUAk/uYOrIfKZxhts7PoS3j4g5VsDqxkPQ035gq+gPReG6nXYcqCHYqVnOxVK0lHlVZFd64rTzSDm1W7+eiRM= Exponent2: evAuKygVGsxghXtEkQ9rOfOMTGDtdyVxiMO8mdKt9plV69kHLz1n9RRtoVXmx28ynQtK/YvFdlUulzb+fWwWHTGv4scq8V9uITKSWwxJcNMx3upCyugDfuh0aoX6vBV5lMXBtWPmnusbOTBZgArvTLSPI/qwCEiedE1j34/dYVs= Coefficient: JTEzUDflC+G0if7uqsJ2sw/x2aCHMjsCxYSmx2bJOW/nhQTQpzafL0N8E6WmKuEP4qAaqQjWrDyxy0XcAJrfcojJb+a3j2ndxYpev7Rq8f7P6M7qqVL0Nzj9rWFH7pyvWMnH584viuhPcDogy8ymHpNNuAF+w98qjnGD8UECiV4= END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::RSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupted' ); # The following tests are not replicated for other RSA/SHA flavours my $wrongkey = new Net::DNS::RR <<'END'; DSA.example. IN DNSKEY 256 3 3 ( CMKzsCaT2Jy1w/sPdpigEE+nbeJ/x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk 7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL 5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyeAH46EQVCq1UBnnaHslvSDkdb+Z1kT bMQ64ZVI/sBRXRbqIcDlXVZurCTDV7JL9KZwwfeyrQcnVyYh5mdHPsXbpX5NQJvoqPgvRZWBpP4h pjkAm9UrUbow9maPCQ1JQ3JuiU5buh9cjAI+QIyGMujKLT2OsogSZD2IFUciaZBL/rSe0gmAUv0q XrczmIYFUCoRGZ6+lKVqQQ6f2U7Gsr6zRbeJN+JCVD6BJ52zjLUaWUPHbakhZb/wMO7roX/tnA/w zoDYBIIF7yuRYWblgPXBJTK2Bp07xre8lKCRbzY4J/VXZFziZgHgcn9tkHnrfov04UG9zlWEdT6X E/60HjrP ; Key ID = 53244 ) END ok( $wrongkey, 'set up non-RSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 3 (DSA) Prime(p): x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyc= Subprime(q): wrOwJpPYnLXD+w92mKAQT6dt4n8= Base(g): gB+OhEFQqtVAZ52h7Jb0g5HW/mdZE2zEOuGVSP7AUV0W6iHA5V1Wbqwkw1eyS/SmcMH3sq0HJ1cmIeZnRz7F26V+TUCb6Kj4L0WVgaT+IaY5AJvVK1G6MPZmjwkNSUNybolOW7ofXIwCPkCMhjLoyi09jrKIEmQ9iBVHImmQS/4= Private_value(x): vdClrOqZ1qONKg0CZH5hVnq1i40= Public_value(y): tJ7SCYBS/SpetzOYhgVQKhEZnr6UpWpBDp/ZTsayvrNFt4k34kJUPoEnnbOMtRpZQ8dtqSFlv/Aw7uuhf+2cD/DOgNgEggXvK5FhZuWA9cElMrYGnTvGt7yUoJFvNjgn9VdkXOJmAeByf22Qeet+i/ThQb3OVYR1PpcT/rQeOs8= END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-RSA private key' ); ok( !eval { Net::DNS::SEC::RSA->sign( $sigdata, $wrongprivate ) }, 'signature not created using wrong private key' ); ok( !eval { Net::DNS::SEC::RSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not verifiable using wrong public key' ); ok( !eval { Net::DNS::SEC::RSA->verify( $sigdata, $key, undef ) }, 'verify fails if signature undefined' ); # test detection of invalid private key descriptors eval { Net::DNS::SEC::Private->new('Kinvalid.private') }; my ($exception1) = split /\n/, "$@\n"; ok( $exception1, "invalid keyfile: [$exception1]" ); eval { Net::DNS::SEC::Private->new('Kinvalid.+0+0.private') }; my ($exception2) = split /\n/, "$@\n"; ok( $exception2, "missing keyfile: [$exception2]" ); eval { Net::DNS::SEC::Private->new( signame => 'private' ) }; my ($exception3) = split /\n/, "$@\n"; ok( $exception3, "unspecified algorithm: [$exception3]" ); eval { Net::DNS::SEC::Private->new( algorithm => 1 ) }; my ($exception4) = split /\n/, "$@\n"; ok( $exception4, "unspecified signame: [$exception4]" ); # exercise code for key with long exponent (not required for DNSSEC) eval { my $longformat = pack 'xn a*', unpack 'C a*', $key->keybin; $key->keybin($longformat); Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); }; exit; __END__ Net-DNS-SEC-1.15/t/52-ECDSA-P384.t0000644000175000017500000000356413616025670014731 0ustar willemwillem# $Id: 52-ECDSA-P384.t 1668 2018-04-23 13:36:44Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_EC_KEY') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::ECDSA'); my $key = new Net::DNS::RR <<'END'; ECDSAP384SHA384.example. IN DNSKEY 256 3 14 ( K4t0AhWiJcLZ25BlpvfxCi2KMlkBr14zECH3Y2imMYOzn5zcMpOh0iPbI9Hnfep8L+BBzQrRFNmc 5r3r0l0y+snHIc/npdK/1Ks0ZG/aMB5r/PfJGeB5MLdtcanFir2S ; Key ID = 25812 ) END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 14 (ECDSAP384SHA384) PrivateKey: mvuhyr+QDMqo4bpeREFRM2w8qZsBiLiCouR0sihdinvpRA3zA/dByohgH4CLI7Kr Created: 20141209021155 Publish: 20141209021155 Activate: 20141209021155 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up ECDSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::ECDSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::ECDSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.15/t/61-Ed25519.t0000644000175000017500000000571413616025670014413 0ustar willemwillem# $Id: 61-Ed25519.t 1668 2018-04-23 13:36:44Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.05, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_private_key') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::EdDSA'); # Specimen private and public keys taken from RFC8080 my $key = new Net::DNS::RR <<'END'; ED25519.example. IN DNSKEY ( 257 3 15 l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= ) ; Key ID = 3613 END ok( $key, 'set up EdDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 15 (ED25519) PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI= END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up EdDSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; ECDSAP256SHA256.example. IN DNSKEY 256 3 13 ( 7Y4BZY1g9uzBwt3OZexWk7iWfkiOt0PZ5o7EMip0KBNxlBD+Z58uWutYZIMolsW8v/3rfgac45lO IikBZK4KZg== ; Key ID = 44222 ) END ok( $wrongkey, 'set up non-EdDSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: m/dWhFblAGQnabJoKbs0vXoQidjNzlTcbPAqntUXWi0= END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-EdDSA private key' ); my $sigdata = 'arbitrary data'; ## Note: ED25519 signing is deterministic my $signature = pack 'H*', join '', qw( cb7a60fedc08b09995d522410962c6eb0fd0ea34e16fe094c99582fbb14e7a87 c14292cf8c28af0efe6ee30cbf9d643cba3ab56f1e1ae27b6074147ed9c55a0e ); my $signed = eval { Net::DNS::SEC::EdDSA->sign( $sigdata, $private ); } || ''; ok( $signed eq $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::EdDSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::EdDSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupted' ); ok( !eval { Net::DNS::SEC::EdDSA->sign( $sigdata, $wrongprivate ) }, 'signature not created using wrong private key' ); ok( !eval { Net::DNS::SEC::EdDSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not verifiable using wrong public key' ); ok( !eval { Net::DNS::SEC::EdDSA->verify( $sigdata, $key, undef ) }, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.15/t/20-digest.t0000644000175000017500000000502413616025670014721 0ustar willemwillem# $Id: 20-digest.t 1766 2020-02-03 14:17:59Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'unable to access OpenSSL libcrypto library' unless eval { Net::DNS::SEC::libcrypto->can('EVP_MD_CTX_new') }; plan tests => 12; my $text = 'The quick brown fox jumps over the lazy dog'; my %digest = ( MD5 => '9e107d9d372bb6826bd81d3542a419d6', SHA1 => '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12', SHA224 => '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525', SHA256 => 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592', SHA384 => 'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1', SHA512 => '07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6', SHA3_224 => 'd15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795', SHA3_256 => '69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04', SHA3_384 => '7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41', SHA3_512 => '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450', ); use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Digest'); sub test { my ( $mnemonic, $class, @parameter ) = @_; my $object = $class->new(@parameter); $object->add($text); is( unpack( 'H*', $object->digest ), $digest{$mnemonic}, "message digest $mnemonic" ); } SKIP: { skip( 'MD5 digest algorithm not supported', 1 ) unless eval { Net::DNS::SEC::libcrypto->can('EVP_md5') }; test( 'MD5', 'Net::DNS::SEC::Digest::MD5' ); } test( 'SHA1', 'Net::DNS::SEC::Digest::SHA', 1 ); test( 'SHA224', 'Net::DNS::SEC::Digest::SHA', 224 ); test( 'SHA256', 'Net::DNS::SEC::Digest::SHA', 256 ); test( 'SHA384', 'Net::DNS::SEC::Digest::SHA', 384 ); test( 'SHA512', 'Net::DNS::SEC::Digest::SHA', 512 ); SKIP: { skip( 'SHA3 digest algorithm not supported', 4 ) unless eval { Net::DNS::SEC::libcrypto->can('EVP_sha3_256') }; test( 'SHA3_224', 'Net::DNS::SEC::Digest::SHA3', 224 ); test( 'SHA3_256', 'Net::DNS::SEC::Digest::SHA3', 256 ); test( 'SHA3_384', 'Net::DNS::SEC::Digest::SHA3', 384 ); test( 'SHA3_512', 'Net::DNS::SEC::Digest::SHA3', 512 ); } exit; __END__ Net-DNS-SEC-1.15/t/51-ECDSA-P256.t0000644000175000017500000000725413616025670014726 0ustar willemwillem# $Id: 51-ECDSA-P256.t 1677 2018-05-22 11:59:10Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_EC_KEY') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::ECDSA'); my $key = new Net::DNS::RR <<'END'; ECDSAP256SHA256.example. IN DNSKEY ( 257 3 13 IYHbvpnqrhxM4i0SuOyAq9hk19tNXpjja7jCQnfAjZBFBfcLorJPnq4FWMVDg6QT2C4JeW0yCxK4 iEhb4w9KWQ== ) ; Key ID = 27566 END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: w+AjPo650IA8DWeEq5QqZ2LWYpuC/oeEaYaGE1ZvKyA= Created: 20141209015301 Publish: 20141209015301 Activate: 20141209015301 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up ECDSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; RSASHA1.example. IN DNSKEY ( 256 3 5 AwEAAZHbngk6sMoFHN8fsYY6bmGR4B9UYJIqDp+mORLEH53Xg0f6RMDtfx+H3/x7bHTUikTr26bV AqsxOs2KxyJ2Xx9RGG0DB9O4gpANljtTq2tLjvaQknhJpSq9vj4CqUtr6Wu152J2aQYITBoQLHDV i8mIIunparIKDmhy8TclVXg9 ) ; Key ID = 1623 END ok( $wrongkey, 'set up non-ECDSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: kdueCTqwygUc3x+xhjpuYZHgH1RgkioOn6Y5EsQfndeDR/pEwO1/H4ff/HtsdNSKROvbptUCqzE6zYrHInZfH1EYbQMH07iCkA2WO1Ora0uO9pCSeEmlKr2+PgK pS2vpa7XnYnZpBghMGhAscNWLyYgi6elqsgoOaHLxNyVVeD0= PublicExponent: AQAB PrivateExponent: Vd6cuMRDxnuiFr367pJB39FYyDkNrZ9zAoyCt0idcHirglmV1ps7px2AQY2MOW/Tg2Xz59EqBA00mEOmnuRfdRXraqo1mxA9C2qGR2xHltNH2RVR5oT lahZLRUYZTDuLI7G/3IiPKrf5z/HFm2DkkzuxGqC8hWf9FOni49CqhYE= Prime1: waSsFnVlQrG/3SGh5GNV5o50PS8gE5L0/+GP2MIjkR3px1zR+LjfkVii1EaTda+Sq7B0ROI+M+R0JLh98Rr6XQ== Prime2: wNOsL3isJAE89C2XaESsJnm46vPZrqZ4XATub1dwOWNqVOji6KI9yTBc3MfmXkZVmy0I8Rm4ILLh5m/+0LNXYQ== Exponent1: muRjmptQ4iZYOEOcwZkLrx4nsIEvgTi9rKf6bgHsfTmWNBf1BKSsgBCMPowti6djBN5iQm9OHigRFwZUBzXzKQ== Exponent2: KE8Xe4T6Vzx7BYBSWlWgtxpS8aqwIrZiCrptLZFVwGlr3PwiEwd3awtVHkIbgjGpy5qKd/wsZYl/d7CJ0A7tgQ== Coefficient: p9WMT9cDpT7BXcKBXnrMLV8O31ujZ17nwlmlFe3+0n2VCx2T/CSz72xssffn0n2q0DaHHfu9SxR1RLgmDUzVEA== END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-ECDSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::ECDSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::ECDSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupted' ); ok( !eval { Net::DNS::SEC::ECDSA->sign( $sigdata, $wrongprivate ) }, 'signature not created using wrong private key' ); ok( !eval { Net::DNS::SEC::ECDSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not verifiable using wrong public key' ); ok( !eval { Net::DNS::SEC::ECDSA->verify( $sigdata, $key, undef ) }, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.15/t/00-pod.t0000644000175000017500000000071713616025670014226 0ustar willemwillem# $Id: 00-pod.t 1613 2018-01-15 13:47:13Z willem $ # use strict; use Test::More; my %prerequisite = ( 'Test::Pod' => 1.45 ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } my @poddirs = qw( blib demo ); my @allpods = all_pod_files(@poddirs); all_pod_files_ok(@allpods); exit; __END__ Net-DNS-SEC-1.15/t/10-keyset.t0000644000175000017500000003361413616025670014753 0ustar willemwillem# $Id: 10-keyset.t 1758 2019-10-14 13:17:11Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA') }; plan tests => 29; use_ok('Net::DNS::SEC::Keyset'); my %filename = ( set1 => 'keyset-test.tld.', set2 => 'prefix-test.tld.', set3 => 'keyset-corrupt-test.tld.', ); END { foreach ( values %filename ) { unlink($_) if -e $_; } } # # RSA keypair 1 # my $keyrr1 = new Net::DNS::RR <<'END'; test.tld. IN DNSKEY ( 256 3 5 AQO1gY5UFltQ4f0ZHnXPFQZfcQQNpXK5r0Rk05rLLmY0XeA1lu8ek7W1VHsBjkge9WU7efdp3U4a mxULRMQj7F0ByOK318agap2sIWYN13jV1RLxF5GPyLq+tp2ihEyI8x0P8c9RzgVn1ix4Xcoq+vKm WqDT1jHE4oBY/DzI8gyuJw== ) ; Key ID = 15791 END ok( $keyrr1, join ' ', algorithm( $keyrr1->algorithm ), 'public key created' ); my $keyfile1 = $filename{key1} = $keyrr1->privatekeyname; open( KEY1, ">$keyfile1" ) or die "Could not open $keyfile1"; print KEY1 << 'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: tYGOVBZbUOH9GR51zxUGX3EEDaVyua9EZNOayy5mNF3gNZbvHpO1tVR7AY5IHvVlO3n3ad1OGpsVC0TEI+xdAcjit9fGoGqdrCFmDdd41dUS8ReRj8i6vradooRMiPMdD/HPUc4FZ9YseF3KKvryplqg09YxxOKAWPw8yPIMric= PublicExponent: Aw== PrivateExponent: eQEJjWQ84Jaou2mj32NZlPYCs8Oh0R+C7eJnMh7uzZPqzmSfabfOeOL8q7QwFKOY0lFPm+jevGdjXNiCwp2TVWZrFINEMwUpxPJCvQQLh0k9Ah3NN2ELPBSlUjkRa10KaRSVSdDaYUM9X1/ZT/9RQagi4ckuy0x6UcRmoSng/Ms= Prime1: 3SNqKvY2geGDxgpqUKy2gGKq2LBRZ0CruBsVQXtoBH2dwq1bUScC9HxrTYaGxn2BELZsYRMeGVqZ1WqzsLXeTw== Prime2: 0h6u5+odYP2A7/eIALrUZtTDEi1rT+k434qR7Tb/4w/UkEIHw5bS/NP+AH2sNXtCzbYUx1h11m5EgDgjgoVUqQ== Exponent1: k2zxcfl5q+utLrGcNch5quxx5crg74Byery41lJFWFO+gcjni29XTahHiQRZ2akAtc7y62IUEOcROPHNIHk+3w== Exponent2: jBR0mpwTlf5V9U+wAHyNmeMstsjyNUYl6lxhSM9VQgqNtYFagmSMqI1UAFPII6eB3nljL5BOjvQtqtAXrFjjGw== Coefficient: YJYWzNpbdj/11mE4kUwaiH9GQbY+uA28tv4aVAwAEcKPaU1QQ2k8Jlm+VXxh9v02QCFJYln3416972oeCx9eyw== END close(KEY1); # # RSA keypair 2 # my $keyrr2 = new Net::DNS::RR <<'END'; test.tld. IN DNSKEY ( 256 3 8 AwEAAcXr1phQtnOdThOrgcwRplS/btblbtLGeHQoba55Gr8Scbx7AAw+LjwtFmbPlDhklC8+4BAf QB+6Jv7hOFT45J/RqDV3W5p0qDYcLYJObNbiFxQ64ogMYHx62w4oUeTS5CvpHNzSoiyhhFlf71RL EVeBK798h+hdPeEWvHdzbwwMxZGIXP/eNN5u5tkNExuuqq3e6BeguCLsuLgMzHdfpl7W20z3BExD c28DgPRWHJtJcB+iUd5oQdrw+G9qSq4kb7vk3OZUGrgkZskicT1A5rQsOgc4SrT4d25Qd6fthmi2 hZ86Y/2DP/NfR1mwWaN8ty7daqdcNpFQmKwQ+qpIV5c= ) ; Key ID = 63427 END ok( $keyrr2, join ' ', algorithm( $keyrr2->algorithm ), 'public key created' ); my $keyfile2 = $filename{key2} = $keyrr2->privatekeyname; open( KEY2, ">$keyfile2" ) or die "Could not open $keyfile2"; print KEY2 << 'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: xevWmFC2c51OE6uBzBGmVL9u1uVu0sZ4dChtrnkavxJxvHsADD4uPC0WZs+UOGSULz7gEB9AH7om/uE4VPjkn9GoNXdbmnSoNhwtgk5s1uIXFDriiAxgfHrbDihR5NLkK+kc3NKiLKGEWV/vVEsRV4Erv3yH6F094Ra8d3NvDAzFkYhc/9403m7m2Q0TG66qrd7oF6C4Iuy4uAzMd1+mXtbbTPcETENzbwOA9FYcm0lwH6JR3mhB2vD4b2pKriRvu+Tc5lQauCRmySJxPUDmtCw6BzhKtPh3blB3p+2GaLaFnzpj/YM/819HWbBZo3y3Lt1qp1w2kVCYrBD6qkhXlw== PublicExponent: AQAB PrivateExponent: S3dyet+Dwi+/3pYtxr8QGg5oV/5htHLC6R+lOrqorSR+Q6zuxrxK6t0SRp9t19bZ/e3Oh7cyvyY+yj7cOOIyYpIRvllFj25d2UwDOkVnEMRiom8Vg2ScwboinpJXL5YONIQNYlHaToRDr8R5wD1jXmc9ZCU6uSocdyAxOqbEN+ZWNnzGHjs4onoGMLyc7f2NbMhSHVW9tp7zilCQ1W3OF6coWI/L/vGk1xBQZ+OtkRRbJCTca3qflLm/1vPq8/H3gS5adrJcO+/mUlhPoKxEqekZZp+FQJVHTYp3MyGTVXVl2M8sozf9lU/malzlqve5snMLfCOWH8MOdsx7eo0N+Q== Prime1: +ajh2Bbk8r2DBvCw3u3ipji7zeD1LLMRdYlSuCpyIWGGoiCJrqX34zFCdDOO1gKa2QQG3OAGk3hZ1ddcgr+bnVNIEuVxJXe0Wg4e0ZPNMCe1333Hyt7ws2U+zosYNfrxOdPkj/S5XZkVyRE1Ixa79WCBJms+zgDPx30AUQXblw0= Prime2: yvKWeFcJhIleHVNwEkNtq+aOgcIhS2ex7zc/zKFGSGYXdWIl17oM3ohiPgmLVznJtIkCIcYoxbfxuLW0NDe2OJC7PUjOB3lAmtHAH3ZafNbr/PdlAZzHUZiLsiHF/m5wd+pN37rCj7emjASwsGjcx3rRsJQvqVZARj/TXe9eQDM= Exponent1: nMBIbKCTR0VtyyG8K3w43hyo7e7cgSA9SgragP9FgWf2XD0JtTpHlcIL82GbwQsJplA87tlJx7W80eLSFtWvIuxzSEn+7INoHVLYTsX6As4sBxK2Ks4nWruq34u9u8a/Rouf6jLBX98KKqA/OLTBdqMM885KNJWV367AUB7ZbNE= Exponent2: FyUHR/4VFcpcs1d6pnqOHVaT1fR/u4u93Rwd6IZT75nE/xwMWMfdA9vl6FFKVM5AVJhzZ8qjh7jsljYSsQnRfC31TI3rASsw1Pcqw+vJcgdIrnbATCjHCmUtOUlkvRl3NhXAf81atu0ozzsRs2yiERXOqCaeMN+nQNuyjTnpM8U= Coefficient: iUz9xrXzP2UaBruIps61HAbh6MV+OYDmliSnudXW5Ii1s3ANXMJodzgwqD+VesjC9dDE2nXMTCXKhpk46Qy8i3OYJ4T7vxoyHEYfID1PM0+whAwebRoKHBqQDEYgwTcqDX+qD4MMc1TaG/do/cgNc/1EyE03DP1plH6HhItECIo= END close(KEY2); # Create keysets my $datarrset = [$keyrr1, $keyrr2]; my $sigrr1 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); ok( $sigrr1, join ' ', algorithm( $sigrr1->algorithm ), 'signature created' ); my $sigrr2 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile2, ttl => 3600 ); ok( $sigrr2, join ' ', algorithm( $sigrr2->algorithm ), 'signature created' ); my $keyset = Net::DNS::SEC::Keyset->new($datarrset); is( ref($keyset), "Net::DNS::SEC::Keyset", "Keyset object created" ); ok( $keyset->string, '$keyset->string' ); $keyset->writekeyset; ok( Net::DNS::SEC::Keyset->new( $filename{set1} ), "write Keyset object" ); $keyset->writekeyset('prefix-'); my $read = Net::DNS::SEC::Keyset->new( $filename{set2} ); is( ref($read), "Net::DNS::SEC::Keyset", "read Keyset object" ); my @ds = $keyset->extract_ds; my $string0 = $ds[0]->string; my $string1 = $ds[1]->string; my $expect0 = new Net::DNS::RR('test.tld. IN DS 15791 5 1 C355F0F3F30C69BF2F7EA253ED82FBC280C2496B')->string; my $expect1 = new Net::DNS::RR('test.tld. IN DS 63426 8 1 6173eae9bf79853e2c041b1cda02a3d70c86a20b')->string; my $alg0 = algorithm( $ds[0]->algorithm ); my $dig0 = digtype( $ds[0]->digtype ); is( $string0, $expect0, "DS ($alg0/$dig0) created from keyset" ); my $alg1 = algorithm( $ds[1]->algorithm ); my $dig1 = digtype( $ds[1]->digtype ); is( $string1, $expect1, "DS ($alg1/$dig1) created from keyset" ); ## # Corrupted keyset open( KEYSET, ">$filename{set3}" ) or die "Could not open $filename{set3}"; print KEYSET $keyrr1->string, "\n"; print KEYSET $keyrr2->string, "\n"; my $sigstr = lc $sigrr1->string; # corrupt the base64 signature $sigstr =~ s/in.rrsig/IN RRSIG/; # fix collateral damage $sigstr =~ s/dnskey/DNSKEY/; print KEYSET $sigstr . "\n"; print KEYSET $sigrr2->string . "\n"; close(KEYSET); my $corrupt = Net::DNS::SEC::Keyset->new( $filename{set3} ); ok( !$corrupt, "Corrupted keyset not loaded" ); like( Net::DNS::SEC::Keyset->keyset_err, '/failed.+key/', 'Expected error message' ); # # The packet contains a keyset as returned from a bind nameserver # the keyset is signed with a signature valid until 2030 06 .. # After that the test may fail :-( # This is the code snippet used to get such a little packet as below. #use Net::DNS::Resolver; #my $res=Net::DNS::Resolver->new(); #$res->nameserver("10.0.53.204"); #$res->dnssec(1); #my $a_packet=$res->send("sub.tld","DNSKEY"); #$a_packet->print; #print unpack("H*",$a_packet->data); my $HexadecimalPacket = "e6cc81a000010004000000010373756203746c 640000300001c00c00300001000000200086010103050103bc54beaee1 1dc1a29ba945bf69d0db27b364b2dfe60396efff4c6fb359127ea696e1 4c66e1c6d23cd6f6c335e1679c61dd3fa4d68a689b8709ea686e43f175 6831193903613f6a5f3ff039b21eed9faad4edcb43191c76490ca0947a 9fa726740bc4449d6c58472a605913337d2dbddc94a7271d25c358fdaa 60fe1272a5f8b9c00c00300001000000200086010003050103f6d63a8a b9f775a0c7194d67edb5f249bf398c3d27d2985facf6fb7e25cc35c876 2eb8ea22200c847963442fb6634916dc2ec21cdbf2c7378799b8e7e399 e751ca1e25133349cab52ebf3fe8a5bc0239c28d64f4d8f609c191a7d2 d364578a159701ef73af93946b281f0aac42b42be17362c68d7a54bbb8 fa7bc6f70f455a75c00c002e000100000020009b003005020000006470 dc814040c02ced39d40373756203746c6400a7d9db75a4115794f871ec 71fc7469c74a6be1cf95434a00363506b354bf15656f7556c51355c8dc ac7f6c0a4061c0923e0bf341094e586619c2cb316949772ce5bd1e9949 f91b016f7e6bee0f6878e16b6e59ece086f8d5df68f048524e1bff3c09 dd15c203d28416600e936451d1646e71611ec95e12d709839369cbc442 c0c00c002e000100000020009b003005020000006470dc814040c02ced fbaf0373756203746c640017c6e59f317119da812c6b1e175e8aaec742 35a4bfad777e7759fa2daf7959f9611c26e11adde9bdc901c624ca6965 7b79653495e22647c5e0e5bedfe5524397d769d816746d10b2067472b4 f9b04fbde8e39d7861bd6773c80f632f55b46c7a537a83f0b5a50200c9 d2847b71d9dfaa643f558383e6e13d4e75f70029849444000029100000 0080000000"; $HexadecimalPacket =~ s/\n//g; $HexadecimalPacket =~ s/\s//g; my $packetdata = pack( "H*", $HexadecimalPacket ); my $packet = Net::DNS::Packet->new( \$packetdata ); $keyset = Net::DNS::SEC::Keyset->new($packet); is( ref($keyset), "Net::DNS::SEC::Keyset", "Keyset object from packet" ); is( join( " ", sort( $keyset->verify ) ), "14804 64431", "Verify method returned the two proper keytags" ); my $keyset2 = Net::DNS::SEC::Keyset->new($datarrset); is( ref($keyset2), "Net::DNS::SEC::Keyset", "Keyset object from DNSKEY RRset" ); #print $Net::DNS::SEC::Keyset->keyset_err; #$keyset->print; ######### my $rr; my @keyrr; my @sigrr; # Note that the order of pushing the RRs is important for successful testing. # All signatures have expiration date in 2030... this test should work for a while $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQOxFlzX8vShSG3JG2J/fngkgy64RoWr8ovG e7MuvPJqOMHTLM5V8+TJIahSoyUd990ictNv hDegUqLtZ8k5oQq44viFCU/H1apdEaJnLnXs cVo+08ATlEb90MYznK9K0pm2ixbyspzRrrXp nPi9vo9iU2xqWqw/Efha4vfi6QVs4w== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO4jhl6ilWV2mYjwWl7kcxrYyQsnnbV7pxX m48p+SgAr+R5SKyihkjg86IjZBQHFJKZ8RsZ dhclH2dikM+53uUEhrqVGhsqF8FsNi4nE9aM ISiX9Zs61pTYGYboYDvgpD1WwFbD4YVVlfk7 rCDP/zOE7H/AhkOenK2w7oiO0Jehcw== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO5fWabr7bNxDXT8YrIeclI9nvYYdKni3ef gJfU749O3QVX9MON6WK0ed00odQF4cLeN3vP SdhasLDI3Z3TzyAPBQS926oodxe78K9zwtPT 1kzJxvunOdJr6+6a7/+B6rF/cwfWTW50I0+q FykldldB44a1uS34u3HgZRQXDmAesw== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO6uGWsox2oH36zusGA0+w3uxkZMdByanSC jiaRHtkOA+gIxT8jmFvohxQBpVfYD+xG2pt+ qUWauWPFPjsIUBoFqHNpqr2/B4CTiZm/rSay HDghZBIMceMa6t4NpaOep79QmiE6oGq6yWRB swBkPZx9uZE7BqG+WLKEp136iwWyyQ== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 11354 example.com. GTqyJTRbKJ0LuWbAnNni1M4JZ1pn+nXY1Zuz Z0Kvt6OMTYCAFMFt0Wv9bncYkUuUSMGM7yGG 9Z7g7tcdb4TKCqQPYo4gr3Qj/xgC4LESoQs0 yAsJtLUiDfO6e4aWHmanpMGyGixYzHriS1pt SRzirL1fTgV+kdNs5zBatUHRnQc=) " ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 28109 example.com. WemQqA+uaeKqCy6sEVBU3LDORG3f+Zmix6qK 9j1WL83UMWdd6sxNh0QJ0YL54lh9NBx+Viz7 gajO+IM4MmayxKY4QVjp+6mHeE5zBVHMpTTu r5T0reNtTsa8sHr15fsI49yn5KOvuq+DKG1C gI6siM5RdFpDsS3Rmf8fiK1PyTs= )" ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 33695 example.com. M3yVwTOMw+jAKYY5c6oS4DH7OjOdfMOevpIe zdKqWXkehoDg9YOwz8ai17AmfgkjZnsoNu0W NMIcaVubR3n02bkVhJb7dEd8bhbegF8T1xkL 7rf9EQrPmM5GhHmVC90BGrcEhe//94hdXSVU CRBi6KPFWSZDldd1go133bk/b/o= )" ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 39800 example.com. Mmhn2Ql6ExmyHvZFWgt+CBRw5No8yM0rdH1b eU4is5gRbd3I0j5z6PdtpYjAkWiZNdYsRT0o P7TQIsADfB0FLIFojoREg8kp+OmbpRTsLTgO QYC95u5WodYGz03O0EbnQ7k4gkje6385G40D JVl0xVfujHBMbB+keiSphD3mG4I= )" ); push( @sigrr, $rr ); my $ks = Net::DNS::SEC::Keyset->new( [@keyrr], [@sigrr] ); ok( $ks, "Keyset created from two arrays." ); my @ks_sigs = $ks->sigs; ok( eq_array( [@ks_sigs], [@sigrr] ), "Sigs out equal to sigs in" ); my @ks_keys = $ks->keys; my @keydiff = key_difference( [@keyrr], [@ks_keys] ); is( scalar(@keydiff), 0, "Keys out equal to keys in" ); $datarrset = [$keyrr1, $keyrr2]; $sigrr1 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); $sigrr2 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile2, ttl => 3600 ); ok( $sigrr1, 'RSA signature created' ); $keyset = Net::DNS::SEC::Keyset->new( $datarrset, [$sigrr1] ); my @keytags = $keyset->verify; is( scalar(@keytags), 1, "Verify method returned the keytags" ); ok( $keyset->verify(15791), "Verification against keytag 15791" ); ok( !$keyset->verify(9734), "Verification against keytag 9734 failed" ); is( $keyset->keyset_err, "No signature made with 9734 found", "Expected error message" ); my $corruptible = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); my $unverifiable = Net::DNS::SEC::Keyset->new( $datarrset, [$corruptible] ); my $badsig = create Net::DNS::RR::RRSIG( [$sigrr1], $keyfile1, ttl => 3600 ); $corruptible->sigbin( $badsig->sigbin ); is( scalar( $unverifiable->extract_ds ), 0, 'No DS from unverifiable keyset' ); my $bogus = new Net::DNS::RR <<'END'; bogus.tld. IN DNSKEY 257 3 5 ( AQO1gY5UFltQ4f0ZHnXPFQZfcQQNpXK5r0Rk05rLLmY0XeA1lu8ek7W1VHsBjkge9WU7efdp3U4a mxULRMQj7F0ByOK318agap2sIWYN13jV1RLxF5GPyLq+tp2ihEyI8x0P8c9RzgVn1ix4Xcoq+vKm WqDT1jHE4oBY/DzI8gyuJw== ; Key ID = 15791 ) END my $mixed = Net::DNS::SEC::Keyset->new( [$bogus], [$sigrr1] ); ok( !$mixed, "Mixed keyset not loaded" ); like( Net::DNS::SEC::Keyset->keyset_err, '/No signature.+SEP/', 'Expected error message' ); like( Net::DNS::SEC::Keyset->keyset_err, '/Multiple names/', 'Expected error message' ); eval { $keyset->writekeyset( File::Spec->rel2abs('nonexdir') ) }; my ($exception) = split /\n/, "$@\n"; ok( $exception, "unwritable file\t[$exception]" ); # 0.17 backward compatibility (exercise code for test coverage only) eval { my $scalar = key_difference( [@keyrr], [@ks_sigs], [] ); }; eval { my @array = key_difference( [@keyrr], [@ks_sigs] ); }; exit; __END__ Net-DNS-SEC-1.15/t/00-install.t0000644000175000017500000000177313616025670015115 0ustar willemwillem# $Id: 00-install.t 1701 2018-07-28 07:36:34Z willem $ -*-perl-*- use strict; use Test::More; use File::Spec; use File::Find; use ExtUtils::MakeMaker; my @files; my $blib = File::Spec->catfile(qw(blib lib)); find( sub { push( @files, $File::Find::name ) if /\.pm$/ }, $blib ); my %manifest; open MANIFEST, 'MANIFEST' or plan skip_all => "MANIFEST: $!"; while () { chomp; my ( $volume, $directory, $name ) = File::Spec->splitpath($_); $manifest{lc $name}++ if $name; } close MANIFEST; plan skip_all => 'No versions from git checkouts' if -e '.git'; plan skip_all => 'Not sure how to parse versions.' unless eval { MM->can('parse_version') }; plan tests => scalar @files; foreach my $file ( sort @files ) { # reconcile files with MANIFEST my $version = MM->parse_version($file); ok( $version =~ /[\d.]{3}/, "file version: $version\t$file" ); my ( $volume, $directory, $name ) = File::Spec->splitpath($file); diag("File not in MANIFEST: $file") unless $manifest{lc $name}; } exit; __END__ Net-DNS-SEC-1.15/t/23-RSA-SHA256.t0000644000175000017500000000515013616025670014740 0ustar willemwillem# $Id: 23-RSA-SHA256.t 1758 2019-10-14 13:17:11Z willem $ -*-perl-*- # use strict; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; next if eval "use $package @revision; 1;"; plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_assign_RSA') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA256.example. IN DNSKEY 256 3 8 ( AwEAAZRSF/5NLnExp5n4M6ynF2Yok3N2aG9AWu8/vKQrZGFQcbL+WPGYbWUtMpiNXmvzTr2j86kN QU4wBawm589mjzXgVQRfXYDMMFhHMtagzEKOiNy2ojhhFyS7r2O2vUbo4hGbnM54ynSM1al+ygKU Gy1TNzHuYMiwh+gsQCsC5hfJ ; Key ID = 35418 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: lFIX/k0ucTGnmfgzrKcXZiiTc3Zob0Ba7z+8pCtkYVBxsv5Y8ZhtZS0ymI1ea/NOvaPzqQ1BTjAFrCbnz2aPNeBVBF9dgMwwWEcy1qDMQo6I3LaiOGEXJLuvY7a9RujiEZucznjKdIzVqX7KApQbLVM3Me5gyLCH6CxAKwLmF8k= PublicExponent: AQAB PrivateExponent: c74UZyhHo6GCDs73VDYYNmpXlnTCTn7D94ufY+VQsfgaofmF4xJ128yHfTBkjI0T1z1H+ZYUbjVfV9YMc3avLcXAb4YOEuNw0CSZrtTFc/oTvAyM9tKoa7hB9MSlYtmYvaWiEatHzKL0wYvo71jtfoTyDLQTISzrBWsA+K1a3hk= Prime1: wvw2lVu+kepiu0fasCrA3BlemVJ3XvWdd/y0sB5+egVGIJCn1bgkaSL/IP+683K28tN7hQYzMGiDBPymu3FeAw== Prime2: wruzE41ctH5D2SLhW4pi/pz+WSyeBUSvsmUe5kr4c9mlIqYUK1k72kmsjjZtD4eJsjq3xb/VGi+pcMuK2t1/Qw== Exponent1: lgk3AxTWfjcqA8wVpesv/ezzku0W95Xtto9YhhDg54m5XYOR8e1A7znDsaO2OnAyAIXlDQYpS32QG71Bmwhv+w== Exponent2: KyNVekFYhgtqkFFvxs2TPIAewDZoExayLTzFaZK2E0PllxVfZnLwFV04wpA//K6zzC3BxCbI2HIygPA2JGHo7Q== Coefficient: R3pSnerhKwfAHrH3iyojUzKzhM+AQ+97CWavx36eyKT3Yr/SIDANeeXGlT9U7RdxbkZzyeWbFNCnT+b89UX1RQ== END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $verified, 'signature verified using public key' ); my $corrupt = 'corrupted data'; my $verifiable = Net::DNS::SEC::RSA->verify( $corrupt, $key, $signature ); ok( !$verifiable, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.15/SEC.xs0000644000175000017500000002747313616025670013575 0ustar willemwillem #define XS_Id "$Id: SEC.xs 1763 2020-02-02 21:48:03Z willem $" =head1 NAME Net::DNS::SEC::libcrypto - Perl interface to OpenSSL libcrypto =head1 DESCRIPTION Perl XS extension providing access to the OpenSSL libcrypto library upon which the Net::DNS::SEC cryptographic components are built. =head1 COPYRIGHT Copyright (c)2018-2020 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut #ifdef __cplusplus extern "C" { #endif #define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include #include #include #ifdef __cplusplus } #endif #ifdef OPENSSL_NO_DSA #define NO_DSA #endif #ifdef OPENSSL_NO_RSA #define NO_RSA #endif #ifdef OPENSSL_NO_EC #define NO_ECCGOST #define NO_ECDSA #define NO_EdDSA #endif #ifndef OPENSSL_VERSION_NUMBER /* 0xMNN00PPSL retain backward compatibility */ #ifdef OPENSSL_VERSION_PRE_RELEASE #define OPENSSL_VERSION_NUMBER \ ( (OPENSSL_VERSION_MAJOR<<28) | (OPENSSL_VERSION_MINOR<<20) | (OPENSSL_VERSION_PATCH<<4) | 0x0L ) #else #define OPENSSL_VERSION_NUMBER \ ( (OPENSSL_VERSION_MAJOR<<28) | (OPENSSL_VERSION_MINOR<<20) | (OPENSSL_VERSION_PATCH<<4) | 0xfL ) #endif #endif #ifdef LIBRESSL_VERSION_NUMBER #undef OPENSSL_VERSION_NUMBER #if (LIBRESSL_VERSION_NUMBER < 0x20700000) #define OPENSSL_VERSION_NUMBER 0x10002000L #else #define OPENSSL_VERSION_NUMBER 0x10100000L #endif #define NO_ECCGOST #endif #if (OPENSSL_VERSION_NUMBER < 0x10101000) #define NO_EdDSA #define NO_SHA3 #define EC_POINT_set_affine_coordinates EC_POINT_set_affine_coordinates_GFp int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sig, size_t *sig_len, const unsigned char *data, size_t data_len) { EVP_DigestUpdate( ctx, data, data_len ); return EVP_DigestSignFinal( ctx, sig, sig_len ); } int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sig, size_t sig_len, const unsigned char *data, size_t data_len) { EVP_DigestUpdate( ctx, data, data_len ); return EVP_DigestVerifyFinal( ctx, sig, sig_len ); } #endif #if (OPENSSL_VERSION_NUMBER < 0x10100000) #define NO_ECCGOST #define EVP_MD_CTX_new() EVP_MD_CTX_create() #define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx)) int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { d->p = p; d->q = q; d->g = g; return 1; } int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { d->priv_key = priv_key; d->pub_key = pub_key; return 1; } int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { r->n = n; r->e = e; r->d = d; return 1; } int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { r->p = p; r->q = q; return 1; } #endif #if (OPENSSL_VERSION_NUMBER < 0x10001000) #define NO_ECDSA #error unsupported libcrypto version #include OPENSSL_VERSION_TEXT /* in error log; by any means, however reprehensible! */ #endif #ifndef NO_ECCGOST BIGNUM *bn_new_hex(const char *hex) { BIGNUM *bn = BN_new(); BN_hex2bn( &bn, hex ); return bn; } #endif int checkret(const int ret, int line) { if ( ret == 1 ) return ret; croak("libcrypto error (%s line %d)", __FILE__, line); } #define checkerr(arg) checkret( (arg), __LINE__ ) #define nocheckerr(arg) /* NOOP */ MODULE = Net::DNS::SEC PACKAGE = Net::DNS::SEC::libcrypto PROTOTYPES: ENABLE SV* VERSION(void) PREINIT: char *v = SvEND( newSVpv(XS_Id, 17) ); CODE: RETVAL = newSVpvf( "%s %s", v-5, OPENSSL_VERSION_TEXT ); OUTPUT: RETVAL #### EVP #### EVP_PKEY* EVP_PKEY_new() SV* EVP_sign(SV *message, EVP_PKEY *pkey, const EVP_MD *md=NULL) INIT: EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char *m = (unsigned char*) SvPVX(message); unsigned char sigbuf[512]; /* RFC3110(2) */ STRLEN mlen = SvCUR(message); STRLEN slen = sizeof(sigbuf); int r; CODE: checkerr( EVP_DigestSignInit( ctx, NULL, md, NULL, pkey ) ); r = EVP_DigestSign( ctx, sigbuf, &slen, m, mlen ); EVP_MD_CTX_free(ctx); EVP_PKEY_free(pkey); checkerr(r); RETVAL = newSVpvn( (char*)sigbuf, slen ); OUTPUT: RETVAL int EVP_verify(SV *message, SV *signature, EVP_PKEY *pkey, const EVP_MD *md=NULL) INIT: EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char *m = (unsigned char*) SvPVX(message); unsigned char *s = (unsigned char*) SvPVX(signature); STRLEN mlen = SvCUR(message); STRLEN slen = SvCUR(signature); CODE: checkerr( EVP_DigestVerifyInit( ctx, NULL, md, NULL, pkey ) ); RETVAL = EVP_DigestVerify( ctx, s, slen, m, mlen ); EVP_MD_CTX_free(ctx); EVP_PKEY_free(pkey); OUTPUT: RETVAL EVP_MD_CTX* EVP_MD_CTX_new() void EVP_MD_CTX_free(EVP_MD_CTX *ctx) void EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) CODE: checkerr( EVP_DigestInit( ctx, type ) ); void EVP_DigestUpdate(EVP_MD_CTX *ctx, SV *message) INIT: unsigned char *m = (unsigned char*) SvPVX(message); unsigned int mlen = SvCUR(message); CODE: checkerr( EVP_DigestUpdate( ctx, m, mlen ) ); SV* EVP_DigestFinal(EVP_MD_CTX *ctx) INIT: unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int size = sizeof(digest); const EVP_MD *type = EVP_MD_CTX_md( ctx ); CODE: checkerr( EVP_DigestFinal( ctx, digest, &size ) ); checkerr( EVP_DigestInit( ctx, type ) ); /* reinitialise; behave like Digest::SHA */ RETVAL = newSVpvn( (char*)digest, size ); OUTPUT: RETVAL const EVP_MD* EVP_md5() const EVP_MD* EVP_sha1() const EVP_MD* EVP_sha224() const EVP_MD* EVP_sha256() const EVP_MD* EVP_sha384() const EVP_MD* EVP_sha512() #ifndef NO_SHA3 const EVP_MD* EVP_sha3_224() const EVP_MD* EVP_sha3_256() const EVP_MD* EVP_sha3_384() const EVP_MD* EVP_sha3_512() #endif #### DSA #### #ifndef NO_DSA int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) CODE: RETVAL = checkerr( EVP_PKEY_assign( pkey, EVP_PKEY_DSA, (char*)key ) ); OUTPUT: RETVAL DSA* DSA_new() int DSA_set0_pqg(DSA *d, SV *p_SV, SV *q_SV, SV *g_SV) INIT: BIGNUM *p = BN_bin2bn( (unsigned char*) SvPVX(p_SV), SvCUR(p_SV), NULL ); BIGNUM *q = BN_bin2bn( (unsigned char*) SvPVX(q_SV), SvCUR(q_SV), NULL ); BIGNUM *g = BN_bin2bn( (unsigned char*) SvPVX(g_SV), SvCUR(g_SV), NULL ); CODE: RETVAL = checkerr( DSA_set0_pqg( d, p, q, g ) ); OUTPUT: RETVAL int DSA_set0_key(DSA *dsa, SV *y_SV, SV *x_SV) INIT: BIGNUM *x = BN_bin2bn( (unsigned char*) SvPVX(x_SV), SvCUR(x_SV), NULL ); BIGNUM *y = BN_bin2bn( (unsigned char*) SvPVX(y_SV), SvCUR(y_SV), NULL ); CODE: RETVAL = checkerr( DSA_set0_key( dsa, y, x ) ); OUTPUT: RETVAL #endif #### RSA #### #ifndef NO_RSA int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) CODE: RETVAL = checkerr( EVP_PKEY_assign( pkey, EVP_PKEY_RSA, (char*)key ) ); OUTPUT: RETVAL RSA* RSA_new() int RSA_set0_factors(RSA *r, SV *p_SV, SV *q_SV) INIT: BIGNUM *p = BN_bin2bn( (unsigned char*) SvPVX(p_SV), SvCUR(p_SV), NULL ); BIGNUM *q = BN_bin2bn( (unsigned char*) SvPVX(q_SV), SvCUR(q_SV), NULL ); CODE: RETVAL = checkerr( RSA_set0_factors( r, p, q ) ); OUTPUT: RETVAL int RSA_set0_key(RSA *r, SV *n_SV, SV *e_SV, SV *d_SV) INIT: BIGNUM *d = BN_bin2bn( (unsigned char*) SvPVX(d_SV), SvCUR(d_SV), NULL ); BIGNUM *e = BN_bin2bn( (unsigned char*) SvPVX(e_SV), SvCUR(e_SV), NULL ); BIGNUM *n = BN_bin2bn( (unsigned char*) SvPVX(n_SV), SvCUR(n_SV), NULL ); CODE: RETVAL = checkerr( RSA_set0_key( r, n, e, d ) ); OUTPUT: RETVAL #endif #### ECDSA #### #ifndef NO_ECDSA int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) CODE: RETVAL = checkerr( EVP_PKEY_assign( pkey, EVP_PKEY_EC, (char*)key ) ); OUTPUT: RETVAL # Creates new EC_KEY object using prescribed curve EC_KEY* EC_KEY_new_by_curve_name(int nid) int EC_KEY_set_private_key(EC_KEY *key, SV *prv_SV) INIT: BIGNUM *prv = BN_bin2bn( (unsigned char*) SvPVX(prv_SV), SvCUR(prv_SV), NULL ); CODE: RETVAL = EC_KEY_set_private_key( key, prv ); BN_clear_free(prv); checkerr(RETVAL); OUTPUT: RETVAL int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, SV *x_SV, SV *y_SV) INIT: BIGNUM *x = BN_bin2bn( (unsigned char*) SvPVX(x_SV), SvCUR(x_SV), NULL ); BIGNUM *y = BN_bin2bn( (unsigned char*) SvPVX(y_SV), SvCUR(y_SV), NULL ); CODE: RETVAL = EC_KEY_set_public_key_affine_coordinates( key, x, y ); BN_free(x); BN_free(y); checkerr(RETVAL); OUTPUT: RETVAL #endif #### EdDSA #### #ifndef NO_EdDSA EVP_PKEY* EVP_PKEY_new_raw_private_key(int nid, SV *key) CODE: RETVAL = EVP_PKEY_new_raw_private_key( nid, NULL, (unsigned char*) SvPVX(key) , SvCUR(key) ); OUTPUT: RETVAL EVP_PKEY* EVP_PKEY_new_raw_public_key(int nid, SV *key) CODE: RETVAL = EVP_PKEY_new_raw_public_key( nid, NULL, (unsigned char*) SvPVX(key) , SvCUR(key) ); OUTPUT: RETVAL #endif #################### #### Verify-only support for obsolete ECC-GOST #### #ifndef NO_ECCGOST EC_KEY* EC_KEY_new_ECCGOST() PREINIT: # GOST_R_34_10_2001_CryptoPro_A BIGNUM *a = bn_new_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94"); BIGNUM *b = bn_new_hex("00A6"); BIGNUM *p = bn_new_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97"); BIGNUM *q = bn_new_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893"); BIGNUM *x = bn_new_hex("01"); BIGNUM *y = bn_new_hex("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"); BIGNUM *h = bn_new_hex("01"); BN_CTX *ctx = BN_CTX_new(); EC_GROUP *group = EC_GROUP_new_curve_GFp(p, a, b, ctx); EC_POINT *G = EC_POINT_new(group); CODE: checkerr( EC_POINT_set_affine_coordinates(group, G, x, y, ctx) ); checkerr( EC_GROUP_set_generator(group, G, q, h) ); EC_POINT_free(G); BN_free(a); BN_free(b); BN_free(p); BN_free(q); BN_free(x); BN_free(y); BN_free(h); nocheckerr( EC_GROUP_check(group, ctx) ); BN_CTX_free(ctx); RETVAL = EC_KEY_new(); checkerr( EC_KEY_set_group(RETVAL, group) ); EC_GROUP_free(group); OUTPUT: RETVAL int ECCGOST_verify(SV *H, SV *r_SV, SV *s_SV, EC_KEY *eckey) INIT: STRLEN len = SvCUR(H); unsigned char *bin = (unsigned char*) SvPVX(H); BIGNUM *alpha = BN_bin2bn( bin, len, NULL ); BIGNUM *r = BN_bin2bn( (unsigned char*) SvPVX(r_SV), SvCUR(r_SV), NULL ); BIGNUM *s = BN_bin2bn( (unsigned char*) SvPVX(s_SV), SvCUR(s_SV), NULL ); const EC_GROUP *group = EC_KEY_get0_group(eckey); BN_CTX *ctx = BN_CTX_new(); BIGNUM *e = BN_new(); BIGNUM *m = BN_new(); BIGNUM *q = BN_new(); ECDSA_SIG *ecsig = ECDSA_SIG_new(); CODE: checkerr( EC_GROUP_get_order(group, q, ctx) ); checkerr( BN_mod(e, alpha, q, ctx) ); if ( BN_is_zero(e) ) BN_set_word(e, 1); BN_free(alpha); /* algebraic transformation of ECC-GOST into equivalent ECDSA problem */ checkerr( BN_mod_sub(m, q, s, q, ctx) ); checkerr( BN_mod_sub(s, q, e, q, ctx) ); BN_CTX_free(ctx); BN_free(e); BN_free(q); checkerr( ECDSA_SIG_set0(ecsig, r, s) ); BN_bn2binpad(m, bin, len); BN_free(m); RETVAL = ECDSA_do_verify( bin, len, ecsig, eckey ); EC_KEY_free(eckey); ECDSA_SIG_free(ecsig); OUTPUT: RETVAL #endif #################### void checkerr(int ret) CODE: checkerr(ret); #ifdef croak_memory_wrap void croak_memory_wrap() #endif #################### Net-DNS-SEC-1.15/MANIFEST0000644000175000017500000000136313616025777013736 0ustar willemwillemChanges Makefile.PL MANIFEST This list of files README SEC.xs typemap demo/getkeyset demo/key2ds demo/make-signed-keyset lib/Net/DNS/SEC.pm lib/Net/DNS/SEC/Digest.pm lib/Net/DNS/SEC/Keyset.pm lib/Net/DNS/SEC/Private.pm lib/Net/DNS/SEC/DSA.pm lib/Net/DNS/SEC/ECDSA.pm lib/Net/DNS/SEC/ECCGOST.pm lib/Net/DNS/SEC/EdDSA.pm lib/Net/DNS/SEC/RSA.pm lib/Net/DNS/SEC/libcrypto.pod t/00-install.t t/00-load.t t/00-pod.t t/10-keyset.t t/20-digest.t t/21-RSA-MD5.t t/22-RSA-SHA1.t t/23-RSA-SHA256.t t/24-RSA-SHA512.t t/31-DSA-SHA1.t t/51-ECDSA-P256.t t/52-ECDSA-P384.t t/61-Ed25519.t t/62-Ed448.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-DNS-SEC-1.15/Makefile.PL0000644000175000017500000001020513616025670014542 0ustar willemwillem# # $Id: Makefile.PL 1763 2020-02-02 21:48:03Z willem $ -*-perl-*- # use strict; use warnings; use Config; use ExtUtils::MakeMaker; use constant MM => eval $ExtUtils::MakeMaker::VERSION; # See perldoc ExtUtils::MakeMaker for details of how to influence # the contents of the Makefile that is written. my @author = ( 'Dick Franks', 'Olaf Kolkman' ); my %metadata = ( NAME => 'Net::DNS::SEC', VERSION_FROM => 'lib/Net/DNS/SEC.pm', ABSTRACT_FROM => 'lib/Net/DNS/SEC.pm', AUTHOR => MM < 6.58 ? "$author[0] et al" : [@author], LICENSE => 'mit', MIN_PERL_VERSION => 5.006, ); my %prerequisite = ( 'DynaLoader' => 1.04, 'File::Find' => 1.05, 'File::Spec' => 0.86, 'IO::File' => 1.08, 'MIME::Base64' => 2.13, 'Net::DNS' => 1.08, 'Test::More' => 0.47, ); my %optional; my @debris = qw(*.gcov *.gcda *.gcno *.lock); my $inc = ''; my $lib = '-lcrypto'; my $nul = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; if ( my $dir = $ENV{OPENSSL_PREFIX} ) { $inc = "-I$dir/include"; $lib = "-L$dir/lib -lcrypto"; } elsif (`pkg-config --modversion libcrypto 2>$nul`) { $inc = `pkg-config --cflags libcrypto 2>$nul`; $lib = `pkg-config --libs libcrypto 2>$nul`; } elsif ( $^O eq 'MSWin32' ) { $lib = '-llibeay32' if $Config{cc} =~ /cl/; $lib = '-leay32' if $Config{cc} =~ /gcc/; } $inc = $ENV{OPENSSL_INCLUDE} if $ENV{OPENSSL_INCLUDE}; $lib = $ENV{OPENSSL_LIB} if $ENV{OPENSSL_LIB}; WriteMakefile( %metadata, PREREQ_PM => {%prerequisite}, INC => $inc, LIBS => [$lib], META_MERGE => {recommends => {%optional}}, clean => {FILES => "@debris"}, ); package MY; ## customise generated Makefile sub test { return shift->SUPER::test() if $^O =~ /cygwin|MSWin/i; join '', shift->SUPER::test(), <<'END'; # suppress parallel test execution FULLPERLRUN = HARNESS_OPTIONS=c $(FULLPERL) END } sub dist { return join '', shift->SUPER::dist(), <<'END'; # $(PERM_RWX) raises security issues downstream PREOP = $(NOECHO) $(CHMOD) $(PERM_RW) demo$(DFSEP)* END } sub install { my $self = shift; my %install_type = qw(perl INSTALLARCHLIB site INSTALLSITEARCH vendor INSTALLVENDORARCH); my $install_site = join '', '$(DESTDIR)$(', $install_type{$self->{INSTALLDIRS}}, ')'; for ($install_site) { s/\$\(([A-Z_]+)\)/$self->{$1}/eg while /\$\(/; # expand Makefile macros s|([/])[/]+|$1|g; # remove gratuitous //s } eval 'require Net::DNS::SEC; $Net::DNS::SEC::VERSION =~ s/(\.\d)$/${1}0/'; my @version = grep $_, ( 'version', $Net::DNS::SEC::VERSION ); my $nameregex = '\W+Net\W+DNS\W+SEC.pm$'; my @installed = grep $_ && m/$nameregex/io, values %INC; my %occluded; foreach (@installed) { my $path = $1 if m/^(.+)$nameregex/i; my %seen; foreach (@INC) { $seen{$_}++; # find $path in @INC last if $_ eq $path; } foreach ( grep !$seen{$_}, @INC ) { $occluded{$_}++; # suppress install } } return $self->SUPER::install(@_) unless $occluded{$install_site}; my $message; warn $message = <<"AMEN"; ## ## The install location for this version of Net::DNS::SEC differs ## from the existing @version in your perl library at ## @installed ## ## The installation will be rendered ineffective because the ## old version will be found on the library search path before ## $install_site ## ## Makefile has been generated to support build and test only. ## AMEN my $echo = ' $(NOECHO) $(ECHO) "##"'; $message =~ s/##/$echo/eg; return join '', <<'END', $message; install : $(NOECHO) $(ECHO) "## Makefile supports build and test only" $(NOECHO) $(ECHO) "## (see message from Makefile.PL)" $(NOECHO) $(FALSE) test :: $(TEST_TYPE) END } sub postamble { my $nul = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; return <<"PlanB" unless `gcov -v 2>$nul`; test_cover : cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover \$(MAKE) test cover -summary PlanB my $ldflags = "-fprofile-arcs -ftest-coverage"; my $ccflags = "-O0 -DNO_ECCGOST $ldflags"; return <<"PlanA"; test_cover : cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover \$(MAKE) -W SEC.xs test CCFLAGS="$ccflags" OTHERLDFLAGS="$ldflags" gcov SEC.xs gcov2perl SEC.xs.gcov cover -summary \$(NOECHO) \$(TOUCH) SEC.c # force partial rebuild before install PlanA } __END__