Commit 3994b1f9 authored by Ondřej Surý's avatar Ondřej Surý

Remove support for obsoleted and insecure DSA and DSA-NSEC3-SHA1 algorithms

parent 6aadf7c8
......@@ -299,8 +299,7 @@
Takes two arguments: keytype (eihter "zsk" or "ksk") and size.
A default value for this option can be set in algorithm policies
as well as in policy classes or zone policies. If no policy is
configured, the default is 1024 bits for DSA keys and 2048 for
RSA.
configured, the default is 2048 bits for RSA keys.
</para>
</listitem>
</varlistentry>
......
......@@ -30,8 +30,8 @@ class dnskey:
'Revoke', 'DSPublish', 'SyncPublish', 'SyncDelete')
_OPTS = (None, '-P', '-A', '-I', '-D', '-R', None, '-Psync', '-Dsync')
_ALGNAMES = (None, 'RSAMD5', 'DH', 'DSA', 'ECC', 'RSASHA1',
'NSEC3DSA', 'NSEC3RSASHA1', 'RSASHA256', None,
_ALGNAMES = (None, 'RSAMD5', None, 'DSA', 'ECC', 'RSASHA1',
None, 'NSEC3RSASHA1', 'RSASHA256', None,
'RSASHA512', None, None, 'ECDSAP256SHA256',
'ECDSAP384SHA384', 'ED25519', 'ED448')
......
......@@ -71,7 +71,7 @@ class PolicyLex:
return t
def t_ALGNAME(self, t):
r'(?i)\b(RSAMD5|DH|DSA|NSEC3DSA|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b'
r'(?i)\b(RSAMD5|DH|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b'
t.value = t.value.upper()
return t
......@@ -132,9 +132,7 @@ class Policy:
keyttl = None
coverage = None
directory = None
valid_key_sz_per_algo = {'DSA': [512, 1024],
'NSEC3DSA': [512, 1024],
'RSAMD5': [1024, 4096],
valid_key_sz_per_algo = {'RSAMD5': [1024, 4096],
'RSASHA1': [1024, 4096],
'NSEC3RSASHA1': [512, 4096],
'RSASHA256': [1024, 4096],
......@@ -264,19 +262,6 @@ class Policy:
return False, 'ZSK key size %d outside valid range %s' \
% (self.zsk_keysize, key_sz_range)
# Specific check for DSA keys
if self.algorithm in ['DSA', 'NSEC3DSA'] and \
self.ksk_keysize % 64 != 0:
return False, \
('KSK key size %d not divisible by 64 ' +
'as required for DSA') % self.ksk_keysize
if self.algorithm in ['DSA', 'NSEC3DSA'] and \
self.zsk_keysize % 64 != 0:
return False, \
('ZSK key size %d not divisible by 64 ' +
'as required for DSA') % self.zsk_keysize
if self.algorithm in ['ECDSAP256SHA256', \
'ECDSAP384SHA384', \
'ED25519', \
......@@ -335,16 +320,6 @@ class dnssec_policy:
p.zsk_keysize = 2048;
# set default algorithm policies
# these need a lower default key size:
self.alg_policy['DSA'] = copy(p)
self.alg_policy['DSA'].algorithm = "DSA"
self.alg_policy['DSA'].name = "DSA"
self.alg_policy['DSA'].ksk_keysize = 1024;
self.alg_policy['NSEC3DSA'] = copy(p)
self.alg_policy['NSEC3DSA'].algorithm = "NSEC3DSA"
self.alg_policy['NSEC3DSA'].name = "NSEC3DSA"
self.alg_policy['NSEC3DSA'].ksk_keysize = 1024;
# these can use default settings
self.alg_policy['RSAMD5'] = copy(p)
......
......@@ -25,15 +25,6 @@ class PolicyTest(unittest.TestCase):
self.assertEqual(p.constructed(), False)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('good_dsa.test', novalidate=True)
self.assertEqual(p.get_name(), "good_dsa.test")
self.assertEqual(p.constructed(), False)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('bad_dsa.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'ZSK key size 769 not divisible by 64 as required for DSA'))
def test_prepublish(self):
pol = policy.dnssec_policy()
pol.load('test-policies/02-prepublish.pol')
......
......@@ -3137,12 +3137,8 @@ do
2) # Diffie Helman
alg=`expr $alg + 1`
continue;;
3) # DSA/SHA1
size="-b 512";;
5) # RSA/SHA-1
size="-b 1024";;
6) # DSA-NSEC3-SHA1
size="-b 512";;
7) # RSASHA1-NSEC3-SHA1
size="-b 1024";;
8) # RSA/SHA-256
......
......@@ -118,7 +118,7 @@ rm -f ns3/test-?.bk
rm -f ns3/test-?.bk.signed
rm -f ns3/test-?.bk.signed.jnl
rm -f import.key Kimport*
rm -f checkdsa checkecdsa
rm -f checkecdsa
rm -f ns3/a-file
rm -f ns*/named.lock
rm -f dig.out.*
......
......@@ -133,7 +133,7 @@ zone=externalkey
rm -f K${zone}.+*+*.key
rm -f K${zone}.+*+*.private
for alg in ECDSAP256SHA256 NSEC3RSASHA1 DSA
for alg in ECDSAP256SHA256 NSEC3RSASHA1
do
k1=`$KEYGEN -q -a $alg -b 1024 -n zone -f KSK $zone`
k2=`$KEYGEN -q -a $alg -b 1024 -n zone $zone`
......
......@@ -945,13 +945,11 @@ n=`expr $n + 1`
echo_i "testing adding external keys to a inline zone ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.3 dnskey externalkey > dig.out.ns3.test$n
for alg in 3 7 13
for alg in 7 13
do
[ $alg = 3 -a ! -f checkdsa ] && continue;
[ $alg = 13 -a ! -f checkecdsa ] && continue;
case $alg in
3) echo_i "checking DSA";;
7) echo_i "checking NSEC3RSASHA1";;
13) echo_i "checking ECDSAP256SHA256";;
*) echo_i "checking $alg";;
......
......@@ -44,9 +44,9 @@ LIBS = @LIBS@
DSTOBJS = @DST_EXTRA_OBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ \
openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
openssl_link.@O@ openssldh_link.@O@ \
opensslecdsa_link.@O@ openssleddsa_link.@O@ opensslrsa_link.@O@ \
pkcs11dsa_link.@O@ pkcs11rsa_link.@O@ \
pkcs11rsa_link.@O@ \
pkcs11ecdsa_link.@O@ pkcs11eddsa_link.@O@ pkcs11.@O@ \
key.@O@
......@@ -82,9 +82,9 @@ OBJS= @DNSTAPOBJS@ ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} \
DSTSRCS = @DST_EXTRA_SRCS@ @PKCS11LINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
dst_result.c gssapi_link.c gssapictx.c hmac_link.c \
openssl_link.c openssldh_link.c openssldsa_link.c \
openssl_link.c openssldh_link.c \
opensslecdsa_link.c openssleddsa_link.c opensslrsa_link.c \
pkcs11dsa_link.c pkcs11rsa_link.c \
pkcs11rsa_link.c \
pkcs11ecdsa_link.c pkcs11eddsa_link.c pkcs11.c \
key.c
......
......@@ -190,8 +190,6 @@ dst_lib_init(isc_mem_t *mctx, const char *engine) {
DST_ALG_RSASHA256));
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512],
DST_ALG_RSASHA512));
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA]));
RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256]));
RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384]));
#ifdef HAVE_OPENSSL_ED25519
......@@ -209,8 +207,6 @@ dst_lib_init(isc_mem_t *mctx, const char *engine) {
RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1]));
RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256]));
RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512]));
RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA]));
RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA]));
RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA256]));
RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA384]));
#ifdef HAVE_PKCS11_ED25519
......@@ -1190,10 +1186,6 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_RSASHA512:
*n = (key->key_size + 7) / 8;
break;
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
*n = DNS_SIG_DSASIGSIZE;
break;
case DST_ALG_ECDSA256:
*n = DNS_SIG_ECDSA256SIZE;
break;
......@@ -1522,8 +1514,6 @@ issymmetric(const dst_key_t *key) {
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
case DST_ALG_DH:
case DST_ALG_ECDSA256:
case DST_ALG_ECDSA384:
......
......@@ -53,7 +53,6 @@
#include <dst/dst.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
......@@ -109,7 +108,6 @@ struct dst_key {
union {
void *generic;
gss_ctx_id_t gssctx;
DSA *dsa;
DH *dh;
#if USE_OPENSSL
EVP_PKEY *pkey;
......@@ -229,7 +227,6 @@ isc_result_t dst__openssldh_init(struct dst_func **funcp);
#if USE_OPENSSL
isc_result_t dst__opensslrsa_init(struct dst_func **funcp,
unsigned char algorithm);
isc_result_t dst__openssldsa_init(struct dst_func **funcp);
isc_result_t dst__opensslecdsa_init(struct dst_func **funcp);
#if HAVE_OPENSSL_ED25519 || HAVE_OPENSSL_ED448
isc_result_t dst__openssleddsa_init(struct dst_func **funcp);
......
......@@ -96,12 +96,6 @@ static struct parse_map map[] = {
{TAG_DH_PRIVATE, "Private_value(x):"},
{TAG_DH_PUBLIC, "Public_value(y):"},
{TAG_DSA_PRIME, "Prime(p):"},
{TAG_DSA_SUBPRIME, "Subprime(q):"},
{TAG_DSA_BASE, "Base(g):"},
{TAG_DSA_PRIVATE, "Private_value(x):"},
{TAG_DSA_PUBLIC, "Public_value(y):"},
{TAG_ECDSA_PRIVATEKEY, "PrivateKey:"},
{TAG_ECDSA_ENGINE, "Engine:" },
{TAG_ECDSA_LABEL, "Label:" },
......@@ -232,26 +226,6 @@ check_dh(const dst_private_t *priv) {
return (0);
}
static int
check_dsa(const dst_private_t *priv, bool external) {
int i, j;
if (external)
return ((priv->nelements == 0)? 0 : -1);
if (priv->nelements != DSA_NTAGS)
return (-1);
for (i = 0; i < DSA_NTAGS; i++) {
for (j = 0; j < priv->nelements; j++)
if (priv->elements[j].tag == TAG(DST_ALG_DSA, i))
break;
if (j == priv->nelements)
return (-1);
}
return (0);
}
static int
check_ecdsa(const dst_private_t *priv, bool external) {
int i, j;
......@@ -370,9 +344,6 @@ check_data(const dst_private_t *priv, const unsigned int alg,
return (check_rsa(priv, external));
case DST_ALG_DH:
return (check_dh(priv));
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
return (check_dsa(priv, external));
case DST_ALG_ECDSA256:
case DST_ALG_ECDSA384:
return (check_ecdsa(priv, external));
......@@ -696,18 +667,12 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_DH:
fprintf(fp, "(DH)\n");
break;
case DST_ALG_DSA:
fprintf(fp, "(DSA)\n");
break;
case DST_ALG_RSASHA1:
fprintf(fp, "(RSASHA1)\n");
break;
case DST_ALG_NSEC3RSASHA1:
fprintf(fp, "(NSEC3RSASHA1)\n");
break;
case DST_ALG_NSEC3DSA:
fprintf(fp, "(NSEC3DSA)\n");
break;
case DST_ALG_RSASHA256:
fprintf(fp, "(RSASHA256)\n");
break;
......
/*
* Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*
* Portions Copyright (C) Network Associates, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*! \file */
#include <config.h>
#if !USE_PKCS11
#include <pk11/site.h>
#include <stdbool.h>
#include <string.h>
#include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/random.h>
#include <isc/safe.h>
#include <isc/sha1.h>
#include <isc/util.h>
#include <dst/result.h>
#include "dst_internal.h"
#include "dst_openssl.h"
#include "dst_parse.h"
#include <openssl/dsa.h>
static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data);
#if !HAVE_DSA_GET0_PQG
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 (p == NULL || q == NULL || g == NULL)
return 0;
BN_free(d->p);
BN_free(d->q);
BN_free(d->g);
d->p = p;
d->q = q;
d->g = g;
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 int
DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) {
/* Note that it is valid for priv_key to be NULL */
if (pub_key == NULL)
return 0;
BN_free(d->pub_key);
BN_free(d->priv_key);
d->pub_key = pub_key;
d->priv_key = priv_key;
return 1;
}
static void
DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {
*pr = sig->r;
*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;
}
#define DSA_clear_flags(d, x) (d)->flags &= ~(x)
#endif /* !HAVE_DSA_GET0_PQG */
static isc_result_t
openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
EVP_MD_CTX *evp_md_ctx;
UNUSED(key);
evp_md_ctx = EVP_MD_CTX_create();
if (evp_md_ctx == NULL)
return (ISC_R_NOMEMORY);
if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
EVP_MD_CTX_destroy(evp_md_ctx);
return (ISC_R_FAILURE);
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
return (ISC_R_SUCCESS);
}
static void
openssldsa_destroyctx(dst_context_t *dctx) {
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
if (evp_md_ctx != NULL) {
EVP_MD_CTX_destroy(evp_md_ctx);
dctx->ctxdata.evp_md_ctx = NULL;
}
}
static isc_result_t
openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
static int
BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) {
int bytes = size - BN_num_bytes(bn);
while (bytes-- > 0)
*buf++ = 0;
BN_bn2bin(bn, buf);
return (size);
}
static isc_result_t
openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
dst_key_t *key = dctx->key;
DSA *dsa = key->keydata.dsa;
isc_region_t region;
DSA_SIG *dsasig;
const BIGNUM *r = 0, *s = NULL;
unsigned int klen;
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
EVP_PKEY *pkey;
unsigned char *sigbuf;
const unsigned char *sb;
unsigned int siglen;
isc_buffer_availableregion(sig, &region);
if (region.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
return (ISC_R_NOSPACE);
pkey = EVP_PKEY_new();
if (pkey == NULL)
return (ISC_R_NOMEMORY);
if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
EVP_PKEY_free(pkey);
return (ISC_R_FAILURE);
}
sigbuf = malloc(EVP_PKEY_size(pkey));
if (sigbuf == NULL) {
EVP_PKEY_free(pkey);
return (ISC_R_NOMEMORY);
}
if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
EVP_PKEY_free(pkey);
free(sigbuf);
return (dst__openssl_toresult3(dctx->category,
"EVP_SignFinal",
ISC_R_FAILURE));
}
INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
EVP_PKEY_free(pkey);
/* Convert from Dss-Sig-Value (RFC2459). */
dsasig = DSA_SIG_new();
if (dsasig == NULL) {
free(sigbuf);
return (ISC_R_NOMEMORY);
}
sb = sigbuf;
if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
free(sigbuf);
return (dst__openssl_toresult3(dctx->category,
"d2i_DSA_SIG",
ISC_R_FAILURE));
}
free(sigbuf);
klen = (key->key_size - 512)/64;
if (klen > 255)
return (ISC_R_FAILURE);
*region.base = klen;
isc_region_consume(&region, 1);
DSA_SIG_get0(dsasig, &r, &s);
BN_bn2bin_fixed(r, region.base, ISC_SHA1_DIGESTLENGTH);
isc_region_consume(&region, ISC_SHA1_DIGESTLENGTH);
BN_bn2bin_fixed(s, region.base, ISC_SHA1_DIGESTLENGTH);
isc_region_consume(&region, ISC_SHA1_DIGESTLENGTH);
DSA_SIG_free(dsasig);
isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
return (ISC_R_SUCCESS);
}
static isc_result_t
openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dst_key_t *key = dctx->key;
DSA *dsa = key->keydata.dsa;
BIGNUM *r = NULL, *s = NULL;
int status = 0;
unsigned char *cp = sig->base;
DSA_SIG *dsasig;
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
unsigned int siglen;
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
/* Only use EVP for the digest */
if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
return (ISC_R_FAILURE);
}
if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) {
return (DST_R_VERIFYFAILURE);
}
cp++; /*%< Skip T */
dsasig = DSA_SIG_new();
if (dsasig == NULL)
return (ISC_R_NOMEMORY);
r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
cp += ISC_SHA1_DIGESTLENGTH;
s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
DSA_SIG_set0(dsasig, r, s);
status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
DSA_SIG_free(dsasig);
switch (status) {
case 1:
return (ISC_R_SUCCESS);
case 0:
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
default:
return (dst__openssl_toresult3(dctx->category,
"DSA_do_verify",
DST_R_VERIFYFAILURE));
}
}
static bool
openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
DSA *dsa1, *dsa2;
const BIGNUM *pub_key1 = NULL, *priv_key1 = NULL;
const BIGNUM *pub_key2 = NULL, *priv_key2 = NULL;
const BIGNUM *p1 = NULL, *q1 = NULL, *g1 = NULL;
const BIGNUM *p2 = NULL, *q2 = NULL, *g2 = NULL;
dsa1 = key1->keydata.dsa;
dsa2 = key2->keydata.dsa;
if (dsa1 == NULL && dsa2 == NULL)
return (true);
else if (dsa1 == NULL || dsa2 == NULL)
return (false);
DSA_get0_key(dsa1, &pub_key1, &priv_key1);
DSA_get0_key(dsa2, &pub_key2, &priv_key2);
DSA_get0_pqg(dsa1, &p1, &q1, &g1);
DSA_get0_pqg(dsa2, &p2, &q2, &g2);
if (BN_cmp(p1, p2) != 0 || BN_cmp(q1, q2) != 0 ||
BN_cmp(g1, g2) != 0 || BN_cmp(pub_key1, pub_key2) != 0)
return (false);
if (priv_key1 != NULL || priv_key2 != NULL) {
if (priv_key1 == NULL || priv_key2 == NULL)
return (false);
if (BN_cmp(priv_key1, priv_key2))
return (false);
}
return (true);
}