Latest update.

This commit is contained in:
2020-01-17 19:45:12 +09:00
parent 016df9f433
commit 0f7abb4eb6
1100 changed files with 47785 additions and 16292 deletions
+7 -3
View File
@@ -1,5 +1,9 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c
SOURCE[../../libcrypto]=$COMMON\
dsa_gen.c dsa_key.c dsa_asn1.c \
dsa_err.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
dsa_meth.c
SOURCE[../../providers/libfips.a]=$COMMON
-151
View File
@@ -15,110 +15,6 @@
#include <openssl/rand.h>
#include "crypto/asn1_dsa.h"
DSA_SIG *DSA_SIG_new(void)
{
DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
if (sig == NULL)
DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
return sig;
}
void DSA_SIG_free(DSA_SIG *sig)
{
if (sig == NULL)
return;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
OPENSSL_free(sig);
}
DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
{
DSA_SIG *sig;
if (len < 0)
return NULL;
if (psig != NULL && *psig != NULL) {
sig = *psig;
} else {
sig = DSA_SIG_new();
if (sig == NULL)
return NULL;
}
if (sig->r == NULL)
sig->r = BN_new();
if (sig->s == NULL)
sig->s = BN_new();
if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
if (psig == NULL || *psig == NULL)
DSA_SIG_free(sig);
return NULL;
}
if (psig != NULL && *psig == NULL)
*psig = sig;
return sig;
}
int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
{
BUF_MEM *buf = NULL;
size_t encoded_len;
WPACKET pkt;
if (ppout == NULL) {
if (!WPACKET_init_null(&pkt, 0))
return -1;
} else if (*ppout == NULL) {
if ((buf = BUF_MEM_new()) == NULL
|| !WPACKET_init_len(&pkt, buf, 0)) {
BUF_MEM_free(buf);
return -1;
}
} else {
if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
return -1;
}
if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
|| !WPACKET_get_total_written(&pkt, &encoded_len)
|| !WPACKET_finish(&pkt)) {
BUF_MEM_free(buf);
WPACKET_cleanup(&pkt);
return -1;
}
if (ppout != NULL) {
if (*ppout == NULL) {
*ppout = (unsigned char *)buf->data;
buf->data = NULL;
BUF_MEM_free(buf);
} else {
*ppout += encoded_len;
}
}
return (int)encoded_len;
}
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;
}
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;
}
/* Override the default free and new methods */
static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
@@ -168,50 +64,3 @@ DSA *DSAparams_dup(const DSA *dsa)
{
return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
}
int DSA_sign(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen, DSA *dsa)
{
DSA_SIG *s;
s = DSA_do_sign(dgst, dlen, dsa);
if (s == NULL) {
*siglen = 0;
return 0;
}
*siglen = i2d_DSA_SIG(s, &sig);
DSA_SIG_free(s);
return 1;
}
/* data has already been hashed (probably with SHA or SHA-1). */
/*-
* returns
* 1: correct signature
* 0: incorrect signature
* -1: error
*/
int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int siglen, DSA *dsa)
{
DSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
s = DSA_SIG_new();
if (s == NULL)
return ret;
if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_DSA_SIG(s, &der);
if (derlen != siglen || memcmp(sigbuf, der, derlen))
goto err;
ret = DSA_do_verify(dgst, dgst_len, s, dsa);
err:
OPENSSL_clear_free(der, derlen);
DSA_SIG_free(s);
return ret;
}
+1 -1
View File
@@ -20,7 +20,7 @@
#define xxxHASH EVP_sha1()
#include <openssl/opensslconf.h>
#if OPENSSL_API_0_9_8
#ifdef OPENSSL_NO_DEPRECATED_0_9_8
NON_EMPTY_TRANSLATION_UNIT
#else
+189 -197
View File
@@ -15,155 +15,9 @@
#include <openssl/asn1.h>
#include <openssl/engine.h>
#include <openssl/dh.h>
#include "crypto/dsa.h"
DSA *DSA_new(void)
{
return DSA_new_method(NULL);
}
int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
{
/*
* NB: The caller is specifically setting a method, so it's not up to us
* to deal with which ENGINE it comes from.
*/
const DSA_METHOD *mtmp;
mtmp = dsa->meth;
if (mtmp->finish)
mtmp->finish(dsa);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(dsa->engine);
dsa->engine = NULL;
#endif
dsa->meth = meth;
if (meth->init)
meth->init(dsa);
return 1;
}
const DSA_METHOD *DSA_get_method(DSA *d)
{
return d->meth;
}
DSA *DSA_new_method(ENGINE *engine)
{
DSA *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->references = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
ret->meth = DSA_get_default_method();
#ifndef OPENSSL_NO_ENGINE
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
if (engine) {
if (!ENGINE_init(engine)) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
goto err;
}
ret->engine = engine;
} else
ret->engine = ENGINE_get_default_DSA();
if (ret->engine) {
ret->meth = ENGINE_get_DSA(ret->engine);
if (ret->meth == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
goto err;
}
}
#endif
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
goto err;
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
goto err;
}
return ret;
err:
DSA_free(ret);
return NULL;
}
void DSA_free(DSA *r)
{
int i;
if (r == NULL)
return;
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
REF_PRINT_COUNT("DSA", r);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
if (r->meth != NULL && r->meth->finish != NULL)
r->meth->finish(r);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(r->engine);
#endif
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
CRYPTO_THREAD_lock_free(r->lock);
BN_clear_free(r->p);
BN_clear_free(r->q);
BN_clear_free(r->g);
BN_clear_free(r->pub_key);
BN_clear_free(r->priv_key);
OPENSSL_free(r);
}
int DSA_up_ref(DSA *r)
{
int i;
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
return 0;
REF_PRINT_COUNT("DSA", r);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
int DSA_size(const DSA *r)
{
int ret, i;
ASN1_INTEGER bs;
unsigned char buf[4]; /* 4 bytes looks really small. However,
* i2d_ASN1_INTEGER() will not look beyond
* the first byte, as long as the second
* parameter is NULL. */
i = BN_num_bits(r->q);
bs.length = (i + 7) / 8;
bs.data = buf;
bs.type = V_ASN1_INTEGER;
/* If the top bit is set the asn1 encoding is 1 larger. */
buf[0] = 0xff;
i = i2d_ASN1_INTEGER(&bs, NULL);
i += i; /* r and s */
ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
return ret;
}
#ifndef FIPS_MODE
int DSA_set_ex_data(DSA *d, int idx, void *arg)
{
@@ -175,13 +29,6 @@ void *DSA_get_ex_data(DSA *d, int idx)
return CRYPTO_get_ex_data(&d->ex_data, idx);
}
int DSA_security_bits(const DSA *d)
{
if (d->p && d->q)
return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
return -1;
}
#ifndef OPENSSL_NO_DH
DH *DSA_dup_DH(const DSA *r)
{
@@ -240,6 +87,189 @@ DH *DSA_dup_DH(const DSA *r)
}
#endif
const BIGNUM *DSA_get0_p(const DSA *d)
{
return d->p;
}
const BIGNUM *DSA_get0_q(const DSA *d)
{
return d->q;
}
const BIGNUM *DSA_get0_g(const DSA *d)
{
return d->g;
}
const BIGNUM *DSA_get0_pub_key(const DSA *d)
{
return d->pub_key;
}
const BIGNUM *DSA_get0_priv_key(const DSA *d)
{
return d->priv_key;
}
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;
}
int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
{
/*
* NB: The caller is specifically setting a method, so it's not up to us
* to deal with which ENGINE it comes from.
*/
const DSA_METHOD *mtmp;
mtmp = dsa->meth;
if (mtmp->finish)
mtmp->finish(dsa);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(dsa->engine);
dsa->engine = NULL;
#endif
dsa->meth = meth;
if (meth->init)
meth->init(dsa);
return 1;
}
#endif /* FIPS_MODE */
const DSA_METHOD *DSA_get_method(DSA *d)
{
return d->meth;
}
static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine)
{
DSA *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->references = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
ret->meth = DSA_get_default_method();
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
if (engine) {
if (!ENGINE_init(engine)) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
goto err;
}
ret->engine = engine;
} else
ret->engine = ENGINE_get_default_DSA();
if (ret->engine) {
ret->meth = ENGINE_get_DSA(ret->engine);
if (ret->meth == NULL) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
goto err;
}
}
#endif
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
#ifndef FIPS_MODE
if (!crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
goto err;
#endif
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
goto err;
}
return ret;
err:
DSA_free(ret);
return NULL;
}
DSA *DSA_new_method(ENGINE *engine)
{
return dsa_new_method(NULL, engine);
}
DSA *DSA_new(void)
{
return DSA_new_method(NULL);
}
void DSA_free(DSA *r)
{
int i;
if (r == NULL)
return;
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
REF_PRINT_COUNT("DSA", r);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
if (r->meth != NULL && r->meth->finish != NULL)
r->meth->finish(r);
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
ENGINE_finish(r->engine);
#endif
#ifndef FIPS_MODE
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
#endif
CRYPTO_THREAD_lock_free(r->lock);
BN_clear_free(r->p);
BN_clear_free(r->q);
BN_clear_free(r->g);
BN_clear_free(r->pub_key);
BN_clear_free(r->priv_key);
OPENSSL_free(r);
}
int DSA_up_ref(DSA *r)
{
int i;
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
return 0;
REF_PRINT_COUNT("DSA", r);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
void DSA_get0_pqg(const DSA *d,
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
@@ -309,49 +339,11 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
return 1;
}
const BIGNUM *DSA_get0_p(const DSA *d)
int DSA_security_bits(const DSA *d)
{
return d->p;
}
const BIGNUM *DSA_get0_q(const DSA *d)
{
return d->q;
}
const BIGNUM *DSA_get0_g(const DSA *d)
{
return d->g;
}
const BIGNUM *DSA_get0_pub_key(const DSA *d)
{
return d->pub_key;
}
const BIGNUM *DSA_get0_priv_key(const DSA *d)
{
return d->priv_key;
}
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;
if (d->p && d->q)
return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
return -1;
}
int DSA_bits(const DSA *dsa)
+5
View File
@@ -26,7 +26,9 @@ struct dsa_st {
/* Normally used to cache montgomery values */
BN_MONT_CTX *method_mont_p;
CRYPTO_REF_COUNT references;
#ifndef FIPS_MODE
CRYPTO_EX_DATA ex_data;
#endif
const DSA_METHOD *meth;
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
@@ -78,3 +80,6 @@ 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);
DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
int dlen, DSA *dsa);
+17 -8
View File
@@ -44,10 +44,12 @@ static DSA_METHOD openssl_dsa_meth = {
static const DSA_METHOD *default_DSA_method = &openssl_dsa_meth;
#ifndef FIPS_MODE
void DSA_set_default_method(const DSA_METHOD *meth)
{
default_DSA_method = meth;
}
#endif /* FIPS_MODE */
const DSA_METHOD *DSA_get_default_method(void)
{
@@ -59,7 +61,8 @@ const DSA_METHOD *DSA_OpenSSL(void)
return &openssl_dsa_meth;
}
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
int dlen, DSA *dsa)
{
BIGNUM *kinv = NULL;
BIGNUM *m, *blind, *blindm, *tmp;
@@ -85,7 +88,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
if (ret->r == NULL || ret->s == NULL)
goto err;
ctx = BN_CTX_new();
ctx = BN_CTX_new_ex(libctx);
if (ctx == NULL)
goto err;
m = BN_CTX_get(ctx);
@@ -121,8 +124,8 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
/* Generate a blinding value */
do {
if (!BN_priv_rand(blind, BN_num_bits(dsa->q) - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->q) - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx))
goto err;
} while (BN_is_zero(blind));
BN_set_flags(blind, BN_FLG_CONSTTIME);
@@ -164,7 +167,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
err:
if (rv == 0) {
DSAerr(DSA_F_DSA_DO_SIGN, reason);
DSAerr(0, reason);
DSA_SIG_free(ret);
ret = NULL;
}
@@ -173,6 +176,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
return ret;
}
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
return dsa_do_sign_int(NULL, dgst, dlen, dsa);
}
static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp)
{
@@ -210,7 +218,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
goto err;
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL)
/* if you don't pass in ctx_in you get a default libctx */
if ((ctx = BN_CTX_new_ex(NULL)) == NULL)
goto err;
} else
ctx = ctx_in;
@@ -232,7 +241,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
dlen, ctx))
goto err;
} else if (!BN_priv_rand_range(k, dsa->q))
} else if (!BN_priv_rand_range_ex(k, dsa->q, ctx))
goto err;
} while (BN_is_zero(k));
@@ -323,7 +332,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
u1 = BN_new();
u2 = BN_new();
t1 = BN_new();
ctx = BN_CTX_new();
ctx = BN_CTX_new_ex(NULL); /* verify does not need a libctx */
if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL)
goto err;
+179 -2
View File
@@ -7,18 +7,195 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/bn.h>
#include "internal/cryptlib.h"
#include "dsa_local.h"
#include <openssl/bn.h>
#include "crypto/asn1_dsa.h"
#include "crypto/dsa.h"
DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
}
#if !OPENSSL_API_3
#ifndef OPENSSL_NO_DEPRECATED_3_0
int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}
#endif
DSA_SIG *DSA_SIG_new(void)
{
DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
if (sig == NULL)
DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
return sig;
}
void DSA_SIG_free(DSA_SIG *sig)
{
if (sig == NULL)
return;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
OPENSSL_free(sig);
}
DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
{
DSA_SIG *sig;
if (len < 0)
return NULL;
if (psig != NULL && *psig != NULL) {
sig = *psig;
} else {
sig = DSA_SIG_new();
if (sig == NULL)
return NULL;
}
if (sig->r == NULL)
sig->r = BN_new();
if (sig->s == NULL)
sig->s = BN_new();
if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
if (psig == NULL || *psig == NULL)
DSA_SIG_free(sig);
return NULL;
}
if (psig != NULL && *psig == NULL)
*psig = sig;
return sig;
}
int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
{
BUF_MEM *buf = NULL;
size_t encoded_len;
WPACKET pkt;
if (ppout == NULL) {
if (!WPACKET_init_null(&pkt, 0))
return -1;
} else if (*ppout == NULL) {
if ((buf = BUF_MEM_new()) == NULL
|| !WPACKET_init_len(&pkt, buf, 0)) {
BUF_MEM_free(buf);
return -1;
}
} else {
if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
return -1;
}
if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
|| !WPACKET_get_total_written(&pkt, &encoded_len)
|| !WPACKET_finish(&pkt)) {
BUF_MEM_free(buf);
WPACKET_cleanup(&pkt);
return -1;
}
if (ppout != NULL) {
if (*ppout == NULL) {
*ppout = (unsigned char *)buf->data;
buf->data = NULL;
BUF_MEM_free(buf);
} else {
*ppout += encoded_len;
}
}
return (int)encoded_len;
}
int DSA_size(const DSA *dsa)
{
int ret;
DSA_SIG sig;
sig.r = sig.s = dsa->q;
ret = i2d_DSA_SIG(&sig, NULL);
if (ret < 0)
ret = 0;
return ret;
}
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;
}
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;
}
int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa)
{
DSA_SIG *s;
/* legacy case uses the method table */
if (libctx == NULL || dsa->meth != DSA_get_default_method())
s = DSA_do_sign(dgst, dlen, dsa);
else
s = dsa_do_sign_int(libctx, dgst, dlen, dsa);
if (s == NULL) {
*siglen = 0;
return 0;
}
*siglen = i2d_DSA_SIG(s, &sig);
DSA_SIG_free(s);
return 1;
}
int DSA_sign(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen, DSA *dsa)
{
return dsa_sign_int(NULL, type, dgst, dlen, sig, siglen, dsa);
}
/* data has already been hashed (probably with SHA or SHA-1). */
/*-
* returns
* 1: correct signature
* 0: incorrect signature
* -1: error
*/
int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int siglen, DSA *dsa)
{
DSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
s = DSA_SIG_new();
if (s == NULL)
return ret;
if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_DSA_SIG(s, &der);
if (derlen != siglen || memcmp(sigbuf, der, derlen))
goto err;
ret = DSA_do_verify(dgst, dgst_len, s, dsa);
err:
OPENSSL_clear_free(der, derlen);
DSA_SIG_free(s);
return ret;
}