Make the DSA structure opaque
authorMatt Caswell <matt@openssl.org>
Wed, 30 Mar 2016 14:21:39 +0000 (15:21 +0100)
committerMatt Caswell <matt@openssl.org>
Sat, 2 Apr 2016 23:23:56 +0000 (00:23 +0100)
Move the dsa_st structure out of the public header file. Add some accessor
functions to enable access to the internal fields, and update all internal
usage to use the new functions.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Stephen Henson <steve@openssl.org>
16 files changed:
apps/dsa.c
apps/dsaparam.c
apps/gendsa.c
apps/testdsa.h
apps/x509.c
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_asn1.c
crypto/dsa/dsa_key.c
crypto/dsa/dsa_lib.c
crypto/dsa/dsa_locl.h
crypto/dsa/dsa_ossl.c
crypto/dsa/dsa_sign.c
crypto/dsa/dsa_vrf.c
crypto/pem/pvkfmt.c
include/openssl/dsa.h
test/dsatest.c

index ed5bf01..9038e3b 100644 (file)
@@ -244,7 +244,7 @@ int dsa_main(int argc, char **argv)
 
     if (modulus) {
         BIO_printf(out, "Public Key=");
-        BN_print(out, dsa->pub_key);
+        BN_print(out, DSA_get0_pub_key(dsa));
         BIO_printf(out, "\n");
     }
 
index 7b9ca63..5b0bb62 100644 (file)
@@ -263,14 +263,14 @@ int dsaparam_main(int argc, char **argv)
     }
 
     if (C) {
-        int len = BN_num_bytes(dsa->p);
-        int bits_p = BN_num_bits(dsa->p);
+        int len = BN_num_bytes(DSA_get0_p(dsa));
+        int bits_p = BN_num_bits(DSA_get0_p(dsa));
         unsigned char *data = app_malloc(len + 20, "BN space");
 
         BIO_printf(bio_out, "DSA *get_dsa%d()\n{\n", bits_p);
-        print_bignum_var(bio_out, dsa->p, "dsap", len, data);
-        print_bignum_var(bio_out, dsa->q, "dsaq", len, data);
-        print_bignum_var(bio_out, dsa->g, "dsag", len, data);
+        print_bignum_var(bio_out, DSA_get0_p(dsa), "dsap", len, data);
+        print_bignum_var(bio_out, DSA_get0_q(dsa), "dsaq", len, data);
+        print_bignum_var(bio_out, DSA_get0_g(dsa), "dsag", len, data);
         BIO_printf(bio_out, "    DSA *dsa = DSA_new();\n"
                             "\n");
         BIO_printf(bio_out, "    if (dsa == NULL)\n"
index 6769968..bf01f56 100644 (file)
@@ -168,7 +168,7 @@ int gendsa_main(int argc, char **argv)
         BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                    app_RAND_load_files(inrand));
 
-    BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(dsa->p));
+    BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(DSA_get0_p(dsa)));
     if (!DSA_generate_key(dsa))
         goto end;
 
index 4eb13d1..6519948 100644 (file)
@@ -92,18 +92,35 @@ static unsigned char dsa512_g[] = {
 DSA *get_dsa512()
 {
     DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
 
     if ((dsa = DSA_new()) == NULL)
         return (NULL);
-    dsa->priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
-    dsa->pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
-    dsa->p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
-    dsa->q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
-    dsa->g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
-    if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL)
-        || (dsa->q == NULL) || (dsa->g == NULL))
-        return (NULL);
-    return (dsa);
+    priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
+    pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
+    p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
+    q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
+    g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
 }
 
 static unsigned char dsa1024_priv[] = {
@@ -161,18 +178,35 @@ static unsigned char dsa1024_g[] = {
 DSA *get_dsa1024()
 {
     DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
 
     if ((dsa = DSA_new()) == NULL)
         return (NULL);
-    dsa->priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
-    dsa->pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
-    dsa->p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
-    dsa->q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
-    dsa->g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
-    if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL)
-        || (dsa->q == NULL) || (dsa->g == NULL))
-        return (NULL);
-    return (dsa);
+    priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
+    pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
+    p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
+    q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
+    g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
 }
 
 static unsigned char dsa2048_priv[] = {
@@ -263,18 +297,35 @@ static unsigned char dsa2048_g[] = {
 DSA *get_dsa2048()
 {
     DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
 
     if ((dsa = DSA_new()) == NULL)
         return (NULL);
-    dsa->priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
-    dsa->pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
-    dsa->p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
-    dsa->q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
-    dsa->g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
-    if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL)
-        || (dsa->q == NULL) || (dsa->g == NULL))
-        return (NULL);
-    return (dsa);
+    priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
+    pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
+    p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
+    q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
+    g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
 }
 
 static const char rnd_seed[] =
index 66dd2ff..4319d69 100644 (file)
@@ -735,7 +735,7 @@ int x509_main(int argc, char **argv)
 #endif
 #ifndef OPENSSL_NO_DSA
                 if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA)
-                    BN_print(out, EVP_PKEY_get0_DSA(pkey)->pub_key);
+                    BN_print(out, DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey)));
                 else
 #endif
                     BIO_printf(out, "Wrong Algorithm type");
index f0f28bd..54cdb3d 100644 (file)
@@ -60,7 +60,7 @@
 #include "internal/cryptlib.h"
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/bn.h>
 #include <openssl/cms.h>
 #include "internal/asn1_int.h"
index c338b5f..1468fb1 100644 (file)
@@ -58,7 +58,7 @@
 
 #include <stdio.h>
 #include "internal/cryptlib.h"
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #include <openssl/rand.h>
index 831c2b1..4415884 100644 (file)
@@ -59,7 +59,7 @@
 #include <time.h>
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/rand.h>
 
 static int dsa_builtin_keygen(DSA *dsa);
index fa8330f..0822618 100644 (file)
@@ -60,7 +60,7 @@
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/asn1.h>
 #include <openssl/engine.h>
 #include <openssl/dh.h>
@@ -280,3 +280,76 @@ DH *DSA_dup_DH(const DSA *r)
     return NULL;
 }
 #endif
+
+BIGNUM *DSA_get0_p(const DSA *d)
+{
+    return d->p;
+}
+
+BIGNUM *DSA_get0_q(const DSA *d)
+{
+    return d->q;
+}
+
+BIGNUM *DSA_get0_g(const DSA *d)
+{
+    return d->g;
+}
+
+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;
+}
+
+BIGNUM *DSA_get0_priv_key(const DSA *d)
+{
+    return d->priv_key;
+}
+
+BIGNUM *DSA_get0_pub_key(const DSA *d)
+{
+    return d->pub_key;
+}
+
+void 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;
+}
+
+void DSA_clear_flags(DSA *d, int flags)
+{
+    d->flags &= ~flags;
+}
+
+int DSA_test_flags(const DSA *d, int flags)
+{
+    return d->flags & flags;
+}
+
+void DSA_set_flags(DSA *d, int flags)
+{
+    d->flags |= flags;
+}
+
+ENGINE *DSA_get0_engine(DSA *d)
+{
+    return d->engine;
+}
index 6182495..9b25634 100644 (file)
 
 #include <openssl/dsa.h>
 
+struct dsa_st {
+    /*
+     * This first variable is used to pick up errors where a DSA is passed
+     * instead of of a EVP_PKEY
+     */
+    int pad;
+    long version;
+    BIGNUM *p;
+    BIGNUM *q;                  /* == 20 */
+    BIGNUM *g;
+    BIGNUM *pub_key;            /* y public key */
+    BIGNUM *priv_key;           /* x private key */
+    int flags;
+    /* Normally used to cache montgomery values */
+    BN_MONT_CTX *method_mont_p;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    const DSA_METHOD *meth;
+    /* functional reference if 'meth' is ENGINE-provided */
+    ENGINE *engine;
+    CRYPTO_RWLOCK *lock;
+};
+
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                          const EVP_MD *evpmd, const unsigned char *seed_in,
                          size_t seed_len, unsigned char *seed_out,
index 31a6d53..9285553 100644 (file)
@@ -61,7 +61,7 @@
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
 #include <openssl/sha.h>
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
 
index ca712cf..b9dcd5b 100644 (file)
@@ -58,7 +58,7 @@
 /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
 
 #include "internal/cryptlib.h"
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 #include <openssl/rand.h>
 #include <openssl/bn.h>
 
index 6724b75..6ce9968 100644 (file)
@@ -58,7 +58,7 @@
 /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
 
 #include "internal/cryptlib.h"
-#include <openssl/dsa.h>
+#include "dsa_locl.h"
 
 int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
                   DSA *dsa)
index 117d2b7..ac4b84c 100644 (file)
@@ -289,34 +289,48 @@ static EVP_PKEY *b2i_dss(const unsigned char **in,
     DSA *dsa = NULL;
     BN_CTX *ctx = NULL;
     unsigned int nbyte;
+    BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
+    BIGNUM *pub_key = NULL;
+
     nbyte = (bitlen + 7) >> 3;
 
     dsa = DSA_new();
     ret = EVP_PKEY_new();
     if (dsa == NULL || ret == NULL)
         goto memerr;
-    if (!read_lebn(&p, nbyte, &dsa->p))
+    if (!read_lebn(&p, nbyte, &pbn))
         goto memerr;
-    if (!read_lebn(&p, 20, &dsa->q))
+
+    if (!read_lebn(&p, 20, &qbn))
         goto memerr;
-    if (!read_lebn(&p, nbyte, &dsa->g))
+
+    if (!read_lebn(&p, nbyte, &gbn))
         goto memerr;
+
     if (ispub) {
-        if (!read_lebn(&p, nbyte, &dsa->pub_key))
+        if (!read_lebn(&p, nbyte, &pub_key))
             goto memerr;
     } else {
-        if (!read_lebn(&p, 20, &dsa->priv_key))
+        if (!read_lebn(&p, 20, &priv_key))
             goto memerr;
+
         /* Calculate public key */
-        if ((dsa->pub_key = BN_new()) == NULL)
+        pub_key = BN_new();
+        if (pub_key == NULL)
             goto memerr;
         if ((ctx = BN_CTX_new()) == NULL)
             goto memerr;
 
-        if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
+        if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
             goto memerr;
+
         BN_CTX_free(ctx);
     }
+    if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
+        goto memerr;
+    pbn = qbn = gbn = NULL;
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto memerr;
 
     EVP_PKEY_set1_DSA(ret, dsa);
     DSA_free(dsa);
@@ -326,6 +340,11 @@ static EVP_PKEY *b2i_dss(const unsigned char **in,
  memerr:
     PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
     DSA_free(dsa);
+    BN_free(pbn);
+    BN_free(qbn);
+    BN_free(gbn);
+    BN_free(pub_key);
+    BN_free(priv_key);
     EVP_PKEY_free(ret);
     BN_CTX_free(ctx);
     return NULL;
@@ -484,16 +503,16 @@ static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
 static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
 {
     int bitlen;
-    bitlen = BN_num_bits(dsa->p);
-    if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
-        || (BN_num_bits(dsa->g) > bitlen))
+    bitlen = BN_num_bits(DSA_get0_p(dsa));
+    if ((bitlen & 7) || (BN_num_bits(DSA_get0_q(dsa)) != 160)
+        || (BN_num_bits(DSA_get0_g(dsa)) > bitlen))
         goto badkey;
     if (ispub) {
-        if (BN_num_bits(dsa->pub_key) > bitlen)
+        if (BN_num_bits(DSA_get0_pub_key(dsa)) > bitlen)
             goto badkey;
         *pmagic = MS_DSS1MAGIC;
     } else {
-        if (BN_num_bits(dsa->priv_key) > 160)
+        if (BN_num_bits(DSA_get0_priv_key(dsa)) > 160)
             goto badkey;
         *pmagic = MS_DSS2MAGIC;
     }
@@ -555,14 +574,14 @@ static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
 static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
 {
     int nbyte;
-    nbyte = BN_num_bytes(dsa->p);
-    write_lebn(out, dsa->p, nbyte);
-    write_lebn(out, dsa->q, 20);
-    write_lebn(out, dsa->g, nbyte);
+    nbyte = BN_num_bytes(DSA_get0_p(dsa));
+    write_lebn(out, DSA_get0_p(dsa), nbyte);
+    write_lebn(out, DSA_get0_q(dsa), 20);
+    write_lebn(out, DSA_get0_g(dsa), nbyte);
     if (ispub)
-        write_lebn(out, dsa->pub_key, nbyte);
+        write_lebn(out, DSA_get0_pub_key(dsa), nbyte);
     else
-        write_lebn(out, dsa->priv_key, 20);
+        write_lebn(out, DSA_get0_priv_key(dsa), 20);
     /* Set "invalid" for seed structure values */
     memset(*out, 0xff, 24);
     *out += 24;
index 240a1af..d0b6315 100644 (file)
@@ -143,29 +143,6 @@ struct dsa_method {
     int (*dsa_keygen) (DSA *dsa);
 };
 
-struct dsa_st {
-    /*
-     * This first variable is used to pick up errors where a DSA is passed
-     * instead of of a EVP_PKEY
-     */
-    int pad;
-    long version;
-    BIGNUM *p;
-    BIGNUM *q;                  /* == 20 */
-    BIGNUM *g;
-    BIGNUM *pub_key;            /* y public key */
-    BIGNUM *priv_key;           /* x private key */
-    int flags;
-    /* Normally used to cache montgomery values */
-    BN_MONT_CTX *method_mont_p;
-    int references;
-    CRYPTO_EX_DATA ex_data;
-    const DSA_METHOD *meth;
-    /* functional reference if 'meth' is ENGINE-provided */
-    ENGINE *engine;
-    CRYPTO_RWLOCK *lock;
-};
-
 # define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
                 (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
 # define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
@@ -264,6 +241,18 @@ DH *DSA_dup_DH(const DSA *r);
 # define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS       (EVP_PKEY_ALG_CTRL + 2)
 # define EVP_PKEY_CTRL_DSA_PARAMGEN_MD           (EVP_PKEY_ALG_CTRL + 3)
 
+BIGNUM *DSA_get0_p(const DSA *d);
+BIGNUM *DSA_get0_q(const DSA *d);
+BIGNUM *DSA_get0_g(const DSA *d);
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+BIGNUM *DSA_get0_priv_key(const DSA *d);
+BIGNUM *DSA_get0_pub_key(const DSA *d);
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+void DSA_clear_flags(DSA *d, int flags);
+int DSA_test_flags(const DSA *d, int flags);
+void DSA_set_flags(DSA *d, int flags);
+ENGINE *DSA_get0_engine(DSA *d);
+
 /* BEGIN ERROR CODES */
 /*
  * The following lines are auto generated by the script mkerr.pl. Any changes
index 27996ac..b8ab2a1 100644 (file)
@@ -172,34 +172,34 @@ int main(int argc, char **argv)
         goto end;
     }
 
-    i = BN_bn2bin(dsa->q, buf);
+    i = BN_bn2bin(DSA_get0_q(dsa), buf);
     j = sizeof(out_q);
     if ((i != j) || (memcmp(buf, out_q, i) != 0)) {
         BIO_printf(bio_err, "q value is wrong\n");
         goto end;
     }
 
-    i = BN_bn2bin(dsa->p, buf);
+    i = BN_bn2bin(DSA_get0_p(dsa), buf);
     j = sizeof(out_p);
     if ((i != j) || (memcmp(buf, out_p, i) != 0)) {
         BIO_printf(bio_err, "p value is wrong\n");
         goto end;
     }
 
-    i = BN_bn2bin(dsa->g, buf);
+    i = BN_bn2bin(DSA_get0_g(dsa), buf);
     j = sizeof(out_g);
     if ((i != j) || (memcmp(buf, out_g, i) != 0)) {
         BIO_printf(bio_err, "g value is wrong\n");
         goto end;
     }
 
-    dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
+    DSA_set_flags(dsa, DSA_FLAG_NO_EXP_CONSTTIME);
     DSA_generate_key(dsa);
     DSA_sign(0, str1, 20, sig, &siglen, dsa);
     if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
         ret = 1;
 
-    dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
+    DSA_clear_flags(dsa, DSA_FLAG_NO_EXP_CONSTTIME);
     DSA_generate_key(dsa);
     DSA_sign(0, str1, 20, sig, &siglen, dsa);
     if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)