From: Matt Caswell Date: Wed, 30 Mar 2016 14:21:39 +0000 (+0100) Subject: Make the DSA structure opaque X-Git-Tag: OpenSSL_1_1_0-pre5~163 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1258396d73cf937e4daaf2c35377011b9366f956;p=oweals%2Fopenssl.git Make the DSA structure opaque 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 Reviewed-by: Stephen Henson --- diff --git a/apps/dsa.c b/apps/dsa.c index ed5bf0175f..9038e3bfb7 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -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"); } diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 7b9ca631a7..5b0bb625c6 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -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" diff --git a/apps/gendsa.c b/apps/gendsa.c index 6769968cdf..bf01f563ba 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -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; diff --git a/apps/testdsa.h b/apps/testdsa.h index 4eb13d14b2..6519948fe6 100644 --- a/apps/testdsa.h +++ b/apps/testdsa.h @@ -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[] = diff --git a/apps/x509.c b/apps/x509.c index 66dd2ff77e..4319d69f81 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -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"); diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index f0f28bdf2a..54cdb3dae0 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -60,7 +60,7 @@ #include "internal/cryptlib.h" #include #include -#include +#include "dsa_locl.h" #include #include #include "internal/asn1_int.h" diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c index c338b5f3a8..1468fb1e66 100644 --- a/crypto/dsa/dsa_asn1.c +++ b/crypto/dsa/dsa_asn1.c @@ -58,7 +58,7 @@ #include #include "internal/cryptlib.h" -#include +#include "dsa_locl.h" #include #include #include diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index 831c2b1d9b..441588498e 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -59,7 +59,7 @@ #include #include "internal/cryptlib.h" #include -#include +#include "dsa_locl.h" #include static int dsa_builtin_keygen(DSA *dsa); diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index fa8330fd84..08226181f9 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -60,7 +60,7 @@ #include #include "internal/cryptlib.h" #include -#include +#include "dsa_locl.h" #include #include #include @@ -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; +} diff --git a/crypto/dsa/dsa_locl.h b/crypto/dsa/dsa_locl.h index 6182495848..9b25634ae3 100644 --- a/crypto/dsa/dsa_locl.h +++ b/crypto/dsa/dsa_locl.h @@ -54,6 +54,29 @@ #include +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, diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 31a6d53c9a..92855537b8 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -61,7 +61,7 @@ #include "internal/cryptlib.h" #include #include -#include +#include "dsa_locl.h" #include #include diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index ca712cf201..b9dcd5b28d 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -58,7 +58,7 @@ /* Original version from Steven Schoch */ #include "internal/cryptlib.h" -#include +#include "dsa_locl.h" #include #include diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c index 6724b7545f..6ce9968eaf 100644 --- a/crypto/dsa/dsa_vrf.c +++ b/crypto/dsa/dsa_vrf.c @@ -58,7 +58,7 @@ /* Original version from Steven Schoch */ #include "internal/cryptlib.h" -#include +#include "dsa_locl.h" int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 117d2b794d..ac4b84c59e 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -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; diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h index 240a1afa84..d0b631504d 100644 --- a/include/openssl/dsa.h +++ b/include/openssl/dsa.h @@ -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 diff --git a/test/dsatest.c b/test/dsatest.c index 27996ac85e..b8ab2a1bae 100644 --- a/test/dsatest.c +++ b/test/dsatest.c @@ -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)