Net-DNS-SEC-1.23/0000755000175000017500000000000014522650756012577 5ustar willemwillemNet-DNS-SEC-1.23/SEC.xs0000644000175000017500000003244714522647606013577 0ustar willemwillem #define XS_Id "$Id: SEC.xs 1942 2023-11-07 13:30:39Z willem $" =head1 NAME Net::DNS::SEC::libcrypto - Perl interface to OpenSSL libcrypto =head1 DESCRIPTION Perl XS extension providing bindings to the OpenSSL libcrypto library upon which the Net::DNS::SEC cryptographic components are built. =head1 COPYRIGHT Copyright (c)2018-2023 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut #ifdef __cplusplus extern "C" { #endif #define PERL_NO_GET_CONTEXT #include #include #include #include #ifndef OPENSSL_VERSION_NUMBER /* 0xMMmmmmppL adapt or die! */ #define OPENSSL_RELEASE \ ( (OPENSSL_VERSION_MAJOR<<24) | (OPENSSL_VERSION_MINOR<<8) | OPENSSL_VERSION_PATCH | 0x0L ) #else #define OPENSSL_RELEASE (OPENSSL_VERSION_NUMBER>>4) #endif #if (OPENSSL_RELEASE < 0x0F000000) #define API_1_1_1 #undef OSSL_DEPRECATED #define OSSL_DEPRECATED(since) extern #include #include #include #endif #if !(OPENSSL_RELEASE < 0x03000000) #define API_3_0_0 #include #include static OSSL_LIB_CTX *libctx = NULL; #endif #include #include #include #ifdef __cplusplus } #endif #ifdef OPENSSL_NO_DSA #define NO_DSA #endif #ifdef OPENSSL_NO_RSA #define NO_RSA #endif #ifdef OPENSSL_NO_EC #define NO_ECDSA #define NO_EdDSA #endif #ifdef OPENSSL_NO_ECX #define NO_EdDSA #endif #if (OPENSSL_RELEASE < 0x01000100) #error ancient libcrypto version #include OPENSSL_VERSION_TEXT /* in error log; by any means, however reprehensible! */ #endif #define EOL 20260907 #if (OPENSSL_RELEASE < 0x03000000) #undef EOL #define EOL 20230911 #endif #if (OPENSSL_RELEASE < 0x01010000) #define EVP_MD_CTX_new() EVP_MD_CTX_create() #define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx)) int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { d->p = p; d->q = q; d->g = g; return 1; } int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { d->priv_key = priv_key; d->pub_key = pub_key; return 1; } int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { r->n = n; r->e = e; r->d = d; return 1; } int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { r->p = p; r->q = q; return 1; } #endif #if (OPENSSL_RELEASE < 0x01010100) #define NO_EdDSA #define NO_SHA3 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sig, size_t *sig_len, const unsigned char *data, size_t data_len) { EVP_DigestUpdate( ctx, data, data_len ); return EVP_DigestSignFinal( ctx, sig, sig_len ); } int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sig, size_t sig_len, const unsigned char *data, size_t data_len) { EVP_DigestUpdate( ctx, data, data_len ); return EVP_DigestVerifyFinal( ctx, sig, sig_len ); } #endif #ifdef OPENSSL_IS_BORINGSSL #undef EOL #ifndef NID_ED25519 #define NO_EdDSA #endif #define NO_DSA #define NO_SHA3 #endif #ifdef LIBRESSL_VERSION_NUMBER #undef EOL #if (LIBRESSL_VERSION_NUMBER < 0x30702000) #define NO_EdDSA #endif #define NO_DSA #define NO_SHA3 #endif #define SV2BN(sv) BN_bin2bn( (unsigned char*) SvPVX(sv), SvCUR(sv), NULL ) #define UNDEF newSVpvn("",0) #define UNUSED(sv) sv=sv; #define checkerr(arg) checkret( (arg), __LINE__ ) void checkret(const int ret, int line) { if ( ret <= 0 ) croak( "libcrypto error (%s line %d)", __FILE__, line ); } #ifdef API_3_0_0 int EVP_PKEY_fromparams(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM_BLD *bld) { int retval; OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); checkerr( EVP_PKEY_fromdata_init(ctx) ); retval = EVP_PKEY_fromdata( ctx, ppkey, selection, params ); OSSL_PARAM_free(params); return retval; } #endif #ifdef EOL char* selecttxt(int d1, int d2, char *txt) { /* select text based on ISO date comparison */ return ( d1 > d2 ) ? txt : ""; } #endif MODULE = Net::DNS::SEC PACKAGE = Net::DNS::SEC::libcrypto PROTOTYPES: ENABLE SV* VERSION(void) INIT: char *v = SvEND( newSVpv(XS_Id, 17) ); #ifdef EOL time_t today = time( NULL ); char buf[10]; char *txt; #endif CODE: #ifdef EOL strftime( buf, sizeof buf, "%Y%m00", gmtime(&today) ); txt = selecttxt( EOL, atoi(buf), "" ); /* get 100% coverage by calling this twice */ txt = selecttxt( atoi(buf), EOL, " [UNSUPPORTED]" ); RETVAL = newSVpvf( "%s %s%s", v-5, OPENSSL_VERSION_TEXT, txt ); #else RETVAL = newSVpvf( "%s %s", v-5, OPENSSL_VERSION_TEXT ); #endif OUTPUT: RETVAL #### EVP #### EVP_PKEY* EVP_PKEY_new() SV* EVP_sign(SV *message, EVP_PKEY *pkey, const EVP_MD *md=NULL) INIT: #define msgbuf (unsigned char*) SvPVX(message) #define msglen SvCUR(message) EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char sigbuf[512]; /* RFC3110(2) */ STRLEN buflen = sizeof(sigbuf); int error; CODE: checkerr( EVP_DigestSignInit( ctx, NULL, md, NULL, pkey ) ); error = EVP_DigestSign( ctx, sigbuf, &buflen, msgbuf, msglen ); EVP_MD_CTX_free(ctx); EVP_PKEY_free(pkey); checkerr(error); RETVAL = newSVpvn( (char*)sigbuf, buflen ); OUTPUT: RETVAL int EVP_verify(SV *message, SV *signature, EVP_PKEY *pkey, const EVP_MD *md=NULL) INIT: #define sigbuf (unsigned char*) SvPVX(signature) #define siglen SvCUR(signature) EVP_MD_CTX *ctx = EVP_MD_CTX_new(); CODE: checkerr( EVP_DigestVerifyInit( ctx, NULL, md, NULL, pkey ) ); RETVAL = EVP_DigestVerify( ctx, sigbuf, siglen, msgbuf, msglen ); EVP_MD_CTX_free(ctx); EVP_PKEY_free(pkey); OUTPUT: RETVAL EVP_MD_CTX* EVP_MD_CTX_new() void EVP_MD_CTX_free(EVP_MD_CTX *ctx) void EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) CODE: checkerr( EVP_DigestInit( ctx, type ) ); void EVP_DigestUpdate(EVP_MD_CTX *ctx, SV *message) CODE: checkerr( EVP_DigestUpdate( ctx, msgbuf, msglen ) ); SV* EVP_DigestFinal(EVP_MD_CTX *ctx) INIT: unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int size = sizeof(digest); CODE: checkerr( EVP_DigestFinal( ctx, digest, &size ) ); RETVAL = newSVpvn( (char*)digest, size ); OUTPUT: RETVAL const EVP_MD* EVP_md5() const EVP_MD* EVP_sha1() const EVP_MD* EVP_sha224() const EVP_MD* EVP_sha256() const EVP_MD* EVP_sha384() const EVP_MD* EVP_sha512() #ifndef NO_SHA3 const EVP_MD* EVP_sha3_224() const EVP_MD* EVP_sha3_256() const EVP_MD* EVP_sha3_384() const EVP_MD* EVP_sha3_512() #endif #### DSA #### #ifndef NO_DSA EVP_PKEY* EVP_PKEY_new_DSA(SV *p_SV, SV *q_SV, SV *g_SV, SV *y_SV, SV *x_SV=UNDEF ) INIT: #ifndef API_3_0_0 DSA *dsa = DSA_new(); #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "DSA", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); BIGNUM *p, *q, *g, *x, *y; #endif CODE: #ifndef API_3_0_0 RETVAL = EVP_PKEY_new(); checkerr( DSA_set0_pqg( dsa, SV2BN(p_SV), SV2BN(q_SV), SV2BN(g_SV) ) ); checkerr( DSA_set0_key( dsa, SV2BN(y_SV), SV2BN(x_SV) ) ); checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_DSA, (char*)dsa ) ); #else RETVAL = NULL; checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_P, p=SV2BN(p_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_Q, q=SV2BN(q_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_G, g=SV2BN(g_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PUB_KEY, y=SV2BN(y_SV) ) ); if ( SvCUR(x_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PRIV_KEY, x=SV2BN(x_SV) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); BN_free(x); } else { checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); BN_free(p); BN_free(q); BN_free(g); BN_free(y); #endif OUTPUT: RETVAL #endif #### RSA #### #ifndef NO_RSA EVP_PKEY* EVP_PKEY_new_RSA(SV *n_SV, SV *e_SV, SV *d_SV=UNDEF, SV *p1_SV=UNDEF, SV *p2_SV=UNDEF, SV *e1_SV=UNDEF, SV *e2_SV=UNDEF, SV *c_SV=UNDEF ) INIT: #ifndef API_3_0_0 RSA *rsa = RSA_new(); #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "RSA", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); BIGNUM *n, *e, *d, *p1, *p2, *e1, *e2, *c; #endif CODE: #ifndef API_3_0_0 RETVAL = EVP_PKEY_new(); checkerr( RSA_set0_factors( rsa, SV2BN(p1_SV), SV2BN(p2_SV) ) ); checkerr( RSA_set0_key( rsa, SV2BN(n_SV), SV2BN(e_SV), SV2BN(d_SV) ) ); checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_RSA, (char*)rsa ) ); UNUSED(e1_SV); UNUSED(e2_SV); UNUSED(c_SV); /* suppress unused variable warnings */ #else RETVAL = NULL; checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_N, n=SV2BN(n_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_E, e=SV2BN(e_SV) ) ); if ( SvCUR(d_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_D, d=SV2BN(d_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, p1=SV2BN(p1_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, p2=SV2BN(p2_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_EXPONENT, e1=SV2BN(e1_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_EXPONENT, e2=SV2BN(e2_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT, c=SV2BN(c_SV) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); BN_free(d); BN_free(p1); BN_free(p2); BN_free(e1); BN_free(e2); BN_free(c); } else { checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); BN_free(n); BN_free(e); #endif OUTPUT: RETVAL #endif #### ECDSA #### #ifndef NO_ECDSA EVP_PKEY* EVP_PKEY_new_ECDSA(SV *curve, SV *qx_SV, SV *qy_SV=UNDEF ) INIT: #ifdef API_1_1_1 EC_KEY *eckey = NULL; #else EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "EC", NULL ); OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); #endif char *name = SvPVX(curve); BIGNUM *qx, *qy; CODE: #ifdef API_1_1_1 RETVAL = EVP_PKEY_new(); if ( strcmp(name,"P-256") == 0 ) eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if ( strcmp(name,"P-384") == 0 ) eckey = EC_KEY_new_by_curve_name(NID_secp384r1); if ( SvCUR(qy_SV) > 0 ) { checkerr( EC_KEY_set_public_key_affine_coordinates( eckey, qx=SV2BN(qx_SV), qy=SV2BN(qy_SV) ) ); BN_free(qy); } else { checkerr( EC_KEY_set_private_key( eckey, qx=SV2BN(qx_SV) ) ); } checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_EC, (char*)eckey ) ); #else RETVAL = NULL; checkerr( OSSL_PARAM_BLD_push_utf8_string( bld, OSSL_PKEY_PARAM_GROUP_NAME, name, 0 ) ); if ( SvCUR(qy_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_EC_PUB_X, qx=SV2BN(qx_SV) ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_EC_PUB_Y, qy=SV2BN(qy_SV) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); BN_free(qx); BN_free(qy); } else { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PRIV_KEY, qx=SV2BN(qx_SV) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); BN_clear_free(qx); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #endif OUTPUT: RETVAL #endif #### EdDSA #### #ifndef NO_EdDSA EVP_PKEY* EVP_PKEY_new_EdDSA(SV *curve, SV *public, SV *private=NULL) INIT: #ifndef API_3_0_0 char *name = SvPVX(curve); int nid = 0; #else OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, SvPVX(curve), NULL ); #endif CODE: RETVAL = NULL; #ifndef API_3_0_0 if ( strcmp(name,"ED25519") == 0 ) nid = NID_ED25519; #ifdef NID_ED448 /* not yet implemented in BoringSSL & LibreSSL */ if ( strcmp(name,"ED448") == 0 ) nid = NID_ED448; #endif if ( private == NULL ) { RETVAL = EVP_PKEY_new_raw_public_key( nid, NULL, (unsigned char*) SvPVX(public), SvCUR(public) ); } else { RETVAL = EVP_PKEY_new_raw_private_key( nid, NULL, (unsigned char*) SvPVX(private), SvCUR(private) ); } #else if ( private == NULL ) { checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PUB_KEY, SvPVX(public), SvCUR(public) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); } else { checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PRIV_KEY, SvPVX(private), SvCUR(private) ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); } OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #endif OUTPUT: RETVAL #endif #################### void checkerr(int ret) #ifdef croak_memory_wrap void croak_memory_wrap() #endif #ifdef DEBUG void ERR_print_errors(SV *filename) CODE: BIO *bio = BIO_new_file( SvPVX(filename), "w" ); ERR_print_errors(bio); BIO_free(bio); #endif #################### Net-DNS-SEC-1.23/demo/0000755000175000017500000000000014522650756013523 5ustar willemwillemNet-DNS-SEC-1.23/demo/getkeyset0000644000175000017500000000413114522647606015451 0ustar willemwillem#!/usr/bin/perl #$Id: getkeyset 1862 2021-12-24 10:09:08Z willem $ use strict; use warnings; use Net::DNS::SEC; use Net::DNS::SEC::Keyset; my $domain = shift || die "At least one argument needed"; my $nameserver = shift; my $res = Net::DNS::Resolver->new; $res->dnssec(1); $res->nameservers($nameserver) if defined $nameserver; my $packet = $res->query( $domain, 'DNSKEY', 'IN' ) || die "No results for query $domain DNSKEY"; my $keyset = Net::DNS::SEC::Keyset->new($packet) || die $Net::DNS::SEC::Keyset::keyset_err; # Print DS records to STD out # my @ds = $keyset->extract_ds; foreach my $ds (@ds) { $ds->print; } # write keyset in current dir. # $keyset->writekeyset; 1; __END__ =head1 NAME getkeyset.pl - DS extraction demo =head1 SYNOPSIS getkeyset.pl [auth_nameserver] =head1 DESCRIPTION The program queries for the key-set of 'domain'. Spits out the DS records and writes the keyset to the current directory. If the second argument is specified the query is performed to that nameserver. =head1 TODO This is only a demonstration program to show how the interface can be used. =head1 COPYRIGHT Copyright (c) 2002 RIPE NCC. Author Olaf M. Kolkman All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.23/demo/key2ds0000644000175000017500000000336014522647606014651 0ustar willemwillem#!/usr/bin/perl #$Id: key2ds 1862 2021-12-24 10:09:08Z willem $ # A little util to convert DNSKEY records to DS records # from stdin to stdout # # Author: Miek Gieben, NLnetLabs use strict; use warnings; use Net::DNS::SEC; use Net::DNS::ZoneFile; my $source = Net::DNS::ZoneFile->new('-'); # STDIN while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); foreach my $digtype (qw(SHA256 SHA1)) { my $ds = Net::DNS::RR::DS->create( $keyrr, digtype => $digtype ); $ds->print; # STDOUT } } exit 0; =head1 NAME key2ds - Utility to create DS records from DNSKEY RRs read from stdin. =head1 SYNOPSIS key2ds ds.txt =head1 DESCRIPTION C reads the key data from STDIN and prints the corresponding DS record on STDOUT. =head1 COPYRIGHT Copyright (c)2002 Miek Gieben 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 original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.23/demo/make-signed-keyset0000644000175000017500000000716014522647606017140 0ustar willemwillem#!/usr/bin/perl #$Id: make-signed-keyset 1862 2021-12-24 10:09:08Z willem $ # # takes a bind public key file and creates a self-signed keyset # use strict; use warnings; use Getopt::Std; use Net::DNS::SEC; use Net::DNS::SEC::Keyset; use Net::DNS::ZoneFile; use File::Basename; # global variables $VERSION = "0.2"; $verbose = 0; $printds = 0; $progname = basename($0); chomp($progname); # main program getopts('dvhVf:n:'); if ( defined($opt_d) ) { $printds = 1; } if ( defined($opt_v) ) { $verbose = 1; } if ( defined($opt_h) ) { &usage(); } if ( defined($opt_V) ) { &version(); } if ( $#ARGV < 0 ) { &usage(); } # silent some compiler warnings until i figure them out $opt_d = 0; $opt_v = 0; $opt_h = 0; $opt_V = 0; &make_keyset(@ARGV); exit(0); # print the usage and exit sub usage { print("usage: $progname [-vhV] file\n"); print("Options:\n"); print(" -d Print the DS record for each key in the keyset.\n"); print(" -v Be verbose.\n"); print(" -h Print this usage message.\n"); print(" -V Print version information.\n"); print(" file BIND public key file.\n"); exit(0); } # print version information sub version { print( "$progname v$VERSION using Net::DNS v", Net::DNS->version, "\n" ); exit(0); } sub make_keyset { my $source = Net::DNS::ZoneFile->new(shift); my $file = $source->name; my $directory = dirname($file); print("Processing file: $file\n"); my @keys; while ( my $keyrr = $source->read ) { next unless $keyrr->isa('Net::DNS::RR::DNSKEY'); print("Read DNSKEY RR\n") if $verbose; push @keys, $keyrr; } print("Creating keyset\n") if $verbose; my $keyset = Net::DNS::SEC::Keyset->new( \@keys, "$directory" ) or die("$progname: unable to create keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); print("Verifying keyset\n") if $verbose; $keyset->verify() or die("$progname: unable to verify keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); if ($verbose) { print("Keyset:\n"); $keyset->print(); print("Writing keyset\n"); } $keyset->writekeyset("signed-") or die("$progname: unable to write keyset. $Net::DNS::SEC::Keyset::keyset_err.\n"); if ($printds) { print("Extracting DS RR\n") if $verbose; my @ds = $keyset->extract_ds(); foreach my $ds (@ds) { $ds->print(); } } return; } =head1 NAME make-signed-keyset - create a self-signed keyset =head1 SYNOPSIS make-signed-keyset [-v] file =head1 DESCRIPTION make-signed-keyset is a program that creates a self-signed keyset from a BIND public key file specified on the command line. The options are as follows: =over =item -v Be verbose. =item -d Print the DS record for each key in the keyset. =back =head1 COPYRIGHT Copyright (c)2002 Wes Griffin 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 original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.23/lib/0000755000175000017500000000000014522650756013345 5ustar willemwillemNet-DNS-SEC-1.23/lib/Net/0000755000175000017500000000000014522650756014073 5ustar willemwillemNet-DNS-SEC-1.23/lib/Net/DNS/0000755000175000017500000000000014522650756014517 5ustar willemwillemNet-DNS-SEC-1.23/lib/Net/DNS/SEC/0000755000175000017500000000000014522650756015131 5ustar willemwillemNet-DNS-SEC-1.23/lib/Net/DNS/SEC/Digest.pm0000644000175000017500000000774214522647606016720 0ustar willemwillempackage Net::DNS::SEC::Digest; use strict; use warnings; our $VERSION = (qw$Id: Digest.pm 1849 2021-08-19 08:25:20Z willem $)[2]; =head1 NAME Net::DNS::SEC::Digest - Message Digest Algorithms =head1 SYNOPSIS require Net::DNS::SEC::Digest; $object = Net::DNS::SEC::Digest::SHA->new(256); $object->add($text); $object->add($more); $digest = $object->digest; =head1 DESCRIPTION Interface package providing access to the message digest algorithm implementations within the OpenSSL libcrypto library. =cut use constant libcrypto_available => Net::DNS::SEC::libcrypto->can('EVP_MD_CTX_new'); BEGIN { die 'Net::DNS::SEC not available' unless libcrypto_available } my %digest = ( MD5 => sub { Net::DNS::SEC::libcrypto::EVP_md5() }, SHA_1 => sub { Net::DNS::SEC::libcrypto::EVP_sha1() }, SHA_224 => sub { Net::DNS::SEC::libcrypto::EVP_sha224() }, SHA_256 => sub { Net::DNS::SEC::libcrypto::EVP_sha256() }, SHA_384 => sub { Net::DNS::SEC::libcrypto::EVP_sha384() }, SHA_512 => sub { Net::DNS::SEC::libcrypto::EVP_sha512() }, SHA3_224 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_224() }, SHA3_256 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_256() }, SHA3_384 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_384() }, SHA3_512 => sub { Net::DNS::SEC::libcrypto::EVP_sha3_512() }, ); sub new { my ( $class, @param ) = @_; my ($index) = reverse split '::', join '_', $class, @param; my $evpmd = $digest{$index}; my $mdctx = Net::DNS::SEC::libcrypto::EVP_MD_CTX_new(); Net::DNS::SEC::libcrypto::EVP_DigestInit( $mdctx, &$evpmd ); return bless( {ctx => $mdctx, md => &$evpmd}, $class ); } sub add { my $self = shift; return Net::DNS::SEC::libcrypto::EVP_DigestUpdate( $self->{ctx}, shift ); } sub digest { my $self = shift; my $dgst = Net::DNS::SEC::libcrypto::EVP_DigestFinal( $self->{ctx} ); # reinitialise; emulate API offered by Digest::SHA Net::DNS::SEC::libcrypto::EVP_DigestInit( $self->{ctx}, $self->{md} ); return $dgst; } DESTROY { my $self = shift; return Net::DNS::SEC::libcrypto::EVP_MD_CTX_free( $self->{ctx} ); } ## no critic ProhibitMultiplePackages package Net::DNS::SEC::Digest::MD5; our @ISA = qw(Net::DNS::SEC::Digest); package Net::DNS::SEC::Digest::SHA; our @ISA = qw(Net::DNS::SEC::Digest); package Net::DNS::SEC::Digest::SHA3; our @ISA = qw(Net::DNS::SEC::Digest); 1; __END__ ######################################## =head1 METHODS =head2 new require Net::DNS::SEC::Digest; $object = Net::DNS::SEC::Digest::SHA->new(256); Creates and initialises a new digest object instance for the specified algorithm class. =head2 add $object->add($data); $object->add($more); Append specified data to the digest stream. =head2 digest $digest = $object->digest; Returns an octet string containing the calculated digest. =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2020,2021 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/libcrypto.pod0000644000175000017500000000277014522647606017652 0ustar willemwillem# # $Id: libcrypto.pod 1853 2021-10-11 10:40:59Z willem $ # =head1 NAME Net::DNS::SEC::libcrypto - Perl interface to OpenSSL libcrypto =head1 DESCRIPTION Perl XS extension providing access to the OpenSSL libcrypto library upon which the Net::DNS::SEC cryptographic components are built. =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/Private.pm0000644000175000017500000001213414522647606017102 0ustar willemwillempackage Net::DNS::SEC::Private; use strict; use warnings; our $VERSION = (qw$Id: Private.pm 1853 2021-10-11 10:40:59Z willem $)[2]; =head1 NAME Net::DNS::SEC::Private - DNSSEC Private key object =head1 SYNOPSIS use Net::DNS::SEC::Private; $private = Net::DNS::SEC::Private->new( $keypath ); $private = Net::DNS::SEC::Private->new( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); =head1 DESCRIPTION Class representing private keys as read from a keyfile generated by BIND dnssec-keygen. The class is written to be used only in the context of the Net::DNS::RR::RRSIG create method. This class is not designed to interact with any other system. =cut use integer; use Carp; use File::Spec; use IO::File; use constant SYMLINK => defined(&CORE::readlink); # Except Win32, VMS, RISC OS sub new { return scalar(@_) > 2 ? &_new_params : &_new_keyfile } sub _new_keyfile { my ( $class, $file ) = @_; my ($keypath) = SYMLINK ? grep( {$_} readlink($file), $file ) : $file; my ( $vol, $dir, $name ) = File::Spec->splitpath($keypath); # Format something like: 'Kbla.foo.+001+12345.private' as created by BIND dnssec-keygen. croak "$file does not appear to be a BIND private key" unless $name =~ /^K([^+]+)\+(\d+)\+(\d+)\.private$/; my @identifier = ( signame => $1, algorithm => 0 + $2, keytag => 0 + $3 ); my $handle = IO::File->new( $file, '<' ) or croak qq("$file": $!); my @content; local $_; while (<$handle>) { chomp; next if /^$/; next if /^\s*[;]/; s/\(.+\)//; my ( $name, $value ) = split; push @content, $name, $value; } return $class->_new_params( @content, @identifier ); } sub _new_params { my ( $class, %parameter ) = @_; my $hashref = {}; while ( my ( $name, $value ) = each %parameter ) { $name =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; $hashref->{$name} = $value; } my $self = bless sub { $hashref->{shift()} }, $class; croak 'no algorithm specified' unless $self->algorithm; croak 'no signame specified' unless $self->signame; return $self; } our $AUTOLOAD; sub AUTOLOAD { ## Default method my ($self) = @_; my ($attribute) = $AUTOLOAD =~ m/::([^:]*)$/; $attribute =~ tr/A-Za-z0-9\000-\377/a-za-z0-9/d; # Build a method in the class no strict 'refs'; ## no critic ProhibitNoStrict *{$AUTOLOAD} = sub { &{shift()}($attribute) }; # and jump to it goto &{$AUTOLOAD}; } 1; __END__ =head1 METHODS =head2 new (from private keyfile) $keypath = '/home/foo/Kexample.com.+013+26512.private'; $private = Net::DNS::SEC::Private->new( $keypath ); The argument is the full path to a private key file generated by the BIND dnssec-keygen tool. Note that the filename contains information about the algorithm and keytag. =head2 new (from private key parameters) $private = Net::DNS::SEC::Private->new( 'algorithm' => '13', 'keytag' => '26512', 'privatekey' => 'h/mc+iq9VDUbNAjQgi8S8JzlEX29IALchwJmNM3QYKk=', 'signame' => 'example.com.' ); The arguments define the private key parameters as (name,value) pairs. The name and data representation are identical to that used in a BIND private keyfile. =head2 private_key_format $format = $private->private_key_format; Returns a string which identifies the format of the private key file. =head2 algorithm, keytag, signame $algorithm = $private->algorithm; $keytag = $private->keytag; $signame = $private->signame; Returns the corresponding attribute determined from the filename. =head2 Private key attributes $attribute = $private->attribute; Returns the value as it appears in the private key file. The attribute names correspond to the tag in the key file, modified to form an acceptable Perl subroutine name. =head2 created, publish, activate $created = $private->created; $publish = $private->publish; $activate = $private->activate; Returns a string which represents a date in the form 20141212123456. Returns undefined value for key formats older than v1.3. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, L, L, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/RSA.pm0000644000175000017500000000742214522647606016121 0ustar willemwillempackage Net::DNS::SEC::RSA; use strict; use warnings; our $VERSION = (qw$Id: RSA.pm 1940 2023-10-30 15:59:20Z willem $)[2]; =head1 NAME Net::DNS::SEC::RSA - DNSSEC RSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::RSA; $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of RSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::RSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::RSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use integer; use MIME::Base64; use constant RSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA'); BEGIN { die 'RSA disabled or application has no "use Net::DNS::SEC"' unless RSA_configured } my %parameters = ( 1 => scalar eval { Net::DNS::SEC::libcrypto::EVP_md5() }, 5 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, 7 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, 8 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha256() }, 10 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha512() }, ); sub _index { return keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $evpmd = $parameters{$private->algorithm}; die 'private key not RSA' unless $evpmd; my @key = qw(Modulus PublicExponent PrivateExponent Prime1 Prime2 Exponent1 Exponent2 Coefficient); my ( $n, $e, $d, $p1, $p2, $e1, $e2, $c ) = map { decode_base64( $private->$_ ) } @key; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $n, $e, $d, $p1, $p2, $e1, $e2, $c ); return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $evpmd = $parameters{$keyrr->algorithm}; die 'public key not RSA' unless $evpmd; return unless $sigbin; my $keybin = $keyrr->keybin; # public key my ( $short, $long ) = unpack( 'Cn', $keybin ); # RFC3110, section 2 my $keyfmt = $short ? "x a$short a*" : "x3 a$long a*"; my ( $exponent, $modulus ) = unpack( $keyfmt, $keybin ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_RSA( $modulus, $exponent ); return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey, $evpmd ); } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC8017, RFC3110, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/ECDSA.pm0000644000175000017500000001013214522647606016303 0ustar willemwillempackage Net::DNS::SEC::ECDSA; use strict; use warnings; our $VERSION = (qw$Id: ECDSA.pm 1940 2023-10-30 15:59:20Z willem $)[2]; =head1 NAME Net::DNS::SEC::ECDSA - DNSSEC ECDSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::ECDSA; $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of ECDSA elliptic curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::ECDSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::ECDSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use integer; use MIME::Base64; use constant ECDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA'); BEGIN { die 'ECDSA disabled or application has no "use Net::DNS::SEC"' unless ECDSA_configured } my %parameters = ( 13 => ['P-256', 32, Net::DNS::SEC::libcrypto::EVP_sha256()], 14 => ['P-384', 48, Net::DNS::SEC::libcrypto::EVP_sha384()], ); sub _index { return keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; my ( $curve, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; die 'private key not ECDSA' unless $curve; my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $curve, $rawkey ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); return _ASN1decode( $asn1, $keylen ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; my ( $curve, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; die 'public key not ECDSA' unless $curve; return unless $sigbin; my ( $x, $y ) = unpack "a$keylen a$keylen", $keyrr->keybin; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_ECDSA( $curve, $x, $y ); my $asn1 = _ASN1encode( $sigbin, $keylen ); return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $asn1, $evpkey, $evpmd ); } ######################################## sub _ASN1encode { my ( $sig, $size ) = @_; my @part = unpack "a$size a$size", $sig; my $length; foreach (@part) { s/^[\000]+//; s/^$/\000/; s/^(?=[\200-\377])/\000/; $_ = pack 'C2 a*', 2, length, $_; $length += length; } return pack 'C2 a* a*', 0x30, $length, @part; } sub _ASN1decode { my ( $asn1, $size ) = @_; my $n = unpack 'x3 C', $asn1; my $m = unpack "x5 x$n C", $asn1; my @part = unpack "x4 a$n x2 a$m", $asn1; return pack 'a* a*', map { substr( pack( "x$size a*", $_ ), -$size ) } @part; } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC6090, RFC6605, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/Keyset.pm0000644000175000017500000002200214522647606016727 0ustar willemwillempackage Net::DNS::SEC::Keyset; use strict; use warnings; our $VERSION = (qw$Id: Keyset.pm 1868 2022-08-31 20:13:35Z willem $)[2]; =head1 NAME Net::DNS::SEC::Keyset - DNSSEC Keyset object class =head1 SYNOPSIS use Net::DNS::SEC::Keyset; =head1 DESCRIPTION A keyset is an "administrative" unit used for DNSSEC maintenance. This class provides interfaces for creating, reading and writing keysets. Object methods are provided to extract DNSKEY, RRSIG and DS records. Note that this class is still being developed. Attributes and methods are subject to change. =cut use Carp; use File::Spec; use IO::File; use Net::DNS::ZoneFile; our $keyset_err; sub new { my ( $class, $arg1, $arg2 ) = @_; my $ref1 = ref($arg1); return &_new_from_file unless $ref1; return &_new_from_packet if $ref1 eq 'Net::DNS::Packet'; return &_new_from_keys unless ref($arg2); return &_new_from_keys_sigs; } =head2 new (from file) $keyset = Net::DNS::SEC::Keyset->new( $filename ); $keyset = Net::DNS::SEC::Keyset->new( $filename, $directory ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Constructor method which reads the specified keyset file and returns a keyset object. The optional second argument specifies the filename base directory. Sets keyset_err and returns undef on failure. =cut sub _new_from_file { my ( $class, $name, @path ) = @_; my $file = File::Spec->catfile( @path, $name ); my @rr = Net::DNS::ZoneFile->new($file)->read; return $class->_new_from_keys_sigs( \@rr, \@rr ); } =head2 new (by signing keys) $keyset = Net::DNS::SEC::Keyset->new( [@keyrr], $privatekeypath ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Creates a keyset object from the keys provided through the reference to an array of Net::DNS::RR::DNSKEY objects. The method will create and self-sign the whole keyset. The private keys as generated by the BIND dnssec-keygen tool are assumed to be in the current directory or, if specified, the directory indicated by $privatekeypath. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys { my ( $class, $keylist, @keypath ) = @_; my @sigrr; foreach my $key ( grep { $_->type eq 'DNSKEY' } @$keylist ) { my $keyname = $key->privatekeyname; my $keyfile = File::Spec->catfile( @keypath, $keyname ); my @rrsig = Net::DNS::RR::RRSIG->create( $keylist, $keyfile ); push @sigrr, grep {defined} @rrsig; } return $class->_new_from_keys_sigs( $keylist, \@sigrr ); } =head2 new (from key and sig RRsets) $keyset = Net::DNS::Keyset->new( [@keyrr], [@sigrr] ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Creates a keyset object from the keys provided through the references to arrays of Net::DNS::RR::DNSKEY and Net::DNS::RR::RRSIG objects. Sets keyset_err and returns undef on failure. =cut sub _new_from_keys_sigs { my ( $class, $key_ref, $sig_ref ) = @_; my @keyrr = grep { $_->type eq 'DNSKEY' } @$key_ref; my @sigrr = grep { $_->type eq 'RRSIG' } @$sig_ref; my $keyset = bless {keys => \@keyrr, sigs => \@sigrr}, $class; return scalar( $keyset->verify ) ? $keyset : undef; } =head2 new (from Packet) $resolver = Net::DNS::Resolver->new; $resolver->dnssec(1); $reply = $res->send ( "example.com", "DNSKEY" ); $keyset = Net::DNS::SEC::Keyset->new( $reply ); die Net::DNS::SEC::Keyset->keyset_err unless $keyset; Creates a keyset object from a Net::DNS::Packet that contains the answer to a query for key records at the zone apex. This is the method you should use for automatically fetching keys. Sets keyset_err and returns undef on failure. =cut sub _new_from_packet { my ( $class, $packet ) = @_; my @rrset = $packet->answer; return $class->_new_from_keys_sigs( \@rrset, \@rrset ); } =head2 keys @keyrr = $keyset->keys; Returns an array of Net::DNS::RR::DNSKEY objects. =cut sub keys { my $self = shift; my @keys = @{$self->{keys}}; return @keys; } =head2 sigs @sigrr = $keyset->sigs; Returns an array of Net::DNS::RR::RRSIG objects. =cut sub sigs { my $self = shift; my @sigs = @{$self->{sigs}}; return @sigs; } =head2 extract_ds @ds = $keyset->extract_ds(); # default SHA-1 @ds = $keyset->extract_ds( digtype => 'SHA-256' ); die Net::DNS::SEC::Keyset->keyset_err unless @ds; Extracts DS records from the keyset. Note that the keyset will be verified during extraction. All keys will need to have a valid self-signature. The method sets keyset_err if verification fails. =cut sub extract_ds { my ( $self, @arg ) = @_; my @ds; @ds = map { Net::DNS::RR::DS->create( $_, @arg ) } $self->keys if $self->verify; return @ds; } =head2 verify @keytags = $keyset->verify(); die Net::DNS::SEC::Keyset->keyset_err unless @keytags; $keyset->verify( $keytag ) || die $keyset->keyset_err; If no arguments are given: =over 2 =item Verifies if all signatures present verify the keyset. =item Verifies if there are DNSKEYs with the SEP flag set, there is at least one RRSIG made using that key. =item Verifies that if there are no DNSKEYs with the SEP flag set there is at least one RRSIG made with one of the keys from the keyset. =back If an argument is given, it is should be the numeric keytag of the key in the keyset which will be verified using the corresponding RRSIG. The method returns a list of keytags of verified keys in the keyset. The method sets keyset_err and returns empty list if verification fails. =cut sub verify { my ( $self, $keyid ) = @_; my @keys = $self->keys; my %keysbytag; push( @{$keysbytag{$_->keytag}}, $_ ) foreach @keys; my @sigs = $self->sigs; my @keyset_err; my %names = map { ( $_->name => $_ ) } @keys, @sigs; my @names = CORE::keys %names; push @keyset_err, "Multiple names in keyset: @names" if scalar(@names) > 1; if ($keyid) { @sigs = grep { $_->keytag == $keyid } @sigs; push @keyset_err, "No signature made with key $keyid" 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; push @keyset_err, "$vrfyerr for keyset @names"; } $keyset_err = join "\n", @keyset_err; my @tags_verified; @tags_verified = map { $_->keytag } @sigs unless $keyset_err; return @tags_verified; } =head2 keyset_err $keyset_err = Net::DNS::SEC::Keyset->keyset_err; Returns the keyset error string. =cut sub keyset_err { return $keyset_err; } =head2 string $string = $keyset->string; Returns a string representation of the keyset. =cut sub string { my $self = shift; return join "\n", map { $_->string } ( $self->keys, $self->sigs ); } =head2 print $keyset->print; # similar to print( $keyset->string ) Prints the keyset. =cut sub print { my $self = shift; foreach ( $self->keys, $self->sigs ) { $_->print } return; } =head2 writekeyset $keyset->writekeyset; $keyset->writekeyset( $path ); $keyset->writekeyset( $prefix ); $keyset->writekeyset( $prefix, $path ); Writes the keyset to a file named "keyset-." in the current working directory or directory defined by the optional $path argument. The optional $prefix argument specifies the prefix that will be prepended to the domain name to form the keyset filename. =cut sub writekeyset { my ( $self, $arg1, @path ) = @_; shift; @path = shift() if $arg1 && File::Spec->file_name_is_absolute($arg1); my $prefix = shift || 'keyset-'; my @keysetrr = ( $self->keys, $self->sigs ); my $domainname = $keysetrr[0]->name; my $keysetname = "$prefix$domainname."; my $filename = File::Spec->catfile( @path, $keysetname ); $filename =~ s/[.]+/\./; ## avoid antisocial consequences of $path with .. my $handle = IO::File->new( $filename, '>' ) or croak qq("$filename": $!); select( ( select($handle), $self->print )[0] ); close($handle); return $filename; } 1; __END__ =head1 COPYRIGHT Copyright (c)2002 RIPE NCC. Author Olaf M. Kolkman Portions Copyright (c)2014 Dick Franks All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/DSA.pm0000644000175000017500000001026614522647606016103 0ustar willemwillempackage Net::DNS::SEC::DSA; use strict; use warnings; our $VERSION = (qw$Id: DSA.pm 1940 2023-10-30 15:59:20Z willem $)[2]; =head1 NAME Net::DNS::SEC::DSA - DNSSEC DSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::DSA; $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of DSA digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::DSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::DSA->verify( $sigdata, $keyrr, $sigbin ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use integer; use MIME::Base64; use constant Digest_SHA1 => Net::DNS::SEC::libcrypto->can('EVP_sha1'); use constant DSA_configured => Digest_SHA1 && Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_DSA'); BEGIN { die 'DSA disabled or application has no "use Net::DNS::SEC"' unless DSA_configured } my %parameters = ( 3 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, 6 => scalar eval { Net::DNS::SEC::libcrypto::EVP_sha1() }, ); sub _index { return keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $evpmd = $parameters{$private->algorithm}; die 'private key not DSA' unless $evpmd; my @key = qw(prime subprime base private_value public_value); my ( $p, $q, $g, $x, $y ) = map { decode_base64( $private->$_ ) } @key; my $t = ( length($g) - 64 ) / 8; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_DSA( $p, $q, $g, $y, $x ); my $asn1 = Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey, $evpmd ); return _ASN1decode( $asn1, $t ); } sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $evpmd = $parameters{$keyrr->algorithm}; die 'public key not DSA' unless $evpmd; return unless $sigbin; my $key = $keyrr->keybin; # public key my $len = 64 + 8 * unpack( 'C', $key ); # RFC2536, section 2 my ( $q, $p, $g, $y ) = unpack "x a20 a$len a$len a$len", $key; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_DSA( $p, $q, $g, $y ); my $asn1 = _ASN1encode($sigbin); return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $asn1, $evpkey, $evpmd ); } ######################################## sub _ASN1encode { my @part = unpack 'x a20 a20', shift; # discard "t" my $length; foreach (@part) { s/^[\000]+//; s/^$/\000/; s/^(?=[\200-\377])/\000/; $_ = pack 'C2 a*', 2, length, $_; $length += length; } return pack 'C2 a* a*', 0x30, $length, @part; } sub _ASN1decode { my ( $asn1, $t ) = @_; my $n = unpack 'x3 C', $asn1; my $m = unpack "x5 x$n C", $asn1; my @part = unpack "x4 a$n x2 a$m", $asn1; return pack 'C a* a*', $t, map { substr( pack( 'x20 a*', $_ ), -20 ) } @part; } 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC2536, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC/EdDSA.pm0000644000175000017500000000727114522647606016356 0ustar willemwillempackage Net::DNS::SEC::EdDSA; use strict; use warnings; our $VERSION = (qw$Id: EdDSA.pm 1937 2023-09-11 09:27:16Z willem $)[2]; =head1 NAME Net::DNS::SEC::EdDSA - DNSSEC EdDSA digital signature algorithm =head1 SYNOPSIS require Net::DNS::SEC::EdDSA; $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private ); $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $sigbin ); =head1 DESCRIPTION Implementation of EdDSA Edwards curve digital signature generation and verification procedures. =head2 sign $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private ); Generates the wire-format signature from the sigdata octet string and the appropriate private key object. =head2 verify $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $signature ); Verifies the signature over the sigdata octet string using the specified public key resource record. =cut use integer; use MIME::Base64; use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA'); BEGIN { die 'EdDSA disabled or application has no "use Net::DNS::SEC"' unless EdDSA_configured } my %parameters = ( 15 => ['ED25519', 32, 64], 16 => ['ED448', 57, 114], ); sub _index { return keys %parameters } sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; my ( $curve, $keylen ) = @{$parameters{$algorithm} || []}; die 'private key not EdDSA' unless $curve; my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey ); my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, '', $rawkey ); return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey ); } sub verify { my ( $class, $sigdata, $keyrr, $signature ) = @_; my $algorithm = $keyrr->algorithm; my ( $curve, $keylen, $siglen ) = @{$parameters{$algorithm} || []}; die 'public key not EdDSA' unless $curve; return unless $signature; my $rawkey = pack "a$keylen", $keyrr->keybin; my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, $rawkey ); my $sigbin = pack "a$siglen", $signature; return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey ); } my $key448 = decode_base64 '69oJdWluramCzd28zK6E/LIZzL6MxVkQ0drFQ/dyeFQon2Tso03D0jCrP1NZ965ASnIC5N+sgwOA'; my $evpkey = eval { Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( 'ED448', $key448 ) }; delete $parameters{16} unless defined $evpkey; ## disallow ED448 if using BoringSSL|LibreSSL 1; __END__ ######################################## =head1 ACKNOWLEDGMENT Thanks are due to Eric Young and the many developers and contributors to the OpenSSL cryptographic library. =head1 COPYRIGHT Copyright (c)2014,2018 Dick Franks. All rights reserved. =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC8032, RFC8080, L =cut Net-DNS-SEC-1.23/lib/Net/DNS/SEC.pm0000644000175000017500000000674014522647606015476 0ustar willemwillempackage Net::DNS::SEC; use strict; use warnings; use Carp; our $SVNVERSION = (qw$Id: SEC.pm 1943 2023-11-08 09:02:03Z willem $)[2]; our $VERSION; $VERSION = '1.23'; use base qw(Exporter DynaLoader); eval { __PACKAGE__->bootstrap($VERSION) }; warn "\n\n$@\n" if $@; use Net::DNS 1.01 qw(:DEFAULT); our @EXPORT = ( @Net::DNS::EXPORT, qw(algorithm digtype key_difference) ); =head1 NAME Net::DNS::SEC - DNSSEC extensions to Net::DNS =head1 SYNOPSIS use Net::DNS::SEC; =head1 DESCRIPTION Net::DNS::SEC is installed as an extension to an existing Net::DNS installation providing packages to support DNSSEC as specified in RFC4033, RFC4034, RFC4035 and related documents. It also provides support for SIG0 which is useful for dynamic updates. Implements cryptographic signature generation and verification functions using RSA, DSA, ECDSA, and Edwards curve algorithms. The extended features are made available by replacing Net::DNS by Net::DNS::SEC in the use declaration. =cut =head1 UTILITY FUNCTIONS =head2 algorithm $mnemonic = algorithm( 5 ); $numeric = algorithm( 'RSA-SHA1' ); print "algorithm mnemonic\t", $mnemonic, "\n"; print "algorithm number:\t", $numeric, "\n"; algorithm() provides conversions between an algorithm code number and the corresponding mnemonic. =cut sub algorithm { return &Net::DNS::RR::DS::algorithm; } =head2 digtype $mnemonic = digtype( 2 ); $numeric = digtype( 'SHA-256' ); print "digest type mnemonic\t", $mnemonic, "\n"; print "digest type number:\t", $numeric, "\n"; digtype() provides conversions between a digest type number and the corresponding mnemonic. =cut sub digtype { return &Net::DNS::RR::DS::digtype; } =head2 key_difference @result = key_difference( \@a, \@b ); Fills @result with all keys in array @a that are not in array @b. =cut sub key_difference { my $a = shift; my $b = shift; my $r = shift || []; ## 0.17 API local $SIG{__DIE__}; my ($x) = grep { !$_->isa('Net::DNS::RR::DNSKEY') } @$a, @$b; croak sprintf( 'unexpected %s object in key list', ref $x ) if $x; my %index = map { ( $_->privatekeyname => 1 ) } @$b; return @$r = grep { !$index{$_->privatekeyname} } @$a; } ######################################## foreach (qw(DS CDS RRSIG)) { Net::DNS::RR->new( type => $_ ); # pre-load to access class methods } 1; __END__ =head1 COPYRIGHT Copyright (c)2014-2021 Dick Franks Copyright (c)2001-2005 RIPE NCC. Author Olaf M. Kolkman All Rights Reserved =head1 LICENSE Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =head1 SEE ALSO L, L, RFC4033, RFC4034, RFC4035, L =cut Net-DNS-SEC-1.23/LICENSE0000644000175000017500000000173714522647606013614 0ustar willemwillem LICENSE ======= Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---- $Id: LICENSE 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.23/MANIFEST0000644000175000017500000000137114522650756013732 0ustar willemwillemChanges LICENSE Makefile.PL MANIFEST This list of files README WARNING SEC.xs typemap demo/getkeyset demo/key2ds demo/make-signed-keyset lib/Net/DNS/SEC.pm lib/Net/DNS/SEC/Digest.pm lib/Net/DNS/SEC/Keyset.pm lib/Net/DNS/SEC/Private.pm lib/Net/DNS/SEC/DSA.pm lib/Net/DNS/SEC/ECDSA.pm lib/Net/DNS/SEC/EdDSA.pm lib/Net/DNS/SEC/RSA.pm lib/Net/DNS/SEC/libcrypto.pod t/00-install.t t/00-load.t t/00-pod.t t/10-keyset.t t/20-digest.t t/21-RSA-MD5.t t/22-RSA-SHA1.t t/23-RSA-SHA256.t t/24-RSA-SHA512.t t/31-DSA-SHA1.t t/51-ECDSA-P256.t t/52-ECDSA-P384.t t/61-Ed25519.t t/62-Ed448.t t/TestToolkit.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-DNS-SEC-1.23/t/0000755000175000017500000000000014522650756013042 5ustar willemwillemNet-DNS-SEC-1.23/t/61-Ed25519.t0000644000175000017500000000614214522647606014414 0ustar willemwillem#!/usr/bin/perl # $Id: 61-Ed25519.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.05, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::EdDSA' ); # Specimen private and public keys taken from RFC8080 my $key = Net::DNS::RR->new( <<'END' ); ED25519.example. IN DNSKEY ( 257 3 15 l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= ) ; Key ID = 3613 END ok( $key, 'set up EdDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 15 (ED25519) PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI= END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up EdDSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'END' ); ECDSAP256SHA256.example. IN DNSKEY 256 3 13 ( 7Y4BZY1g9uzBwt3OZexWk7iWfkiOt0PZ5o7EMip0KBNxlBD+Z58uWutYZIMolsW8v/3rfgac45lO IikBZK4KZg== ; Key ID = 44222 ) END ok( $wrongkey, 'set up non-EdDSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'END'; Private-key-format: v1.2 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: m/dWhFblAGQnabJoKbs0vXoQidjNzlTcbPAqntUXWi0= END close($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-EdDSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = pack 'H*', join '', qw( cb7a60fedc08b09995d522410962c6eb0fd0ea34e16fe094c99582fbb14e7a87 c14292cf8c28af0efe6ee30cbf9d643cba3ab56f1e1ae27b6074147ed9c55a0e ); my $signed = eval { $class->sign( $sigdata, $private ); } || ''; # Note: ED25519 signing is deterministic ok( $signed eq $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.23/t/52-ECDSA-P384.t0000644000175000017500000000401214522647606014723 0ustar willemwillem#!/usr/bin/perl # $Id: 52-ECDSA-P384.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::ECDSA' ); my $key = Net::DNS::RR->new( <<'END' ); ECDSAP384SHA384.example. IN DNSKEY 256 3 14 ( K4t0AhWiJcLZ25BlpvfxCi2KMlkBr14zECH3Y2imMYOzn5zcMpOh0iPbI9Hnfep8L+BBzQrRFNmc 5r3r0l0y+snHIc/npdK/1Ks0ZG/aMB5r/PfJGeB5MLdtcanFir2S ; Key ID = 25812 ) END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.3 Algorithm: 14 (ECDSAP384SHA384) PrivateKey: mvuhyr+QDMqo4bpeREFRM2w8qZsBiLiCouR0sihdinvpRA3zA/dByohgH4CLI7Kr Created: 20141209021155 Publish: 20141209021155 Activate: 20141209021155 END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up ECDSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.23/t/00-install.t0000644000175000017500000000225314522647606015114 0ustar willemwillem#!/usr/bin/perl # $Id: 00-install.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; use Test::More; use File::Spec; use File::Find; use IO::File; use ExtUtils::MakeMaker; my %manifest; my $handle = IO::File->new( 'MANIFEST', '<' ) or BAIL_OUT("MANIFEST: $!"); while (<$handle>) { my ($filename) = split; $manifest{$filename}++; } close $handle; plan skip_all => 'No versions from git checkouts' if -e '.git'; plan skip_all => 'Not sure how to parse versions.' unless eval { MM->can('parse_version') }; plan tests => scalar keys %manifest; foreach ( sort keys %manifest ) { # reconcile files with MANIFEST next unless ok( -f $_, "file exists\t$_" ); next unless /\.pm$/; next unless /^lib/; my $module = File::Spec->catfile( 'blib', $_ ); # library component diag("Missing module: $module") unless -f $module; my $version = MM->parse_version($_); # module version diag("\$VERSION = $version\t$_") unless $version =~ /^\d/; } my @files; # flag MANIFEST omissions find( sub { push( @files, $File::Find::name ) if /\.pm$/ }, 'lib' ); foreach ( sort @files ) { diag("Filename not in MANIFEST: $_") unless $manifest{$_}; } exit; __END__ Net-DNS-SEC-1.23/t/24-RSA-SHA512.t0000644000175000017500000000552214522647606014744 0ustar willemwillem#!/usr/bin/perl # $Id: 24-RSA-SHA512.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'END' ); RSASHA512.example. IN DNSKEY 256 3 10 ( AwEAAdLaxcxvgdQKF3zSOuXQgwWPQ+dKzJ3Ob4w3r+o73i2MnhE0HBHuTzUZGVjGR05VGqZaJx64 LNt0Wlxxoxt3Uwaq55t5MzN3LYYYEcMQ1XPhPG1nNuD0LiqlqL+KmQqlAo3cm4F71gr/GXQiPG3O WM11ulruDKZpyfYg1NWryu3F ; Key ID = 35741 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.3 Algorithm: 10 (RSASHA512) Modulus: 0trFzG+B1AoXfNI65dCDBY9D50rMnc5vjDev6jveLYyeETQcEe5PNRkZWMZHTlUaplonHrgs23RaXHGjG3dTBqrnm3kzM3cthhgRwxDVc+E8bWc24PQuKqWov4qZCqUCjdybgXvWCv8ZdCI8bc5YzXW6Wu4MpmnJ9iDU1avK7cU= PublicExponent: AQAB PrivateExponent: hTutzo8LBzPVQY8JnluR3rp3Grgd8P0XaQ9q/eQUcM2wt4go0H+31wJkDL9FIU8PRtwiafvQhF7SFiXL/bf5YlCBhCNnYmz8fZuIsZr9OC5tYDFU43AziHYrwhE0myYMJF16nrJTe8RfGnvkvsBUJovu92L86lUOexTQCeIJPeE= Prime1: 7Pq9K1h4B8UfhEH1+zh+LW4BS6OHPVt7WGPSob/8EqirMqsv1xNxfp/La9abLEJemyXJUZ7SjTN6MbNMHfH1rQ== Prime2: 48c9vC+ynHyq5mNbVr2pQKoWVdCoeK6wgMHXnoSyMnxwmnP+NNXM1NKDSX7TIJOmGerRL7MGsiTSf3W39IjreQ== Exponent1: I9lCaJ43eiVtwRohVeGT5NdxRrn0KWn/XL2tDV73iPMPAtk2oXiFgLw3j5alXqqjmSC8Naaq/0U8ROx0pUsG+Q== Exponent2: ulbOrFsg9WAPt3ZkzKtQATSkHQQcLs5KWqs5p9bKqP6gZ9qohbS6Ywjsmn2EXswrQFyXUTxWJ/pzsg4ttYElkQ== Coefficient: kZkMqvGGOYegRIujd89qRGgHR/A8RN/BUXiuS3GbUemX9RtFRwtf12BfTAf5glTBL+7kOojarbt+CD+qkFbd6A== Created: 20141208233433 Publish: 20141208233433 Activate: 20141208233433 END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.23/t/00-pod.t0000644000175000017500000000100314522647606014220 0ustar willemwillem#!/usr/bin/perl # $Id: 00-pod.t 1808 2020-09-28 22:08:11Z willem $ -*-perl-*- # use strict; use warnings; use Test::More; my %prerequisite = ( 'Test::Pod' => 1.45 ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } my @poddirs = qw( blib demo ); my @allpods = all_pod_files(@poddirs); all_pod_files_ok(@allpods); exit; __END__ Net-DNS-SEC-1.23/t/21-RSA-MD5.t0000644000175000017500000000552514522647606014466 0ustar willemwillem#!/usr/bin/perl # $Id: 21-RSA-MD5.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA') }; plan skip_all => 'disabled MD5' unless eval { Net::DNS::SEC::libcrypto->can('EVP_md5') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'END' ); RSAMD5.example. IN KEY 512 3 1 ( AwEAAc6K704XNTQYlCPw1R5qBNdPg3SxOdhEWdDFlPdCeeBL1UDSdUG1ijcNkoGCKpFXLaTqeJAH +VkXhOGUSvFxIOOmtxb3ubwFf80Up1iKwACNmfCgDlGm8EzGKVoPGcuXkwcxFsQtBoKqT6lWR3at 6MT/bnuwIIVaD91u1L+/tVw7 ; Key ID = 46428 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: zorvThc1NBiUI/DVHmoE10+DdLE52ERZ0MWU90J54EvVQNJ1QbWKNw2SgYIqkVctpOp4kAf5WReE4ZRK8XEg46a3Fve5vAV/zRSnWIrAAI2Z8KAOUabwTMYpWg8Zy5eTBzEWxC0GgqpPqVZHdq3oxP9ue7AghVoP3W7Uv7+1XDs= PublicExponent: AQAB PrivateExponent: hMPcJddXNMCj4SJ67Az8Rabv+j+9zh3JmiCXrAUIMLyuPPfLtcxLJy5LQYJ5eGmQhpTNoM/vYWxz10kqj17H40ZpAbrfD8/TZtQDnEA2Nzlp3F+qswpmMRih82LzqzpBm0l8lbqnyIRthHfytisG52YWW8pZ0jlBuQb7whO+ajk= Prime1: 6hj6OPHOP/1AuLiiQo8FcxFyES6WAKvJlcqKX2wb7Gxz6yPfTQlR7WcueEn60r75rF9VAS46qxa3XIsvBuETJw== Prime2: 4d35IrQ/bVCtdQ7A9DyUNmOVtS6bPCJBEVLI+M6dmj1icGJiiwNdCXbX3uaOG0SEh2/oXGBbw9wX8D1xDWqKzQ== Exponent1: FvM17Mk/+CQC6Vkohy/wT9ShAzA3An/U9ntxz2MQ5b/IKYBNzwaf4o9gDejqzyhr38tE0SXQGJ/UgB0hEiKUtw== Exponent2: KEOs3Q3q3K7sLRjzNtbxyPxZvNHRJJgqp07tusUCfXOB7+zqCkQQOtavxvGs1ZmSUp6VeppG4ZSDw/UACVc75Q== Coefficient: QIVRcEFrFbmhJntBjCZOgJ4tKaiJJ3s4J97RMR6xQ1pLVwlOKKozJbjVx2tZyb11/UQliVTHlgrqYGL/oWBMKw== END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.23/t/62-Ed448.t0000644000175000017500000000470214522647606014247 0ustar willemwillem#!/usr/bin/perl # $Id: 62-Ed448.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.05, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA') }; Net::DNS::SEC::libcrypto->VERSION =~ /(BoringSSL|LibreSSL)/i; plan skip_all => "ED448 not yet supported by $1" unless grep { $_ == 16 } Net::DNS::SEC::EdDSA->_index; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::EdDSA' ); # Specimen private and public keys taken from RFC8080 my $key = Net::DNS::RR->new( <<'END' ); ED448.example.com. IN DNSKEY ( 257 3 16 3kgROaDjrh0H2iuixWBrc8g2EpBBLCdGzHmn+G2MpTPhpj/OiBVHHSfPodx1FYYUcJKm1MDpJtIA ) ; Key ID = 9713 END ok( $key, 'set up EdDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 16 (ED448) PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up EdDSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = pack 'H*', join '', qw( 01f546bfe2fd040170133b3797c1c95a31dbb2f216d95f44ced76998f7dc8e16 8f7082550a83eea4ebeb66e34696249d790db5ba76047ca9002a3dedc10e6d26 bddc8378ff1a81815aa146e72a0d9672553b2aa5cc38354cbdf2b9c4b8e36a1c f7651f828fb64c200e2ee5d0686490910c00 ); my $signed = eval { $class->sign( $sigdata, $private ); } || ''; # Note: ED448 signing is deterministic ok( $signed eq $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.23/t/20-digest.t0000644000175000017500000000516714522647606014736 0ustar willemwillem#!/usr/bin/perl # $Id: 20-digest.t 1863 2022-03-14 14:59:21Z willem $ -*-perl-*- # use strict; use warnings; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'unable to access OpenSSL libcrypto library' unless eval { Net::DNS::SEC::libcrypto->can('EVP_MD_CTX_new') }; plan tests => 22; my $text = 'The quick brown fox jumps over the lazy dog'; my %digest = ( MD5 => '9e107d9d372bb6826bd81d3542a419d6', SHA1 => '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12', SHA224 => '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525', SHA256 => 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592', SHA384 => 'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1', SHA512 => '07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6', SHA3_224 => 'd15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795', SHA3_256 => '69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04', SHA3_384 => '7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41', SHA3_512 => '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450', ); use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Digest'); sub test { my ( $mnemonic, $class, @parameter ) = @_; my ( $head, $tail ) = unpack 'a20 a*', $text; SKIP: { my $object = eval { $class->new(@parameter) }; skip( "digest algorithm $mnemonic not supported", 2 ) unless $object; $object->add($text); is( unpack( 'H*', $object->digest ), $digest{$mnemonic}, "digest algorithm $mnemonic" ); $object->add($head); $object->add($tail); is( unpack( 'H*', $object->digest ), $digest{$mnemonic}, "digest algorithm $mnemonic (concatenated)" ); } return; } test( 'MD5', 'Net::DNS::SEC::Digest::MD5' ); test( 'SHA1', 'Net::DNS::SEC::Digest::SHA', 1 ); test( 'SHA224', 'Net::DNS::SEC::Digest::SHA', 224 ); test( 'SHA256', 'Net::DNS::SEC::Digest::SHA', 256 ); test( 'SHA384', 'Net::DNS::SEC::Digest::SHA', 384 ); test( 'SHA512', 'Net::DNS::SEC::Digest::SHA', 512 ); test( 'SHA3_224', 'Net::DNS::SEC::Digest::SHA3', 224 ); test( 'SHA3_256', 'Net::DNS::SEC::Digest::SHA3', 256 ); test( 'SHA3_384', 'Net::DNS::SEC::Digest::SHA3', 384 ); test( 'SHA3_512', 'Net::DNS::SEC::Digest::SHA3', 512 ); exit; __END__ Net-DNS-SEC-1.23/t/31-DSA-SHA1.t0000644000175000017500000001150314522647606014551 0ustar willemwillem#!/usr/bin/perl # $Id: 31-DSA-SHA1.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled DSA" unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_DSA') }; plan skip_all => "disabled SHA1" unless eval { Net::DNS::SEC::libcrypto->can('EVP_sha1') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::DSA' ); my $key = Net::DNS::RR->new( <<'END' ); DSA.example. IN DNSKEY ( 257 3 3 CKrKbLrir4slVXYFrA4Y8Rik/UxzkCo1Rp0Spz907VrJL8u3I/YKTTvoMh/GL2n3/NL/KgzNRWb8 pLB3FIWHjXXhn3r3sbld180DI4tv98CZKr86UDP0UUHVE/DkkEZw5PAy2nyhhKTJRvbR4ZT0OSZY +GZA2hIzmMYk4gR2mwa3jCmAGqw2i0OtAYzSOe06uoELZLl96kRsFk69OcQxzrDKz5BEZZpNBpfZ UBk/CRPDxBE2xjJkq3VpehAUCMOFpPQlEuW2D6CNuIbJY5pNpOF3RF17vkvxQx6678ZLIN3PdeG/ nGwoJJArbt7Y/q+b/NxnIu6RwApE40p/7pOq6qKcqPVU2oHR/N7oNiyHnh68gSonUFfy5lETiyw8 vDaJS/JhC2WQKzxxBo4oa/KFXFAd6NR6bE5h5XRWWqZvm2sBgcy+sKTbKcR4PDvaAoMguBjDeigm /NV6phNbARV926NyQZOi5uUeBYA16v1KnUll7A3I9wt3ykVIbx0WqB4Ozzk2PF/3vH3wudO5bL72 zK1Yox60 ) ; Key ID = 53264 END ok( $key, 'set up DSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 3 (DSA) Prime(p): kCo1Rp0Spz907VrJL8u3I/YKTTvoMh/GL2n3/NL/KgzNRWb8pLB3FIWHjXXhn3r3sbld180DI4tv98CZKr86UDP0UUHVE/DkkEZw5PAy2nyhhKTJRvbR4ZT0OSZY+GZA2hIzmMYk4gR2mwa3jCmAGqw2i0OtAYzSOe06uoELZLk= Subprime(q): qspsuuKviyVVdgWsDhjxGKT9THM= Base(g): fepEbBZOvTnEMc6wys+QRGWaTQaX2VAZPwkTw8QRNsYyZKt1aXoQFAjDhaT0JRLltg+gjbiGyWOaTaThd0Rde75L8UMeuu/GSyDdz3Xhv5xsKCSQK27e2P6vm/zcZyLukcAKRONKf+6TquqinKj1VNqB0fze6DYsh54evIEqJ1A= Private_value(x): drOKJBTwCM0O9U6tpIgymGyBrao= Public_value(y): V/LmUROLLDy8NolL8mELZZArPHEGjihr8oVcUB3o1HpsTmHldFZapm+bawGBzL6wpNspxHg8O9oCgyC4GMN6KCb81XqmE1sBFX3bo3JBk6Lm5R4FgDXq/UqdSWXsDcj3C3fKRUhvHRaoHg7POTY8X/e8ffC507lsvvbMrVijHrQ= END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up DSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'END' ); RSAMD5.example. IN KEY ( 512 3 1 AwEAAcUHtdNvhdBKMkUle+MJ+ntJ148yfsITtZC0g93EguURfU113BQVk6tzgXP/aXs4OptkCgrL sTapAZr5+vQ8jNbLp/uUTqEUzBRMBqi0W78B3aEb7vEsC0FB6VLoCcjylDcKzzWHm4rj1ACN2Zbu 6eT88lDYHTPiGQskw5LGCze7 ) ; Key ID = 2871 END ok( $wrongkey, 'set up non-DSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'END'; Private-key-format: v1.2 Algorithm: 1 (RSA) Modulus: xQe102+F0EoyRSV74wn6e0nXjzJ+whO1kLSD3cSC5RF9TXXcFBWTq3OBc/9pezg6m2QKCsuxNqkBmvn69DyM1sun+5ROoRTMFEwGqLRbvwHdoRvu8SwLQUHpUugJyPKUNwrPNYebiuPUAI3Zlu7p5PzyUNgdM+IZCyTDksYLN7s= PublicExponent: AQAB PrivateExponent: yOATgH0y8Ci1F8ofhFmoBgpCurvAgB2X/vALgQ3YZbJvDYob1l4pL6OTV7AO2pF5LvPPSTJielfUSyyRrnANJSST/Dr19DgpSpnY2GWE7xmJ6/QqnIaJ2+10pFzVRXShijJZjt9dY7JXmNIoQ+JseE08aquKHFEGVfsvkThk8Q== Prime1: 9lyWnGhbZZwVQo/qNHjVeWEDyc0hsc/ynT4Qp/AjVhROY+eJnBEvhtmqj3sq2gDQm2ZfT8uubSH5ZkNrnJjL2Q== Prime2: zL0L5kwZXqUyRiPqZgbhFEib210WZne+AI88iyi39tU/Iplx1Q6DhHmOuPhUgCCj2nqQhWs9BAkQwemLylfHsw== Exponent1: rcETgHChtYJmBDIYTrXCaf8get2wnAY76ObzPF7DrVxZBWExzt7YFFXEU7ncuTDF8DQ9mLvg45uImLWIWkPx0Q== Exponent2: qtb8vPi3GrDCGKETkHshCank09EDRhGY7CKZpI0fpMogWqCrydrIh5xfKZ2d9SRHVaF8QrhPO7TM1OIqkXdZ3Q== Coefficient: IUxSSCxp+TotMTbloOt/aTtxlaz0b5tSS7dBoLa7//tmHZvHQjftEw8KbXC89QhHd537YZX4VcK/uYbU6SesRA== END close($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-DSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.23/t/10-keyset.t0000644000175000017500000002407514522647606014761 0ustar willemwillem#!/usr/bin/perl # $Id: 10-keyset.t 1924 2023-05-17 13:56:25Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; use TestToolkit; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'Digest::SHA' => 5.23, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA') }; plan tests => 27; use_ok('Net::DNS::SEC::Keyset'); my %filename = ( set1 => 'keyset-test.tld.', set2 => 'prefix-test.tld.', set3 => 'keyset-corrupt-test.tld.', ); END { foreach ( values %filename ) { unlink($_) if -e $_; } } # # RSA keypair 1 # my $keyrr1 = Net::DNS::RR->new( <<'END' ); test.tld. IN DNSKEY ( 257 3 10 AwEAAb/7yz0lSf3nFy7MPhkbnqOlaExKlJ8rMmYVEhFYZ5qS/ufQbfQ3stb0opr68eitrauolthm P325OvNxdzSq5rgURjx9ZitDlhxDyPfQhDzY+/CBhY/z++DRIr+v3AN/7kRW8sYwC+2Hoa1+VxQZ 1fSQ4J46ZwoN5slpar9G/Gv5aPgsvweQDI285eQVlIQ9NL00bODOHzoKvh9BAx07MOOcT9q6r9xs MPg6M4C8ykH2zVY5x1iGxT8Syzh/mecSiJtv+b1W4j49pCNj19uenW3oUnyfHg/FBmQpxTiHqs6b 1ZfVH7akvsQqwk12xT0hDEfeyj4jswDiSsEsLqt1DM0= ) ; Key ID = 39948 END ok( $keyrr1, join ' ', algorithm( $keyrr1->algorithm ), 'public key created' ); my $keyfile1 = $filename{key1} = $keyrr1->privatekeyname; my $handle1 = IO::File->new( $keyfile1, '>' ) or die qq(open: "$keyfile1" $!); print $handle1 <<'END'; Private-key-format: v1.2 Algorithm: 10 (RSASHA512) Modulus: v/vLPSVJ/ecXLsw+GRueo6VoTEqUnysyZhUSEVhnmpL+59Bt9Dey1vSimvrx6K2tq6iW2GY/fbk683F3NKrmuBRGPH1mK0OWHEPI99CEPNj78IGFj/P74NEiv6/cA3/uRFbyxjAL7YehrX5XFBnV9JDgnjpnCg3myWlqv0b8a/lo+Cy/B5AMjbzl5BWUhD00vTRs4M4fOgq+H0EDHTsw45xP2rqv3Gww+DozgLzKQfbNVjnHWIbFPxLLOH+Z5xKIm2/5vVbiPj2kI2PX256dbehSfJ8eD8UGZCnFOIeqzpvVl9UftqS+xCrCTXbFPSEMR97KPiOzAOJKwSwuq3UMzQ== PublicExponent: AQAB PrivateExponent: MnqyZdF4MxqgLd3mNhPdEopbcjPqADALgGvp5EWqeCpOfAWB48UBcSPB3Z4+HUANeiVKBHxeFWCu73PWNDL7l0s9bIpMYvPSdHweS4q4OoeTNxnXVJKCmAplaKGE6CarL6ztCM95U2tmR4gAvXhNmZC+ftw8W5hsJmlheAniNUFaRK28K0+Tlge7XkRxSwK63sjMRHHxAbclr8K2j/GUVkXG9yOrMqgXUJ0WOg9E5BTW+gdkGl4kB5U2gvgRwxkEwY9x7yzrg2cUxrEi9hDlS9HiG5NZizcQqAWkKcdHo28ZB5E4NZBLrKQFjrkOQz3ZjtpUcsTRf/lOvkCOoaveAQ== Prime1: 7lgM8XyKy3IHYC3+GX1bS0LZFqBhUvYuZ52i2dfKoG9XglVKKe0Pmu/Hkgkdc2/mottVdYHpMZ4t/Wt0OXdqfttoYTgIOFTw4t3Jk9HV4aPIRvVD7LRnRQiKEW9OiS9ixplatrlgMqyOIpx3bou6eRzOs1yfBsNSr+LZbHQ50/U= Prime2: zjSQ7ylj386G6bFXMKLAjApYy7cQA9T4/URnonUYjXwzQRaDvfAGoRNRA4e0RagVd/x2Dk5hs2UYLMIhpmQWNoSK/ZAFS02RzapMZTV2jya4cJZ83qjYtMYEx8Lff5dHX3lz/uAkcJCasIbyEodi0btJkCZQFAsCMbGlhguTpnk= Exponent1: U8jEFAfRyp61FQxV7KPyecxv/9I1JDLCMU5qtuVyp188heZxgbeB6tcrcpydq7zEeK9dpUcbsIOIazNg0eq2lw2N7c8CpLrHSxjoCXyUERPADaGeVRE91DiiQGq+Ut9De8jg6KbVuDqMZIJYQZYA4R5NUyPWC0ySPp4iDEv3IBk= Exponent2: tJ867SM2Rs6jQoSCuSl2u7Q8f4UE1DZzO3X1yUoEjbpjMvpDv9ZGGEXRSuRNtk47L/TGfFWQIxHEkUAjNZqqEmsbTGwhFwsFUj9/149zIIVsPcKz8l24JPDnMwuxthOPA0RhpLo1cRxZQ5OQ60YH+2qwT0IgFs5lx52yPa5aURE= Coefficient: Y7KhcJe8vcW9h/bxClHMjlB0sYYvdqo7/iwjxiaCD4suPAUpLMxNgeR3TJHT1RYaHQSuFB3Mc9f58hoHe3dncxF+Eey9SdTH53c0+V95tJpAsqirFaqvei+xgikcmhYsWLOQHayul5ZMsfpiph3R90QUYg3Kpbni4W0ALeGswv4= END close($handle1); # # RSA keypair 2 # my $keyrr2 = Net::DNS::RR->new( <<'END' ); test.tld. IN DNSKEY ( 256 3 8 AwEAAcXr1phQtnOdThOrgcwRplS/btblbtLGeHQoba55Gr8Scbx7AAw+LjwtFmbPlDhklC8+4BAf QB+6Jv7hOFT45J/RqDV3W5p0qDYcLYJObNbiFxQ64ogMYHx62w4oUeTS5CvpHNzSoiyhhFlf71RL EVeBK798h+hdPeEWvHdzbwwMxZGIXP/eNN5u5tkNExuuqq3e6BeguCLsuLgMzHdfpl7W20z3BExD c28DgPRWHJtJcB+iUd5oQdrw+G9qSq4kb7vk3OZUGrgkZskicT1A5rQsOgc4SrT4d25Qd6fthmi2 hZ86Y/2DP/NfR1mwWaN8ty7daqdcNpFQmKwQ+qpIV5c= ) ; Key ID = 63427 END ok( $keyrr2, join ' ', algorithm( $keyrr2->algorithm ), 'public key created' ); my $keyfile2 = $filename{key2} = $keyrr2->privatekeyname; my $handle2 = IO::File->new( $keyfile2, '>' ) or die qq(open: "$keyfile2" $!); print $handle2 <<'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: xevWmFC2c51OE6uBzBGmVL9u1uVu0sZ4dChtrnkavxJxvHsADD4uPC0WZs+UOGSULz7gEB9AH7om/uE4VPjkn9GoNXdbmnSoNhwtgk5s1uIXFDriiAxgfHrbDihR5NLkK+kc3NKiLKGEWV/vVEsRV4Erv3yH6F094Ra8d3NvDAzFkYhc/9403m7m2Q0TG66qrd7oF6C4Iuy4uAzMd1+mXtbbTPcETENzbwOA9FYcm0lwH6JR3mhB2vD4b2pKriRvu+Tc5lQauCRmySJxPUDmtCw6BzhKtPh3blB3p+2GaLaFnzpj/YM/819HWbBZo3y3Lt1qp1w2kVCYrBD6qkhXlw== PublicExponent: AQAB PrivateExponent: S3dyet+Dwi+/3pYtxr8QGg5oV/5htHLC6R+lOrqorSR+Q6zuxrxK6t0SRp9t19bZ/e3Oh7cyvyY+yj7cOOIyYpIRvllFj25d2UwDOkVnEMRiom8Vg2ScwboinpJXL5YONIQNYlHaToRDr8R5wD1jXmc9ZCU6uSocdyAxOqbEN+ZWNnzGHjs4onoGMLyc7f2NbMhSHVW9tp7zilCQ1W3OF6coWI/L/vGk1xBQZ+OtkRRbJCTca3qflLm/1vPq8/H3gS5adrJcO+/mUlhPoKxEqekZZp+FQJVHTYp3MyGTVXVl2M8sozf9lU/malzlqve5snMLfCOWH8MOdsx7eo0N+Q== Prime1: +ajh2Bbk8r2DBvCw3u3ipji7zeD1LLMRdYlSuCpyIWGGoiCJrqX34zFCdDOO1gKa2QQG3OAGk3hZ1ddcgr+bnVNIEuVxJXe0Wg4e0ZPNMCe1333Hyt7ws2U+zosYNfrxOdPkj/S5XZkVyRE1Ixa79WCBJms+zgDPx30AUQXblw0= Prime2: yvKWeFcJhIleHVNwEkNtq+aOgcIhS2ex7zc/zKFGSGYXdWIl17oM3ohiPgmLVznJtIkCIcYoxbfxuLW0NDe2OJC7PUjOB3lAmtHAH3ZafNbr/PdlAZzHUZiLsiHF/m5wd+pN37rCj7emjASwsGjcx3rRsJQvqVZARj/TXe9eQDM= Exponent1: nMBIbKCTR0VtyyG8K3w43hyo7e7cgSA9SgragP9FgWf2XD0JtTpHlcIL82GbwQsJplA87tlJx7W80eLSFtWvIuxzSEn+7INoHVLYTsX6As4sBxK2Ks4nWruq34u9u8a/Rouf6jLBX98KKqA/OLTBdqMM885KNJWV367AUB7ZbNE= Exponent2: FyUHR/4VFcpcs1d6pnqOHVaT1fR/u4u93Rwd6IZT75nE/xwMWMfdA9vl6FFKVM5AVJhzZ8qjh7jsljYSsQnRfC31TI3rASsw1Pcqw+vJcgdIrnbATCjHCmUtOUlkvRl3NhXAf81atu0ozzsRs2yiERXOqCaeMN+nQNuyjTnpM8U= Coefficient: iUz9xrXzP2UaBruIps61HAbh6MV+OYDmliSnudXW5Ii1s3ANXMJodzgwqD+VesjC9dDE2nXMTCXKhpk46Qy8i3OYJ4T7vxoyHEYfID1PM0+whAwebRoKHBqQDEYgwTcqDX+qD4MMc1TaG/do/cgNc/1EyE03DP1plH6HhItECIo= END close($handle2); # Create keysets my $keyrrset = [$keyrr1, $keyrr2]; my $sigrr1 = Net::DNS::RR::RRSIG->create( $keyrrset, $keyfile1, ttl => 3600 ); ok( $sigrr1, join ' ', algorithm( $sigrr1->algorithm ), 'signature created' ); my $sigrr2 = Net::DNS::RR::RRSIG->create( $keyrrset, $keyfile2, ttl => 3600 ); ok( $sigrr2, join ' ', algorithm( $sigrr2->algorithm ), 'signature created' ); my $keyset = Net::DNS::SEC::Keyset->new($keyrrset); 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( digtype => 'SHA-256' ); my $string0 = $ds[0]->string; my $string1 = $ds[1]->string; my $expect0 = Net::DNS::RR->new('test.tld. IN DS 39948 10 2 94e22598a45d485926d8e3944f871dc605ef52db59f346066bf2b0d20d6d8ed4')->string; my $expect1 = Net::DNS::RR->new('test.tld. IN DS 63426 8 2 ee74fe86f0d9499ef1abe414039ffaf34f05d3e71a4899882c714395d9047368')->string; my $alg0 = algorithm( $ds[0]->algorithm ); my $dig0 = digtype( $ds[0]->digtype ); is( $string0, $expect0, "DS ($alg0/$dig0) created from keyset" ); my $alg1 = algorithm( $ds[1]->algorithm ); my $dig1 = digtype( $ds[1]->digtype ); is( $string1, $expect1, "DS ($alg1/$dig1) created from keyset" ); ## # Corrupted keyset my $handle3 = IO::File->new( $filename{set3}, '>' ) or die qq(open: "$filename{set3}" $!); print $handle3 $keyrr1->string, "\n"; print $handle3 $keyrr2->string, "\n"; my $sigstr = lc $sigrr1->string; # corrupt the base64 signature $sigstr =~ s/in.rrsig/IN RRSIG/; # fix collateral damage $sigstr =~ s/dnskey/DNSKEY/; print $handle3 $sigstr . "\n"; print $handle3 $sigrr2->string . "\n"; close($handle3); my $corrupt = Net::DNS::SEC::Keyset->new( $filename{set3} ); ok( !$corrupt, "Corrupted keyset not loaded" ); my $corrupt_keyset = Net::DNS::SEC::Keyset->keyset_err; like( $corrupt_keyset, '/failed.+key/', "Expected error [$corrupt_keyset]" ); my @keyrr = ( $keyrr1, $keyrr2 ); my @sigrr = ( $sigrr1, $sigrr2 ); 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" ); my @keytags = $ks->verify; is( scalar(@keytags), 2, "Verify method returned the keytags" ); my $good_tag = 39948; ok( $ks->verify($good_tag), "Verification against keytag $good_tag" ); my $bad_tag = 9734; ok( !$ks->verify($bad_tag), "Verification against keytag $bad_tag failed" ); my $missing_signature = Net::DNS::SEC::Keyset->keyset_err; like( $missing_signature, "/No signature.+$bad_tag/", "Expected error [$missing_signature]" ); my $corruptible = Net::DNS::RR::RRSIG->create( $keyrrset, $keyfile1, ttl => 3600 ); my $unverifiable = Net::DNS::SEC::Keyset->new( $keyrrset, [$corruptible] ); my $badsig = Net::DNS::RR::RRSIG->create( [$sigrr1], $keyfile1, ttl => 3600 ); $corruptible->sigbin( $badsig->sigbin ); is( scalar( $unverifiable->extract_ds ), 0, 'No DS from unverifiable keyset' ); my $bogus = Net::DNS::RR->new( <<'END' ); bogus.tld. IN DNSKEY 257 3 5 ( AQO1gY5UFltQ4f0ZHnXPFQZfcQQNpXK5r0Rk05rLLmY0XeA1lu8ek7W1VHsBjkge9WU7efdp3U4a mxULRMQj7F0ByOK318agap2sIWYN13jV1RLxF5GPyLq+tp2ihEyI8x0P8c9RzgVn1ix4Xcoq+vKm WqDT1jHE4oBY/DzI8gyuJw== ; Key ID = 15792 ) 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 "No signature for KSK" error' ); like( Net::DNS::SEC::Keyset->keyset_err, '/Multiple names/', 'Expected "Multiple names" error' ); my $packet = Net::DNS::Packet->new( 'test.tld', 'DNSKEY' ); $packet->push( answer => @keyrr, @sigrr ); ok( Net::DNS::SEC::Keyset->new($packet)->verify(), "Verify keyset extracted from packet" ); ok( Net::DNS::SEC::Keyset->new( [$keyrr2] )->verify(), "Verify keyset with no KSK" ); exception( 'unwritable file', sub { $keyset->writekeyset( File::Spec->rel2abs('nonexdir') ) } ); # 0.17 backward compatibility (exercise code for test coverage only) eval { my $scalar = key_difference( [@keyrr], [@ks_sigs], [] ); }; eval { my @array = key_difference( [@keyrr], [@ks_sigs] ); }; exit; __END__ Net-DNS-SEC-1.23/t/TestToolkit.pm0000644000175000017500000000502014522647606015662 0ustar willemwillem# $Id: TestToolkit.pm 1924 2023-05-17 13:56:25Z willem $ -*-perl-*- package TestToolkit; =head1 NAME TestToolkit - Convenient tools to simplify test script construction. =cut use strict; use warnings; use Carp; use Test::Builder; use Test::More; use base qw(Exporter); our @EXPORT = qw(exception noexception NonFatalBegin NonFatalEnd); =head1 exception noexception [no]exception( 'test description', sub { code fragment } ); Executes the supplied code fragment and reports a raised exception or warning using the Test::More ok() mechanism. =cut sub exception { my ( $name, $code ) = @_; my $exception = _execute($code); my $boolean = $exception ? 1 : 0; my $tb = Test::Builder->new; return $tb->ok( $boolean, "$name\t[$exception]" ); } sub noexception { my ( $name, $code ) = @_; my $exception = _execute($code); my $boolean = $exception ? 0 : 1; my $tb = Test::Builder->new; return $tb->ok( $boolean, $exception ? "$name\t[$exception]" : $name ); } sub _execute { my $code = shift; my @warning; local $SIG{__WARN__} = sub { push @warning, "@_" }; local ( $@, $!, $SIG{__DIE__} ); ## isolate eval eval { &$code; croak shift(@warning) if @warning; }; my ($exception) = split /[\r\n]+/, "$@\n"; return $exception; } ######################################## # # Test::More test functions all eventually call Test::Builder::ok # (on the (singular) builder instance) to report the status. # The NonFatal package defines a subclass derived from Test::Builder, # with a redefined ok method that overrides the completion status # seen by the test harness. # # Note: Modified behaviour is enabled by the 't/online.nonfatal' file. # =head1 NonFatalBegin NonFatalEnd Tests that are between these functions will always appear to succeed. The failure report itself is not suppressed. =cut sub NonFatalBegin { return bless Test::Builder->new, qw(NonFatal) } sub NonFatalEnd { return bless Test::Builder->new, qw(Test::Builder) } package NonFatal; use base qw(Test::Builder); my $enabled = eval { -e 't/online.nonfatal' }; my @failed; sub ok { my ( $self, $test, @name ) = @_; return $self->SUPER::ok( $test, @name ) if $test; if ($enabled) { my $number = $self->current_test + 1; push @failed, join( "\t", $number, @name ); @name = "NOT OK (tolerating failure) @name"; } return $self->SUPER::ok( $enabled, @name ); } END { my $n = scalar(@failed) || return; my $s = ( $n == 1 ) ? '' : 's'; my $tb = __PACKAGE__->SUPER::new(); $tb->diag( join "\n", "\nDisregarding $n failed sub-test$s", @failed ); } 1; __END__ Net-DNS-SEC-1.23/t/23-RSA-SHA256.t0000644000175000017500000001110414522647606014741 0ustar willemwillem#!/usr/bin/perl # $Id: 23-RSA-SHA256.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; use TestToolkit; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA') }; plan tests => 17; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'END' ); RSASHA256.example. IN DNSKEY 256 3 8 ( AwEAAZRSF/5NLnExp5n4M6ynF2Yok3N2aG9AWu8/vKQrZGFQcbL+WPGYbWUtMpiNXmvzTr2j86kN QU4wBawm589mjzXgVQRfXYDMMFhHMtagzEKOiNy2ojhhFyS7r2O2vUbo4hGbnM54ynSM1al+ygKU Gy1TNzHuYMiwh+gsQCsC5hfJ ; Key ID = 35418 ) END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 8 (RSASHA256) Modulus: lFIX/k0ucTGnmfgzrKcXZiiTc3Zob0Ba7z+8pCtkYVBxsv5Y8ZhtZS0ymI1ea/NOvaPzqQ1BTjAFrCbnz2aPNeBVBF9dgMwwWEcy1qDMQo6I3LaiOGEXJLuvY7a9RujiEZucznjKdIzVqX7KApQbLVM3Me5gyLCH6CxAKwLmF8k= PublicExponent: AQAB PrivateExponent: c74UZyhHo6GCDs73VDYYNmpXlnTCTn7D94ufY+VQsfgaofmF4xJ128yHfTBkjI0T1z1H+ZYUbjVfV9YMc3avLcXAb4YOEuNw0CSZrtTFc/oTvAyM9tKoa7hB9MSlYtmYvaWiEatHzKL0wYvo71jtfoTyDLQTISzrBWsA+K1a3hk= Prime1: wvw2lVu+kepiu0fasCrA3BlemVJ3XvWdd/y0sB5+egVGIJCn1bgkaSL/IP+683K28tN7hQYzMGiDBPymu3FeAw== Prime2: wruzE41ctH5D2SLhW4pi/pz+WSyeBUSvsmUe5kr4c9mlIqYUK1k72kmsjjZtD4eJsjq3xb/VGi+pcMuK2t1/Qw== Exponent1: lgk3AxTWfjcqA8wVpesv/ezzku0W95Xtto9YhhDg54m5XYOR8e1A7znDsaO2OnAyAIXlDQYpS32QG71Bmwhv+w== Exponent2: KyNVekFYhgtqkFFvxs2TPIAewDZoExayLTzFaZK2E0PllxVfZnLwFV04wpA//K6zzC3BxCbI2HIygPA2JGHo7Q== Coefficient: R3pSnerhKwfAHrH3iyojUzKzhM+AQ+97CWavx36eyKT3Yr/SIDANeeXGlT9U7RdxbkZzyeWbFNCnT+b89UX1RQ== END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); # The following tests are not replicated for other RSA/SHA flavours my $wrongkey = Net::DNS::RR->new( <<'END' ); ECDSAP256SHA256.example. IN DNSKEY ( 257 3 13 IYHbvpnqrhxM4i0SuOyAq9hk19tNXpjja7jCQnfAjZBFBfcLorJPnq4FWMVDg6QT2C4JeW0yCxK4 iEhb4w9KWQ== ) ; Key ID = 27566 END ok( $wrongkey, 'set up non-RSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'END'; Private-key-format: v1.3 ; comment discarded ; empty line discarded Algorithm: 13 (ECDSAP256SHA256) PrivateKey: w+AjPo650IA8DWeEq5QqZ2LWYpuC/oeEaYaGE1ZvKyA= Created: 20141209015301 Publish: 20141209015301 Activate: 20141209015301 END close($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-RSA private key' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); # test detection of invalid private key descriptors exception( 'invalid keyfile', sub { Net::DNS::SEC::Private->new('Kinvalid.private') } ); exception( 'missing keyfile', sub { Net::DNS::SEC::Private->new('Kinvalid.+0+0.private') } ); exception( 'unspecified algorithm', sub { Net::DNS::SEC::Private->new( signame => 'private' ) } ); exception( 'unspecified signame', sub { Net::DNS::SEC::Private->new( algorithm => 1 ) } ); # exercise code for key with long exponent (not required for DNSSEC) eval { my $longformat = pack 'xn a*', unpack 'C a*', $key->keybin; $key->keybin($longformat); $class->verify( $sigdata, $key, $signature ); }; exit; __END__ Net-DNS-SEC-1.23/t/00-load.t0000644000175000017500000000265414522647606014372 0ustar willemwillem#!/usr/bin/perl # $Id: 00-load.t 1924 2023-05-17 13:56:25Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More tests => 3; use TestToolkit; my @module = qw( Net::DNS Net::DNS::SEC Net::DNS::SEC::libcrypto ); my %metadata; my $handle = IO::File->new('MYMETA.json') || IO::File->new('META.json'); if ($handle) { my $json = join '', (<$handle>); for ($json) { s/\s:\s/ => /g; # Perl? en voilĂ ! my $hashref = eval $_; %metadata = %$hashref; } close $handle; } my %prerequisite; foreach ( values %{$metadata{prereqs}} ) { # build, runtime, etc. foreach ( values %$_ ) { # requires $prerequisite{$_}++ for keys %$_; } delete @prerequisite{@module}; delete $prerequisite{perl}; } my @diag; foreach my $module ( @module, sort keys %prerequisite ) { eval "require $module"; ## no critic for ( eval { $module->VERSION || () } ) { s/^(\d+\.\d)$/${1}0/; push @diag, sprintf "%-25s %s", $module, $_; } } diag join "\n\t", "\nThese tests were run using:", @diag; ok( eval { Net::DNS::SEC::libcrypto->VERSION }, 'XS component SEC.xs loaded' ) || BAIL_OUT("Unable to access OpenSSL libcrypto library"); use_ok('Net::DNS::SEC'); # Exercise checkerr() response to failed OpenSSL operation exception( 'XS libcrypto error', sub { Net::DNS::SEC::libcrypto::checkerr(0) } ); exit; END { eval { Net::DNS::SEC::libcrypto::croak_memory_wrap() } # paper over crack in Devel::Cover } __END__ Net-DNS-SEC-1.23/t/22-RSA-SHA1.t0000644000175000017500000000741214522647606014573 0ustar willemwillem#!/usr/bin/perl # $Id: 22-RSA-SHA1.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.15, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled RSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_RSA') }; plan skip_all => 'disabled SHA1' unless eval { Net::DNS::SEC::libcrypto->can('EVP_sha1') }; plan tests => 8; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::RSA' ); my $key = Net::DNS::RR->new( <<'END' ); RSASHA1.example. IN DNSKEY ( 257 3 5 AwEAAefP0RzK3K39a5wznjeWA1PssI2dxqPb9SL+ppY8wcimOuEBmSJP5n6/bwg923VFlRiYJHe5 if4saxWCYenQ46hWz44sK943K03tfHkxo54ayAk/7dMj1wQ7Dby5FJ1AAMGZZO65BlKSD+2BTcwp IL9mAYuhHYfkG6FTEEKgHVmOVmtyKWA3gl3RrSSgXzTWnUS5b/jEeh2SflXG9eXabaoVXEHQN+oJ dTiAiErZW4+Zlx5pIrSycZBpIdWvn4t71L3ik6GctQqG9ln12j2ngji3blVI3ENMnUc237jUeYsy k7E5TughQctLYOFXHaeTMgJt0LUTyv3gIgDTRmvgQDU= ) ; Key ID = 4501 END ok( $key, 'set up RSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: 58/RHMrcrf1rnDOeN5YDU+ywjZ3Go9v1Iv6mljzByKY64QGZIk/mfr9vCD3bdUWVGJgkd7mJ/ixrFYJh6dDjqFbPjiwr3jcrTe18eTGjnhrICT/t0yPXBDsNvLkUnUAAwZlk7rkGUpIP7YFNzCkgv2YBi6Edh+QboVMQQqAdWY5Wa3IpYDeCXdGtJKBfNNadRLlv+MR6HZJ+Vcb15dptqhVcQdA36gl1OICIStlbj5mXHmkitLJxkGkh1a+fi3vUveKToZy1Cob2WfXaPaeCOLduVUjcQ0ydRzbfuNR5izKTsTlO6CFBy0tg4Vcdp5MyAm3QtRPK/eAiANNGa+BANQ== PublicExponent: AQAB PrivateExponent: qVfDp4j61ZAAAMgkmO7Z14FdKNdNuX6CAeKNx8rytaXZ9W25dLtx4r3uWtL1cyI13RWn7l54VFoWkEwDQ0/6P4vLbE0QbvFWjUMkX1TH9kQSRc+R6WCRPuH1Ex0R1h5fbw6kEVDRMZjKUfLX5oFVDv1xu5Mjg5Y8KQoJIuLdDgHtRRV7ZETcGcSXBQ1eY2rNxui2YzM0mtqzApgGq7pLb3GfiM5aqW5fSdRaFajGC2VIXkN3jZYxAryT8EYJ6uRFJk0X3VegEwj6keHOem/tBV2DaNlv1JWidauPeU67evKNTQVW3h3AbQxnOtegdWrRKoa9Ksf27bgoKAlveHIfsQ== Prime1: +s1y+iP+AoB4UVS4S5njIZD21AWm36JTaqEvRPdevjuzc9q7yJATROdRdcAitdSPHeRC8xtQw/C9zGhJRdynlxfmUTeyYgM0EYHYiG7PLwkW5Wu9EeXJ7/Fpct51L+ednloQ0d7tYP/5QUd6cqbFGGKH0yF5zZMO0k+ZZ/saeCs= Prime2: 7J2eVZ5Psue4BTNya8PMA89cC0Gf51zFeQ8dPBZIOpN28DJN2EN6C6fwGtnr6BO+M/6loXzcekPGgRkpNcQ6MzJup8hZQmU8RxESAMlmQzOtaBbtmMwPa0p6IcZBUWpbRaKwQ4ZjAUS9R13PFwgEU+a855o0XRRTupdmyZ6OmR8= Exponent1: nGakbdMmIx9EaMuhRhwIJTWGhz+jCdDrnhI4LRTqM019oiDke7VFHvH1va18t9F/Ek/3ZC1Dl304jxD1qKhqpnGUAk/uYOrIfKZxhts7PoS3j4g5VsDqxkPQ035gq+gPReG6nXYcqCHYqVnOxVK0lHlVZFd64rTzSDm1W7+eiRM= Exponent2: evAuKygVGsxghXtEkQ9rOfOMTGDtdyVxiMO8mdKt9plV69kHLz1n9RRtoVXmx28ynQtK/YvFdlUulzb+fWwWHTGv4scq8V9uITKSWwxJcNMx3upCyugDfuh0aoX6vBV5lMXBtWPmnusbOTBZgArvTLSPI/qwCEiedE1j34/dYVs= Coefficient: JTEzUDflC+G0if7uqsJ2sw/x2aCHMjsCxYSmx2bJOW/nhQTQpzafL0N8E6WmKuEP4qAaqQjWrDyxy0XcAJrfcojJb+a3j2ndxYpev7Rq8f7P6M7qqVL0Nzj9rWFH7pyvWMnH584viuhPcDogy8ymHpNNuAF+w98qjnGD8UECiV4= END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); exit; __END__ Net-DNS-SEC-1.23/t/51-ECDSA-P256.t0000644000175000017500000000750514522647606014732 0ustar willemwillem#!/usr/bin/perl # $Id: 51-ECDSA-P256.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; use warnings; use IO::File; use Test::More; my %prerequisite = ( 'Net::DNS::SEC' => 1.01, 'MIME::Base64' => 2.13, ); foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => 'disabled ECDSA' unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_ECDSA') }; plan tests => 13; my %filename; END { foreach ( values %filename ) { unlink($_) if -e $_; } } use_ok('Net::DNS::SEC'); use_ok('Net::DNS::SEC::Private'); use_ok( my $class = 'Net::DNS::SEC::ECDSA' ); my $key = Net::DNS::RR->new( <<'END' ); ECDSAP256SHA256.example. IN DNSKEY ( 257 3 13 IYHbvpnqrhxM4i0SuOyAq9hk19tNXpjja7jCQnfAjZBFBfcLorJPnq4FWMVDg6QT2C4JeW0yCxK4 iEhb4w9KWQ== ) ; Key ID = 27566 END ok( $key, 'set up ECDSA public key' ); my $keyfile = $filename{keyfile} = $key->privatekeyname; my $privatekey = IO::File->new( $keyfile, '>' ) or die qq(open: "$keyfile" $!); print $privatekey <<'END'; Private-key-format: v1.3 Algorithm: 13 (ECDSAP256SHA256) PrivateKey: w+AjPo650IA8DWeEq5QqZ2LWYpuC/oeEaYaGE1ZvKyA= Created: 20141209015301 Publish: 20141209015301 Activate: 20141209015301 END close($privatekey); my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up ECDSA private key' ); my $wrongkey = Net::DNS::RR->new( <<'END' ); RSASHA1.example. IN DNSKEY ( 256 3 5 AwEAAZHbngk6sMoFHN8fsYY6bmGR4B9UYJIqDp+mORLEH53Xg0f6RMDtfx+H3/x7bHTUikTr26bV AqsxOs2KxyJ2Xx9RGG0DB9O4gpANljtTq2tLjvaQknhJpSq9vj4CqUtr6Wu152J2aQYITBoQLHDV i8mIIunparIKDmhy8TclVXg9 ) ; Key ID = 1623 END ok( $wrongkey, 'set up non-ECDSA public key' ); my $wrongfile = $filename{wrongfile} = $wrongkey->privatekeyname; my $handle = IO::File->new( $wrongfile, '>' ) or die qq(open: "$wrongfile" $!); print $handle <<'END'; Private-key-format: v1.2 Algorithm: 5 (RSASHA1) Modulus: kdueCTqwygUc3x+xhjpuYZHgH1RgkioOn6Y5EsQfndeDR/pEwO1/H4ff/HtsdNSKROvbptUCqzE6zYrHInZfH1EYbQMH07iCkA2WO1Ora0uO9pCSeEmlKr2+PgK pS2vpa7XnYnZpBghMGhAscNWLyYgi6elqsgoOaHLxNyVVeD0= PublicExponent: AQAB PrivateExponent: Vd6cuMRDxnuiFr367pJB39FYyDkNrZ9zAoyCt0idcHirglmV1ps7px2AQY2MOW/Tg2Xz59EqBA00mEOmnuRfdRXraqo1mxA9C2qGR2xHltNH2RVR5oT lahZLRUYZTDuLI7G/3IiPKrf5z/HFm2DkkzuxGqC8hWf9FOni49CqhYE= Prime1: waSsFnVlQrG/3SGh5GNV5o50PS8gE5L0/+GP2MIjkR3px1zR+LjfkVii1EaTda+Sq7B0ROI+M+R0JLh98Rr6XQ== Prime2: wNOsL3isJAE89C2XaESsJnm46vPZrqZ4XATub1dwOWNqVOji6KI9yTBc3MfmXkZVmy0I8Rm4ILLh5m/+0LNXYQ== Exponent1: muRjmptQ4iZYOEOcwZkLrx4nsIEvgTi9rKf6bgHsfTmWNBf1BKSsgBCMPowti6djBN5iQm9OHigRFwZUBzXzKQ== Exponent2: KE8Xe4T6Vzx7BYBSWlWgtxpS8aqwIrZiCrptLZFVwGlr3PwiEwd3awtVHkIbgjGpy5qKd/wsZYl/d7CJ0A7tgQ== Coefficient: p9WMT9cDpT7BXcKBXnrMLV8O31ujZ17nwlmlFe3+0n2VCx2T/CSz72xssffn0n2q0DaHHfu9SxR1RLgmDUzVEA== END close($handle); my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-ECDSA private key' ); my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); ok( $signature, 'signature created using private key' ); my $verified = $class->verify( $sigdata, $key, $signature ); is( $verified, 1, 'signature verified using public key' ); my $verifiable = $class->verify( $corrupt, $key, $signature ); is( $verifiable, 0, 'signature not verifiable if data corrupted' ); is( eval { $class->sign( $sigdata, $wrongprivate ) }, undef, 'signature not created using wrong private key' ); is( eval { $class->verify( $sigdata, $wrongkey, $signature ) }, undef, 'verify fails using wrong public key' ); is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if signature undefined' ); exit; __END__ Net-DNS-SEC-1.23/META.json0000664000175000017500000000257414522650756014232 0ustar willemwillem{ "abstract" : "DNSSEC extensions to Net::DNS", "author" : [ "Dick Franks", "Olaf Kolkman" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010", "license" : [ "mit" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-DNS-SEC", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.48" } }, "runtime" : { "requires" : { "Carp" : "1.1", "DynaLoader" : "1.09", "Exporter" : "5.56", "File::Spec" : "3.29", "IO::File" : "1.14", "MIME::Base64" : "2.13", "Net::DNS" : "1.08", "perl" : "5.008009" } }, "test" : { "requires" : { "ExtUtils::MakeMaker" : "0", "File::Find" : "1.13", "File::Spec" : "3.29", "IO::File" : "1.14", "Test::More" : "0.8" } } }, "release_status" : "stable", "version" : "1.23", "x_serialization_backend" : "JSON::PP version 4.16" } Net-DNS-SEC-1.23/Changes0000644000175000017500000004640114522647606014077 0ustar willemwillemRevision history for Perl extension Net::DNS::SEC. **** 1.23 Nov 8, 2023 Code refactoring of XS component. **** 1.22 Sep 12, 2023 Enable Ed25519 sign/verify for BoringSSL & LibreSSL. Use EC curve names instead of literal NIDs. Circumvent sign/verify test failures on EBCDIC platforms. Fix: rt.cpan.org #149643 openssl-SNAP-20230831 breaks RSA sign/verify **** 1.21 Jun 1, 2023 Add new t/TestToolkit.pm Rework pre-installation test scripts. Fix: rt.cpan.org #148367 libressl-3.7.1 breaks DSA verify **** 1.20 Oct 4, 2022 Improve Net::DNS::SEC::Keyset tests and error reporting. Avoid test failures if/when DSA|MD5|SHA1 become unsupported. **** 1.19 Oct 11, 2021 Discontinue support for obsolete ECC-GOST. Add LICENSE file to comply with Fedora/RedHat announcement and WARNING of restrictions on use of strong cryptography. **** 1.18 Oct 2, 2020 Eliminate bareword filehandle usage. Eliminate indirect object syntax. Eliminate grep/map . **** 1.17 Jun 26, 2020 Recognise BIND private key accessed via symbolic link. **** 1.16 May 11, 2020 Improve testing of verify() functions. Rework code in Digest.pm SEC.xs code reduction. **** 1.15 February 3, 2020 Provide access to OpenSSL message digest implementations. **** 1.14 October 14, 2019 Improve exception capture in test scripts. Support more efficient algorithm mapping in Net::DNS. **** 1.13 May 6, 2019 Tweaks to resolve compilation errors with BoringSSL. **** 1.12 Mar 19, 2019 Avoid use of EC_POINT_set_affine_coordinates_GFp which is deprecated in OpenSSL 3.0.0 Reduce level of support for OpenSSL non-LTS releases. **** 1.11 Dec 11, 2018 Explain why compilation aborted in Net::DNS::SEC::DSA et al. Fix Makefile.PL to suppress parallel test execution. **** 1.10 Aug 31, 2018 Collect test coverage metrics for SEC.xs using gcc and gcov. **** 1.09 Jun 4, 2018 Avoid use of EC_GROUP_new, EC_GROUP_set_curve_GFp, and EC_GFp_mont_method which are expected to disappear. Fix filename conflict when tests run in parallel. **** 1.08 May 11, 2018 Internal reorganisation to use OpenSSL EVP interface **** 1.07 April 5, 2018 Fix: rt.cpan.org #124880 1.06 will not install on macOS Feature Support for Ed25519 and Ed448 algorithms **** 1.06 March 22, 2018 Functionally identical to 1.05 All changes address build/test issues on some platforms **** 1.05 March 20, 2018 Feature Interim support for Ed25519 and Ed448 algorithms Fix: rt.cpan.org #124650 Net::DNS::SEC::Private must not die if attribute is not present **** 1.04 February 15, 2018 Feature Cryptographic library access re-engineered using PerlXS directly instead of CPAN Crypt::OpenSSL::(DSA|EDSA|RSA) distributions which have fallen into disrepair. **** 1.03 August 26, 2016 Fix: rt.cpan.org #108908 Tests break when Net::DNS gets shadowed by existing pre-1.01 version. **** 1.02 September 16, 2015 Fix: Bug in t/10-keyset.t raises exception in Net::DNS **** 1.01 August 3, 2015 Feature The RRs previously implemented in Net::DNS::SEC are now integrated with Net::DNS. Fix: rt.cpan.org #105808 Version test for Pod::Test is broken Fix: rt.cpan.org #105698 Net-DNS 1.01 conflicts with Net-DNS-SEC 0.22 **** 0.22 February 11, 2015 Fix: rt.cpan.org #101184 make siginception and sigexpiration available as time() values Fix: rt.cpan.org #101183 wrong URL for blog in README Fix: rt.cpan.org #83031 [RRSIG] lack of ECDSA support ***0.21 October 24, 2014 Fix: rt.cpan.org #99250 [RRSIG] validation fails when Signer's Name is upper case Fix: rt.cpan.org #99106 Premature end of base64 data (in 14-misc.t test script) ***0.20 August 15, 2014 Fix: rt.cpan.org #97457 !hex! error when parsing NSEC3 with empty salt ***0.19 Jun 6, 2014 Remove inappropriate deprecation warning in DNSKEY.pm ***0.18 May 8, 2014 Recode RR implementations to provide Net::DNS 0.69+ interface. Fix: rt.cpan.org #95034 Failure to parse NSEC3PARAM record with null salt Fix: rt.cpan.org #81289 Failure to handle GOST DS records ***0.17 November 29, 2013 Fix: rt.cpan.org #90270 NSEC3->covered() should use case-insensitive comparisons Fix: rt.cpan.org #79606 Lower case zone-name part with DNSKEY::privatename Allow to specify algorithms with ::Private->new_rsa_private and ::Private->generate_rsa instead of assuming RSASHA1. Fix: rt.cpan.org #55621 Specify license type (mit) in META.yml Fix: rt.cpan.org #60269 Remove Digest::SHA1 prerequirement Fix: rt.cpan.org #62387 & #63273 Typo fixes Fix: rt.cpan.org #62386 Make Net::DNS::RR::DS::digtype method work Fix: rt.cpan.org #62385 Do not compress Next Domain Name in NSEC rdata. Fix: rt.cpan.org #61104 Spelling correction in DS.pm and fix of key2ds demo program Fix: rt.cpan.org #60185 Make sure %main::SIG hash keeps its values when compiling Net::DNS::RR::SIG in perl versions before 5.14. See also: rt.perl.org #76138 Fix: rt.cpan.org #64552 and rt.cpan.org #79606 Support for private-key-format v1.3 Fix: rt.cpan.org #75892 Do not canonicalize the "Next Domain Name" rdata field of a NSEC RR for draft-ietf-dnsext-dnssec-bis-updates-17 compliance. BUG FIX/FEATURE: validation of wildcard RRs now available. Duane Wessels is acknowledged for submitting the initial code on which this fix is based. FIX: case sensitivity of ownername during DS generation (Acknowledgements Jens Wagner) ***0.16 March 12, 2010 Feature: KEY inherits DNSKEY This helps maintenance in one part of the code. Feature: keylength method (rt.cpan.org #53468) Added keylength method for RSA and DSA Acknowledgements Hugo Salgado Fix: rt.cpan.org #51778 Empty bitmap would cause error about undefined ARRAY in NSEC/NSEC3. Now the code will allow empty bitmaps gracefully Feature: New Algorithm Support (rt.cpan.org #51092) SHA2 algorithm support, including NSEC3 algorithm parameters updated Acknowledgement Jakob Shlyter Fix: rt.cpan.org #42089 NSEC3 Algorithm support in NSEC3 broken patch by Wes Hardaker ***0.15 December 31, 2008 Fix: digestbin not set when an empty value passed to hash. Feature: Added DLV (rfcc 4431). The RR object is simply a clone of the DS RR and inherits ... everything Feature: Added NSEC3 and NSEC3PARAM support (RFC5155). This adds Mime::Base32 to the module dependency list. The RR type was still experimental at that time and is maintained in Net::DNS::RR. Fix: Test script recognizes change in Time::Local. Note that Time::Local does not deal with dates beyond 03:14:07 UTC on Tuesday, 19 January 2038. Therefore this code has a year 2038 problem. Fix: DS create_from_hash now produces objects that can create wireformat. Other: minor changes to the debug statements added t/05-rr.t (and identified a couple of bugs using it) Fix: a few inconsistencies with respect to parsing of trailing dots. During development the test signatures generated with the BIND tools were re-generated in order to troubleshoot a bug that (most probably) was caused by a version incompatibility between Net::DNS and Net::DNS::SEC. Before release the original test from the 0.14 release were ran against this version too. 0.14 February 14, 2005 FIX: The introducion of the keytag warning triggered a bug with RSAMD5 keys, causing RSAMD5 keys not to be loaded. 0.13 December 9, 2005 FEAT: rt.cpan.org 14588 Added support for passing (a reference to) an array of keys to the RRSIG verify function. FIX/FEAT: The Net::DNS::SEC::Private function will for RSA based keys verify if the keytag in the filename is actually correct. Since at parsing the value of the DNSKEY RR flags is not known we test against the currently defined flag values 256 and 257. If we cannot find a keytag match a warning is printed and Private key generation fails This inconsistency was spotted by Jakob Shlyter. FEAT: Added support for SHA256 to the DS RR. Assigned the expected digest type2 for SHA256 type hashes. Note that this makes the Net::DNS::SEC depend on Digest::SHA instead of Digest::SHA1. The default digest type is still set to 1. NB. The code makes assumptions about the IANA assignment of the digest type. The assignment may change. Do not use SHA256 in production zones!! FIX: rt.cpan.org #15662 Roy Arends noticed and patched the label counting did not ignore an initial asterisk label. FIX: Wes Hardaker noticed the default TTL values for created signatures to be different from the TTLs from the data that is being signed. FIX: Wes Hardaker reported there was a problem with validating RRsets that had ownernames with capitals. The fix depends on a fix in Net::DNS::RR that is available in version 0.53_03 or later of the Net::DNS distribution. FEAT: Propper dealing with mnemonics for algorithm and digest type added to DS FIX/FEAT: Mnemonics were written as RSA/MD5 and RSA/SHA1. This has been corrected tp RSASHA1 and RSAMD5, as in the IANA registry. 0.12_02 June 6, 2005 (beta 2 release for 0.13) Bug: new_from_hash would not correctly create the RR since internally typebm is used to store the data this has been fixed so that the following works Net::DNS::RR->new(name=>$name, ttl=>$ttl, type=>"NSEC", nxtdname=>$nxtdname, typelist=>join(" ",@types) ); FEAT: Introduced the "use bytes" pragma to force character interpretation of all the scalars. Any utf processing by perl makes the code behave unpredictable. 0.12_01 April 18, 2005. (beta release for version 0.13) FEAT (!!!): Changed the symantics of the Net::DNS::Keyset::verify method. Read the perldoc for details. The requirement that each key in a keyset has to be selfsigned has been loosened. FEAT: Added a "carp" to the new methods of the NXT RR. Warning that that record is deprecated. FEAT: Cleaned the tests so that RRSIG and DNSKEY are used except for SIG0 based tests. FEAT: Changed the name of the siginceptation[SIC] to siginception. Thanks Jakob Schlyter for notifying me of this mistyping. An alias for the method remains available. FEAT: Renamed unset_sep() to clear_sep(). NOTE: To avoid confusion the Net::DNS::SIG::Private class has been removed. Use Net::DNS::SEC::Private! DOC: Added references to RFC 4033, RFC 4034 and RFC 4035. Rewrote parts of the perlpod. 0.12 June 2004 "DNSSEC-bis Release" FEAT: Added utility function key_difference() to Net::DNS::SEC. See perlpod for details. I needed this in other software and figured they are generic enough to make them available through this module. FEAT: Modified some functions to use DNSKEY and RRSIG instead off KEY and SIG. - Net::DNS::Keyset now uses DNSKEY and RRSIG. - the demo function getkeyset.pl now uses DNSKEY too. FEAT: Added the possibility to create a keyset out of two arrays of dnskey and rrsig object. FEAT: Added some helperfunctions to Net::DNS::SEC::Private to read X509 formated private keys and dump them into bind format. This functionality has not been tested well. BUG : When reading a RRSIG from a packet the signame would not have a trailing dot. 0.11_4 Apr 24 2004 Development snapshot. BUG: - Fixed MANIFEST. FEAT: Removed critical dependency on bubblebabble. It is available to DS if installed but not critically dependend. 0.11_3 Mar 4 2004 Development snapshot. BUG: - Fixed minor in signing unknown RR types. 0.11_2 Jan 27 2004 Development snapshot. FEAT: - Prelimanary support for draft-ietf-dnssec-nsec-rdata-02. This depends on support for unknown RR types (Net::DNS version 0.44) 0.11_1 Sep 23 2003 Development snapshot. FEAT: - To be able to deal with argument supplied as either mnemonics or by value the Net::DNS::SEC::argument method was created. It can be used as a class method but it is also inherited by Net::DNS::RR::RRSIG and Net::DNS::RR::DNSKEY. 0.11 August 28 2003 FEAT: - Implemented draft-ietf-dnsext-dnssec-2535typcode-change-04.txt This document has been through review and will be published as standard track RFCs shortly. (Publsished as RFC3755). IMPORTANT: the implementation of the typecode roll deprecated the use of SIG->create for any other reason than SIG0. If you try to create SIGs over RRsets you will be warned. FEAT: - Modified the namespace for the module that holds the name of the private key from Net::DNS::RR::SIG::Private to Net::DNS::SEC::Private. !!!!! Net::DNS::RR::SIG::Private will be deprecated in a next release. !!!!! CLEAN:- Crypt::OpenSSL::RSA v 0.19 introduced the possibility to create keys directly from parameters, although this introduced a dependency on Crypt::OpenSSL::Bignum it allowed to get rid from converting all parameters to DER/ANS1 encoding. Got rid of a number of lines of code. 0.10 January 8 2003 BUG: - Crypt::OpenSSL::RSA::new method has been deprecated. Code has been modified to deal with the new constructors 0.09 January 6 2003 FEAT: - Added Net::DNS::RR::SIG::Private. The class provides an abstraction to the private key material. The SIG create method now either takes a filename, like previously, or a Private key object as an argument. If you have to create many signatures the latter is preferred because you only have to read the file with the private key material once. Note that by adding this feature a modification to Net::DNS::Resolver was needed to properly do SIG0. Use Net::DNS version 0.32 or later in combination with this version FEAT: - Wes Griffen added a parameter change to keyset: 'Attached is a diff for Net::DNS::SEC v0.8 that adds a parameter changes keyset->writekeyset($path) to keyset->writekeyset($prefix,$path) where prefix is an optional string that is prepended to the filename of the keyset. That way I can keep my unsigned keyset in keyset-. and have the signed keyset in signed-keyset-.' FEAT: - Babblebubble, handy for telephone confirmation of hashes. Added babblebubble string as comment to DS RR. DS->babble returns the babble bubble string FEAT: - Miek Gieben contributed demo/key2ds 0.08 November 4 2002 BUG: - DSA signature verification failed at random about 1 per 10 sigatures. Corrected allignment problem that lead to this. Added 'stresstest' that loops over creation and verification of signatures to spot these kind of seldomly occuring errors. On my VAIO PII 500Mhz the take about a minute: Files=3, Tests=3056, 69 wallclock secs (63.30 cusr + 0.70 csys = 63.99 CPU) FEAT: - Added Test::More as dependency as on some systems diag was failing. 0.07 October 2 2002 FEAT: - Added demo/make-signed-keyset, a contribution by Wes Griffin. FEAT: - Removed dependency on Math::Pari by porting away from Crypt::DSA to Crypt::OpenSSL::DSA (version 0.10). This should increase portability over platform. T.J. Mather, the Crypt::OpenSSL::DSA maintainer has been particularly helpfull and responsive by adding a few methods to the DSA modules. 0.06 August 16 2002 NOTE: In one of ther versions prior to Net::DNS 0.26 a bug got introduced that made Net::DNS::SEC break. The bug was fixed in version 0.27. BUG: - Check on the existence of the private file improved in SIG.pm - signame got trailing dot with the create methods and not with others. FEAT: - Added privatekeyname method to KEY.pm - Started work on Net::DNS::Keyset. - Added RSA/SHA1 (algorithm ID 5) to SIG.pm. Patch supplied by Andy Vaskys, Network Associates Laboratories. - Rewrote regexp's to not use $' (Postmatch). 0.05 and 0.04 June 17, 2002 BUG: Makefile.PL needed a fix for unused dependency. This failed made the installation fail :-(. 0.04 introduced another failing dependency. DOC: Clarified the documentation at points. 0.03 June 14, 2002 DOC: Few Clarifications 0.02 June 4, 2002 First CPAN Release. Some modifications to the packaging. 0.01 May 25, 2002 Version 0.01 of the package is an alpha for CPAN release. --------------------------------------------------------------------------- The extensions used to be published as a modified version of Net::DNS. The history of those is documented below. 0.20-DNSSEC-0.2: Branched off Net::DNS version 0.20 release (CPAN May 15, 2002) 0.20-DNSSEC-0.1: This version had limited distribution First patch against a version 0.20 snapshot (2002-03-27). http://www.dyndns.org/~ctriv/net-dns-snaps/2002/03/ Modified t/09-dnssec.t; uses Test::More now and includes a number of self consistency checks. DOC Cleaned up the documentation and removed some references to functions and libraries that where not used anyway. FIX 'aesthetic' patch supplied by Simon Josefsson reordering the NXT RR map for the print method. FEAT Added checks on keytype and updated to latest specs for DS Added SIG0 support. See Net::DNS::Packet for details. The verify and create methods of SIG.pm where modified somewhat to cope with the difference. Changed RSA backend from Crypt::RSA to Crypt::OpenSSL::RSA because Crypt::RSA failed during a 'loss of Math::Pari precision in Crypt::Primes'. 0.19-DNSSEC-0.5: BUG DS create method: Hash calculation was done over concatenation of name and key material while the hash should be taken over concatenation of canonical name and key rdata. (Fix by Mike Schiraldi) 0.19-DNSSEC-0.4: Added CERT support: Courtesy of Mike Schiraldi for VeriSign BUG Fixed MANIFEST file. make dist will result in proper module tar ball 0.19-DNSSEC-0.3: Solved patch problems that where due to the $ Id $ in headers not being from the original distribution. Added DSA signature creation Added DS support You have to uncomment line 77 in Net/DNS.pm to fully enable DS This will assign QTYPE 93 to the DS RR. That value is not assigned by IANA. Added this README.DNSSEC file Added t/09-dnssec.t to the test script with a number of consistency checks. after patching the original distribution direction perl Makefile.PL make test will call this function among other things. BUG KeyID set to 0 for null keys. BUG Sorting of canonical RDATA; Data over which SIG was created was not sorted properly (RFC2535 sect 8.3) causing signature verification errors for RDATA within a RRset having different length (e.g. some NS RRsets would not verify.) 0.19-DNSSEC-0.2: First somewhat public release. --------------------------------------------------------------------------- $Id: Changes 1943 2023-11-08 09:02:03Z willem $ Net-DNS-SEC-1.23/META.yml0000664000175000017500000000140614522650756014053 0ustar willemwillem--- abstract: 'DNSSEC extensions to Net::DNS' author: - 'Dick Franks' - 'Olaf Kolkman' build_requires: ExtUtils::MakeMaker: '0' File::Find: '1.13' File::Spec: '3.29' IO::File: '1.14' Test::More: '0.8' configure_requires: ExtUtils::MakeMaker: '6.48' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010' license: mit meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-DNS-SEC no_index: directory: - t - inc requires: Carp: '1.1' DynaLoader: '1.09' Exporter: '5.56' File::Spec: '3.29' IO::File: '1.14' MIME::Base64: '2.13' Net::DNS: '1.08' perl: '5.008009' version: '1.23' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Net-DNS-SEC-1.23/Makefile.PL0000644000175000017500000001056614522647606014561 0ustar willemwillem# # $Id: Makefile.PL 1926 2023-05-31 12:05:13Z willem $ -*-perl-*- # use 5.008009; use strict; use warnings; use Config; use ExtUtils::MakeMaker; use constant MSWin32 => $^O eq 'MSWin32'; my $distro = 'Net::DNS::SEC'; my $module = join '/', 'lib', split /::/, "$distro.pm"; my $author = ['Dick Franks', 'Olaf Kolkman']; $author = join ', ', @$author if $ExtUtils::MakeMaker::VERSION < 6.58; # See perldoc ExtUtils::MakeMaker for details of how to influence # the contents of the Makefile that is written. my %metadata = ( NAME => $distro, VERSION_FROM => $module, ABSTRACT_FROM => $module, AUTHOR => $author, LICENSE => 'mit', MIN_PERL_VERSION => 5.008009, CONFIGURE_REQUIRES => {'ExtUtils::MakeMaker' => 6.48}, TEST_REQUIRES => { 'ExtUtils::MakeMaker' => 0, 'File::Find' => 1.13, 'File::Spec' => 3.29, 'IO::File' => 1.14, 'Test::More' => 0.80, } ); my %prerequisite = ( 'Carp' => 1.10, 'DynaLoader' => 1.09, 'Exporter' => 5.56, 'File::Spec' => 3.29, 'IO::File' => 1.14, 'MIME::Base64' => 2.13, 'Net::DNS' => 1.08, ); my @debris = qw(*.gcov *.gcda *.gcno *.lock); my $inc = ''; my $lib = '-lcrypto'; my $nul = MSWin32 ? 'nul' : '/dev/null'; if (`pkg-config --modversion libcrypto 2>$nul`) { $inc = `pkg-config --cflags libcrypto 2>$nul`; $lib = `pkg-config --libs libcrypto 2>$nul`; } elsif (MSWin32) { $lib = '-llibeay32' if $Config{cc} =~ /cl/; $lib = '-leay32' if $Config{cc} =~ /gcc/; } if ( my $dir = $ENV{OPENSSL_PREFIX} ) { chomp $dir; $inc = "-I$dir/include"; $lib = "-L$dir/lib $lib"; } $inc = $ENV{OPENSSL_INCLUDE} if $ENV{OPENSSL_INCLUDE}; $lib = $ENV{OPENSSL_LIB} if $ENV{OPENSSL_LIB}; chomp $_ for ( $inc, $lib ); WriteMakefile( %metadata, PREREQ_PM => {%prerequisite}, INC => $inc, LIBS => [$lib], clean => {FILES => "@debris"}, ); exit; package MY; ## customise generated Makefile sub constants { return join "\n", shift->SUPER::constants(), <<'END' if $^O =~ /MSWin/i; # include test directory TEST_DIR = t FULLPERLRUN = $(FULLPERL) "-I$(TEST_DIR)" END return join "\n", shift->SUPER::constants(), <<'END'; # suppress parallel test execution include test directory TEST_DIR = t FULLPERLRUN = HARNESS_OPTIONS=j1:c $(FULLPERL) "-I$(TEST_DIR)" END } sub dist { return join "\n", shift->SUPER::dist(), <<'END'; # $(PERM_RWX) raises security issues downstream PREOP = $(CHMOD) $(PERM_RW) $(DISTVNAME)$(DFSEP)demo$(DFSEP)* END } sub install { my $self = shift; my %install_type = qw(perl INSTALLARCHLIB site INSTALLSITEARCH vendor INSTALLVENDORARCH); my $install_site = join '', '$(DESTDIR)$(', $install_type{$self->{INSTALLDIRS}}, ')'; for ($install_site) { s/\$\(([A-Z_]+)\)/$self->{$1}/eg while /\$\(/; # expand Makefile macros s|([/])[/]+|$1|g; # remove gratuitous //s } eval "require $distro"; ## no critic my @version = ( 'version', eval { $distro->VERSION } ); my $nameregex = join '\W+', '', split /::/, "$distro.pm\$"; my @installed = grep { $_ && m/$nameregex/io } values %INC; my %occluded; foreach (@installed) { my $path = m/^(.+)$nameregex/io ? $1 : ''; my %seen; foreach (@INC) { $seen{$_}++; # find $path in @INC last if $_ eq $path; } foreach ( grep { !$seen{$_} } @INC ) { $occluded{$_}++; # suppress install } } return $self->SUPER::install(@_) unless $occluded{$install_site}; my $message; warn $message = <<"AMEN"; ## ## The install location for this version of $distro ## differs from the existing @version in your perl library at ## @installed ## ## The installation would be rendered ineffective because the ## existing @version occurs in the library search path before ## $install_site ## ## The generated Makefile supports build and test only. ## AMEN my $echo = ' $(NOECHO) $(ECHO) "##"'; $message =~ s/##/$echo/eg; return join '', <<"END"; install : $message \$(NOECHO) \$(FALSE) END } sub postamble { my $ldflags = "-fprofile-arcs -ftest-coverage"; my $ccflags = "-O0 $ldflags"; my $devnull = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; return <<"PlanA" if `gcov -v 2>$devnull`; test_cover : cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover \$(MAKE) -W SEC.xs test CCFLAGS="$ccflags" OTHERLDFLAGS="$ldflags" cover \$(NOECHO) \$(TOUCH) SEC.c # force XS rebuild before install PlanA return <<'PlanB'; test_cover : cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover $(MAKE) test cover PlanB } __END__ Net-DNS-SEC-1.23/WARNING0000644000175000017500000000105414522647606013627 0ustar willemwillem------------------------------------------------------------------------------ *************** ** WARNING ** *************** THE USE AND/OR HANDLING OF STRONG ENCRYPTION TECHNOLOGIES IS PROHIBITED OR SEVERELY RESTRICTED IN MANY TERRITORIES. PLEASE BE SURE THAT YOU FULLY UNDERSTAND THE LEGAL POSITION IN YOUR COUNTRY BEFORE ATTEMPTING TO INSTALL THIS MODULE OR ANY OF THE PREREQUISITE CRYPTOGRAPHY PACKAGES. ------------------------------------------------------------------------------ $Id: WARNING 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.23/README0000644000175000017500000001215014522647606013456 0ustar willemwillemNet::DNS::SEC - DNSSEC extensions to Net::DNS ============================================= 1. DESCRIPTION ----------- This module is designed as an extension the Net::DNS package (https://metacpan.org/release/Net-DNS). The module implements the cryptographic signature generation and verification functions that are relevant for DNSSEC operations. ** ** *************** ** ** WARNING ** ** *************** ** THE USE AND/OR HANDLING OF STRONG ENCRYPTION TECHNOLOGIES IS ** PROHIBITED OR SEVERELY RESTRICTED IN MANY TERRITORIES. ** PLEASE BE SURE THAT YOU FULLY UNDERSTAND THE LEGAL POSITION ** IN YOUR COUNTRY BEFORE ATTEMPTING TO INSTALL THIS MODULE OR ** ANY OF THE PREREQUISITE CRYPTOGRAPHY PACKAGES. ** Net::DNS::SEC also provides a class for handling keysets. Keysets are administrative files used by the BIND tools for key maintenance tasks. Net::DNS::SEC::Keyset provides an abstract interface for doing fun things with them. See also the 'pod' documentation in: Net::DNS::RR::DNSKEY Net::DNS::RR::DS Net::DNS::RR::RRSIG Net::DNS::SEC::Private and for the use of SIG0 see: Net::DNS::Packet (sign_sig0) Net::DNS::RR::SIG 2. AVAILABILITY ------------ You can get the latest version of Net::DNS::SEC from the Comprehensive Perl Archive Network (CPAN): https://metacpan.org/release/Net-DNS-SEC or through http://www.net-dns.org/ Additionally a subversion repository is made available through http://www.net-dns.org/svn/net-dns-sec/ The version on the "trunk" (http://www.net-dns.org/svn/net-dns-sec/trunk) is the version that is targeted for next release. Please note that the SVN version at any given moment may be broken. 3. PREREQUISITES ------------- This package relies on Net-DNS version 1.01 or later which has features specifically designed to support Net::DNS::SEC. The availability of prerequisites for Net::DNS::SEC is tested at installation time. These are the packages that need to be available: File::Find File::Spec MIME::Base64 Test::More The cryptographic heavy lifting is performed using the OpenSSL libcrypto library distributed under separate license. You will also require a C compiler. 4. INSTALLATION ------------ Please install any modules mentioned in the PREREQUISITES section above. When you run "perl Makefile.PL", Perl should complain if any of the required modules is missing. To build this module, run the following commands: tar xvzf Net-DNS-SEC-1.??.tar.gz cd Net-DNS-SEC-1.?? perl Makefile.PL make make test make install 'make test' will do some tests that should all succeed once all dependencies are satisfied. Please report any failure during the test phase. Alternatively, install the package using CPAN: perl -MCPAN -e shell; cpan> install Net::DNS::SEC To build the libcrypto library, run the following: tar xvzf openssl-3.*.tar.gz cd openssl-3.* ./config shared make # require only libcrypto.so* and include/openssl/*.h 5. MAINTENANCE ----------- Please use the CPAN request tracker to report bugs in the extensions. The request tracker is available through: https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-DNS-SEC 6. STAYING UP TO DATE ------------------ Announcements about Net::DNS::SEC will be published on http://www.net-dns.org/blog/. An RSS feed is available. 7. DEMOS ----- demo/getkeyset.pl A small demonstration program that will fetch the keyset for a specified domain, store the keys and print DS RRs to STDOUT. demo/key2ds Reads the key data from STDIN and prints the corresponding DS record on STDOUT. Contributed by Miek Gieben demo/make-signed-keyset Creates a self-signed keyset from a BIND public key specified on the command line. Contributed by Wes Griffin 8. ACKNOWLEDGEMENTS ---------------- Thanks are due to Eric Young and the many developers and contributors to the OpenSSL project and cryptographic library. 9. COPYRIGHT --------- Authorship of individual components and significant contributions is shown in the copyright notice attached to the relevant documentation. Copyright in all components is retained by their respective authors. 10. LICENSE ------- Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ $Id: README 1849 2021-08-19 08:25:20Z willem $ Net-DNS-SEC-1.23/typemap0000644000175000017500000000025714522647606014205 0ustar willemwillem# # $Id: typemap 1763 2020-02-02 21:48:03Z willem $ # TYPEMAP DSA* T_PTROBJ EC_KEY* T_PTROBJ EVP_MD_CTX* T_PTROBJ EVP_PKEY* T_PTROBJ const EVP_MD* T_PTROBJ RSA* T_PTROBJ #