Net-DNS-SEC-1.19/0000755000175000017500000000000014131012565012566 5ustar willemwillemNet-DNS-SEC-1.19/typemap0000644000175000017500000000025714131012547014174 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.19/WARNING0000644000175000017500000000105414131012547013616 0ustar willemwillem------------------------------------------------------------------------------ *************** ** 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. ------------------------------------------------------------------------------ $Id: WARNING 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.19/lib/0000755000175000017500000000000014131012565013334 5ustar willemwillemNet-DNS-SEC-1.19/lib/Net/0000755000175000017500000000000014131012565014062 5ustar willemwillemNet-DNS-SEC-1.19/lib/Net/DNS/0000755000175000017500000000000014131012565014506 5ustar willemwillemNet-DNS-SEC-1.19/lib/Net/DNS/SEC/0000755000175000017500000000000014131012565015120 5ustar willemwillemNet-DNS-SEC-1.19/lib/Net/DNS/SEC/Digest.pm0000644000175000017500000000774214131012547016707 0ustar willemwillempackage Net::DNS::SEC::Digest; use strict; use warnings; our $VERSION = (qw$Id: Digest.pm 1849 2021-08-19 08:25:20Z willem $)[2]; =head1 NAME Net::DNS::SEC::Digest - Message Digest Algorithms =head1 SYNOPSIS require Net::DNS::SEC::Digest; $object = Net::DNS::SEC::Digest::SHA->new(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 constant libcrypto_available => Net::DNS::SEC::libcrypto->can('EVP_MD_CTX_new'); BEGIN { die 'Net::DNS::SEC not available' unless libcrypto_available } my %digest = ( MD5 => sub { Net::DNS::SEC::libcrypto::EVP_md5() }, SHA_1 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, SHA_224 => sub { Net::DNS::SEC::libcrypto::EVP_sha224() }, SHA_256 => sub { Net::DNS::SEC::libcrypto::EVP_sha256() }, SHA_384 => sub { Net::DNS::SEC::libcrypto::EVP_sha384() }, SHA_512 => sub { Net::DNS::SEC::libcrypto::EVP_sha512() }, SHA3_224 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_224() }, SHA3_256 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_256() }, SHA3_384 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_384() }, SHA3_512 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_512() }, ); sub new { my ( $class, @param ) = @_; my ($index) = reverse split '::', join '_', $class, @param; my $evpmd = $digest{$index}; my $mdctx = Net::DNS::SEC::libcrypto::EVP_MD_CTX_new(); Net::DNS::SEC::libcrypto::EVP_DigestInit( $mdctx, &$evpmd ); return bless( {ctx => $mdctx, md => &$evpmd}, $class ); } sub add { my $self = shift; return Net::DNS::SEC::libcrypto::EVP_DigestUpdate( $self->{ctx}, shift ); } sub digest { my $self = shift; my $dgst = Net::DNS::SEC::libcrypto::EVP_DigestFinal( $self->{ctx} ); # reinitialise; emulate API offered by Digest::SHA Net::DNS::SEC::libcrypto::EVP_DigestInit( $self->{ctx}, $self->{md} ); return $dgst; } DESTROY { my $self = shift; return Net::DNS::SEC::libcrypto::EVP_MD_CTX_free( $self->{ctx} ); } ## no critic ProhibitMultiplePackages package Net::DNS::SEC::Digest::MD5; our @ISA = qw(Net::DNS::SEC::Digest); package Net::DNS::SEC::Digest::SHA; our @ISA = qw(Net::DNS::SEC::Digest); package Net::DNS::SEC::Digest::SHA3; our @ISA = qw(Net::DNS::SEC::Digest); 1; __END__ ######################################## =head1 METHODS =head2 new require Net::DNS::SEC::Digest; $object = Net::DNS::SEC::Digest::SHA->new(256); Creates and initialises a new digest object instance for the specified algorithm class. =head2 add $object->add($data); $object->add($more); Append specified data to the digest stream. =head2 digest $digest = $object->digest; Returns an octet string containing the calculated digest. =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2020,2021 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/DSA.pm0000644000175000017500000001010314131012547016060 0ustar willemwillempackage Net::DNS::SEC::DSA; use strict; use warnings; our $VERSION = (qw$Id: DSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 integer; use MIME::Base64; use constant DSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_DSA'); BEGIN { die 'DSA disabled or application has no "use Net::DNS::SEC"' unless DSA_configured } my %parameters = ( 3 => Net::DNS::SEC::libcrypto::EVP_sha1(), 6 => Net::DNS::SEC::libcrypto::EVP_sha1(), ); sub _index { return 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 $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_DSA( $p, $q, $g, $y, $x ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); return _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 $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_DSA( $p, $q, $g, $y, '' ); my $asn1 = _ASN1encode($sigbin); return 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; } return 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; return 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/libcrypto.pod0000644000175000017500000000277014131012547017641 0ustar willemwillem# # $Id: libcrypto.pod 1853 2021-10-11 10:40:59Z 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 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/ECCGOST.pm0000644000175000017500000000561014131012547016547 0ustar willemwillempackage Net::DNS::SEC::ECCGOST; use strict; use warnings; our $VERSION = (qw$Id: ECCGOST.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 constant Digest_GOST => defined( eval { require Digest::GOST } ); 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 { return 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 ( $y, $x ) = unpack 'a32 a32', reverse $keyrr->keybin; # public key my $eckey = Net::DNS::SEC::libcrypto::EC_KEY_new_ECCGOST( $x, $y ); my ( $s, $r ) = unpack 'a32 a32', $sigbin; # RFC5933, RFC4490 return 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/ECDSA.pm0000644000175000017500000001011214131012547016270 0ustar willemwillempackage Net::DNS::SEC::ECDSA; use strict; use warnings; our $VERSION = (qw$Id: ECDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 integer; use MIME::Base64; use constant ECDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA'); BEGIN { die 'ECDSA disabled or application has no "use Net::DNS::SEC"' unless ECDSA_configured } my %parameters = ( 13 => [415, 32, Net::DNS::SEC::libcrypto::EVP_sha256()], 14 => [715, 48, Net::DNS::SEC::libcrypto::EVP_sha384()], ); sub _index { return 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 $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $nid, $rawkey, '' ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); return _ASN1decode( $asn1, $keylen ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; die 'public key not ECDSA' unless $nid; return unless $sigbin; my ( $x, $y ) = unpack "a$keylen a$keylen", $keyrr->keybin; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $nid, $x, $y ); my $asn1 = _ASN1encode( $sigbin, $keylen ); return 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; } return 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; return 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/RSA.pm0000644000175000017500000000722114131012547016105 0ustar willemwillempackage Net::DNS::SEC::RSA; use strict; use warnings; our $VERSION = (qw$Id: RSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 integer; use MIME::Base64; use constant RSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA'); BEGIN { die 'RSA disabled or application has no "use Net::DNS::SEC"' unless RSA_configured } my %parameters = ( 1 => Net::DNS::SEC::libcrypto::EVP_md5(), 5 => Net::DNS::SEC::libcrypto::EVP_sha1(), 7 => Net::DNS::SEC::libcrypto::EVP_sha1(), 8 => Net::DNS::SEC::libcrypto::EVP_sha256(), 10 => Net::DNS::SEC::libcrypto::EVP_sha512(), ); sub _index { return 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 $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $n, $e, $d, $p, $q ); return 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 $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $modulus, $exponent, '', '', '' ); return 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/Keyset.pm0000644000175000017500000002172114131012547016725 0ustar willemwillempackage Net::DNS::SEC::Keyset; use strict; use warnings; our $VERSION = (qw$Id: Keyset.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 Carp; use File::Spec; use IO::File; 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 = File::Spec->catfile( @path, $name ); my @rr = Net::DNS::ZoneFile->new($file)->read; return $class->_new_from_keys_sigs( \@rr, \@rr ); } =head2 new (by signing keys) $keyset = Net::DNS::SEC::Keyset->new( [@keyrr], $privatekeypath ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; 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 = File::Spec->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] ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; 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) $resolver = Net::DNS::Resolver->new; $resolver->dnssec(1); $reply = $res->send ( "example.com", "DNSKEY" ); $keyset = Net::DNS::SEC::Keyset->new( $reply ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Creates a keyset object from a Net::DNS::Packet that contains the answer to a query for key records at the zone apex. 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}}; return @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}}; return @sigs; } =head2 extract_ds @ds = $keyset->extract_ds; die Net::DNS::SEC::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 Net::DNS::SEC::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; 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 } return; } =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, $arg1, @path ) = @_; shift; @path = shift() if $arg1 && File::Spec->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 = File::Spec->catfile( @path, $keysetname ); $filename =~ s/[.]+/\./; ## avoid antisocial consequences of $path with .. my $handle = IO::File->new( $filename, '>' ) or croak qq("$filename": $!); select( ( select($handle), $self->print )[0] ); close($handle); 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/Private.pm0000644000175000017500000001213414131012547017071 0ustar willemwillempackage Net::DNS::SEC::Private; use strict; use warnings; our $VERSION = (qw$Id: Private.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =head1 NAME Net::DNS::SEC::Private - DNSSEC Private key object =head1 SYNOPSIS use Net::DNS::SEC::Private; $private = Net::DNS::SEC::Private->new( $keypath ); $private = Net::DNS::SEC::Private->new( '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 integer; use Carp; use File::Spec; use IO::File; use constant SYMLINK => defined(&CORE::readlink); # Except Win32, VMS, RISC OS sub new { return scalar(@_) > 2 ? &_new_params : &_new_keyfile } sub _new_keyfile { my ( $class, $file ) = @_; my ($keypath) = SYMLINK ? grep( {$_} readlink($file), $file ) : $file; my ( $vol, $dir, $name ) = File::Spec->splitpath($keypath); # Format something like: 'Kbla.foo.+001+12345.private' as created by BIND dnssec-keygen. croak "$file does not appear to be a BIND private key" unless $name =~ /^K([^+]+)\+(\d+)\+(\d+)\.private$/; my @identifier = ( signame => $1, algorithm => 0 + $2, keytag => 0 + $3 ); my $handle = IO::File->new( $file, '<' ) or croak qq("$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, %parameter ) = @_; my $hashref = {}; while ( my ( $name, $value ) = each %parameter ) { $name =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; $hashref->{$name} = $value; } my $self = bless sub { $hashref->{shift()} }, $class; croak 'no algorithm specified' unless $self->algorithm; croak 'no signame specified' unless $self->signame; return $self; } our $AUTOLOAD; sub AUTOLOAD { ## Default method my ($self) = @_; my ($attribute) = $AUTOLOAD =~ m/::([^:]*)$/; $attribute =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; # Build a method in the class no strict 'refs'; ## no critic ProhibitNoStrict *{$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 = Net::DNS::SEC::Private->new( $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 = Net::DNS::SEC::Private->new( '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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC/EdDSA.pm0000644000175000017500000000663114131012547016344 0ustar willemwillempackage Net::DNS::SEC::EdDSA; use strict; use warnings; our $VERSION = (qw$Id: EdDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =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 integer; 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 { return keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; my ( $nid, $keylen ) = @{$parameters{$algorithm} || []}; die 'private key not EdDSA' unless $nid; my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_raw_private_key( $nid, $rawkey ); return 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 $nid; 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; return 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 original copyright notices appear in all copies and that both 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.19/lib/Net/DNS/SEC.pm0000644000175000017500000000674514131012547015472 0ustar willemwillempackage Net::DNS::SEC; use strict; use warnings; our $VERSION; $VERSION = '1.19'; our $SVNVERSION = (qw$Id: SEC.pm 1854 2021-10-11 10:43:36Z willem $)[2]; =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 base qw(Exporter DynaLoader); use Net::DNS 1.01 qw(:DEFAULT); our @EXPORT = ( @Net::DNS::EXPORT, qw(algorithm digtype key_difference) ); use integer; 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 { return &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 { return &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 API local $SIG{__DIE__}; my ($x) = grep { !$_->isa('Net::DNS::RR::DNSKEY') } @$a, @$b; croak sprintf( 'unexpected %s object in key list', ref $x ) if $x; my %index = map { ( $_->privatekeyname => 1 ) } @$b; return @$r = grep { !$index{$_->privatekeyname} } @$a; } ######################################## eval { Net::DNS::SEC->bootstrap($VERSION) } || croak; foreach (qw(DS CDS RRSIG)) { Net::DNS::RR->new( type => $_ ); # pre-load to access class methods } 1; __END__ =head1 COPYRIGHT Copyright (c)2014-2021 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 original copyright notices appear in all copies and that both 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.19/SEC.xs0000644000175000017500000003046214131012547013561 0ustar willemwillem #define XS_Id "$Id: SEC.xs 1853 2021-10-11 10:40:59Z 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-2021 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 original copyright notices appear in all copies and that both 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 #define PERL_REENTRANT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #ifndef OPENSSL_VERSION_NUMBER /* 0xMNN00PP0L retain backward compatibility */ #define OPENSSL_VERSION_NUMBER \ ( (OPENSSL_VERSION_MAJOR<<28) | (OPENSSL_VERSION_MINOR<<20) | (OPENSSL_VERSION_PATCH<<4) | 0x0L ) #endif #if (OPENSSL_VERSION_NUMBER < 0x40000000) #define OBSOLETE_API #undef OSSL_DEPRECATED #define OSSL_DEPRECATED(since) extern #include #include #include #include #include #else #include #include #include static OSSL_LIB_CTX *libctx = NULL; #endif #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_ECDSA #define NO_EdDSA #endif #ifdef OPENSSL_IS_BORINGSSL #define NO_SHA3 #endif #ifdef LIBRESSL_VERSION_NUMBER #undef OPENSSL_VERSION_NUMBER #define OPENSSL_VERSION_NUMBER 0x10100000L #endif #if (OPENSSL_VERSION_NUMBER < 0x10001000) #error unsupported libcrypto version #include OPENSSL_VERSION_TEXT /* in error log; by any means, however reprehensible! */ #endif #if (OPENSSL_VERSION_NUMBER < 0x10100000) #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 < 0x10101000) #define NO_EdDSA #define NO_SHA3 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 #define checkerr(arg) checkret( (arg), __LINE__ ) void checkret(const int ret, int line) { if ( ret <= 0 ) croak( "libcrypto error (%s line %d)", __FILE__, line ); } #ifndef OBSOLETE_API int EVP_PKEY_fromparams(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM_BLD *bld) { OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); int retval; checkerr( EVP_PKEY_fromdata_init(ctx) ); retval = EVP_PKEY_fromdata( ctx, ppkey, selection, params ); OSSL_PARAM_free(params); return retval; } #endif 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); STRLEN 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); CODE: checkerr( EVP_DigestFinal( ctx, digest, &size ) ); 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 EVP_PKEY* EVP_PKEY_new_DSA(SV *p_SV, SV *q_SV, SV *g_SV, SV *y_SV, SV *x_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 ); 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: #ifdef OBSOLETE_API DSA *dsa = DSA_new(); DSA_set0_pqg( dsa, p, q, g ); DSA_set0_key( dsa, y, x ); RETVAL = EVP_PKEY_new(); EVP_PKEY_assign( RETVAL, EVP_PKEY_DSA, (char*)dsa ); #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "DSA", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_P, p ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_Q, q ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_G, g ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PUB_KEY, y ) ); RETVAL = NULL; if ( SvCUR(x_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PRIV_KEY, x ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); } else { checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); BN_free(p); BN_free(q); BN_free(g); BN_free(x); BN_free(y); #endif OUTPUT: RETVAL #endif #### RSA #### #ifndef NO_RSA EVP_PKEY* EVP_PKEY_new_RSA(SV *n_SV, SV *e_SV, SV *d_SV, SV *p_SV, SV *q_SV) INIT: BIGNUM *n = BN_bin2bn( (unsigned char*) SvPVX(n_SV), SvCUR(n_SV), NULL ); BIGNUM *e = BN_bin2bn( (unsigned char*) SvPVX(e_SV), SvCUR(e_SV), NULL ); BIGNUM *d = BN_bin2bn( (unsigned char*) SvPVX(d_SV), SvCUR(d_SV), NULL ); 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: #ifdef OBSOLETE_API RSA *rsa = RSA_new(); RSA_set0_factors( rsa, p, q ); RSA_set0_key( rsa, n, e, d ); RETVAL = EVP_PKEY_new(); EVP_PKEY_assign( RETVAL, EVP_PKEY_RSA, (char*)rsa ); #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "RSA", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_N, n ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_E, e ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_D, d ) ); RETVAL = NULL; if ( SvCUR(p_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, p ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, q ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); } else { checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); BN_free(n); BN_free(e); BN_free(d); BN_free(p); BN_free(q); #endif OUTPUT: RETVAL #endif #### ECDSA #### #ifndef NO_ECDSA EVP_PKEY* EVP_PKEY_new_ECDSA(int nid, SV *qx_SV, SV *qy_SV) INIT: BIGNUM *qx = BN_bin2bn( (unsigned char*) SvPVX(qx_SV), SvCUR(qx_SV), NULL ); BIGNUM *qy = BN_bin2bn( (unsigned char*) SvPVX(qy_SV), SvCUR(qy_SV), NULL ); #ifdef OBSOLETE_API EC_KEY *eckey = EC_KEY_new_by_curve_name(nid); #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "EC", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); #endif CODE: #ifdef OBSOLETE_API if ( SvCUR(qy_SV) > 0 ) { checkerr( EC_KEY_set_public_key_affine_coordinates( eckey, qx, qy ) ); } else { checkerr( EC_KEY_set_private_key( eckey, qx ) ); } RETVAL = EVP_PKEY_new(); checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_EC, (char*)eckey ) ); #else if ( nid == 415 ) checkerr( OSSL_PARAM_BLD_push_utf8_string( bld, OSSL_PKEY_PARAM_GROUP_NAME, "P-256", 0 ) ); if ( nid == 715 ) checkerr( OSSL_PARAM_BLD_push_utf8_string( bld, OSSL_PKEY_PARAM_GROUP_NAME, "P-384", 0 ) ); RETVAL = NULL; if ( SvCUR(qy_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_EC_PUB_X, qx ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_EC_PUB_Y, qy ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } else { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PRIV_KEY, qx ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #endif BN_clear_free(qx); BN_clear_free(qy); OUTPUT: RETVAL #endif #### EdDSA #### #ifndef NO_EdDSA EVP_PKEY* EVP_PKEY_new_raw_public_key(int nid, SV *key) ALIAS: EVP_PKEY_new_raw_private_key = 1 INIT: unsigned char *rawkey = (unsigned char*) SvPVX(key); STRLEN keylen = SvCUR(key); #ifndef OBSOLETE_API EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); #endif CODE: #ifdef OBSOLETE_API if ( ix > 0 ) { RETVAL = EVP_PKEY_new_raw_private_key( nid, NULL, rawkey , keylen ); } else { RETVAL = EVP_PKEY_new_raw_public_key( nid, NULL, rawkey , keylen ); } #else if ( nid == 1087 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED25519", NULL ); if ( nid == 1088 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED448", NULL ); RETVAL = NULL; if ( ix > 0 ) { checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PRIV_KEY, rawkey, keylen ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); } else { checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PUB_KEY, rawkey, keylen ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #endif OUTPUT: RETVAL #endif #################### void checkerr(int ret) #ifdef croak_memory_wrap void croak_memory_wrap() #endif #ifdef DEBUG void ERR_print_errors(SV *filename) CODE: BIO *bio = BIO_new_file( SvPVX(filename), "w" ); ERR_print_errors(bio); BIO_free(bio); #endif #################### Net-DNS-SEC-1.19/Changes0000644000175000017500000004535214131012547014072 0ustar willemwillemRevision history for Perl extension Net::DNS::SEC. **** 1.19 Oct 11, 2021 Use new EVP_PKEY construction API for OpenSSL post 3.x.x. Remove support for obsolete ECC-GOST. Add LICENSE file to comply with Fedora/RedHat announcement and WARNING of restrictions on use of strong cryptography. **** 1.18 Oct 2, 2020 Eliminate bareword filehandle usage. Eliminate indirect object syntax. Eliminate grep/map . **** 1.17 Jun 26, 2020 Recognise BIND private key accessed via symbolic link. **** 1.16 May 11, 2020 Improve testing of verify() functions. Rework code in Digest.pm SEC.xs code reduction. **** 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. **** 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 1854 2021-10-11 10:43:36Z willem $ Net-DNS-SEC-1.19/t/0000755000175000017500000000000014131012565013031 5ustar willemwillemNet-DNS-SEC-1.19/t/20-digest.t0000644000175000017500000000540214131012547014715 0ustar willemwillem#!/usr/bin/perl # $Id: 20-digest.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; 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;"; ## no critic 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 => 22; 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); my ( $head, $tail ) = unpack 'a20 a*', $text; $object->add($text); is( unpack( 'H*', $object->digest ), $digest{$mnemonic}, "message digest $mnemonic" ); $object->add($head); $object->add($tail); is( unpack( 'H*', $object->digest ), $digest{$mnemonic}, "concatenated digest $mnemonic" ); return; } 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', 8 ) 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.19/t/62-Ed448.t0000644000175000017500000000433614131012547014241 0ustar willemwillem#!/usr/bin/perl # $Id: 62-Ed448.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; 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;"; ## no critic 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( my $class = 'Net::DNS::SEC::EdDSA' ); # Specimen private and public keys taken from RFC8080 my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 16 (ED448) PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up EdDSA private key' ); my $sigdata = 'arbitrary data'; ## Note: ED448 signing is deterministic my $corrupt = 'corrupted data'; my $signature = pack 'H*', join '', qw( 01f546bfe2fd040170133b3797c1c95a31dbb2f216d95f44ced76998f7dc8e16 8f7082550a83eea4ebeb66e34696249d790db5ba76047ca9002a3dedc10e6d26 bddc8378ff1a81815aa146e72a0d9672553b2aa5cc38354cbdf2b9c4b8e36a1c f7651f828fb64c200e2ee5d0686490910c00 ); my $signed = eval { $class->sign( $sigdata, $private ) } || ''; ok( $signed eq $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.19/t/00-load.t0000644000175000017500000000442414131012547014356 0ustar willemwillem#!/usr/bin/perl # $Id: 00-load.t 1831 2021-02-11 23:03:17Z willem $ -*-perl-*- # use strict; use warnings; 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::Spec IO::File MIME::Base64 Net::DNS Test::More ); my @diag = "\nThese tests were run using:"; foreach my $module ( sort @module ) { eval "require $module"; ## no critic for ( 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"; ## no critic 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( $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.19/t/00-pod.t0000644000175000017500000000100314131012547014207 0ustar willemwillem#!/usr/bin/perl # $Id: 00-pod.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; 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;"; ## no critic 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.19/t/23-RSA-SHA256.t0000644000175000017500000000530514131012547014736 0ustar willemwillem#!/usr/bin/perl # $Id: 23-RSA-SHA256.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'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($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.19/t/21-RSA-MD5.t0000644000175000017500000000526614131012547014457 0ustar willemwillem#!/usr/bin/perl # $Id: 21-RSA-MD5.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'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($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.19/t/10-keyset.t0000644000175000017500000003347114131012547014750 0ustar willemwillem#!/usr/bin/perl # $Id: 10-keyset.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'Digest::SHA' => 5.23, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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 = Net::DNS::RR->new( <<'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; my $handle1 = IO::File->new( $keyfile1, '>' ) or die qq(open: "$keyfile1" $!); print $handle1 <<'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($handle1); # # RSA keypair 2 # my $keyrr2 = Net::DNS::RR->new( <<'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; my $handle2 = IO::File->new( $keyfile2, '>' ) or die qq(open: "$keyfile2" $!); print $handle2 <<'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($handle2); # Create keysets my $datarrset = [$keyrr1, $keyrr2]; my $sigrr1 = Net::DNS::RR::RRSIG->create( $datarrset, $keyfile1, ttl => 3600 ); ok( $sigrr1, join ' ', algorithm( $sigrr1->algorithm ), 'signature created' ); my $sigrr2 = Net::DNS::RR::RRSIG->create( $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 = Net::DNS::RR->new('test.tld. IN DS 15791 5 1 C355F0F3F30C69BF2F7EA253ED82FBC280C2496B')->string; my $expect1 = Net::DNS::RR->new('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 my $handle3 = IO::File->new( $filename{set3}, '>' ) or die qq(open: "$filename{set3}" $!); print $handle3 $keyrr1->string, "\n"; print $handle3 $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 $handle3 $sigstr . "\n"; print $handle3 $sigrr2->string . "\n"; close($handle3); 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 push( @keyrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN DNSKEY 256 3 5 ( AQOxFlzX8vShSG3JG2J/fngkgy64RoWr8ovGe7MuvPJqOMHTLM5V8+TJIahSoyUd990ictNv hDegUqLtZ8k5oQq44viFCU/H1apdEaJnLnXscVo+08ATlEb90MYznK9K0pm2ixbyspzRrrXp nPi9vo9iU2xqWqw/Efha4vfi6QVs4w== ) END push( @keyrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN DNSKEY 256 3 5 ( AQO4jhl6ilWV2mYjwWl7kcxrYyQsnnbV7pxXm48p+SgAr+R5SKyihkjg86IjZBQHFJKZ8RsZ dhclH2dikM+53uUEhrqVGhsqF8FsNi4nE9aMISiX9Zs61pTYGYboYDvgpD1WwFbD4YVVlfk7 rCDP/zOE7H/AhkOenK2w7oiO0Jehcw== ) END push( @keyrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN DNSKEY 256 3 5 ( AQO5fWabr7bNxDXT8YrIeclI9nvYYdKni3efgJfU749O3QVX9MON6WK0ed00odQF4cLeN3vP SdhasLDI3Z3TzyAPBQS926oodxe78K9zwtPT1kzJxvunOdJr6+6a7/+B6rF/cwfWTW50I0+q FykldldB44a1uS34u3HgZRQXDmAesw== ) END push( @keyrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN DNSKEY 256 3 5 ( AQO6uGWsox2oH36zusGA0+w3uxkZMdByanSCjiaRHtkOA+gIxT8jmFvohxQBpVfYD+xG2pt+ qUWauWPFPjsIUBoFqHNpqr2/B4CTiZm/rSayHDghZBIMceMa6t4NpaOep79QmiE6oGq6yWRB swBkPZx9uZE7BqG+WLKEp136iwWyyQ== ) END push( @sigrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 11354 example.com. GTqyJTRbKJ0LuWbAnNni1M4JZ1pn+nXY1ZuzZ0Kvt6OMTYCAFMFt0Wv9bncYkUuUSMGM7yGG 9Z7g7tcdb4TKCqQPYo4gr3Qj/xgC4LESoQs0yAsJtLUiDfO6e4aWHmanpMGyGixYzHriS1pt SRzirL1fTgV+kdNs5zBatUHRnQc= ) END push( @sigrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 28109 example.com. WemQqA+uaeKqCy6sEVBU3LDORG3f+Zmix6qK9j1WL83UMWdd6sxNh0QJ0YL54lh9NBx+Viz7 gajO+IM4MmayxKY4QVjp+6mHeE5zBVHMpTTur5T0reNtTsa8sHr15fsI49yn5KOvuq+DKG1C gI6siM5RdFpDsS3Rmf8fiK1PyTs= ) END push( @sigrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 33695 example.com. M3yVwTOMw+jAKYY5c6oS4DH7OjOdfMOevpIezdKqWXkehoDg9YOwz8ai17AmfgkjZnsoNu0W NMIcaVubR3n02bkVhJb7dEd8bhbegF8T1xkL7rf9EQrPmM5GhHmVC90BGrcEhe//94hdXSVU CRBi6KPFWSZDldd1go133bk/b/o= ) END push( @sigrr, Net::DNS::RR->new( <<'END' ) ); example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 39800 example.com. Mmhn2Ql6ExmyHvZFWgt+CBRw5No8yM0rdH1beU4is5gRbd3I0j5z6PdtpYjAkWiZNdYsRT0o P7TQIsADfB0FLIFojoREg8kp+OmbpRTsLTgOQYC95u5WodYGz03O0EbnQ7k4gkje6385G40D JVl0xVfujHBMbB+keiSphD3mG4I= ) END 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 = Net::DNS::RR::RRSIG->create( $datarrset, $keyfile1, ttl => 3600 ); $sigrr2 = Net::DNS::RR::RRSIG->create( $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 = Net::DNS::RR::RRSIG->create( $datarrset, $keyfile1, ttl => 3600 ); my $unverifiable = Net::DNS::SEC::Keyset->new( $datarrset, [$corruptible] ); my $badsig = Net::DNS::RR::RRSIG->create( [$sigrr1], $keyfile1, ttl => 3600 ); $corruptible->sigbin( $badsig->sigbin ); is( scalar( $unverifiable->extract_ds ), 0, 'No DS from unverifiable keyset' ); my $bogus = Net::DNS::RR->new( <<'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.19/t/51-ECDSA-P256.t0000644000175000017500000000740514131012547014720 0ustar willemwillem#!/usr/bin/perl # $Id: 51-ECDSA-P256.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; 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;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA') }; 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( my $class = 'Net::DNS::SEC::ECDSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.3 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: w+AjPo650IA8DWeEq5QqZ2LWYpuC/oeEaYaGE1ZvKyA= Created: 20141209015301 Publish: 20141209015301 Activate: 20141209015301 END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up ECDSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'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; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'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($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-ECDSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.19/t/00-install.t0000644000175000017500000000225314131012547015103 0ustar willemwillem#!/usr/bin/perl # $Id: 00-install.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; use Test::More; use File::Spec; use File::Find; use IO::File; use ExtUtils::MakeMaker; my %manifest; my $handle = IO::File->new( 'MANIFEST', '<' ) or BAIL_OUT("MANIFEST: $!"); while (<$handle>) { my ($filename) = split; $manifest{$filename}++; } close $handle; 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 keys %manifest; foreach ( sort keys %manifest ) { # reconcile files with MANIFEST next unless ok( -f $_, "file exists\t$_" ); next unless /\.pm$/; next unless /^lib/; my $module = File::Spec->catfile( 'blib', $_ ); # library component diag("Missing module: $module") unless -f $module; my $version = MM->parse_version($_); # module version diag("\$VERSION = $version\t$_") unless $version =~ /^\d/; } my @files; # flag MANIFEST omissions find( sub { push( @files, $File::Find::name ) if /\.pm$/ }, 'lib' ); foreach ( sort @files ) { diag("Filename not in MANIFEST: $_") unless $manifest{$_}; } exit; __END__ Net-DNS-SEC-1.19/t/22-RSA-SHA1.t0000644000175000017500000001510514131012547014560 0ustar willemwillem#!/usr/bin/perl # $Id: 22-RSA-SHA1.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'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($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); # The following tests are not replicated for other RSA/SHA flavours my $wrongkey = Net::DNS::RR->new( <<'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; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'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($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-RSA private key' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, 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); $class->verify( $sigdata, $key, $signature ); }; exit; __END__ Net-DNS-SEC-1.19/t/31-DSA-SHA1.t0000644000175000017500000001124414131012547014542 0ustar willemwillem#!/usr/bin/perl # $Id: 31-DSA-SHA1.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; 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;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled DSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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( my $class = 'Net::DNS::SEC::DSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'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($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up DSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'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; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'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($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-DSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.19/t/52-ECDSA-P384.t0000644000175000017500000000371214131012547014720 0ustar willemwillem#!/usr/bin/perl # $Id: 52-ECDSA-P384.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; 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;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA') }; 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( my $class = 'Net::DNS::SEC::ECDSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.3 Algorithm: 14 (ECDSAP384SHA384) PrivateKey: mvuhyr+QDMqo4bpeREFRM2w8qZsBiLiCouR0sihdinvpRA3zA/dByohgH4CLI7Kr Created: 20141209021155 Publish: 20141209021155 Activate: 20141209021155 END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up ECDSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.19/t/24-RSA-SHA512.t0000644000175000017500000000542014131012547014730 0ustar willemwillem#!/usr/bin/perl # $Id: 24-RSA-SHA512.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_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( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'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($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupt' ); exit; __END__ Net-DNS-SEC-1.19/t/61-Ed25519.t0000644000175000017500000000605214131012547014403 0ustar willemwillem#!/usr/bin/perl # $Id: 61-Ed25519.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; 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;"; ## no critic 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( my $class = 'Net::DNS::SEC::EdDSA' ); # Specimen private and public keys taken from RFC8080 my $key = Net::DNS::RR->new( <<'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; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 15 (ED25519) PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI= END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up EdDSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'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; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'END'; Private-key-format: v1.2 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: m/dWhFblAGQnabJoKbs0vXoQidjNzlTcbPAqntUXWi0= END close($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-EdDSA private key' ); my $sigdata = 'arbitrary data'; ## Note: ED25519 signing is deterministic my $corrupt = 'corrupted data'; my $signature = pack 'H*', join '', qw( cb7a60fedc08b09995d522410962c6eb0fd0ea34e16fe094c99582fbb14e7a87 c14292cf8c28af0efe6ee30cbf9d643cba3ab56f1e1ae27b6074147ed9c55a0e ); my $signed = eval { $class->sign( $sigdata, $private ); } || ''; ok( $signed eq $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.19/MANIFEST0000644000175000017500000000140314131012565013715 0ustar willemwillemChanges LICENSE Makefile.PL MANIFEST This list of files README WARNING 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.19/Makefile.PL0000644000175000017500000001042714131012547014544 0ustar willemwillem# # $Id: Makefile.PL 1853 2021-10-11 10:40:59Z willem $ -*-perl-*- # use 5.008008; use strict; use warnings; use Config; use ExtUtils::MakeMaker; my $MM = $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.008008, CONFIGURE_REQUIRES => { 'ExtUtils::MakeMaker' => 6.66, }, TEST_REQUIRES => { 'File::Find' => 1.05, 'File::Spec' => 0.86, 'Test::More' => 0.47, } ); my %prerequisite = ( 'Carp' => 1.10, 'DynaLoader' => 1.04, 'Exporter' => 5.56, 'File::Spec' => 0.86, 'MIME::Base64' => 2.13, 'Net::DNS' => 1.08, ); 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; return 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 = $(CHMOD) $(PERM_RW) $(DISTVNAME)$(DFSEP)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 } my @version = ( 'version', eval { require Net::DNS::SEC; $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 = m/^(.+)$nameregex/io ? $1 : ''; 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 would be rendered ineffective because the ## installed version occurs in the library search path before ## $install_site ## ## The generated Makefile supports 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 $devnull = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; return <<"PlanB" unless `gcov -v 2>$devnull`; test_cover : cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover \$(MAKE) test cover -summary PlanB my $ldflags = "-fprofile-arcs -ftest-coverage"; my $ccflags = "-O0 $ldflags"; return <<"PlanA"; test_cover : cover -delete \$(NOECHO) \$(TOUCH) SEC.c # recompile XS component 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 XS rebuild before install PlanA } __END__ Net-DNS-SEC-1.19/META.json0000664000175000017500000000245614131012565014220 0ustar willemwillem{ "abstract" : "DNSSEC extensions to Net::DNS", "author" : [ "Dick Franks", "Olaf Kolkman" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.44, 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" : "6.66" } }, "runtime" : { "recommends" : {}, "requires" : { "Carp" : "1.1", "DynaLoader" : "1.04", "Exporter" : "5.56", "File::Spec" : "0.86", "MIME::Base64" : "2.13", "Net::DNS" : "1.08", "perl" : "5.008008" } }, "test" : { "requires" : { "File::Find" : "1.05", "File::Spec" : "0.86", "Test::More" : "0.47" } } }, "release_status" : "stable", "version" : "1.19", "x_serialization_backend" : "JSON::PP version 4.00" } Net-DNS-SEC-1.19/LICENSE0000644000175000017500000000173714131012547013603 0ustar willemwillem 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 original copyright notices appear in all copies and that both 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: LICENSE 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.19/README0000644000175000017500000001215014131012547013445 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::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 library, run the following: tar xvzf openssl-3.*.tar.gz cd openssl-3.* ./config shared make # require only libcrypto.so* 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 original copyright notices appear in all copies and that both 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 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.19/META.yml0000664000175000017500000000136014131012565014041 0ustar willemwillem--- abstract: 'DNSSEC extensions to Net::DNS' author: - 'Dick Franks' - 'Olaf Kolkman' build_requires: ExtUtils::MakeMaker: '0' File::Find: '1.05' File::Spec: '0.86' Test::More: '0.47' configure_requires: ExtUtils::MakeMaker: '6.66' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.44, 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: Carp: '1.1' DynaLoader: '1.04' Exporter: '5.56' File::Spec: '0.86' MIME::Base64: '2.13' Net::DNS: '1.08' perl: '5.008008' version: '1.19' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Net-DNS-SEC-1.19/demo/0000755000175000017500000000000014131012565013512 5ustar willemwillemNet-DNS-SEC-1.19/demo/key2ds0000644000175000017500000000162714131012547014644 0ustar willemwillem#!/usr/bin/perl #$Id: key2ds 1807 2020-09-28 11:38:28Z willem $ # A little util to convert DNSKEY records to DS records # from stdin to stdout # # Author: Miek Gieben, NLnetLabs use strict; use warnings; use Net::DNS::SEC; use Net::DNS::ZoneFile; my $source = Net::DNS::ZoneFile->new('-'); # STDIN while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); foreach my $digtype (qw(SHA256 SHA1)) { my $ds = Net::DNS::RR::DS->create( $keyrr, digtype => $digtype ); $ds->print; # STDOUT } } 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 Net-DNS-SEC-1.19/demo/getkeyset0000644000175000017500000000413314131012547015442 0ustar willemwillem#!/usr/bin/perl #$Id: getkeyset 1807 2020-09-28 11:38:28Z willem $ use strict; use warnings; 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.19/demo/make-signed-keyset0000644000175000017500000000532314131012547017126 0ustar willemwillem#!/usr/bin/perl #$Id: make-signed-keyset 1807 2020-09-28 11:38:28Z willem $ # # takes a bind public key file and creates a self-signed keyset # use strict; use warnings; 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 = Net::DNS::ZoneFile->new(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 my $ds (@ds) { $ds->print(); } } return; } =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