summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2023-09-30 00:27:03 +0200
committergregor herrmann <gregoa@debian.org>2023-09-30 00:27:03 +0200
commit7bbbdd9ee084a86528f1f7c50dedb0dfde3aebd2 (patch)
tree918523bbdeb7aae34425f0bdc020af1024e806cb
parentf68147a2413be08a4a77f30409092cbeb483068d (diff)
New upstream version 1.22
-rw-r--r--Changes22
-rw-r--r--MANIFEST1
-rw-r--r--META.json4
-rw-r--r--META.yml4
-rw-r--r--Makefile.PL60
-rw-r--r--SEC.xs181
-rw-r--r--lib/Net/DNS/SEC.pm4
-rw-r--r--lib/Net/DNS/SEC/ECDSA.pm18
-rw-r--r--lib/Net/DNS/SEC/EdDSA.pm25
-rw-r--r--t/00-load.t12
-rw-r--r--t/10-keyset.t7
-rw-r--r--t/21-RSA-MD5.t6
-rw-r--r--t/22-RSA-SHA1.t6
-rw-r--r--t/23-RSA-SHA256.t23
-rw-r--r--t/24-RSA-SHA512.t6
-rw-r--r--t/31-DSA-SHA1.t6
-rw-r--r--t/51-ECDSA-P256.t6
-rw-r--r--t/52-ECDSA-P384.t6
-rw-r--r--t/61-Ed25519.t6
-rw-r--r--t/62-Ed448.t10
-rw-r--r--t/TestToolkit.pm116
21 files changed, 341 insertions, 188 deletions
diff --git a/Changes b/Changes
index 51b49a2..2efe084 100644
--- a/Changes
+++ b/Changes
@@ -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 $
diff --git a/MANIFEST b/MANIFEST
index c708eec..4f7089c 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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)
diff --git a/META.json b/META.json
index 61e910e..d6ff3a4 100644
--- a/META.json
+++ b/META.json
@@ -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"
}
diff --git a/META.yml b/META.yml
index 8a9d4d9..22d778e 100644
--- a/META.yml
+++ b/META.yml
@@ -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
}
diff --git a/SEC.xs b/SEC.xs
index 2c93ad4..a60bc8f 100644
--- a/SEC.xs
+++ b/SEC.xs
@@ -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__
+