Commit 706a13f1 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Make DSA_SIG opaque.



This adds a new accessor function DSA_SIG_get0.
The customisation of DSA_SIG structure initialisation has been removed this
means that the 'r' and 's' components are automatically allocated when
DSA_SIG_new() is called. Update documentation.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 9cae86d5
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -488,13 +488,16 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
    if (dsa_sig) {
        int rv = 0;
        BIGNUM *r, *s;

        DSA_SIG_get0(&r, &s, dsa_sig);

        if (BIO_write(bp, "\n", 1) != 1)
            goto err;

        if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, NULL, indent))
        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
            goto err;
        if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, NULL, indent))
        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
            goto err;
        rv = 1;
 err:
+9 −21
Original line number Diff line number Diff line
@@ -62,33 +62,21 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/rand.h>
#include "dsa_locl.h"

/* Override the default new methods */
static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                  void *exarg)
{
    if (operation == ASN1_OP_NEW_PRE) {
        DSA_SIG *sig;
        sig = OPENSSL_malloc(sizeof(*sig));
        if (sig == NULL) {
            DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        sig->r = NULL;
        sig->s = NULL;
        *pval = (ASN1_VALUE *)sig;
        return 2;
    }
    return 1;
}

ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
ASN1_SEQUENCE(DSA_SIG) = {
        ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
        ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
} static_ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
} static_ASN1_SEQUENCE_END(DSA_SIG)

IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)

void DSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, DSA_SIG *sig)
{
    *pr = sig->r;
    *ps = sig->s;
}

/* Override the default free and new methods */
static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                  void *exarg)
+5 −0
Original line number Diff line number Diff line
@@ -65,3 +65,8 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
                          size_t seed_len, int idx, unsigned char *seed_out,
                          int *counter_ret, unsigned long *h_ret,
                          BN_GENCB *cb);

struct DSA_SIG_st {
    BIGNUM *r;
    BIGNUM *s;
};
+27 −29
Original line number Diff line number Diff line
@@ -133,13 +133,15 @@ const DSA_METHOD *DSA_OpenSSL(void)

static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
    BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL;
    BIGNUM *m;
    BIGNUM *xr;
    BIGNUM *r, *s;
    BN_CTX *ctx = NULL;
    int reason = ERR_R_BN_LIB;
    DSA_SIG *ret = NULL;
    int noredo = 0;
    int rv = 0;

    m = BN_new();
    xr = BN_new();
@@ -151,9 +153,12 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        goto err;
    }

    s = BN_new();
    if (s == NULL)
    ret = DSA_SIG_new();
    if (ret == NULL)
        goto err;

    DSA_SIG_get0(&r, &s, ret);

    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
@@ -193,23 +198,20 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        }
        goto redo;
    }
    ret = DSA_SIG_new();
    if (ret == NULL)
        goto err;
    ret->r = r;
    ret->s = s;

    rv = 1;

 err:
    if (ret == NULL) {
    if (rv == 0) {
        DSAerr(DSA_F_DSA_DO_SIGN, reason);
        BN_free(r);
        BN_free(s);
        DSA_SIG_free(ret);
        ret = NULL;
    }
    BN_CTX_free(ctx);
    BN_clear_free(m);
    BN_clear_free(xr);
    BN_clear_free(kinv);
    return (ret);
    return ret;
}

static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
@@ -223,7 +225,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
                          const unsigned char *dgst, int dlen)
{
    BN_CTX *ctx = NULL;
    BIGNUM *k, *kq, *K, *kinv = NULL, *r = NULL;
    BIGNUM *k, *kq, *K, *kinv = NULL, *r = *rp;
    int ret = 0;

    if (!dsa->p || !dsa->q || !dsa->g) {
@@ -242,9 +244,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
    } else
        ctx = ctx_in;

    if ((r = BN_new()) == NULL)
        goto err;

    /* Get random k */
    do {
        if (dgst != NULL) {
@@ -305,19 +304,15 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
    BN_clear_free(*kinvp);
    *kinvp = kinv;
    kinv = NULL;
    BN_clear_free(*rp);
    *rp = r;
    ret = 1;
 err:
    if (!ret) {
    if (!ret)
        DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);
        BN_clear_free(r);
    }
    if (ctx != ctx_in)
        BN_CTX_free(ctx);
    BN_clear_free(k);
    BN_clear_free(kq);
    return (ret);
    return ret;
}

static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
@@ -326,6 +321,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
    BN_CTX *ctx;
    BIGNUM *u1, *u2, *t1;
    BN_MONT_CTX *mont = NULL;
    BIGNUM *r, *s;
    int ret = -1, i;
    if (!dsa->p || !dsa->q || !dsa->g) {
        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
@@ -350,13 +346,15 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
    if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL)
        goto err;

    if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
        BN_ucmp(sig->r, dsa->q) >= 0) {
    DSA_SIG_get0(&r, &s, sig);

    if (BN_is_zero(r) || BN_is_negative(r) ||
        BN_ucmp(r, dsa->q) >= 0) {
        ret = 0;
        goto err;
    }
    if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
        BN_ucmp(sig->s, dsa->q) >= 0) {
    if (BN_is_zero(s) || BN_is_negative(s) ||
        BN_ucmp(s, dsa->q) >= 0) {
        ret = 0;
        goto err;
    }
@@ -364,7 +362,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
    /*
     * Calculate W = inv(S) mod Q save W in u2
     */
    if ((BN_mod_inverse(u2, sig->s, dsa->q, ctx)) == NULL)
    if ((BN_mod_inverse(u2, s, dsa->q, ctx)) == NULL)
        goto err;

    /* save M in u1 */
@@ -383,7 +381,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
        goto err;

    /* u2 = r * w mod q */
    if (!BN_mod_mul(u2, sig->r, u2, dsa->q, ctx))
    if (!BN_mod_mul(u2, r, u2, dsa->q, ctx))
        goto err;

    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
@@ -403,7 +401,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
    /*
     * V is now in u1.  If the signature is correct, it will be equal to R.
     */
    ret = (BN_ucmp(u1, sig->r) == 0);
    ret = (BN_ucmp(u1, r) == 0);

 err:
    if (ret < 0)
+5 −2
Original line number Diff line number Diff line
@@ -9,8 +9,8 @@ DSA_SIG_new, DSA_SIG_free - allocate and free DSA signature objects
 #include <openssl/dsa.h>

 DSA_SIG *DSA_SIG_new(void);

 void DSA_SIG_free(DSA_SIG *a);
 void DSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, DSA_SIG *sig);

=head1 DESCRIPTION

@@ -19,6 +19,9 @@ DSA_SIG_new() allocates and initializes a B<DSA_SIG> structure.
DSA_SIG_free() frees the B<DSA_SIG> structure and its components. The
values are erased before the memory is returned to the system.

DSA_SIG_get0() returns internal pointers the B<r> and B<s> values contained
in B<sig>. The values can then be examined or initialised.

=head1 RETURN VALUES

If the allocation fails, DSA_SIG_new() returns B<NULL> and sets an
Loading