Net-DNS-SEC-1.03/0000755000175000017500000000000012760026557012573 5ustar willemwillemNet-DNS-SEC-1.03/META.json0000664000175000017500000000256012760026557014221 0ustar willemwillem{ "abstract" : "DNSSEC extensions to Net::DNS", "author" : [ "Olaf Kolkman", "Dick Franks" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.18, CPAN::Meta::Converter version 2.143240", "license" : [ "mit" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Net-DNS-SEC", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "recommends" : { "Crypt::OpenSSL::DSA" : "0.15", "Crypt::OpenSSL::EC" : "1.01", "Crypt::OpenSSL::ECDSA" : "0.06", "Crypt::OpenSSL::Random" : "0.1", "Digest::GOST" : "0.06", "Digest::SHA" : "5.23" }, "requires" : { "Crypt::OpenSSL::Bignum" : "0.05", "Crypt::OpenSSL::RSA" : "0.28", "File::Spec" : "0.86", "MIME::Base64" : "2.11", "Net::DNS" : "1.01", "Test::More" : "0.47", "perl" : "5.006" } } }, "release_status" : "stable", "version" : "1.03" } Net-DNS-SEC-1.03/README0000644000175000017500000001227512760026475013461 0ustar willemwillemNet::DNS::SEC - DNSSEC extensions to Net::DNS ============================================= 1. DESCRIPTION ----------- This module is designed as an extension the Net::DNS package (http://www.net-dns.org/). The module implements the cryptographic signature generation and verification functions that are relevant for DNSSEC operations. ** ** *************** ** ** WARNING ** ** *************** ** THE USE AND/OR HANDLING OF STRONG ENCRYPTION TECHNOLOGIES IS ** PROHIBITED OR SEVERELY RESTRICTED IN MANY TERRITORIES. ** PLEASE BE SURE THAT YOU FULLY UNDERSTAND THE LEGAL POSITION ** IN YOUR COUNTRY BEFORE ATTEMPTING TO INSTALL THIS MODULE OR ** ANY OF THE PREREQUISITE CRYPTOGRAPHY PACKAGES. ** Net::DNS::SEC also provides a class for handling keysets. Keysets are administrative files used by the BIND tools for key maintenance tasks. Net::DNS::SEC::Keyset provides an abstract interface for doing fun things with them. See also the 'pod' documentation in: Net::DNS::RR::DNSKEY Net::DNS::RR::DS Net::DNS::RR::NSEC Net::DNS::RR::NSEC3 Net::DNS::RR::RRSIG Net::DNS::SEC::Private and for the use of SIG0 see: Net::DNS::Packet (sign_sig0) Net::DNS::RR::SIG 2. AVAILABILITY ------------ You can get the latest version of Net::DNS::SEC from the Comprehensive Perl Archive Network (CPAN): http://search.cpan.org/dist/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: Crypt::OpenSSL::Bignum Crypt::OpenSSL::DSA Crypt::OpenSSL::RSA File::Spec MIME::Base64 Test::More Optional packages extend the repertoire of encryption algorithms. Version incompatibilities are reported at installation time, which may be corrected following installation. Crypt::OpenSSL::EC Crypt::OpenSSL::ECDSA Digest::GOST Digest::SHA 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-?.??.tar.gz cd Net-DNS-SEC-?.?? 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 failures during the test phase. Alternatively, install the package using CPAN: perl -MCPAN -e shell; cpan> install Net::DNS::SEC 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 Ian Robertson, T.J. Mather, and Mike McCauley for their support and help with the Crypt::OpenSSL::[RSA|DSA|EC] modules. Mike McCauley created Crypt::OpenSSL::ECDSA specifically for this development. 9. COPYRIGHT --------- Authorship of individual components and significant contributions is shown in the copyright notice attached to the relevant documentation. Copyright in all components is retained by their respective authors. 10. LICENSE ------- Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ $Id: README 1378 2015-07-14 07:50:38Z willem $ Net-DNS-SEC-1.03/MANIFEST0000644000175000017500000000115512760026557013726 0ustar willemwillemChanges Makefile.PL MANIFEST This list of files README demo/getkeyset.pl demo/key2ds demo/make-signed-keyset lib/Net/DNS/SEC.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/RSA.pm t/00-load.t t/00-pod.t t/10-keyset.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/41-ECC-GOST.t t/51-ECDSA-P256.t t/52-ECDSA-P384.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-DNS-SEC-1.03/t/0000755000175000017500000000000012760026557013036 5ustar willemwillemNet-DNS-SEC-1.03/t/24-RSA-SHA512.t0000644000175000017500000000471412760026475014741 0ustar willemwillem# $Id: 24-RSA-SHA512.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::RSA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 7; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA512.example. IN DNSKEY 256 3 10 ( AwEAAdLaxcxvgdQKF3zSOuXQgwWPQ+dKzJ3Ob4w3r+o73i2MnhE0HBHuTzUZGVjGR05VGqZaJx64 LNt0Wlxxoxt3Uwaq55t5MzN3LYYYEcMQ1XPhPG1nNuD0LiqlqL+KmQqlAo3cm4F71gr/GXQiPG3O WM11ulruDKZpyfYg1NWryu3F ; Key ID = 35741 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 10 (RSASHA512) Modulus: 0trFzG+B1AoXfNI65dCDBY9D50rMnc5vjDev6jveLYyeETQcEe5PNRkZWMZHTlUaplonHrgs23RaXHGjG3dTBqrnm3kzM3cthhgRwxDVc+E8bWc24PQuKqWov4qZCqUCjdybgXvWCv8ZdCI8bc5YzXW6Wu4MpmnJ9iDU1avK7cU= PublicExponent: AQAB PrivateExponent: hTutzo8LBzPVQY8JnluR3rp3Grgd8P0XaQ9q/eQUcM2wt4go0H+31wJkDL9FIU8PRtwiafvQhF7SFiXL/bf5YlCBhCNnYmz8fZuIsZr9OC5tYDFU43AziHYrwhE0myYMJF16nrJTe8RfGnvkvsBUJovu92L86lUOexTQCeIJPeE= Prime1: 7Pq9K1h4B8UfhEH1+zh+LW4BS6OHPVt7WGPSob/8EqirMqsv1xNxfp/La9abLEJemyXJUZ7SjTN6MbNMHfH1rQ== Prime2: 48c9vC+ynHyq5mNbVr2pQKoWVdCoeK6wgMHXnoSyMnxwmnP+NNXM1NKDSX7TIJOmGerRL7MGsiTSf3W39IjreQ== Exponent1: I9lCaJ43eiVtwRohVeGT5NdxRrn0KWn/XL2tDV73iPMPAtk2oXiFgLw3j5alXqqjmSC8Naaq/0U8ROx0pUsG+Q== Exponent2: ulbOrFsg9WAPt3ZkzKtQATSkHQQcLs5KWqs5p9bKqP6gZ9qohbS6Ywjsmn2EXswrQFyXUTxWJ/pzsg4ttYElkQ== Coefficient: kZkMqvGGOYegRIujd89qRGgHR/A8RN/BUXiuS3GbUemX9RtFRwtf12BfTAf5glTBL+7kOojarbt+CD+qkFbd6A== Created: 20141208233433 Publish: 20141208233433 Activate: 20141208233433 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); exit; __END__ Net-DNS-SEC-1.03/t/51-ECDSA-P256.t0000644000175000017500000000506612760026475014725 0ustar willemwillem# $Id: 51-ECDSA-P256.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::EC => 0.5, Crypt::OpenSSL::ECDSA => 0.05, Digest::SHA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 11; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::ECDSA'); my $key = new Net::DNS::RR <<'END'; ECDSAP256SHA256.example. IN DNSKEY 256 3 13 ( 7Y4BZY1g9uzBwt3OZexWk7iWfkiOt0PZ5o7EMip0KBNxlBD+Z58uWutYZIMolsW8v/3rfgac45lO IikBZK4KZg== ; Key ID = 44222 ) END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: m/dWhFblAGQnabJoKbs0vXoQidjNzlTcbPAqntUXWi0= Created: 20141209020038 Publish: 20141209020038 Activate: 20141209020038 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up ECDSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; ecc-gost.example. IN DNSKEY 256 3 12 ( 6VwgNT1BXxXNVpTQXcJQ82PcsCYmI60oN88Plbl028ruvl6DqJby/uBGULHT5FXmZiXBJozE6kP0 +BirN9YPBQ== ; Key ID = 46387 ) END ok( $wrongkey, 'set up non-ECDSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 12 (ECC-GOST) PrivateKey: nBnGCP/hYTdJX0znDstyFTVYSA6b0nFeHy0FJUj7LhU= Created: 20150102211707 Publish: 20150102211707 Activate: 20150102211707 END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-ECDSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); ok( !eval { Net::DNS::SEC::ECDSA->sign( $sigdata, $wrongprivate ) }, 'signature not generated using wrong private key' ); ok( !eval { Net::DNS::SEC::ECDSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not validated using wrong public key' ); exit; __END__ Net-DNS-SEC-1.03/t/52-ECDSA-P384.t0000644000175000017500000000327112760026475014724 0ustar willemwillem# $Id: 52-ECDSA-P384.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::EC => 0.5, Crypt::OpenSSL::ECDSA => 0.05, Digest::SHA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 7; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::ECDSA'); my $key = new Net::DNS::RR <<'END'; ECDSAP384SHA384.example. IN DNSKEY 256 3 14 ( K4t0AhWiJcLZ25BlpvfxCi2KMlkBr14zECH3Y2imMYOzn5zcMpOh0iPbI9Hnfep8L+BBzQrRFNmc 5r3r0l0y+snHIc/npdK/1Ks0ZG/aMB5r/PfJGeB5MLdtcanFir2S ; Key ID = 25812 ) END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 14 (ECDSAP384SHA384) PrivateKey: mvuhyr+QDMqo4bpeREFRM2w8qZsBiLiCouR0sihdinvpRA3zA/dByohgH4CLI7Kr Created: 20141209021155 Publish: 20141209021155 Activate: 20141209021155 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up ECDSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); exit; __END__ Net-DNS-SEC-1.03/t/31-DSA-SHA1.t0000644000175000017500000001040012760026475014537 0ustar willemwillem# $Id: 31-DSA-SHA1.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::DSA => 0, Digest::SHA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 11; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::DSA'); my $key = new Net::DNS::RR <<'END'; DSA.example. IN DNSKEY 256 3 3 ( CMKzsCaT2Jy1w/sPdpigEE+nbeJ/x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk 7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL 5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyeAH46EQVCq1UBnnaHslvSDkdb+Z1kT bMQ64ZVI/sBRXRbqIcDlXVZurCTDV7JL9KZwwfeyrQcnVyYh5mdHPsXbpX5NQJvoqPgvRZWBpP4h pjkAm9UrUbow9maPCQ1JQ3JuiU5buh9cjAI+QIyGMujKLT2OsogSZD2IFUciaZBL/rSe0gmAUv0q XrczmIYFUCoRGZ6+lKVqQQ6f2U7Gsr6zRbeJN+JCVD6BJ52zjLUaWUPHbakhZb/wMO7roX/tnA/w zoDYBIIF7yuRYWblgPXBJTK2Bp07xre8lKCRbzY4J/VXZFziZgHgcn9tkHnrfov04UG9zlWEdT6X E/60HjrP ; Key ID = 53244 ) END ok( $key, 'set up DSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 3 (DSA) Prime(p): x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyc= Subprime(q): wrOwJpPYnLXD+w92mKAQT6dt4n8= Base(g): gB+OhEFQqtVAZ52h7Jb0g5HW/mdZE2zEOuGVSP7AUV0W6iHA5V1Wbqwkw1eyS/SmcMH3sq0HJ1cmIeZnRz7F26V+TUCb6Kj4L0WVgaT+IaY5AJvVK1G6MPZmjwkNSUNybolOW7ofXIwCPkCMhjLoyi09jrKIEmQ9iBVHImmQS/4= Private_value(x): vdClrOqZ1qONKg0CZH5hVnq1i40= Public_value(y): tJ7SCYBS/SpetzOYhgVQKhEZnr6UpWpBDp/ZTsayvrNFt4k34kJUPoEnnbOMtRpZQ8dtqSFlv/Aw7uuhf+2cD/DOgNgEggXvK5FhZuWA9cElMrYGnTvGt7yUoJFvNjgn9VdkXOJmAeByf22Qeet+i/ThQb3OVYR1PpcT/rQeOs8= END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up DSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; RSAMD5.example. IN KEY 512 3 1 ( AwEAAc6K704XNTQYlCPw1R5qBNdPg3SxOdhEWdDFlPdCeeBL1UDSdUG1ijcNkoGCKpFXLaTqeJAH +VkXhOGUSvFxIOOmtxb3ubwFf80Up1iKwACNmfCgDlGm8EzGKVoPGcuXkwcxFsQtBoKqT6lWR3at 6MT/bnuwIIVaD91u1L+/tVw7 ; Key ID = 46428 ) END ok( $wrongkey, 'set up non-DSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: zorvThc1NBiUI/DVHmoE10+DdLE52ERZ0MWU90J54EvVQNJ1QbWKNw2SgYIqkVctpOp4kAf5WReE4ZRK8XEg46a3Fve5vAV/zRSnWIrAAI2Z8KAOUabwTMYpWg8Zy5eTBzEWxC0GgqpPqVZHdq3oxP9ue7AghVoP3W7Uv7+1XDs= PublicExponent: AQAB PrivateExponent: hMPcJddXNMCj4SJ67Az8Rabv+j+9zh3JmiCXrAUIMLyuPPfLtcxLJy5LQYJ5eGmQhpTNoM/vYWxz10kqj17H40ZpAbrfD8/TZtQDnEA2Nzlp3F+qswpmMRih82LzqzpBm0l8lbqnyIRthHfytisG52YWW8pZ0jlBuQb7whO+ajk= Prime1: 6hj6OPHOP/1AuLiiQo8FcxFyES6WAKvJlcqKX2wb7Gxz6yPfTQlR7WcueEn60r75rF9VAS46qxa3XIsvBuETJw== Prime2: 4d35IrQ/bVCtdQ7A9DyUNmOVtS6bPCJBEVLI+M6dmj1icGJiiwNdCXbX3uaOG0SEh2/oXGBbw9wX8D1xDWqKzQ== Exponent1: FvM17Mk/+CQC6Vkohy/wT9ShAzA3An/U9ntxz2MQ5b/IKYBNzwaf4o9gDejqzyhr38tE0SXQGJ/UgB0hEiKUtw== Exponent2: KEOs3Q3q3K7sLRjzNtbxyPxZvNHRJJgqp07tusUCfXOB7+zqCkQQOtavxvGs1ZmSUp6VeppG4ZSDw/UACVc75Q== Coefficient: QIVRcEFrFbmhJntBjCZOgJ4tKaiJJ3s4J97RMR6xQ1pLVwlOKKozJbjVx2tZyb11/UQliVTHlgrqYGL/oWBMKw== END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-DSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); ok( $signature, 'signature generated using private key' ); my $validated = Net::DNS::SEC::DSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); ok( !eval { Net::DNS::SEC::DSA->sign( $sigdata, $wrongprivate ) }, 'signature not generated using wrong private key' ); ok( !eval { Net::DNS::SEC::DSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not validated using wrong public key' ); exit; __END__ Net-DNS-SEC-1.03/t/00-pod.t0000644000175000017500000000061612760026475014224 0ustar willemwillem# $Id: 00-pod.t 1378 2015-07-14 07:50:38Z willem $ # use strict; use Test::More; my %prerequisite = qw( Test::Pod 1.45 ); while ( my ( $package, $rev ) = each %prerequisite ) { eval "use $package $rev"; next unless $@; plan skip_all => "$package $rev required for testing POD"; exit; } my @poddirs = qw( blib demo ); my @allpods = all_pod_files(@poddirs); all_pod_files_ok(@allpods); Net-DNS-SEC-1.03/t/23-RSA-SHA256.t0000644000175000017500000000460112760026475014740 0ustar willemwillem# $Id: 23-RSA-SHA256.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::RSA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 7; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA256.example. IN DNSKEY 256 3 8 ( AwEAAZRSF/5NLnExp5n4M6ynF2Yok3N2aG9AWu8/vKQrZGFQcbL+WPGYbWUtMpiNXmvzTr2j86kN QU4wBawm589mjzXgVQRfXYDMMFhHMtagzEKOiNy2ojhhFyS7r2O2vUbo4hGbnM54ynSM1al+ygKU Gy1TNzHuYMiwh+gsQCsC5hfJ ; Key ID = 35418 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: lFIX/k0ucTGnmfgzrKcXZiiTc3Zob0Ba7z+8pCtkYVBxsv5Y8ZhtZS0ymI1ea/NOvaPzqQ1BTjAFrCbnz2aPNeBVBF9dgMwwWEcy1qDMQo6I3LaiOGEXJLuvY7a9RujiEZucznjKdIzVqX7KApQbLVM3Me5gyLCH6CxAKwLmF8k= PublicExponent: AQAB PrivateExponent: c74UZyhHo6GCDs73VDYYNmpXlnTCTn7D94ufY+VQsfgaofmF4xJ128yHfTBkjI0T1z1H+ZYUbjVfV9YMc3avLcXAb4YOEuNw0CSZrtTFc/oTvAyM9tKoa7hB9MSlYtmYvaWiEatHzKL0wYvo71jtfoTyDLQTISzrBWsA+K1a3hk= Prime1: wvw2lVu+kepiu0fasCrA3BlemVJ3XvWdd/y0sB5+egVGIJCn1bgkaSL/IP+683K28tN7hQYzMGiDBPymu3FeAw== Prime2: wruzE41ctH5D2SLhW4pi/pz+WSyeBUSvsmUe5kr4c9mlIqYUK1k72kmsjjZtD4eJsjq3xb/VGi+pcMuK2t1/Qw== Exponent1: lgk3AxTWfjcqA8wVpesv/ezzku0W95Xtto9YhhDg54m5XYOR8e1A7znDsaO2OnAyAIXlDQYpS32QG71Bmwhv+w== Exponent2: KyNVekFYhgtqkFFvxs2TPIAewDZoExayLTzFaZK2E0PllxVfZnLwFV04wpA//K6zzC3BxCbI2HIygPA2JGHo7Q== Coefficient: R3pSnerhKwfAHrH3iyojUzKzhM+AQ+97CWavx36eyKT3Yr/SIDANeeXGlT9U7RdxbkZzyeWbFNCnT+b89UX1RQ== END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); exit; __END__ Net-DNS-SEC-1.03/t/41-ECC-GOST.t0000644000175000017500000000515612760026475014617 0ustar willemwillem# $Id: 41-ECC-GOST.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::EC => 1.01, Crypt::OpenSSL::ECDSA => 0.06, Digest::GOST => 0.06, Digest::GOST::CryptoPro => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 11; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::ECCGOST'); my $key = new Net::DNS::RR <<'END'; ecc-gost.example. IN DNSKEY 256 3 12 ( 6VwgNT1BXxXNVpTQXcJQ82PcsCYmI60oN88Plbl028ruvl6DqJby/uBGULHT5FXmZiXBJozE6kP0 +BirN9YPBQ== ; Key ID = 46387 ) END ok( $key, 'set up ECC-GOST public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 12 (ECC-GOST) PrivateKey: nBnGCP/hYTdJX0znDstyFTVYSA6b0nFeHy0FJUj7LhU= Created: 20150102211707 Publish: 20150102211707 Activate: 20150102211707 END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up ECC-GOST private key' ); my $wrongkey = new Net::DNS::RR <<'END'; ECDSAP256SHA256.example. IN DNSKEY 256 3 13 ( 7Y4BZY1g9uzBwt3OZexWk7iWfkiOt0PZ5o7EMip0KBNxlBD+Z58uWutYZIMolsW8v/3rfgac45lO IikBZK4KZg== ; Key ID = 44222 ) END ok( $wrongkey, 'set up non-ECC-GOST public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.3 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: m/dWhFblAGQnabJoKbs0vXoQidjNzlTcbPAqntUXWi0= Created: 20141209020038 Publish: 20141209020038 Activate: 20141209020038 END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-ECC-GOST private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::ECCGOST->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::ECCGOST->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); ok( !eval { Net::DNS::SEC::ECCGOST->sign( $sigdata, $wrongprivate ) }, 'signature not generated using wrong private key' ); ok( !eval { Net::DNS::SEC::ECCGOST->verify( $sigdata, $wrongkey, $signature ) }, 'signature not validated using wrong public key' ); exit; __END__ Net-DNS-SEC-1.03/t/21-RSA-MD5.t0000644000175000017500000001215212760026475014453 0ustar willemwillem# $Id: 21-RSA-MD5.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::RSA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 15; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); # test coverage only for RSA key generation eval { my $k1 = Net::DNS::SEC::Private->generate_rsa(qw(domain 256 1024)); my $k2 = Net::DNS::SEC::Private->generate_rsa(qw(domain 0 0 1234 1)); local $SIG{__WARN__} = sub { }; $k1->dump_rsa_keytag; }; ok( !eval { Net::DNS::SEC::Private->new('Kinvalid.private') }, "invalid keyfile: [$@]" ); ok( !eval { Net::DNS::SEC::Private->new('Kinvalid.+0+0.private') }, "missing keyfile: [$@]" ); ok( !eval { Net::DNS::SEC::Private->new( signame => 'example' ) }, "undef algorithm: [$@]" ); ok( !eval { Net::DNS::SEC::Private->new( algorithm => 1 ) }, "undef signame: [$@]" ); my $key = new Net::DNS::RR <<'END'; RSAMD5.example. IN KEY 512 3 1 ( AwEAAc6K704XNTQYlCPw1R5qBNdPg3SxOdhEWdDFlPdCeeBL1UDSdUG1ijcNkoGCKpFXLaTqeJAH +VkXhOGUSvFxIOOmtxb3ubwFf80Up1iKwACNmfCgDlGm8EzGKVoPGcuXkwcxFsQtBoKqT6lWR3at 6MT/bnuwIIVaD91u1L+/tVw7 ; Key ID = 46428 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; ; comment discarded ; empty line discarded Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: zorvThc1NBiUI/DVHmoE10+DdLE52ERZ0MWU90J54EvVQNJ1QbWKNw2SgYIqkVctpOp4kAf5WReE4ZRK8XEg46a3Fve5vAV/zRSnWIrAAI2Z8KAOUabwTMYpWg8Zy5eTBzEWxC0GgqpPqVZHdq3oxP9ue7AghVoP3W7Uv7+1XDs= PublicExponent: AQAB PrivateExponent: hMPcJddXNMCj4SJ67Az8Rabv+j+9zh3JmiCXrAUIMLyuPPfLtcxLJy5LQYJ5eGmQhpTNoM/vYWxz10kqj17H40ZpAbrfD8/TZtQDnEA2Nzlp3F+qswpmMRih82LzqzpBm0l8lbqnyIRthHfytisG52YWW8pZ0jlBuQb7whO+ajk= Prime1: 6hj6OPHOP/1AuLiiQo8FcxFyES6WAKvJlcqKX2wb7Gxz6yPfTQlR7WcueEn60r75rF9VAS46qxa3XIsvBuETJw== Prime2: 4d35IrQ/bVCtdQ7A9DyUNmOVtS6bPCJBEVLI+M6dmj1icGJiiwNdCXbX3uaOG0SEh2/oXGBbw9wX8D1xDWqKzQ== Exponent1: FvM17Mk/+CQC6Vkohy/wT9ShAzA3An/U9ntxz2MQ5b/IKYBNzwaf4o9gDejqzyhr38tE0SXQGJ/UgB0hEiKUtw== Exponent2: KEOs3Q3q3K7sLRjzNtbxyPxZvNHRJJgqp07tusUCfXOB7+zqCkQQOtavxvGs1ZmSUp6VeppG4ZSDw/UACVc75Q== Coefficient: QIVRcEFrFbmhJntBjCZOgJ4tKaiJJ3s4J97RMR6xQ1pLVwlOKKozJbjVx2tZyb11/UQliVTHlgrqYGL/oWBMKw== END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $wrongkey = new Net::DNS::RR <<'END'; DSA.example. IN DNSKEY 256 3 3 ( CMKzsCaT2Jy1w/sPdpigEE+nbeJ/x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk 7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL 5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyeAH46EQVCq1UBnnaHslvSDkdb+Z1kT bMQ64ZVI/sBRXRbqIcDlXVZurCTDV7JL9KZwwfeyrQcnVyYh5mdHPsXbpX5NQJvoqPgvRZWBpP4h pjkAm9UrUbow9maPCQ1JQ3JuiU5buh9cjAI+QIyGMujKLT2OsogSZD2IFUciaZBL/rSe0gmAUv0q XrczmIYFUCoRGZ6+lKVqQQ6f2U7Gsr6zRbeJN+JCVD6BJ52zjLUaWUPHbakhZb/wMO7roX/tnA/w zoDYBIIF7yuRYWblgPXBJTK2Bp07xre8lKCRbzY4J/VXZFziZgHgcn9tkHnrfov04UG9zlWEdT6X E/60HjrP ; Key ID = 53244 ) END ok( $wrongkey, 'set up non-RSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; open( KEY, ">$wrongfile" ) or die "$wrongfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 3 (DSA) Prime(p): x5C6cruWvStVum6/YulcR7MHeujx9c2iBDbo3kW4X8/l+qgk7ZEZ+yV5lphWtJMmMtOHIU+YdAhgLpt84NKhcupWL8wfuBW/97cqIv5Z+51fwn0YEAcZsoCrE0nL5+31VfkK9LTNuVo38hsbWa3eWZFalID5NesF6sJRgXZoAyc= Subprime(q): wrOwJpPYnLXD+w92mKAQT6dt4n8= Base(g): gB+OhEFQqtVAZ52h7Jb0g5HW/mdZE2zEOuGVSP7AUV0W6iHA5V1Wbqwkw1eyS/SmcMH3sq0HJ1cmIeZnRz7F26V+TUCb6Kj4L0WVgaT+IaY5AJvVK1G6MPZmjwkNSUNybolOW7ofXIwCPkCMhjLoyi09jrKIEmQ9iBVHImmQS/4= Private_value(x): vdClrOqZ1qONKg0CZH5hVnq1i40= Public_value(y): tJ7SCYBS/SpetzOYhgVQKhEZnr6UpWpBDp/ZTsayvrNFt4k34kJUPoEnnbOMtRpZQ8dtqSFlv/Aw7uuhf+2cD/DOgNgEggXvK5FhZuWA9cElMrYGnTvGt7yUoJFvNjgn9VdkXOJmAeByf22Qeet+i/ThQb3OVYR1PpcT/rQeOs8= END close(KEY); my $wrongprivate = new Net::DNS::SEC::Private($wrongfile); ok( $wrongprivate, 'set up non-RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature generated using private key' ); my $validated = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature generated using public key' ); ok( !eval { Net::DNS::SEC::RSA->sign( $sigdata, $wrongprivate ) }, 'signature not generated using wrong private key' ); ok( !eval { Net::DNS::SEC::RSA->verify( $sigdata, $wrongkey, $signature ) }, 'signature not validated using wrong public key' ); # exercise code for key with long exponent (not required for DNSSEC) eval { my $longformat = pack 'xn a*', unpack 'C a*', $key->keybin; $key->keybin($longformat); Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); }; exit; __END__ Net-DNS-SEC-1.03/t/22-RSA-SHA1.t0000644000175000017500000000457212760026475014572 0ustar willemwillem# $Id: 22-RSA-SHA1.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Crypt::OpenSSL::Bignum => 0, Crypt::OpenSSL::RSA => 0, Net::DNS => 1.01, Net::DNS::SEC::Private => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 7; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS'); use_ok('Net::DNS::SEC::Private'); use_ok('Net::DNS::SEC::RSA'); my $key = new Net::DNS::RR <<'END'; RSASHA1.example. IN DNSKEY 256 3 5 ( AwEAAZHbngk6sMoFHN8fsYY6bmGR4B9UYJIqDp+mORLEH53Xg0f6RMDtfx+H3/x7bHTUikTr26bV AqsxOs2KxyJ2Xx9RGG0DB9O4gpANljtTq2tLjvaQknhJpSq9vj4CqUtr6Wu152J2aQYITBoQLHDV i8mIIunparIKDmhy8TclVXg9 ; Key ID = 1623 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; open( KEY, ">$keyfile" ) or die "$keyfile $!"; print KEY <<'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: kdueCTqwygUc3x+xhjpuYZHgH1RgkioOn6Y5EsQfndeDR/pEwO1/H4ff/HtsdNSKROvbptUCqzE6zYrHInZfH1EYbQMH07iCkA2WO1Ora0uO9pCSeEmlKr2+PgKpS2vpa7XnYnZpBghMGhAscNWLyYgi6elqsgoOaHLxNyVVeD0= PublicExponent: AQAB PrivateExponent: Vd6cuMRDxnuiFr367pJB39FYyDkNrZ9zAoyCt0idcHirglmV1ps7px2AQY2MOW/Tg2Xz59EqBA00mEOmnuRfdRXraqo1mxA9C2qGR2xHltNH2RVR5oTlahZLRUYZTDuLI7G/3IiPKrf5z/HFm2DkkzuxGqC8hWf9FOni49CqhYE= Prime1: waSsFnVlQrG/3SGh5GNV5o50PS8gE5L0/+GP2MIjkR3px1zR+LjfkVii1EaTda+Sq7B0ROI+M+R0JLh98Rr6XQ== Prime2: wNOsL3isJAE89C2XaESsJnm46vPZrqZ4XATub1dwOWNqVOji6KI9yTBc3MfmXkZVmy0I8Rm4ILLh5m/+0LNXYQ== Exponent1: muRjmptQ4iZYOEOcwZkLrx4nsIEvgTi9rKf6bgHsfTmWNBf1BKSsgBCMPowti6djBN5iQm9OHigRFwZUBzXzKQ== Exponent2: KE8Xe4T6Vzx7BYBSWlWgtxpS8aqwIrZiCrptLZFVwGlr3PwiEwd3awtVHkIbgjGpy5qKd/wsZYl/d7CJ0A7tgQ== Coefficient: p9WMT9cDpT7BXcKBXnrMLV8O31ujZ17nwlmlFe3+0n2VCx2T/CSz72xssffn0n2q0DaHHfu9SxR1RLgmDUzVEA== END close(KEY); my $private = new Net::DNS::SEC::Private($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = 'arbitrary data'; my $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $validated = Net::DNS::SEC::RSA->verify( $sigdata, $key, $signature ); ok( $validated, 'signature validated using public key' ); exit; __END__ Net-DNS-SEC-1.03/t/10-keyset.t0000644000175000017500000003164212760026475014752 0ustar willemwillem# $Id: 10-keyset.t 1494 2016-08-22 09:34:07Z willem $ -*-perl-*- # use Test::More; my %prerequisite = ( Net::DNS => 1.01, Net::DNS::SEC::Private => 0, Net::DNS::SEC::RSA => 0, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep $_, $prerequisite{$package}; eval "use $package @revision"; next unless $@; plan skip_all => "missing prerequisite $package @revision"; exit; } plan tests => 30; use_ok('Net::DNS::SEC'); # test 1 use_ok('Net::DNS::SEC::Keyset'); # test 2 my %filename = ( set1 => 'keyset-test.tld.', set2 => 'prefix-test.tld.', set3 => 'keyset-corrupt-test.tld.', ); END { foreach ( values %filename ) { unlink($_) if -e $_; } } # # RSA keypair 1 # my $keyrr1 = new Net::DNS::RR <<'END'; test.tld. IN DNSKEY 256 3 5 ( AQO1gY5UFltQ4f0ZHnXPFQZfcQQNpXK5r0Rk05rLLmY0XeA1lu8ek7W1VHsBjkge9WU7efdp3U4a mxULRMQj7F0ByOK318agap2sIWYN13jV1RLxF5GPyLq+tp2ihEyI8x0P8c9RzgVn1ix4Xcoq+vKm WqDT1jHE4oBY/DzI8gyuJw== ) ; Key ID = 15791 END ok( $keyrr1, join ' ', algorithm( $keyrr1->algorithm ), 'public key created' ); my $keyfile1 = $filename{key1} = $keyrr1->privatekeyname; open( KEY1, ">$keyfile1" ) or die "Could not open $keyfile1"; print KEY1 << 'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: tYGOVBZbUOH9GR51zxUGX3EEDaVyua9EZNOayy5mNF3gNZbvHpO1tVR7AY5IHvVlO3n3ad1OGpsVC0TEI+xdAcjit9fGoGqdrCFmDdd41dUS8ReRj8i6vradooRMiPMdD/HPUc4FZ9YseF3KKvryplqg09YxxOKAWPw8yPIMric= PublicExponent: Aw== PrivateExponent: eQEJjWQ84Jaou2mj32NZlPYCs8Oh0R+C7eJnMh7uzZPqzmSfabfOeOL8q7QwFKOY0lFPm+jevGdjXNiCwp2TVWZrFINEMwUpxPJCvQQLh0k9Ah3NN2ELPBSlUjkRa10KaRSVSdDaYUM9X1/ZT/9RQagi4ckuy0x6UcRmoSng/Ms= Prime1: 3SNqKvY2geGDxgpqUKy2gGKq2LBRZ0CruBsVQXtoBH2dwq1bUScC9HxrTYaGxn2BELZsYRMeGVqZ1WqzsLXeTw== Prime2: 0h6u5+odYP2A7/eIALrUZtTDEi1rT+k434qR7Tb/4w/UkEIHw5bS/NP+AH2sNXtCzbYUx1h11m5EgDgjgoVUqQ== Exponent1: k2zxcfl5q+utLrGcNch5quxx5crg74Byery41lJFWFO+gcjni29XTahHiQRZ2akAtc7y62IUEOcROPHNIHk+3w== Exponent2: jBR0mpwTlf5V9U+wAHyNmeMstsjyNUYl6lxhSM9VQgqNtYFagmSMqI1UAFPII6eB3nljL5BOjvQtqtAXrFjjGw== Coefficient: YJYWzNpbdj/11mE4kUwaiH9GQbY+uA28tv4aVAwAEcKPaU1QQ2k8Jlm+VXxh9v02QCFJYln3416972oeCx9eyw== END close(KEY1); # # RSA keypair 2 # my $keyrr2 = new Net::DNS::RR <<'END'; test.tld. IN DNSKEY ( 256 3 8 AwEAAZRSF/5NLnExp5n4M6ynF2Yok3N2aG9AWu8/vKQrZGFQcbL+WPGYbWUtMpiNXmvzTr2j86kN QU4wBawm589mjzXgVQRfXYDMMFhHMtagzEKOiNy2ojhhFyS7r2O2vUbo4hGbnM54ynSM1al+ygKU Gy1TNzHuYMiwh+gsQCsC5hfJ ) ; Key ID = 35418 END ok( $keyrr2, join ' ', algorithm( $keyrr2->algorithm ), 'public key created' ); my $keyfile2 = $filename{key2} = $keyrr2->privatekeyname; open( KEY2, ">$keyfile2" ) or die "Could not open $keyfile2"; print KEY2 << 'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: 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(KEY2); # Create keysets my $datarrset = [$keyrr1, $keyrr2]; my $sigrr1 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); ok( $sigrr1, join ' ', algorithm( $sigrr1->algorithm ), 'signature created' ); my $sigrr2 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile2, ttl => 3600 ); ok( $sigrr2, join ' ', algorithm( $sigrr2->algorithm ), 'signature created' ); my $keyset = Net::DNS::SEC::Keyset->new($datarrset); is( ref($keyset), "Net::DNS::SEC::Keyset", "Keyset object created" ); ok( $keyset->string, '$keyset->string' ); $keyset->writekeyset; ok( Net::DNS::SEC::Keyset->new( $filename{set1} ), "write Keyset object" ); $keyset->writekeyset('prefix-'); my $read = Net::DNS::SEC::Keyset->new( $filename{set2} ); is( ref($read), "Net::DNS::SEC::Keyset", "read Keyset object" ); my @ds = $keyset->extract_ds; my $string0 = $ds[0]->string; my $string1 = $ds[1]->string; my $expect0 = new Net::DNS::RR('test.tld. IN DS 15791 5 1 C355F0F3F30C69BF2F7EA253ED82FBC280C2496B')->string; my $expect1 = new Net::DNS::RR('test.tld. IN DS 35418 8 1 6f3dd1c760c2a4971b3d44ce20e3cb8b60d7aff6')->string; my $alg0 = algorithm( $ds[0]->algorithm ); my $dig0 = digtype( $ds[0]->digtype ); is( $string0, $expect0, "DS ($alg0/$dig0) created from keyset" ); my $alg1 = algorithm( $ds[1]->algorithm ); my $dig1 = digtype( $ds[1]->digtype ); is( $string1, $expect1, "DS ($alg1/$dig1) created from keyset" ); ## # Corrupted keyset open( KEYSET, ">$filename{set3}" ) or die "Could not open $filename{set3}"; print KEYSET $keyrr1->string, "\n"; print KEYSET $keyrr2->string, "\n"; my $sigstr = lc $sigrr1->string; # corrupt the base64 signature $sigstr =~ s/in.rrsig.dnskey/IN RRSIG DNSKEY/; # fix collateral damage print KEYSET $sigstr . "\n"; print KEYSET $sigrr2->string . "\n"; close(KEYSET); my $corrupt = Net::DNS::SEC::Keyset->new( $filename{set3} ); ok( !$corrupt, "Corrupted keyset not loaded" ); like( Net::DNS::SEC::Keyset->keyset_err, '/failed.+key/', 'Expected error message' ); # # The packet contains a keyset as returned from a bind nameserver # the keyset is signed with a signature valid until 2030 06 .. # After that the test may fail :-( # This is the code snippet used to get such a little packet as below. #use Net::DNS::Resolver; #my $res=Net::DNS::Resolver->new(); #$res->nameserver("10.0.53.204"); #$res->dnssec(1); #my $a_packet=$res->send("sub.tld","DNSKEY"); #$a_packet->print; #print unpack("H*",$a_packet->data); my $HexadecimalPacket = "e6cc81a000010004000000010373756203746c 640000300001c00c00300001000000200086010103050103bc54beaee1 1dc1a29ba945bf69d0db27b364b2dfe60396efff4c6fb359127ea696e1 4c66e1c6d23cd6f6c335e1679c61dd3fa4d68a689b8709ea686e43f175 6831193903613f6a5f3ff039b21eed9faad4edcb43191c76490ca0947a 9fa726740bc4449d6c58472a605913337d2dbddc94a7271d25c358fdaa 60fe1272a5f8b9c00c00300001000000200086010003050103f6d63a8a b9f775a0c7194d67edb5f249bf398c3d27d2985facf6fb7e25cc35c876 2eb8ea22200c847963442fb6634916dc2ec21cdbf2c7378799b8e7e399 e751ca1e25133349cab52ebf3fe8a5bc0239c28d64f4d8f609c191a7d2 d364578a159701ef73af93946b281f0aac42b42be17362c68d7a54bbb8 fa7bc6f70f455a75c00c002e000100000020009b003005020000006470 dc814040c02ced39d40373756203746c6400a7d9db75a4115794f871ec 71fc7469c74a6be1cf95434a00363506b354bf15656f7556c51355c8dc ac7f6c0a4061c0923e0bf341094e586619c2cb316949772ce5bd1e9949 f91b016f7e6bee0f6878e16b6e59ece086f8d5df68f048524e1bff3c09 dd15c203d28416600e936451d1646e71611ec95e12d709839369cbc442 c0c00c002e000100000020009b003005020000006470dc814040c02ced fbaf0373756203746c640017c6e59f317119da812c6b1e175e8aaec742 35a4bfad777e7759fa2daf7959f9611c26e11adde9bdc901c624ca6965 7b79653495e22647c5e0e5bedfe5524397d769d816746d10b2067472b4 f9b04fbde8e39d7861bd6773c80f632f55b46c7a537a83f0b5a50200c9 d2847b71d9dfaa643f558383e6e13d4e75f70029849444000029100000 0080000000"; $HexadecimalPacket =~ s/\n//g; $HexadecimalPacket =~ s/\s//g; my $packetdata = pack( "H*", $HexadecimalPacket ); my $packet = Net::DNS::Packet->new( \$packetdata ); $keyset = Net::DNS::SEC::Keyset->new($packet); is( ref($keyset), "Net::DNS::SEC::Keyset", "Keyset object from packet" ); is( join( " ", sort( $keyset->verify ) ), "14804 64431", "Verify method returned the two proper keytags" ); my $keyset2 = Net::DNS::SEC::Keyset->new($datarrset); is( ref($keyset2), "Net::DNS::SEC::Keyset", "Keyset object from DNSKEY RRset" ); #print $Net::DNS::SEC::Keyset->keyset_err; #$keyset->print; ######### my $rr; my @keyrr; my @sigrr; # Note that the order of pushing the RRs is important for successful testing. # All signatures have expiration date in 2030... this test should work for a while $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQOxFlzX8vShSG3JG2J/fngkgy64RoWr8ovG e7MuvPJqOMHTLM5V8+TJIahSoyUd990ictNv hDegUqLtZ8k5oQq44viFCU/H1apdEaJnLnXs cVo+08ATlEb90MYznK9K0pm2ixbyspzRrrXp nPi9vo9iU2xqWqw/Efha4vfi6QVs4w== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO4jhl6ilWV2mYjwWl7kcxrYyQsnnbV7pxX m48p+SgAr+R5SKyihkjg86IjZBQHFJKZ8RsZ dhclH2dikM+53uUEhrqVGhsqF8FsNi4nE9aM ISiX9Zs61pTYGYboYDvgpD1WwFbD4YVVlfk7 rCDP/zOE7H/AhkOenK2w7oiO0Jehcw== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO5fWabr7bNxDXT8YrIeclI9nvYYdKni3ef gJfU749O3QVX9MON6WK0ed00odQF4cLeN3vP SdhasLDI3Z3TzyAPBQS926oodxe78K9zwtPT 1kzJxvunOdJr6+6a7/+B6rF/cwfWTW50I0+q FykldldB44a1uS34u3HgZRQXDmAesw== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN DNSKEY 256 3 5 ( AQO6uGWsox2oH36zusGA0+w3uxkZMdByanSC jiaRHtkOA+gIxT8jmFvohxQBpVfYD+xG2pt+ qUWauWPFPjsIUBoFqHNpqr2/B4CTiZm/rSay HDghZBIMceMa6t4NpaOep79QmiE6oGq6yWRB swBkPZx9uZE7BqG+WLKEp136iwWyyQ== ) " ); push( @keyrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 11354 example.com. GTqyJTRbKJ0LuWbAnNni1M4JZ1pn+nXY1Zuz Z0Kvt6OMTYCAFMFt0Wv9bncYkUuUSMGM7yGG 9Z7g7tcdb4TKCqQPYo4gr3Qj/xgC4LESoQs0 yAsJtLUiDfO6e4aWHmanpMGyGixYzHriS1pt SRzirL1fTgV+kdNs5zBatUHRnQc=) " ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 28109 example.com. WemQqA+uaeKqCy6sEVBU3LDORG3f+Zmix6qK 9j1WL83UMWdd6sxNh0QJ0YL54lh9NBx+Viz7 gajO+IM4MmayxKY4QVjp+6mHeE5zBVHMpTTu r5T0reNtTsa8sHr15fsI49yn5KOvuq+DKG1C gI6siM5RdFpDsS3Rmf8fiK1PyTs= )" ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 33695 example.com. M3yVwTOMw+jAKYY5c6oS4DH7OjOdfMOevpIe zdKqWXkehoDg9YOwz8ai17AmfgkjZnsoNu0W NMIcaVubR3n02bkVhJb7dEd8bhbegF8T1xkL 7rf9EQrPmM5GhHmVC90BGrcEhe//94hdXSVU CRBi6KPFWSZDldd1go133bk/b/o= )" ); push( @sigrr, $rr ); $rr = Net::DNS::RR->new( "example.com 100 IN RRSIG DNSKEY 5 2 100 20300101000000 ( 20040601105519 39800 example.com. Mmhn2Ql6ExmyHvZFWgt+CBRw5No8yM0rdH1b eU4is5gRbd3I0j5z6PdtpYjAkWiZNdYsRT0o P7TQIsADfB0FLIFojoREg8kp+OmbpRTsLTgO QYC95u5WodYGz03O0EbnQ7k4gkje6385G40D JVl0xVfujHBMbB+keiSphD3mG4I= )" ); push( @sigrr, $rr ); my $ks = Net::DNS::SEC::Keyset->new( \@keyrr, \@sigrr ); ok( $ks, "Keyset created from two arrays." ); my @ks_sigs = $ks->sigs; ok( eq_array( \@ks_sigs, \@sigrr ), "Sigs out equal to sigs in" ); my @ks_keys = $ks->keys; my @keydiff = key_difference( \@keyrr, \@ks_keys ); is( scalar(@keydiff), 0, "Keys out equal to keys in" ); $datarrset = [$keyrr1, $keyrr2]; $sigrr1 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); $sigrr2 = create Net::DNS::RR::RRSIG( $datarrset, $keyfile2, ttl => 3600 ); ok( $sigrr1, 'RSA signature created' ); $keyset = Net::DNS::SEC::Keyset->new( $datarrset, [$sigrr1] ); my @keytags = $keyset->verify; is( scalar(@keytags), 1, "Verify method returned the keytags" ); ok( $keyset->verify(15791), "Verification against keytag 15791" ); ok( !$keyset->verify(9734), "Verification against keytag 9734 failed" ); is( $keyset->keyset_err, "No signature made with 9734 found", "Expected error message" ); my $corruptible = create Net::DNS::RR::RRSIG( $datarrset, $keyfile1, ttl => 3600 ); my $unverifiable = Net::DNS::SEC::Keyset->new( $datarrset, [$corruptible] ); my $badsig = create Net::DNS::RR::RRSIG( [$sigrr1], $keyfile1, ttl => 3600 ); $corruptible->sigbin( $badsig->sigbin ); is( scalar( $unverifiable->extract_ds ), 0, 'No DS from unverifiable keyset' ); my $bogus = new Net::DNS::RR <<'END'; bogus.tld. IN DNSKEY 257 3 5 ( AQO1gY5UFltQ4f0ZHnXPFQZfcQQNpXK5r0Rk05rLLmY0XeA1lu8ek7W1VHsBjkge9WU7efdp3U4a mxULRMQj7F0ByOK318agap2sIWYN13jV1RLxF5GPyLq+tp2ihEyI8x0P8c9RzgVn1ix4Xcoq+vKm WqDT1jHE4oBY/DzI8gyuJw== ; Key ID = 15791 ) END my $mixed = Net::DNS::SEC::Keyset->new( [$bogus], [$sigrr1] ); ok( !$mixed, "Mixed keyset not loaded" ); like( Net::DNS::SEC::Keyset->keyset_err, '/No signature.+SEP/', 'Expected error message' ); like( Net::DNS::SEC::Keyset->keyset_err, '/Multiple names/', 'Expected error message' ); eval { $keyset->writekeyset( File::Spec->rel2abs('nonexdir') ) }; my $exception = $1 if $@ =~ /^(.+)\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; Net-DNS-SEC-1.03/t/00-load.t0000644000175000017500000000131512760026475014356 0ustar willemwillem# $Id: 00-load.t 1494 2016-08-22 09:34:07Z willem $ # use strict; use Test::More tests => 1; my @module = qw( Net::DNS::SEC Net::DNS::SEC::DSA Net::DNS::SEC::ECCGOST Net::DNS::SEC::ECDSA Net::DNS::SEC::RSA Net::DNS::SEC::Keyset Net::DNS::SEC::Private Crypt::OpenSSL::Bignum Crypt::OpenSSL::Random Crypt::OpenSSL::DSA Crypt::OpenSSL::EC Crypt::OpenSSL::ECDSA Crypt::OpenSSL::RSA Digest::GOST Digest::SHA File::Spec MIME::Base64 Net::DNS ); diag("\nThese tests were run with:\n"); foreach my $module (@module) { my $loaded = eval("require $module") || 0; my $revnum = $loaded ? $module->VERSION : "\t\tn/a"; diag sprintf "\t%-25s %s", $module, $revnum || '?'; } use_ok('Net::DNS::SEC'); Net-DNS-SEC-1.03/demo/0000755000175000017500000000000012760026557013517 5ustar willemwillemNet-DNS-SEC-1.03/demo/make-signed-keyset0000644000175000017500000000522212760026475017130 0ustar willemwillem#!/usr/bin/perl #$Id: make-signed-keyset 1295 2015-01-08 13:14:03Z willem $ # # takes a bind public key file and creates a self-signed keyset # use Getopt::Std; use Net::DNS::SEC; use Net::DNS::Keyset; use Net::DNS::ZoneFile; use File::Basename; # global variables $VERSION = "0.2"; $verbose = 0; $printds = 0; $progname = basename($0); chomp($progname); # main program getopts('dvhVf:n:'); if ( defined($opt_d) ) { $printds = 1; } if ( defined($opt_v) ) { $verbose = 1; } if ( defined($opt_h) ) { &usage(); } if ( defined($opt_V) ) { &version(); } if ( $#ARGV < 0 ) { &usage(); } # silent some compiler warnings until i figure them out $opt_d = 0; $opt_v = 0; $opt_h = 0; $opt_V = 0; &make_keyset(@ARGV); exit(0); # print the usage and exit sub usage { print("usage: $progname [-vhV] file\n"); print("Options:\n"); print(" -d Print the DS record for each key in the keyset.\n"); print(" -v Be verbose.\n"); print(" -h Print this usage message.\n"); print(" -V Print version information.\n"); print(" file BIND public key file.\n"); exit(0); } # print version information sub version { print( "$progname v$VERSION using Net::DNS v", Net::DNS->version, "\n" ); exit(0); } sub make_keyset { my $source = new Net::DNS::ZoneFile(shift); my $file = $source->name; my $directory = dirname($file); print("Processing file: $file\n"); my @keys; while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); print("Read DNSKEY RR\n") if $verbose; push @keys, $keyrr; } print("Creating keyset\n") if $verbose; my $keyset = Net::DNS::Keyset->new( \@keys, "$directory" ) or die("$progname: unable to create keyset. $Net::DNS::Keyset::keyset_err.\n"); print("Verifying keyset\n") if $verbose; $keyset->verify() or die("$progname: unable to verify keyset. $Net::DNS::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::Keyset::keyset_err.\n"); if ($printds) { print("Extracting DS RR\n") if $verbose; my @ds = $keyset->extract_ds(); foreach $ds (@ds) { $ds->print(); } } } =head1 NAME make-signed-keyset - create a self-signed keyset =head1 SYNOPSIS make-signed-keyset [-v] file =head1 DESCRIPTION make-signed-keyset is a program that creates a self-signed keyset from a BIND public key file specified on the command line. The options are as follows: =over =item -v Be verbose. =item -d Print the DS record for each key in the keyset. =back =head1 AUTHOR Contributed by Wes Griffin =cut Net-DNS-SEC-1.03/demo/key2ds0000644000175000017500000000161612760026475014646 0ustar willemwillem#!/usr/bin/perl #$Id: key2ds 1295 2015-01-08 13:14:03Z willem $ # A little util to convert DNSKEY records to DS records # from stdin to stdout # # Author: Miek Gieben, NLnetLabs use strict; use Net::DNS::SEC; use Net::DNS::ZoneFile; my $handle = \*STDIN; my $source = new Net::DNS::ZoneFile($handle); while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); foreach my $digtype (qw(SHA256 SHA1)) { my $ds = create Net::DNS::RR::DS( $keyrr, digtype => $digtype ); $ds->print; } } exit 0; =head1 NAME key2ds - Utility to create DS records from DNSKEY RRs read from stdin. =head1 SYNOPSIS key2ds ds.txt =head1 DESCRIPTION C reads the key data from STDIN and prints the corresponding DS record on STDOUT. =head1 COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 0; Net-DNS-SEC-1.03/demo/getkeyset.pl0000755000175000017500000000411712760026475016065 0ustar willemwillem#!/usr/bin/perl #$Id: getkeyset.pl 1295 2015-01-08 13:14:03Z willem $ use strict; use Net::DNS::SEC; use Net::DNS::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::Keyset->new($packet) || print $Net::DNS::Keyset::keyset_err && return 0; # 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.03/Makefile.PL0000644000175000017500000000271312760026475014547 0ustar willemwillem# # $Id: Makefile.PL 1495 2016-08-23 08:54:04Z willem $ -*-perl-*- # warn < eval $ExtUtils::MakeMaker::VERSION; # See perldoc ExtUtils::MakeMaker for details of how to influence # the contents of the Makefile that is written. my @author = ( 'Olaf Kolkman', 'Dick Franks' ); my %metadata = ( NAME => 'Net::DNS::SEC', VERSION_FROM => 'lib/Net/DNS/SEC.pm', ABSTRACT_FROM => 'lib/Net/DNS/SEC.pm', AUTHOR => MM < 6.5702 ? shift(@author) : [@author], LICENSE => 'mit', MIN_PERL_VERSION => 5.006, ); my %prerequisite = ( Net::DNS => 1.01, Crypt::OpenSSL::Bignum => 0.05, Crypt::OpenSSL::RSA => 0.28, File::Spec => 0.86, MIME::Base64 => 2.11, Test::More => 0.47, ); my %optional = ( Crypt::OpenSSL::DSA => 0.15, Crypt::OpenSSL::EC => 1.01, Crypt::OpenSSL::ECDSA => 0.06, Crypt::OpenSSL::Random => 0.10, Digest::GOST => 0.06, Digest::SHA => 5.23, ); WriteMakefile( %metadata, PREREQ_PM => {%prerequisite}, META_MERGE => {recommends => {%optional}}, ); sub MY::libscan { my $path = $_[1]; return '' if $path =~ /\B\.svn\b/; return $path; } __END__ Net-DNS-SEC-1.03/META.yml0000664000175000017500000000146412760026557014053 0ustar willemwillem--- abstract: 'DNSSEC extensions to Net::DNS' author: - 'Olaf Kolkman' - 'Dick Franks' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.18, CPAN::Meta::Converter version 2.143240' 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: Crypt::OpenSSL::DSA: '0.15' Crypt::OpenSSL::EC: '1.01' Crypt::OpenSSL::ECDSA: '0.06' Crypt::OpenSSL::Random: '0.1' Digest::GOST: '0.06' Digest::SHA: '5.23' requires: Crypt::OpenSSL::Bignum: '0.05' Crypt::OpenSSL::RSA: '0.28' File::Spec: '0.86' MIME::Base64: '2.11' Net::DNS: '1.01' Test::More: '0.47' perl: '5.006' version: '1.03' Net-DNS-SEC-1.03/lib/0000755000175000017500000000000012760026557013341 5ustar willemwillemNet-DNS-SEC-1.03/lib/Net/0000755000175000017500000000000012760026557014067 5ustar willemwillemNet-DNS-SEC-1.03/lib/Net/DNS/0000755000175000017500000000000012760026557014513 5ustar willemwillemNet-DNS-SEC-1.03/lib/Net/DNS/SEC/0000755000175000017500000000000012760026557015125 5ustar willemwillemNet-DNS-SEC-1.03/lib/Net/DNS/SEC/Private.pm0000644000175000017500000002264012760026475017100 0ustar willemwillempackage Net::DNS::SEC::Private; # # $Id: Private.pm 1397 2015-09-15 18:45:17Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1397 $)[1]; =head1 NAME Net::DNS::SEC::Private - DNSSEC Private key object =head1 SYNOPSIS use Net::DNS::SEC::Private; $private = new Net::DNS::SEC::Private( $keypath ); $private = new Net::DNS::SEC::Private( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); =head1 DESCRIPTION Class representing private keys as read from a keyfile generated by BIND dnssec-keygen. The class is written to be used only in the context of the Net::DNS::RR::RRSIG create method. This class is not designed to interact with any other system. =cut use strict; use integer; use warnings; use Carp; use File::Spec; use FileHandle; use MIME::Base64; sub new { scalar(@_) > 2 ? &_new_params : &_new_keyfile } sub _new_keyfile { my ( $class, $file ) = @_; my ( $vol, $dir, $keyname ) = File::Spec->splitpath($file); # Format something like: /Kbla.foo.+001+60114.private' # assuming proper file name. # We determine the algorithm from the filename. croak "$keyname does not appear to be a private key" unless $keyname =~ /^K(.*\.)\+(\d+)\+(\d+)\.private$/; my @identifier = ( signame => $1, algorithm => 0 + $2, keytag => $3 ); my $handle = new FileHandle($file) or croak qq(open: "$file" $!); my @content; local $_; while (<$handle>) { chomp; next if /^$/; next if /^\s*[;]/; s/\(.+\)//; my ( $name, $value ) = split; push @content, $name, $value; } return $class->_new_params( @content, @identifier ); } sub _new_params { my $class = shift; my $param = {}; while (@_) { my $name = shift @_; $name =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; $param->{$name} = shift @_; } my $self = bless sub { $param->{shift()} }, $class; croak 'algorithm not specified' unless defined $self->algorithm; croak 'signame not specified' unless defined $self->signame; return $self; } sub generate_rsa { my ( $class, $domain, $flags, $keysize, $entropy, $algcode ) = @_; $keysize ||= 1024; require Crypt::OpenSSL::RSA; if ( defined($entropy) ) { require Crypt::OpenSSL::Random; Crypt::OpenSSL::Random::random_seed($entropy); Crypt::OpenSSL::RSA->import_random_seed(); } my $rsa = Crypt::OpenSSL::RSA->generate_key($keysize); my $keyblob = $rsa->get_private_key_string; return $class->new_rsa_priv( $keyblob, $domain, $flags, $algcode ); } sub new_rsa_priv { my $class = shift; my $keyblob = shift; my $domain = shift; my $flags = shift || 256; my $algcode = shift || 5; require Crypt::OpenSSL::RSA; my $rsa = Crypt::OpenSSL::RSA->new_private_key($keyblob); my @params = map $_->to_bin, $rsa->get_key_parameters; my @base64 = map encode_base64( $_, '' ), @params; # private key my ( $modulus, $exponent ) = @params; # public key my $explen = length $exponent; # my $format = $explen < 256 ? 'C a* a*' : 'xn a* a*'; # RFC3110, section 2 my $format = 'C a* a*'; # real world my $keybin = pack $format, $explen, $exponent, $modulus; my $dnskey = new Net::DNS::RR( name => $domain, type => 'DNSKEY', algorithm => $algcode, flags => $flags, keybin => $keybin, ); my $algorithm = $dnskey->algorithm; my $mnemonic = $dnskey->algorithm('MNEMONIC'); my $keytag = $dnskey->keytag; my $private_key = <<"END"; Private-key-format: v1.2 Algorithm: $algorithm ($mnemonic) Modulus: $base64[0] PublicExponent: $base64[1] PrivateExponent: $base64[2] Prime1: $base64[3] Prime2: $base64[4] Exponent1: $base64[5] Exponent2: $base64[6] Coefficient: $base64[7] END return $class->_new_params( algorithm => $algorithm, keytag => $keytag, signame => $dnskey->signame, privatekeyname => $dnskey->privatekeyname, flags => $dnskey->flags, Modulus => $base64[0], PublicExponent => $base64[1], PrivateExponent => $base64[2], Prime1 => $base64[3], Prime2 => $base64[4], Exponent1 => $base64[5], Exponent2 => $base64[6], Coefficient => $base64[7], dump_rsa_priv => $private_key, dump_rsa_pub => $dnskey->key, dump_rsa_keytag => $keytag, dump_rsa_private_pem => $rsa->get_private_key_string, dump_rsa_private_der => $rsa->get_private_key_string, # historical ); } use vars qw($AUTOLOAD); sub AUTOLOAD { ## Default method my ($self) = @_; no strict q/refs/; my ($attribute) = $AUTOLOAD =~ m/::([^:]*)$/; $attribute =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; # Build a method in the class *{$AUTOLOAD} = sub { my $self = shift; &$self($attribute); }; carp <<"END" if $attribute =~ /^dumprsa/; Warning: $AUTOLOAD is deprecated and may be removed in a future release END # and jump to it goto &{$AUTOLOAD}; } 1; __END__ =head1 METHODS =head2 new (from private keyfile) $keypath = '/home/foo/Kexample.com.+013+26512.private'; $private = new Net::DNS::SEC::Private( $keypath ); The argument is the full path to a private key file generated by the BIND dnssec-keygen tool. Note that the filename contains information about the algorithm and keytag. =head2 new (from private key parameters) $private = new Net::DNS::SEC::Private( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); The arguments define the private key parameters as (name,value) pairs. The name and data representation are identical to that used in a BIND private keyfile. =head2 private_key_format $format = $private->private_key_format; Returns a string which identifies the format of the private key file. =head2 algorithm, keytag, signame $algorithm = $private->algorithm; $keytag = $private->keytag; $signame = $private->signame; Returns the corresponding attribute determined from the filename. =head2 Private key attributes $attribute = $private->attribute; Returns the value as it appears in the private key file. The attribute names correspond to the tag in the key file, modified to form an acceptable Perl subroutine name. =head2 created, publish, activate $created = $private->created; $publish = $private->publish; $activate = $private->activate; Returns a string which represents a date in the form 20141212123456. Returns undefined value for key formats older than v1.3. =head1 RSA SPECIFIC HELPER FUNCTIONS These functions may be useful to generate RSA private keys and import PEM format RSA private keys. =head2 new_rsa_priv $private = Net::DNS::SEC::Private->new_rsa_priv( $keyblob, $domain, $flag, $algorithm ); Constructor method which creates a Net::DNS::SEC::Private object from the supplied PEM keyblob. The second argument specifies the domain name for which this key will be used. The flag argument should be either 257 or 256 for SEP and non-SEP key respectively. The keyblob should include the -----BEGIN...----- and -----END...----- lines. The padding is set to PKCS1_OAEP. =head2 dump_rsa_priv $BIND_private_key = $private->dump_rsa_priv(); Returns the content of a BIND private keyfile (Private-key-format: v1.2). =head2 dump_rsa_pub $public_key = $private->dump_rsa_pub(); Returns the public key field of the DNSKEY resource record. =head2 dump_rsa_keytag $keytag = $private->dump_rsa_keytag(); Returns the keytag field of the DNSKEY resource record. =head2 dump_rsa_private_pem $keyblob = $private->dump_rsa_private_pem(); Return the PEM-encoded representation of the private key. (Same format that can be read with the new_rsa_priv method.) =head2 generate_rsa $newkey = Net::DNS::SEC::Private->generate_rsa( "example.com", 256, 1024, $random, $algorithm ); print $newkey->dump_rsa_priv(); print $newkey->dump_rsa_pub(); Uses Crypt::OpenSSL::RSA generate_key to create a keypair. The first argument is the name of the key. The flag field takes the value of 257 for key-signing keys and ther value of 256 for zone signing keys. The 3rd argument is the keysize (default 1024). The 4th argument, if defined, is passed to the Crypt::OpenSSL::Random random_seed method (see Crypt::OpenSSL::RSA for details), not needed with a proper /dev/random. The 5th argument specifies the algorithm if not RSASHA1 (the default). =head1 COPYRIGHT Copyright (c)2014 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, L, L, L =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC/DSA.pm0000644000175000017500000000761712760026475016104 0ustar willemwillempackage Net::DNS::SEC::DSA; # # $Id: DSA.pm 1376 2015-07-12 19:16:04Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1376 $)[1]; =head1 NAME Net::DNS::SEC::DSA - DNSSEC DSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::DSA; $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of DSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); Generates the wire-format binary signature from the binary sigdata and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the binary sigdata using the specified public key resource record. =cut use strict; use integer; use warnings; use Carp; use Digest::SHA; use MIME::Base64; use Crypt::OpenSSL::DSA 0.14; my %DSA = ( 3 => ['Digest::SHA'], 6 => ['Digest::SHA'], ); sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; # digest sigdata my ( $object, @param ) = @{$DSA{$algorithm} || []}; die 'private key not DSA' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $dsa = Crypt::OpenSSL::DSA->new(); # private key $dsa->set_p( decode_base64 $private->prime ); $dsa->set_q( decode_base64 $private->subprime ); $dsa->set_g( decode_base64 $private->base ); $dsa->set_priv_key( decode_base64 $private->private_value ); my $dsasig = $dsa->do_sign( $hash->digest ); my $T = ( length( $dsa->get_g ) - 64 ) / 8; my $R = $dsasig->get_r; my $S = $dsasig->get_s; # both the R and S parameters need to be 20 octets: my $Rpad = 20 - length($R); my $Spad = 20 - length($S); pack "C x$Rpad a* x$Spad a*", $T, $R, $S; # RFC2536, section 3 } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; # digest sigdata my ( $object, @param ) = @{$DSA{$algorithm} || []}; die 'public key not DSA' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $keybin = $keyrr->keybin; # public key my $numlen = 64 + 8 * unpack( 'C', $keybin ); # RFC2536, section 2 my ( $Q, $P, $G, $Y ) = unpack "x a20 a$numlen a$numlen a$numlen", $keybin; my $dsa = Crypt::OpenSSL::DSA->new(); $dsa->set_q($Q); $dsa->set_g($G); $dsa->set_p($P); $dsa->set_pub_key($Y); my $dsasig = Crypt::OpenSSL::DSA::Signature->new(); my ( $R, $S ) = unpack 'x a20 a20', $sigbin; # RFC2536, section 3 $dsasig->set_r($R); $dsasig->set_s($S); $dsa->do_verify( $hash->digest, $dsasig ); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT The Crypt::OpenSSL::DSA package was created by T.J. Mather. =head1 COPYRIGHT Copyright (c)2014 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, RFC2536 =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC/ECCGOST.pm0000644000175000017500000001663612760026475016565 0ustar willemwillempackage Net::DNS::SEC::ECCGOST; # # $Id: ECCGOST.pm 1497 2016-08-24 09:31:25Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1497 $)[1]; =head1 NAME Net::DNS::SEC::ECCGOST - DNSSEC ECC-GOST digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::ECCGOST; $signature = Net::DNS::SEC::ECCGOST->sign( $sigdata, $private ); $validated = Net::DNS::SEC::ECCGOST->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of GOST R 34.10-2001 elliptic curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::ECCGOST->sign( $sigdata, $private ); Generates the wire-format binary signature from the binary sigdata and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::ECCGOST->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the binary sigdata using the specified public key resource record. =cut use strict; use integer; use warnings; use Carp; use MIME::Base64; use Crypt::OpenSSL::Bignum; use Crypt::OpenSSL::EC 1.01; use Crypt::OpenSSL::ECDSA 0.06; use Digest::GOST 0.06; use Digest::GOST::CryptoPro; my %ECcurve; my %GOST = ( 12 => ['Digest::GOST::CryptoPro'] ); sub sign { my ( $class, $sigdata, $private ) = @_; my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); my $key = decode_base64( $private->PrivateKey ); my $d = Crypt::OpenSSL::Bignum->new_from_bin($key); my $algorithm = $private->algorithm; # step 1 (nomenclature per RFC5832) my ( $object, @param ) = @{$GOST{$algorithm} || []}; croak 'private key not GOST' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $H = reverse $hash->digest; my $alpha = Crypt::OpenSSL::Bignum->new_from_bin($H); # step 2 my $group = $ECcurve{$algorithm}->dup(); # precalculated curve my $q = Crypt::OpenSSL::Bignum->zero; $group->get_order( $q, $ctx ); my $e = $alpha->mod( $q, $ctx ); # Note: alpha can exceed but is never longer than q $e = Crypt::OpenSSL::Bignum->one if $e->is_zero; # uncoverable branch my $zeta; my $P = $group->get0_generator(); { # step 3 $hash->add($key); $hash->add( time() ^ ( $$ + ( $$ << 15 ) ) ); $hash->add( $hash->digest ); my $m = Crypt::OpenSSL::Bignum->new_from_bin( $hash->digest ); my $k = $m->mod( $q, $ctx ); redo if $k->is_zero; # uncoverable branch my $x = Crypt::OpenSSL::Bignum->zero; # step 4 my $y = Crypt::OpenSSL::Bignum->zero; my $C = Crypt::OpenSSL::EC::EC_POINT::new($group); Crypt::OpenSSL::EC::EC_POINT::mul( $group, $C, $q, $P, $k, $ctx ); Crypt::OpenSSL::EC::EC_POINT::get_affine_coordinates_GFp( $group, $C, $x, $y, $ctx ); my $r = $x->mod( $q, $ctx ); redo if $r->is_zero; # uncoverable branch my $v = $r->mul( $d, $ctx ); # step 5 my $w = $k->mul( $e, $ctx ); my $s = $v->add($w)->mod( $q, $ctx ); redo if $s->is_zero; # uncoverable branch my $size = length $H; # step 6 $zeta = pack "a$size a$size", reverse( $s->to_bin ), reverse( $r->to_bin ); } return $zeta; } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; # Implementation (ab)using Crypt::OpenSSL::ECDSA my $zeta = $sigbin; # step 1 (nomenclature per RFC5832) my $size = length($zeta) >> 1; my ( $s, $r ) = unpack( "a$size a*", $zeta ); my $algorithm = $keyrr->algorithm; # step 2 my ( $object, @param ) = @{$GOST{$algorithm} || []}; croak 'public key not GOST' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $H = reverse $hash->digest; my $alpha = Crypt::OpenSSL::Bignum->new_from_bin($H); # step 3 my $group = $ECcurve{$algorithm}->dup(); # precalculated curve my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); my $q = Crypt::OpenSSL::Bignum->zero; $group->get_order( $q, $ctx ); my $e = $alpha->mod( $q, $ctx ); # Note: alpha can exceed but is never longer than q $e = Crypt::OpenSSL::Bignum->one if $e->is_zero; # uncoverable branch my $keybin = reverse $keyrr->keybin; # public key my $keylen = length($keybin) >> 1; my ( $y, $x ) = map Crypt::OpenSSL::Bignum->new_from_bin($_), unpack "a$keylen a*", $keybin; my $Q = Crypt::OpenSSL::EC::EC_POINT::new($group); Crypt::OpenSSL::EC::EC_POINT::set_affine_coordinates_GFp( $group, $Q, $x, $y, $ctx ); my $eckey = Crypt::OpenSSL::EC::EC_KEY::new(); $eckey->set_group($group); $eckey->set_public_key($Q); # algebraic transformation of ECC-GOST into equivalent ECDSA problem my $dsasig = Crypt::OpenSSL::ECDSA::ECDSA_SIG->new(); $dsasig->set_r($r); $dsasig->set_s( $q->sub($e)->to_bin ); my $m = $q->sub( Crypt::OpenSSL::Bignum->new_from_bin($s) )->mod( $q, $ctx ); Crypt::OpenSSL::ECDSA::ECDSA_do_verify( $m->to_bin, $dsasig, $eckey ); } ######################################## BEGIN { my %GOST_R_34_10_2001_CryptoPro_A = ( # RFC4357 a => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94', # -3 mod p b => '00A6', # 166 p => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97', q => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893', x => '01', y => '8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14' ); my $_curve = sub { my %param = @_; my $p = Crypt::OpenSSL::Bignum->new_from_hex( $param{p} ); my $a = Crypt::OpenSSL::Bignum->new_from_hex( $param{a} ); my $b = Crypt::OpenSSL::Bignum->new_from_hex( $param{b} ); my $x = Crypt::OpenSSL::Bignum->new_from_hex( $param{x} ); my $y = Crypt::OpenSSL::Bignum->new_from_hex( $param{y} ); my $n = Crypt::OpenSSL::Bignum->new_from_hex( $param{q} ); my $h = Crypt::OpenSSL::Bignum->one; my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); my $method = Crypt::OpenSSL::EC::EC_GFp_mont_method(); my $group = Crypt::OpenSSL::EC::EC_GROUP::new($method); $group->set_curve_GFp( $p, $a, $b, $ctx ); # y^2 = x^3 + a*x + b mod p my $G = Crypt::OpenSSL::EC::EC_POINT::new($group); Crypt::OpenSSL::EC::EC_POINT::set_affine_coordinates_GFp( $group, $G, $x, $y, $ctx ); $group->set_generator( $G, $n, $h ); die 'bad curve' unless Crypt::OpenSSL::EC::EC_GROUP::check( $group, $ctx ); # uncoverable branch return $group; }; $ECcurve{12} = &$_curve(%GOST_R_34_10_2001_CryptoPro_A); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Mike McCauley created the Crypt::OpenSSL::ECDSA perl extension module specifically for this development. =head1 COPYRIGHT Copyright (c)2014 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, L, RFC4357, RFC5832, RFC5933 =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC/Keyset.pm0000644000175000017500000002135412760026475016733 0ustar willemwillempackage Net::DNS::SEC::Keyset; # # $Id: Keyset.pm 1395 2015-09-14 21:16:13Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1395 $)[1]; =head1 NAME Net::DNS::SEC::Keyset - DNSSEC Keyset object class =head1 SYNOPSIS use Net::DNS::SEC::Keyset; =head1 DESCRIPTION A keyset is an "administrative" unit used for DNSSEC maintenance. This class provides interfaces for creating, reading and writing keysets. Object methods are provided to extract DNSKEY, RRSIG and DS records. Note that this class is still being developed. Attributes and methods are subject to change. =cut use strict; use integer; use warnings; use Carp; use File::Spec::Functions; use Net::DNS::ZoneFile; use vars qw($keyset_err); sub new { my ( $class, $arg1, $arg2 ) = @_; my $ref1 = ref($arg1); return &_new_from_file unless $ref1; return &_new_from_packet if $ref1 eq 'Net::DNS::Packet'; return &_new_from_keys unless ref($arg2); return &_new_from_keys_sigs; } =head2 new (from file) $keyset = Net::DNS::SEC::Keyset->new( $filename ); $keyset = Net::DNS::SEC::Keyset->new( $filename, $directory ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Constructor method which reads the specified keyset file and returns a keyset object. The optional second argument specifies the filename base directory. Sets keyset_err and returns undef on failure. =cut sub _new_from_file { my ( $class, $name, @path ) = @_; my $file = catfile( @path, $name ); my @rr = new Net::DNS::ZoneFile($file)->read; return $class->_new_from_keys_sigs( \@rr, \@rr ); } =head2 new (by signing keys) $keyset = Net::DNS::SEC::Keyset->new( \@keyrr, $privatekeypath ); Creates a keyset object from the keys provided through the reference to an array of Net::DNS::RR::Key objects. The method will create and self-sign the whole keyset. The private keys as generated by the BIND dnssec-keygen tool are assumed to be in the current directory or, if specified, the directory indicated by $privatekeypath. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys { my ( $class, $keylist, @keypath ) = @_; my @sigrr; foreach my $key ( grep $_->type eq 'DNSKEY', @$keylist ) { my $keyname = $key->privatekeyname; my $keyfile = catfile( @keypath, $keyname ); my @rrsig = Net::DNS::RR::RRSIG->create( $keylist, $keyfile ); push @sigrr, grep defined, @rrsig; } return $class->_new_from_keys_sigs( $keylist, \@sigrr ); } =head2 new (from key and sig RRsets) $keyset = Net::DNS::Keyset->new( \@keyrr, \@sigrr ); Creates a keyset object from the keys provided through the references to arrays of Net::DNS::RR::DNSKEY and Net::DNS::RR::RRSIG objects. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys_sigs { my ( $class, $key_ref, $sig_ref ) = @_; my @keyrr = grep $_->type eq 'DNSKEY', @$key_ref; my @sigrr = grep $_->type eq 'RRSIG', @$sig_ref; my $keyset = bless {keys => \@keyrr, sigs => \@sigrr}, $class; return scalar( $keyset->verify ) ? $keyset : undef; } =head2 new (from Packet) $res = Net::DNS::Resolver->new; $res->dnssec(1); $packet = $res->query ( "example.com", "DNSKEY", "IN" ); $keyset = Net::DNS::SEC::Keyset->new( $packet ) Creates a keyset object from a Net::DNS::Packet that contains the answer to a query for the apex key records. This is the method you should use for automatically fetching keys. Sets keyset_err and returns undef on failure. =cut sub _new_from_packet { my ( $class, $packet ) = @_; my @rrset = $packet->answer; return $class->_new_from_keys_sigs( \@rrset, \@rrset ); } =head2 keys @keyrr = $keyset->keys; Returns an array of Net::DNS::RR::DNSKEY objects. =cut sub keys { my $self = shift; my @keys = @{$self->{keys}}; } =head2 sigs @sigrr = $keyset->sigs; Returns an array of Net::DNS::RR::RRSIG objects. =cut sub sigs { my $self = shift; my @sigs = @{$self->{sigs}}; } =head2 extract_ds @ds = $keyset->extract_ds; die $keyset->keyset_err unless @ds; Extracts DS records from the keyset. Note that the keyset will be verified during extraction. All keys will need to have a valid self-signature. The method sets keyset_err if verification fails. =cut sub extract_ds { my $self = shift; my @ds; @ds = map Net::DNS::RR::DS->create($_), $self->keys if $self->verify; return @ds; } =head2 verify @keytags = $keyset->verify(); die $keyset->keyset_err unless @keytags; $keyset->verify( $keytag ) || die $keyset->keyset_err; If no arguments are given: =over 2 =item Verifies if all signatures present verify the keyset. =item Verifies if there are DNSKEYs with the SEP flag set, there is at least one RRSIG made using that key. =item Verifies that if there are no DNSKEYs with the SEP flag set there is at least one RRSIG made with one of the keys from the keyset. =back If an argument is given, it is should be the numeric keytag of the key in the keyset which will be verified using the corresponding RRSIG. The method returns a list of keytags of verified keys in the keyset. The method sets keyset_err and returns empty list if verification fails. =cut sub verify { my ( $self, $keyid ) = @_; my @keys = $self->keys; my %keysbytag; push( @{$keysbytag{$_->keytag}}, $_ ) foreach @keys; my @sigs = $self->sigs; my @keyset_err; my %names = map { ( $_->name => $_ ) } @keys, @sigs; my @names = CORE::keys %names; push @keyset_err, "Multiple names in keyset: @names" if scalar(@names) > 1; if ($keyid) { @sigs = grep $_->keytag == $keyid, @sigs; push @keyset_err, "No signature made with $keyid found" unless @sigs; } elsif ( my @sepkeys = grep $_->sep, @keys ) { my %sepkey = map { ( $_->keytag => $_ ) } @sepkeys; push @keyset_err, 'No signature found for key with SEP flag' unless grep $sepkey{$_->keytag}, @sigs; } foreach my $sig (@sigs) { my $keytag = $sig->keytag; next if $sig->verify( \@keys, $keysbytag{$keytag} || [] ); my $vrfyerr = $sig->vrfyerrstr; my $signame = $sig->signame; push @keyset_err, "$vrfyerr on key $signame $keytag "; } $keyset_err = join "\n", @keyset_err; my @tags_verified; @tags_verified = map $_->keytag, @sigs unless $keyset_err; return @tags_verified; } =head2 keyset_err $keyset_err = Net::DNS::SEC::Keyset->keyset_err; $keyset_err = $keyset->keyset_err; Returns the keyset error string. =cut sub keyset_err { return $keyset_err; } =head2 string $string = $keyset->string; Returns a string representation of the keyset. =cut sub string { my $self = shift; return join "\n", map $_->string, ( $self->keys, $self->sigs ); } =head2 print $keyset->print; # similar to print( $keyset->string ) Prints the keyset. =cut sub print { my $self = shift; foreach ( $self->keys, $self->sigs ) { $_->print } } =head2 writekeyset $keyset->writekeyset; $keyset->writekeyset( $path ); $keyset->writekeyset( $prefix ); $keyset->writekeyset( $prefix, $path ); Writes the keyset to a file named "keyset-." in the current working directory or directory defined by the optional $path argument. The optional $prefix argument specifies the prefix that will be prepended to the domain name to form the keyset filename. =cut sub writekeyset { my $self = shift; my ( $arg1, @path ) = @_; @path = shift() if $arg1 && file_name_is_absolute($arg1); my $prefix = shift || 'keyset-'; my @keysetrr = ( $self->keys, $self->sigs ); my $domainname = $keysetrr[0]->name; my $keysetname = "$prefix$domainname."; my $filename = catfile( @path, $keysetname ); $filename =~ s/[.]+/\./; ## avoid antisocial consequences of $path with .. open( KEYSET, ">$filename" ) or croak qq(open: "$filename" $!); select( ( select(KEYSET), $self->print )[0] ); close(KEYSET); return $filename; } 1; __END__ =head1 COPYRIGHT Copyright (c)2002 RIPE NCC. Author Olaf M. Kolkman Portions Copyright (c)2014 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC/RSA.pm0000644000175000017500000000706212760026475016114 0ustar willemwillempackage Net::DNS::SEC::RSA; # # $Id: RSA.pm 1376 2015-07-12 19:16:04Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1376 $)[1]; =head1 NAME Net::DNS::SEC::RSA - DNSSEC RSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::RSA; $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of RSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); Generates the wire-format binary signature from the binary sigdata and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the binary sigdata using the specified public key resource record. =cut use strict; use integer; use warnings; use Carp; use MIME::Base64; use Crypt::OpenSSL::Bignum; use Crypt::OpenSSL::RSA 0.27; my %RSA = ( 1 => 'use_md5_hash', 5 => 'use_sha1_hash', 7 => 'use_sha1_hash', 8 => 'use_sha256_hash', 10 => 'use_sha512_hash', ); sub sign { my ( $class, $sigdata, $private ) = @_; my $hash = $RSA{$private->algorithm} || die 'private key not RSA'; my @param = map Crypt::OpenSSL::Bignum->new_from_bin( decode_base64( $private->$_ ) ), qw(Modulus PublicExponent PrivateExponent Prime1 Prime2 Exponent1 Exponent2 Coefficient); my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters(@param); $rsa->use_pkcs1_oaep_padding; $rsa->$hash; $rsa->sign($sigdata); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $hash = $RSA{$keyrr->algorithm} || die 'public key not RSA'; 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 $bn_modulus = Crypt::OpenSSL::Bignum->new_from_bin($modulus); my $bn_exponent = Crypt::OpenSSL::Bignum->new_from_bin($exponent); my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters( $bn_modulus, $bn_exponent ); $rsa->use_pkcs1_oaep_padding; $rsa->$hash; $rsa->verify( $sigdata, $sigbin ); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Andy Vaskys (Network Associates Laboratories) supplied the code for handling RSA with SHA1 (Algorithm 5). The Crypt::OpenSSL::RSA package was created by Ian Robertson. =head1 COPYRIGHT Copyright (c)2014 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, RFC2437, RFC3110 =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC/ECDSA.pm0000644000175000017500000001576612760026475016320 0ustar willemwillempackage Net::DNS::SEC::ECDSA; # # $Id: ECDSA.pm 1376 2015-07-12 19:16:04Z willem $ # use vars qw($VERSION); $VERSION = (qw$LastChangedRevision: 1376 $)[1]; =head1 NAME Net::DNS::SEC::ECDSA - DNSSEC ECDSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::ECDSA; $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of ECDSA elliptic curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); Generates the wire-format binary signature from the binary sigdata and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the binary sigdata using the specified public key resource record. =cut use strict; use integer; use warnings; use Carp; use Digest::SHA; use MIME::Base64; use Crypt::OpenSSL::Bignum; use Crypt::OpenSSL::EC 0.5; use Crypt::OpenSSL::ECDSA 0.05; my %ECcurve; my %ECDSA = ( 13 => ['Digest::SHA', 256], 14 => ['Digest::SHA', 384], ); sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; # digest sigdata my ( $object, @param ) = @{$ECDSA{$algorithm} || []}; die 'private key not ECDSA' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $digest = $hash->digest; my $keybin = decode_base64( $private->PrivateKey ); my $bignum = Crypt::OpenSSL::Bignum->new_from_bin($keybin); my $group = $ECcurve{$algorithm}->dup(); # precalculated curve my $eckey = Crypt::OpenSSL::EC::EC_KEY::new(); $eckey->set_group($group); $eckey->set_private_key($bignum); my $ecsig = Crypt::OpenSSL::ECDSA::ECDSA_do_sign( $digest, $eckey ); my ( $R, $S ) = ( $ecsig->get_r, $ecsig->get_s ); # both the R and S parameters need to be zero padded: my $size = length $digest; my $Rpad = $size - length $R; my $Spad = $size - length $S; pack "x$Rpad a* x$Spad a*", $R, $S; } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; # digest sigdata my ( $object, @param ) = @{$ECDSA{$algorithm} || []}; die 'public key not ECDSA' unless $object; my $hash = $object->new(@param); $hash->add($sigdata); my $digest = $hash->digest; my $keybin = $keyrr->keybin; # public key my $keylen = length($keybin) >> 1; my ( $x, $y ) = map Crypt::OpenSSL::Bignum->new_from_bin($_), unpack "a$keylen a*", $keybin; my $group = $ECcurve{$algorithm}->dup(); # precalculated curve my $key = Crypt::OpenSSL::EC::EC_POINT::new($group); my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); Crypt::OpenSSL::EC::EC_POINT::set_affine_coordinates_GFp( $group, $key, $x, $y, $ctx ); my $eckey = Crypt::OpenSSL::EC::EC_KEY::new(); $eckey->set_group($group); $eckey->set_public_key($key); my $siglen = length($sigbin) >> 1; # signature my ( $R, $S ) = unpack( "a$siglen a*", $sigbin ); my $dsasig = Crypt::OpenSSL::ECDSA::ECDSA_SIG->new(); $dsasig->set_r($R); $dsasig->set_s($S); Crypt::OpenSSL::ECDSA::ECDSA_do_verify( $digest, $dsasig, $eckey ); } ######################################## BEGIN { my %NIST_P256 = ( ## FIPS 186-4, D.1.2.3 p => 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', a => 'ffffffff00000001000000000000000000000000fffffffffffffffffffffffc', # -3 mod p b => '5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b', x => '6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296', y => '4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5', n => 'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', s => 'c49d360886e704936a6678e1139d26b7819f7e90', c => '7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0d' ); my %NIST_P384 = ( ## FIPS 186-4, D.1.2.4 p => 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff', a => 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc', b => 'b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef', x => 'aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7', y => '3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f', n => 'ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973', s => 'a335926aa319a27a1d00896a6773a4827acdac73', c => '79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483' ); my $_curve = sub { my %param = @_; my $p = Crypt::OpenSSL::Bignum->new_from_hex( $param{p} ); my $a = Crypt::OpenSSL::Bignum->new_from_hex( $param{a} ); my $b = Crypt::OpenSSL::Bignum->new_from_hex( $param{b} ); my $x = Crypt::OpenSSL::Bignum->new_from_hex( $param{x} ); my $y = Crypt::OpenSSL::Bignum->new_from_hex( $param{y} ); my $n = Crypt::OpenSSL::Bignum->new_from_hex( $param{n} ); my $h = Crypt::OpenSSL::Bignum->one; my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); my $method = Crypt::OpenSSL::EC::EC_GFp_mont_method(); my $group = Crypt::OpenSSL::EC::EC_GROUP::new($method); $group->set_curve_GFp( $p, $a, $b, $ctx ); # y^2 = x^3 + a*x + b mod p my $G = Crypt::OpenSSL::EC::EC_POINT::new($group); Crypt::OpenSSL::EC::EC_POINT::set_affine_coordinates_GFp( $group, $G, $x, $y, $ctx ); $group->set_generator( $G, $n, $h ); die 'bad curve' unless Crypt::OpenSSL::EC::EC_GROUP::check( $group, $ctx ); # uncoverable branch return $group; }; $ECcurve{13} = &$_curve(%NIST_P256); $ECcurve{14} = &$_curve(%NIST_P384); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Mike McCauley created the Crypt::OpenSSL::ECDSA perl extension module specifically for this development. =head1 COPYRIGHT Copyright (c)2014 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, L, RFC6090, RFC6605 =cut Net-DNS-SEC-1.03/lib/Net/DNS/SEC.pm0000644000175000017500000000660512760026475015471 0ustar willemwillempackage Net::DNS::SEC; # # $Id: SEC.pm 1503 2016-08-26 11:51:16Z willem $ # use vars qw($VERSION $SVNVERSION); $VERSION = '1.03'; $VERSION = eval $VERSION; $SVNVERSION = (qw$LastChangedRevision: 1503 $)[1]; =head1 NAME Net::DNS::SEC - DNSSEC extensions to Net::DNS =head1 SYNOPSIS use Net::DNS::SEC; =head1 DESCRIPTION The Net::DNS::SEC suite provides additional packages required to support DNSSEC as described in RFC4033, RFC4034, RFC4035 and subsequent related documents. Net::DNS::SEC is installed as an extension to an existing Net::DNS installation. The extended features are made available by substituting Net::DNS::SEC for Net::DNS in the use declaration. =cut use strict; use base qw(Exporter); use Net::DNS 1.01 qw(:DEFAULT); use vars qw(@EXPORT); @EXPORT = ( @Net::DNS::EXPORT, qw(algorithm digtype key_difference) ); use integer; use warnings; use Carp; use Net::DNS::RR::CDS; use Net::DNS::RR::DLV; use Net::DNS::RR::DS; use Net::DNS::RR::RRSIG; use Net::DNS::RR::SIG; =head1 UTILITY FUNCTIONS =head2 algorithm $mnemonic = algorithm( 5 ); $numeric = algorithm( 'RSA-SHA1' ); print "algorithm mnemonic\t", $mnemonic, "\n"; print "algorithm number:\t", $numeric, "\n"; algorithm() provides conversions between an algorithm code number and the corresponding mnemonic. =cut sub algorithm { &Net::DNS::RR::DS::algorithm; } =head2 digtype $mnemonic = digtype( 2 ); $numeric = digtype( 'SHA-256' ); print "digest type mnemonic\t", $mnemonic, "\n"; print "digest type number:\t", $numeric, "\n"; digtype() provides conversions between a digest type number and the corresponding mnemonic. =cut sub digtype { &Net::DNS::RR::DS::digtype; } =head2 key_difference @result = key_difference( \@a, \@b ); Fills @result with all keys in array @a that are not in array @b. =cut sub key_difference { my $a = shift; my $b = shift; my $r = shift || []; ## 0.17 interface eval { local $SIG{__DIE__}; my ($x) = grep !$_->isa('Net::DNS::RR::DNSKEY'), @$a, @$b; die sprintf 'unexpected %s object in key list', ref($x) if $x; my %index = map { ( $_->privatekeyname => 1 ) } @$b; @$r = grep !$index{$_->privatekeyname}, @$a; 1; } || do { croak($@) if wantarray; }; return wantarray ? (@$r) : $@; } 1; __END__ =head1 COPYRIGHT Copyright (c)2001-2005 RIPE NCC. Author Olaf M. Kolkman Portions Copyright (c)2014-2015 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC4033, RFC4034, RFC4035 =cut Net-DNS-SEC-1.03/Changes0000644000175000017500000004113212760026475014066 0ustar willemwillemRevision history for Perl extension Net::DNS::SEC. **** 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 depricated. 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 depricated. 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 1503 2016-08-26 11:51:16Z willem $