control: tags -1 patch
On 2016-06-26 12:22:30 [+0200], Kurt Roeckx wrote:
> There is a libssl-dev package available in experimental that contains a recent
> snapshot, I suggest you try building against that to see if everything works.
two patches attached. The testsuite passes.
Functions like set_p() need to query old q & g because with openssl
1.1.0 it is no longer possible to assign only one of them. That means
for the first assignment I have two dummy arguments which are later
overwritten. The better way would be to change the perl API to also
assign p, q and g at once. It also not possible to assign the private
key without the public key. Is this possible?
I needed to extend the length of the seed argument (in the testsuite)
for generate_parameters because 3 ("foo") is too small and openssl 1.1.0
no longer ignores this invalid argument.
> Kurt
Sebastian
>From 6efaaad1f6b5ed33b5079d2f116db8795a708d8c Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <[email protected]>
Date: Mon, 3 Oct 2016 12:32:38 +0000
Subject: [PATCH 1/2] libcrypt-openssl-dsa-perl: add openssl 1.1.0 support
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
DSA.xs | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 170 insertions(+), 15 deletions(-)
diff --git a/DSA.xs b/DSA.xs
index 00e6b270a9de..25810e539338 100755
--- a/DSA.xs
+++ b/DSA.xs
@@ -14,6 +14,95 @@ extern "C" {
#include <openssl/dsa.h>
#include <openssl/ssl.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static void DSA_get0_pqg(const DSA *d,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = d->p;
+ if (q != NULL)
+ *q = d->q;
+ if (g != NULL)
+ *g = d->g;
+}
+
+static int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p, q and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((d->p == NULL && p == NULL)
+ || (d->q == NULL && q == NULL)
+ || (d->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(d->p);
+ d->p = p;
+ }
+ if (q != NULL) {
+ BN_free(d->q);
+ d->q = q;
+ }
+ if (g != NULL) {
+ BN_free(d->g);
+ d->g = g;
+ }
+
+ return 1;
+}
+
+static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in d is NULL, the corresponding input
+ * * parameters MUST be non-NULL. The priv_key field may
+ * * be left NULL.
+ * */
+ if (d->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(d->pub_key);
+ d->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(d->priv_key);
+ d->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+static void DSA_get0_key(const DSA *d,
+ const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = d->pub_key;
+ if (priv_key != NULL)
+ *priv_key = d->priv_key;
+}
+
+static void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+static int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+#endif
+
#ifdef __cplusplus
}
#endif
@@ -52,9 +141,12 @@ generate_parameters(CLASS, bits, seed = NULL)
if (seed) {
seedpv = SvPV(seed, seed_len);
}
- dsa = DSA_generate_parameters(bits, seedpv, seed_len, NULL, NULL, NULL, NULL);
+
+ dsa = DSA_new();
if (!dsa)
croak("%s", ERR_reason_error_string(ERR_get_error()));
+ if (!DSA_generate_parameters_ex(dsa, bits, seedpv, seed_len, NULL, NULL, NULL))
+ croak("%s", ERR_reason_error_string(ERR_get_error()));
RETVAL = dsa;
OUTPUT:
RETVAL
@@ -259,9 +351,11 @@ get_p(dsa)
PREINIT:
char *to;
int len;
+ const BIGNUM *p;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa->p, to);
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ len = BN_bn2bin(p, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -273,9 +367,11 @@ get_q(dsa)
PREINIT:
char *to;
int len;
+ const BIGNUM *q;
CODE:
to = malloc(sizeof(char) * 20);
- len = BN_bn2bin(dsa->q, to);
+ DSA_get0_pqg(dsa, NULL, &q, NULL);
+ len = BN_bn2bin(q, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -287,9 +383,11 @@ get_g(dsa)
PREINIT:
char *to;
int len;
+ const BIGNUM *g;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa->g, to);
+ DSA_get0_pqg(dsa, NULL, NULL, &g);
+ len = BN_bn2bin(g, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -301,9 +399,11 @@ get_pub_key(dsa)
PREINIT:
char *to;
int len;
+ const BIGNUM *pub_key;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa->pub_key, to);
+ DSA_get0_key(dsa, &pub_key, NULL);
+ len = BN_bn2bin(pub_key, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -315,9 +415,11 @@ get_priv_key(dsa)
PREINIT:
char *to;
int len;
+ const BIGNUM *priv_key;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa->priv_key, to);
+ DSA_get0_key(dsa, NULL, &priv_key);
+ len = BN_bn2bin(priv_key, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -329,9 +431,17 @@ set_p(dsa, p_SV)
SV * p_SV
PREINIT:
int len;
+ const BIGNUM *old_q, *old_g;
+ BIGNUM *new_q = NULL, *new_g = NULL;
CODE:
+ DSA_get0_pqg(dsa, NULL, &old_q, &old_g);
+ if (!old_q)
+ new_q = BN_new();
+ if (!old_g)
+ new_g = BN_new();
len = SvCUR(p_SV);
- dsa->p = BN_bin2bn(SvPV(p_SV, len), len, NULL);
+ if (!DSA_set0_pqg(dsa, BN_bin2bn(SvPV(p_SV, len), len, NULL), new_q, new_g))
+ croak("DSA_set0_pqg() failed");
void
set_q(dsa, q_SV)
@@ -339,9 +449,17 @@ set_q(dsa, q_SV)
SV * q_SV
PREINIT:
int len;
+ const BIGNUM *old_p, *old_g;
+ BIGNUM *new_p = NULL, *new_g = NULL;
CODE:
+ DSA_get0_pqg(dsa, &old_p, NULL, &old_g);
+ if (!old_p)
+ new_p = BN_new();
+ if (!old_g)
+ new_g = BN_new();
len = SvCUR(q_SV);
- dsa->q = BN_bin2bn(SvPV(q_SV, len), len, NULL);
+ if (!DSA_set0_pqg(dsa, new_p, BN_bin2bn(SvPV(q_SV, len), len, NULL), new_g))
+ croak("DSA_set0_pqg() failed");
void
set_g(dsa, g_SV)
@@ -349,9 +467,17 @@ set_g(dsa, g_SV)
SV * g_SV
PREINIT:
int len;
+ const BIGNUM *old_p, *old_q;
+ BIGNUM *new_p = NULL, *new_q = NULL;
CODE:
+ DSA_get0_pqg(dsa, &old_p, &old_q, NULL);
+ if (!old_p)
+ new_p = BN_new();
+ if (!old_q)
+ new_q = BN_new();
len = SvCUR(g_SV);
- dsa->g = BN_bin2bn(SvPV(g_SV, len), len, NULL);
+ if (!DSA_set0_pqg(dsa, new_p, new_q, BN_bin2bn(SvPV(g_SV, len), len, NULL)))
+ croak("DSA_set0_pqg() failed");
void
set_pub_key(dsa, pub_key_SV)
@@ -361,7 +487,8 @@ set_pub_key(dsa, pub_key_SV)
int len;
CODE:
len = SvCUR(pub_key_SV);
- dsa->pub_key = BN_bin2bn(SvPV(pub_key_SV, len), len, NULL);
+ if (!DSA_set0_key(dsa, BN_bin2bn(SvPV(pub_key_SV, len), len, NULL), NULL))
+ croak("DSA_set0_key() failed");
void
set_priv_key(dsa, priv_key_SV)
@@ -369,9 +496,16 @@ set_priv_key(dsa, priv_key_SV)
SV * priv_key_SV
PREINIT:
int len;
+ const BIGNUM *old_pub;
+ BIGNUM *new_pub = NULL;
CODE:
len = SvCUR(priv_key_SV);
- dsa->priv_key = BN_bin2bn(SvPV(priv_key_SV, len), len, NULL);
+ DSA_get0_key(dsa, &old_pub, NULL);
+ if (!old_pub)
+ new_pub = BN_new();
+
+ if (!DSA_set0_key(dsa, new_pub, BN_bin2bn(SvPV(priv_key_SV, len), len, NULL)))
+ croak("DSA_set0_key() failed");
MODULE = Crypt::OpenSSL::DSA PACKAGE = Crypt::OpenSSL::DSA::Signature
@@ -395,9 +529,11 @@ get_r(dsa_sig)
PREINIT:
char *to;
int len;
+ const BIGNUM *r;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa_sig->r, to);
+ DSA_SIG_get0(dsa_sig, &r, NULL);
+ len = BN_bn2bin(r, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -409,9 +545,11 @@ get_s(dsa_sig)
PREINIT:
char *to;
int len;
+ const BIGNUM *s;
CODE:
to = malloc(sizeof(char) * 128);
- len = BN_bn2bin(dsa_sig->s, to);
+ DSA_SIG_get0(dsa_sig, NULL, &s);
+ len = BN_bn2bin(s, to);
RETVAL = newSVpvn(to, len);
free(to);
OUTPUT:
@@ -423,9 +561,17 @@ set_r(dsa_sig, r_SV)
SV * r_SV
PREINIT:
int len;
+ const BIGNUM *old_s;
+ BIGNUM *new_s;
CODE:
+ DSA_SIG_get0(dsa_sig, NULL, &old_s);
+ if (old_s)
+ new_s = BN_dup(old_s);
+ else
+ new_s = BN_new();
len = SvCUR(r_SV);
- dsa_sig->r = BN_bin2bn(SvPV(r_SV, len), len, NULL);
+ if (!DSA_SIG_set0(dsa_sig, BN_bin2bn(SvPV(r_SV, len), len, NULL), new_s))
+ croak("DSA_SIG_set0() failed");
void
set_s(dsa_sig, s_SV)
@@ -433,6 +579,15 @@ set_s(dsa_sig, s_SV)
SV * s_SV
PREINIT:
int len;
+ const BIGNUM *old_r;
+ BIGNUM *new_r;
CODE:
+ DSA_SIG_get0(dsa_sig, &old_r, NULL);
+ if (old_r)
+ new_r = BN_dup(old_r);
+ else
+ new_r = BN_new();
+
len = SvCUR(s_SV);
- dsa_sig->s = BN_bin2bn(SvPV(s_SV, len), len, NULL);
+ if (!DSA_SIG_set0(dsa_sig, new_r, BN_bin2bn(SvPV(s_SV, len), len, NULL)))
+ croak("DSA_SIG_set0() failed");
--
2.9.3
>From ea1e9a9a4adf5d8510004cf1acba203db6bc13a1 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <[email protected]>
Date: Mon, 3 Oct 2016 16:11:00 +0000
Subject: [PATCH 2/2] test: increase seed
As of openssl 1.1.0 a too small seed is no longer ignored. from the
manpage:
|bits is the length of the prime p to be generated. For lengths under 2048
|bits, the length of q is 160 bits; for lengths greater than or equal to 2048
|bits, the length of q is set to 256 bits.
|
|If seed is NULL, the primes will be generated at random. If seed_len is
|less than the length of q, an error is returned.
The testsuite is adjusted.
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
t/10-selftest.t | 2 +-
t/90-openssl-compat.t | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/10-selftest.t b/t/10-selftest.t
index 54b517a04568..1435cc8797d0 100755
--- a/t/10-selftest.t
+++ b/t/10-selftest.t
@@ -9,7 +9,7 @@ BEGIN { plan tests => 30 }
my $message = "foo bar";
-my $dsa = Crypt::OpenSSL::DSA->generate_parameters( 512, "foo" );
+my $dsa = Crypt::OpenSSL::DSA->generate_parameters( 512, "foofoofoofoofoofoofo");
$dsa->generate_key;
diff --git a/t/90-openssl-compat.t b/t/90-openssl-compat.t
index eba43fe1a9f8..6347710a3d9d 100755
--- a/t/90-openssl-compat.t
+++ b/t/90-openssl-compat.t
@@ -25,7 +25,7 @@ else {
}
my $why_skip = $HAS_SHA1 ? "Need openssl binary in path" : "Need Digest::SHA to test";
-my $dsa = Crypt::OpenSSL::DSA->generate_parameters( 512, "foo" );
+my $dsa = Crypt::OpenSSL::DSA->generate_parameters( 512, "foofoofoofoofoofoofo" );
$dsa->generate_key;
ok($dsa->write_pub_key("dsa.pub.pem"), 1);
--
2.9.3