diff options
author | gregor herrmann <gregoa@debian.org> | 2023-09-30 00:27:03 +0200 |
---|---|---|
committer | gregor herrmann <gregoa@debian.org> | 2023-09-30 00:27:03 +0200 |
commit | 7bbbdd9ee084a86528f1f7c50dedb0dfde3aebd2 (patch) | |
tree | 918523bbdeb7aae34425f0bdc020af1024e806cb | |
parent | f68147a2413be08a4a77f30409092cbeb483068d (diff) |
New upstream version 1.22
-rw-r--r-- | Changes | 22 | ||||
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | META.json | 4 | ||||
-rw-r--r-- | META.yml | 4 | ||||
-rw-r--r-- | Makefile.PL | 60 | ||||
-rw-r--r-- | SEC.xs | 181 | ||||
-rw-r--r-- | lib/Net/DNS/SEC.pm | 4 | ||||
-rw-r--r-- | lib/Net/DNS/SEC/ECDSA.pm | 18 | ||||
-rw-r--r-- | lib/Net/DNS/SEC/EdDSA.pm | 25 | ||||
-rw-r--r-- | t/00-load.t | 12 | ||||
-rw-r--r-- | t/10-keyset.t | 7 | ||||
-rw-r--r-- | t/21-RSA-MD5.t | 6 | ||||
-rw-r--r-- | t/22-RSA-SHA1.t | 6 | ||||
-rw-r--r-- | t/23-RSA-SHA256.t | 23 | ||||
-rw-r--r-- | t/24-RSA-SHA512.t | 6 | ||||
-rw-r--r-- | t/31-DSA-SHA1.t | 6 | ||||
-rw-r--r-- | t/51-ECDSA-P256.t | 6 | ||||
-rw-r--r-- | t/52-ECDSA-P384.t | 6 | ||||
-rw-r--r-- | t/61-Ed25519.t | 6 | ||||
-rw-r--r-- | t/62-Ed448.t | 10 | ||||
-rw-r--r-- | t/TestToolkit.pm | 116 |
21 files changed, 341 insertions, 188 deletions
@@ -1,9 +1,27 @@ Revision history for Perl extension Net::DNS::SEC. +**** 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 - Circumvent failure of EdDSA test on EBCDIC platforms. Improve Net::DNS::SEC::Keyset tests and error reporting. Avoid test failures if/when DSA|MD5|SHA1 become unsupported. @@ -657,4 +675,4 @@ Net::DNS. The history of those is documented below. --------------------------------------------------------------------------- -$Id: Changes 1882 2022-10-04 19:53:44Z willem $ +$Id: Changes 1939 2023-09-12 13:34:55Z willem $ @@ -32,5 +32,6 @@ 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) @@ -34,7 +34,7 @@ "runtime" : { "requires" : { "Carp" : "1.1", - "DynaLoader" : "1.04", + "DynaLoader" : "1.09", "Exporter" : "5.56", "File::Spec" : "3.29", "IO::File" : "1.14", @@ -54,6 +54,6 @@ } }, "release_status" : "stable", - "version" : "1.20", + "version" : "1.22", "x_serialization_backend" : "JSON::PP version 4.08" } @@ -24,12 +24,12 @@ no_index: - inc requires: Carp: '1.1' - DynaLoader: '1.04' + 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.20' +version: '1.22' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/Makefile.PL b/Makefile.PL index 6206247..97f3419 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,5 +1,5 @@ # -# $Id: Makefile.PL 1874 2022-09-23 13:37:00Z willem $ -*-perl-*- +# $Id: Makefile.PL 1926 2023-05-31 12:05:13Z willem $ -*-perl-*- # use 5.008009; @@ -37,7 +37,7 @@ my %metadata = ( my %prerequisite = ( 'Carp' => 1.10, - 'DynaLoader' => 1.04, + 'DynaLoader' => 1.09, 'Exporter' => 5.56, 'File::Spec' => 3.29, 'IO::File' => 1.14, @@ -53,20 +53,20 @@ my $inc = ''; my $lib = '-lcrypto'; my $nul = MSWin32 ? 'nul' : '/dev/null'; -if ( my $dir = $ENV{OPENSSL_PREFIX} ) { - chomp $dir; - $inc = "-I$dir/include"; - $lib = "-L$dir/lib -lcrypto"; - -} elsif (`pkg-config --modversion libcrypto 2>$nul`) { +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 ); @@ -85,19 +85,22 @@ exit; package MY; ## customise generated Makefile -sub test { - return shift->SUPER::test() if $^O =~ /cygwin|MSWin/i; - - return join '', shift->SUPER::test(), <<'END'; -# suppress parallel test execution -FULLPERLRUN = HARNESS_OPTIONS=j1:c $(FULLPERL) +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 '', shift->SUPER::dist(), <<'END'; - + return join "\n", shift->SUPER::dist(), <<'END'; # $(PERM_RWX) raises security issues downstream PREOP = $(CHMOD) $(PERM_RW) $(DISTVNAME)$(DFSEP)demo$(DFSEP)* END @@ -115,7 +118,7 @@ sub install { } eval "require $distro"; ## no critic - my @version = grep {$_} 'version', eval { $distro->VERSION }; + my @version = ( 'version', eval { $distro->VERSION } ); my $nameregex = join '\W+', '', split /::/, "$distro.pm\$"; my @installed = grep { $_ && m/$nameregex/io } values %INC; @@ -161,24 +164,23 @@ END sub postamble { - my $devnull = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; - return <<"PlanB" unless `gcov -v 2>$devnull`; -test_cover : - cover -delete - HARNESS_PERL_SWITCHES=-MDevel::Cover \$(MAKE) test - cover -summary -PlanB my $ldflags = "-fprofile-arcs -ftest-coverage"; my $ccflags = "-O0 $ldflags"; - return <<"PlanA"; + 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" - gcov SEC.xs - gcov2perl SEC.xs.gcov - cover -summary + 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 } @@ -1,5 +1,5 @@ -#define XS_Id "$Id: SEC.xs 1872 2022-09-16 09:33:02Z willem $" +#define XS_Id "$Id: SEC.xs 1937 2023-09-11 09:27:16Z willem $" =head1 NAME @@ -13,7 +13,7 @@ upon which the Net::DNS::SEC cryptographic components are built. =head1 COPYRIGHT -Copyright (c)2018-2021 Dick Franks +Copyright (c)2018-2023 Dick Franks All Rights Reserved @@ -49,30 +49,32 @@ extern "C" { #include <XSUB.h> #include <openssl/opensslv.h> -#include <openssl/bn.h> -#include <openssl/err.h> #ifndef OPENSSL_VERSION_NUMBER /* 0xMNN00PP0L retain backward compatibility */ #define OPENSSL_VERSION_NUMBER \ ( (OPENSSL_VERSION_MAJOR<<28) | (OPENSSL_VERSION_MINOR<<20) | (OPENSSL_VERSION_PATCH<<4) | 0x0L ) #endif -#if (OPENSSL_VERSION_NUMBER < 0x40000000) -#define OBSOLETE_API +#if (OPENSSL_VERSION_NUMBER < 0x7FF00000) +#define API_1_1_1 #undef OSSL_DEPRECATED #define OSSL_DEPRECATED(since) extern -#include <openssl/evp.h> #include <openssl/dsa.h> -#include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/rsa.h> -#else -#include <openssl/evp.h> +#endif + +#if !(OPENSSL_VERSION_NUMBER < 0x30000000) +#define API_3_0_0 #include <openssl/core_names.h> #include <openssl/param_build.h> static OSSL_LIB_CTX *libctx = NULL; #endif +#include <openssl/bn.h> +#include <openssl/err.h> +#include <openssl/evp.h> + #ifdef __cplusplus } #endif @@ -91,26 +93,35 @@ static OSSL_LIB_CTX *libctx = NULL; #define NO_EdDSA #endif +#ifdef OPENSSL_NO_ECX +#define NO_EdDSA +#endif + #ifdef OPENSSL_IS_BORINGSSL -#define NO_DSA +#ifndef NID_ED25519 #define NO_EdDSA +#endif +#define NO_DSA #define NO_SHA3 #endif #ifdef LIBRESSL_VERSION_NUMBER +#if (LIBRESSL_VERSION_NUMBER < 0x30702000) #undef OPENSSL_VERSION_NUMBER #define OPENSSL_VERSION_NUMBER 0x10100000L #endif +#define NO_DSA +#define NO_SHA3 +#endif #if (OPENSSL_VERSION_NUMBER < 0x10001000) -#error unsupported libcrypto version +#error ancient libcrypto version #include OPENSSL_VERSION_TEXT /* in error log; by any means, however reprehensible! */ #endif #if (OPENSSL_VERSION_NUMBER < 0x10100000) - #define EVP_MD_CTX_new() EVP_MD_CTX_create() #define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx)) @@ -147,10 +158,8 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) #if (OPENSSL_VERSION_NUMBER < 0x10101000) -#define EOL #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) @@ -169,15 +178,8 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, #endif -#ifndef OBSOLETE_API -int EVP_PKEY_fromparams(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM_BLD *bld) -{ - OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld); - int retval = EVP_PKEY_fromdata_init(ctx); - if ( retval > 0 ) retval = EVP_PKEY_fromdata( ctx, ppkey, selection, params ); - OSSL_PARAM_free(params); - return retval; -} +#if (OPENSSL_VERSION_NUMBER < 0x30000000) +#define EOL #endif @@ -188,6 +190,19 @@ void checkret(const int ret, int 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 + + MODULE = Net::DNS::SEC PACKAGE = Net::DNS::SEC::libcrypto PROTOTYPES: ENABLE @@ -219,13 +234,13 @@ EVP_sign(SV *message, EVP_PKEY *pkey, const EVP_MD *md=NULL) EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char sigbuf[512]; /* RFC3110(2) */ STRLEN buflen = sizeof(sigbuf); - int r; + int error; CODE: checkerr( EVP_DigestSignInit( ctx, NULL, md, NULL, pkey ) ); - r = EVP_DigestSign( ctx, sigbuf, &buflen, msgbuf, msglen ); + error = EVP_DigestSign( ctx, sigbuf, &buflen, msgbuf, msglen ); EVP_MD_CTX_free(ctx); EVP_PKEY_free(pkey); - checkerr(r); + checkerr(error); RETVAL = newSVpvn( (char*)sigbuf, buflen ); OUTPUT: RETVAL @@ -315,26 +330,29 @@ EVP_sha3_512() EVP_PKEY* EVP_PKEY_new_DSA(SV *p_SV, SV *q_SV, SV *g_SV, SV *y_SV, SV *x_SV) 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(); +#endif BIGNUM *p = BN_bin2bn( (unsigned char*) SvPVX(p_SV), SvCUR(p_SV), NULL ); BIGNUM *q = BN_bin2bn( (unsigned char*) SvPVX(q_SV), SvCUR(q_SV), NULL ); BIGNUM *g = BN_bin2bn( (unsigned char*) SvPVX(g_SV), SvCUR(g_SV), NULL ); BIGNUM *x = BN_bin2bn( (unsigned char*) SvPVX(x_SV), SvCUR(x_SV), NULL ); BIGNUM *y = BN_bin2bn( (unsigned char*) SvPVX(y_SV), SvCUR(y_SV), NULL ); CODE: -#ifdef OBSOLETE_API - DSA *dsa = DSA_new(); - DSA_set0_pqg( dsa, p, q, g ); - DSA_set0_key( dsa, y, x ); +#ifndef API_3_0_0 RETVAL = EVP_PKEY_new(); - EVP_PKEY_assign( RETVAL, EVP_PKEY_DSA, (char*)dsa ); + checkerr( DSA_set0_pqg( dsa, p, q, g ) ); + checkerr( DSA_set0_key( dsa, y, x ) ); + checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_DSA, (char*)dsa ) ); #else - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "DSA", NULL ); - OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + RETVAL = NULL; checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_P, p ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_Q, q ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_FFC_G, g ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PUB_KEY, y ) ); - RETVAL = NULL; if ( SvCUR(x_SV) > 0 ) { checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_PRIV_KEY, x ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); @@ -362,26 +380,29 @@ EVP_PKEY_new_DSA(SV *p_SV, SV *q_SV, SV *g_SV, SV *y_SV, SV *x_SV) EVP_PKEY* EVP_PKEY_new_RSA(SV *n_SV, SV *e_SV, SV *d_SV, SV *p_SV, SV *q_SV) 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(); +#endif BIGNUM *n = BN_bin2bn( (unsigned char*) SvPVX(n_SV), SvCUR(n_SV), NULL ); BIGNUM *e = BN_bin2bn( (unsigned char*) SvPVX(e_SV), SvCUR(e_SV), NULL ); BIGNUM *d = BN_bin2bn( (unsigned char*) SvPVX(d_SV), SvCUR(d_SV), NULL ); BIGNUM *p = BN_bin2bn( (unsigned char*) SvPVX(p_SV), SvCUR(p_SV), NULL ); BIGNUM *q = BN_bin2bn( (unsigned char*) SvPVX(q_SV), SvCUR(q_SV), NULL ); CODE: -#ifdef OBSOLETE_API - RSA *rsa = RSA_new(); - RSA_set0_factors( rsa, p, q ); - RSA_set0_key( rsa, n, e, d ); +#ifndef API_3_0_0 RETVAL = EVP_PKEY_new(); - EVP_PKEY_assign( RETVAL, EVP_PKEY_RSA, (char*)rsa ); + checkerr( RSA_set0_factors( rsa, p, q ) ); + checkerr( RSA_set0_key( rsa, n, e, d ) ); + checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_RSA, (char*)rsa ) ); #else - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, "RSA", NULL ); - OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + RETVAL = NULL; checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_N, n ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_E, e ) ); - checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_D, d ) ); - RETVAL = NULL; if ( SvCUR(p_SV) > 0 ) { + checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_D, d ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, p ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_RSA_FACTOR, q ) ); checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); @@ -407,29 +428,31 @@ EVP_PKEY_new_RSA(SV *n_SV, SV *e_SV, SV *d_SV, SV *p_SV, SV *q_SV) #ifndef NO_ECDSA EVP_PKEY* -EVP_PKEY_new_ECDSA(int nid, SV *qx_SV, SV *qy_SV) +EVP_PKEY_new_ECDSA(SV *curve, SV *qx_SV, SV *qy_SV) INIT: - BIGNUM *qx = BN_bin2bn( (unsigned char*) SvPVX(qx_SV), SvCUR(qx_SV), NULL ); - BIGNUM *qy = BN_bin2bn( (unsigned char*) SvPVX(qy_SV), SvCUR(qy_SV), NULL ); -#ifdef OBSOLETE_API - EC_KEY *eckey = EC_KEY_new_by_curve_name(nid); +#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 = BN_bin2bn( (unsigned char*) SvPVX(qx_SV), SvCUR(qx_SV), NULL ); + BIGNUM *qy = BN_bin2bn( (unsigned char*) SvPVX(qy_SV), SvCUR(qy_SV), NULL ); CODE: -#ifdef OBSOLETE_API +#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, qy ) ); } else { checkerr( EC_KEY_set_private_key( eckey, qx ) ); } - RETVAL = EVP_PKEY_new(); checkerr( EVP_PKEY_assign( RETVAL, EVP_PKEY_EC, (char*)eckey ) ); #else - if ( nid == 415 ) checkerr( OSSL_PARAM_BLD_push_utf8_string( bld, OSSL_PKEY_PARAM_GROUP_NAME, "P-256", 0 ) ); - if ( nid == 715 ) checkerr( OSSL_PARAM_BLD_push_utf8_string( bld, OSSL_PKEY_PARAM_GROUP_NAME, "P-384", 0 ) ); RETVAL = NULL; + 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 ) ); checkerr( OSSL_PARAM_BLD_push_BN( bld, OSSL_PKEY_PARAM_EC_PUB_Y, qy ) ); @@ -454,39 +477,35 @@ EVP_PKEY_new_ECDSA(int nid, SV *qx_SV, SV *qy_SV) #ifndef NO_EdDSA EVP_PKEY* -EVP_PKEY_new_raw_public_key(int nid, SV *key) - CODE: -#define rawkey (unsigned char*) SvPVX(key) -#define keylen SvCUR(key) -#ifdef OBSOLETE_API - RETVAL = EVP_PKEY_new_raw_public_key( nid, NULL, rawkey , keylen ); +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 - EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); - RETVAL = NULL; - if ( nid == 1087 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED25519", NULL ); - if ( nid == 1088 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED448", NULL ); - checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PUB_KEY, rawkey, keylen ) ); - checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_PUBLIC_KEY, bld ) ); - OSSL_PARAM_BLD_free(bld); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name( libctx, SvPVX(curve), NULL ); #endif - OUTPUT: - RETVAL - -EVP_PKEY* -EVP_PKEY_new_raw_private_key(int nid, SV *key) CODE: -#ifdef OBSOLETE_API - RETVAL = EVP_PKEY_new_raw_private_key( nid, NULL, rawkey , keylen ); -#else - EVP_PKEY_CTX *ctx = NULL; - OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); RETVAL = NULL; - if ( nid == 1087 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED25519", NULL ); - if ( nid == 1088 ) ctx = EVP_PKEY_CTX_new_from_name( libctx, "ED448", NULL ); - checkerr( OSSL_PARAM_BLD_push_octet_string( bld, OSSL_PKEY_PARAM_PRIV_KEY, rawkey, keylen ) ); - checkerr( EVP_PKEY_fromparams( ctx, &RETVAL, EVP_PKEY_KEYPAIR, bld ) ); +#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 diff --git a/lib/Net/DNS/SEC.pm b/lib/Net/DNS/SEC.pm index 406162e..62882d4 100644 --- a/lib/Net/DNS/SEC.pm +++ b/lib/Net/DNS/SEC.pm @@ -4,9 +4,9 @@ use strict; use warnings; use Carp; -our $SVNVERSION = (qw$Id: SEC.pm 1882 2022-10-04 19:53:44Z willem $)[2]; +our $SVNVERSION = (qw$Id: SEC.pm 1939 2023-09-12 13:34:55Z willem $)[2]; our $VERSION; -$VERSION = '1.20'; +$VERSION = '1.22'; use base qw(Exporter DynaLoader); diff --git a/lib/Net/DNS/SEC/ECDSA.pm b/lib/Net/DNS/SEC/ECDSA.pm index b9c5d6c..f76251f 100644 --- a/lib/Net/DNS/SEC/ECDSA.pm +++ b/lib/Net/DNS/SEC/ECDSA.pm @@ -3,7 +3,7 @@ package Net::DNS::SEC::ECDSA; use strict; use warnings; -our $VERSION = (qw$Id: ECDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; +our $VERSION = (qw$Id: ECDSA.pm 1937 2023-09-11 09:27:16Z willem $)[2]; =head1 NAME @@ -50,8 +50,8 @@ BEGIN { die 'ECDSA disabled or application has no "use Net::DNS::SEC"' unless EC my %parameters = ( - 13 => [415, 32, Net::DNS::SEC::libcrypto::EVP_sha256()], - 14 => [715, 48, Net::DNS::SEC::libcrypto::EVP_sha384()], + 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 } @@ -61,11 +61,11 @@ sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; - my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; - die 'private key not ECDSA' unless $nid; + 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( $nid, $rawkey, '' ); + 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 ); @@ -76,13 +76,13 @@ sub verify { my ( $class, $sigdata, $keyrr, $sigbin ) = @_; my $algorithm = $keyrr->algorithm; - my ( $nid, $keylen, $evpmd ) = @{$parameters{$algorithm} || []}; - die 'public key not ECDSA' unless $nid; + 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( $nid, $x, $y ); + 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 ); diff --git a/lib/Net/DNS/SEC/EdDSA.pm b/lib/Net/DNS/SEC/EdDSA.pm index 8aee8e0..7262c77 100644 --- a/lib/Net/DNS/SEC/EdDSA.pm +++ b/lib/Net/DNS/SEC/EdDSA.pm @@ -3,7 +3,7 @@ package Net::DNS::SEC::EdDSA; use strict; use warnings; -our $VERSION = (qw$Id: EdDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2]; +our $VERSION = (qw$Id: EdDSA.pm 1937 2023-09-11 09:27:16Z willem $)[2]; =head1 NAME @@ -44,14 +44,14 @@ public key resource record. use integer; use MIME::Base64; -use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_public_key'); +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 => [1087, 32, 64], - 16 => [1088, 57, 114], + 15 => ['ED25519', 32, 64], + 16 => ['ED448', 57, 114], ); sub _index { return keys %parameters } @@ -61,11 +61,11 @@ sub sign { my ( $class, $sigdata, $private ) = @_; my $algorithm = $private->algorithm; - my ( $nid, $keylen ) = @{$parameters{$algorithm} || []}; - die 'private key not EdDSA' unless $nid; + 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_raw_private_key( $nid, $rawkey ); + my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_EdDSA( $curve, '', $rawkey ); return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey ); } @@ -75,19 +75,24 @@ sub verify { my ( $class, $sigdata, $keyrr, $signature ) = @_; my $algorithm = $keyrr->algorithm; - my ( $nid, $keylen, $siglen ) = @{$parameters{$algorithm} || []}; - die 'public key not EdDSA' unless $nid; + 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_raw_public_key( $nid, $rawkey ); + 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__ diff --git a/t/00-load.t b/t/00-load.t index fd40df8..5abf423 100644 --- a/t/00-load.t +++ b/t/00-load.t @@ -1,11 +1,12 @@ #!/usr/bin/perl -# $Id: 00-load.t 1872 2022-09-16 09:33:02Z willem $ -*-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 @@ -51,13 +52,8 @@ ok( eval { Net::DNS::SEC::libcrypto->VERSION }, 'XS component SEC.xs loaded' ) use_ok('Net::DNS::SEC'); -eval { - # Exercise checkerr() response to failed OpenSSL operation - Net::DNS::SEC::libcrypto::checkerr(0); -}; -my ($exception) = split /\n/, "$@\n"; -ok( $exception, "XS libcrypto error\t[$exception]" ); - +# Exercise checkerr() response to failed OpenSSL operation +exception( 'XS libcrypto error', sub { Net::DNS::SEC::libcrypto::checkerr(0) } ); exit; diff --git a/t/10-keyset.t b/t/10-keyset.t index 3bde253..c14258d 100644 --- a/t/10-keyset.t +++ b/t/10-keyset.t @@ -1,11 +1,12 @@ #!/usr/bin/perl -# $Id: 10-keyset.t 1868 2022-08-31 20:13:35Z willem $ -*-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, @@ -232,9 +233,7 @@ ok( Net::DNS::SEC::Keyset->new($packet)->verify(), "Verify keyset extracted from ok( Net::DNS::SEC::Keyset->new( [$keyrr2] )->verify(), "Verify keyset with no KSK" ); -eval { $keyset->writekeyset( File::Spec->rel2abs('nonexdir') ) }; -my ($exception) = split /\n/, "$@\n"; -ok( $exception, "unwritable file\t[$exception]" ); +exception( 'unwritable file', sub { $keyset->writekeyset( File::Spec->rel2abs('nonexdir') ) } ); # 0.17 backward compatibility (exercise code for test coverage only) diff --git a/t/21-RSA-MD5.t b/t/21-RSA-MD5.t index 85c17b2..881bd52 100644 --- a/t/21-RSA-MD5.t +++ b/t/21-RSA-MD5.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 21-RSA-MD5.t 1863 2022-03-14 14:59:21Z willem $ -*-perl-*- +# $Id: 21-RSA-MD5.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -74,7 +74,7 @@ my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/22-RSA-SHA1.t b/t/22-RSA-SHA1.t index 317d444..84c4582 100644 --- a/t/22-RSA-SHA1.t +++ b/t/22-RSA-SHA1.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 22-RSA-SHA1.t 1863 2022-03-14 14:59:21Z willem $ -*-perl-*- +# $Id: 22-RSA-SHA1.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -75,7 +75,7 @@ my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/23-RSA-SHA256.t b/t/23-RSA-SHA256.t index 13a5be6..cc0290d 100644 --- a/t/23-RSA-SHA256.t +++ b/t/23-RSA-SHA256.t @@ -1,11 +1,12 @@ #!/usr/bin/perl -# $Id: 23-RSA-SHA256.t 1863 2022-03-14 14:59:21Z willem $ -*-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, @@ -14,7 +15,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -71,7 +72,7 @@ my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); @@ -124,21 +125,13 @@ is( eval { $class->verify( $sigdata, $key, undef ) }, undef, 'verify fails if si # test detection of invalid private key descriptors -eval { Net::DNS::SEC::Private->new('Kinvalid.private') }; -my ($exception1) = split /\n/, "$@\n"; -ok( $exception1, "invalid keyfile: [$exception1]" ); +exception( 'invalid keyfile', sub { Net::DNS::SEC::Private->new('Kinvalid.private') } ); -eval { Net::DNS::SEC::Private->new('Kinvalid.+0+0.private') }; -my ($exception2) = split /\n/, "$@\n"; -ok( $exception2, "missing keyfile: [$exception2]" ); +exception( 'missing keyfile', sub { Net::DNS::SEC::Private->new('Kinvalid.+0+0.private') } ); -eval { Net::DNS::SEC::Private->new( signame => 'private' ) }; -my ($exception3) = split /\n/, "$@\n"; -ok( $exception3, "unspecified algorithm: [$exception3]" ); +exception( 'unspecified algorithm', sub { Net::DNS::SEC::Private->new( signame => 'private' ) } ); -eval { Net::DNS::SEC::Private->new( algorithm => 1 ) }; -my ($exception4) = split /\n/, "$@\n"; -ok( $exception4, "unspecified signame: [$exception4]" ); +exception( 'unspecified signame', sub { Net::DNS::SEC::Private->new( algorithm => 1 ) } ); # exercise code for key with long exponent (not required for DNSSEC) diff --git a/t/24-RSA-SHA512.t b/t/24-RSA-SHA512.t index 84a92d5..96de309 100644 --- a/t/24-RSA-SHA512.t +++ b/t/24-RSA-SHA512.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 24-RSA-SHA512.t 1862 2021-12-24 10:09:08Z willem $ -*-perl-*- +# $Id: 24-RSA-SHA512.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -74,7 +74,7 @@ my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up RSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/31-DSA-SHA1.t b/t/31-DSA-SHA1.t index bd49c72..90c3d6d 100644 --- a/t/31-DSA-SHA1.t +++ b/t/31-DSA-SHA1.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 31-DSA-SHA1.t 1863 2022-03-14 14:59:21Z willem $ -*-perl-*- +# $Id: 31-DSA-SHA1.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -107,7 +107,7 @@ my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-DSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/51-ECDSA-P256.t b/t/51-ECDSA-P256.t index 22504f1..14f89fc 100644 --- a/t/51-ECDSA-P256.t +++ b/t/51-ECDSA-P256.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 51-ECDSA-P256.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- +# $Id: 51-ECDSA-P256.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -98,7 +98,7 @@ my $wrongprivate = Net::DNS::SEC::Private->new($wrongfile); ok( $wrongprivate, 'set up non-ECDSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/52-ECDSA-P384.t b/t/52-ECDSA-P384.t index 8978370..0c19bb2 100644 --- a/t/52-ECDSA-P384.t +++ b/t/52-ECDSA-P384.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 52-ECDSA-P384.t 1830 2021-01-26 09:08:12Z willem $ -*-perl-*- +# $Id: 52-ECDSA-P384.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,7 +14,7 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } @@ -66,7 +66,7 @@ my $private = Net::DNS::SEC::Private->new($keyfile); ok( $private, 'set up ECDSA private key' ); -my $sigdata = 'arbitrary data'; +my $sigdata = Net::DNS::RR->new('. TXT arbitrary data')->txtdata; # character set independent my $corrupt = 'corrupted data'; my $signature = $class->sign( $sigdata, $private ); diff --git a/t/61-Ed25519.t b/t/61-Ed25519.t index 29d3dde..86f325b 100644 --- a/t/61-Ed25519.t +++ b/t/61-Ed25519.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 61-Ed25519.t 1868 2022-08-31 20:13:35Z willem $ -*-perl-*- +# $Id: 61-Ed25519.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,13 +14,13 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" - unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_private_key') }; + unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_EdDSA') }; plan tests => 13; diff --git a/t/62-Ed448.t b/t/62-Ed448.t index 6d47eb7..811253f 100644 --- a/t/62-Ed448.t +++ b/t/62-Ed448.t @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $Id: 62-Ed448.t 1868 2022-08-31 20:13:35Z willem $ -*-perl-*- +# $Id: 62-Ed448.t 1937 2023-09-11 09:27:16Z willem $ -*-perl-*- # use strict; @@ -14,13 +14,17 @@ my %prerequisite = ( foreach my $package ( sort keys %prerequisite ) { my @revision = grep {$_} $prerequisite{$package}; - next if eval "use $package @revision; 1;"; ## no critic + next if eval "use $package @revision; 1;"; ## no critic plan skip_all => "missing prerequisite $package @revision"; exit; } plan skip_all => "disabled EdDSA" - unless eval { Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_private_key') }; + 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; diff --git a/t/TestToolkit.pm b/t/TestToolkit.pm new file mode 100644 index 0000000..2c6d159 --- /dev/null +++ b/t/TestToolkit.pm @@ -0,0 +1,116 @@ +# $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__ + |