mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-30 13:01:23 +03:00
pki_crypto: Store DSA raw signature in ssh_signature
Store the raw signature instead of the internal backend structure. Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
ba67555764
commit
132c7bee64
134
src/pki_crypto.c
134
src/pki_crypto.c
@@ -1424,24 +1424,41 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
|
|||||||
{
|
{
|
||||||
char buffer[40] = { 0 };
|
char buffer[40] = { 0 };
|
||||||
ssh_string sig_blob = NULL;
|
ssh_string sig_blob = NULL;
|
||||||
const BIGNUM *pr, *ps;
|
const BIGNUM *pr = NULL, *ps = NULL;
|
||||||
|
|
||||||
ssh_string r;
|
ssh_string r = NULL;
|
||||||
int r_len, r_offset_in, r_offset_out;
|
int r_len, r_offset_in, r_offset_out;
|
||||||
|
|
||||||
ssh_string s;
|
ssh_string s = NULL;
|
||||||
int s_len, s_offset_in, s_offset_out;
|
int s_len, s_offset_in, s_offset_out;
|
||||||
|
|
||||||
DSA_SIG_get0(sig->dsa_sig, &pr, &ps);
|
const unsigned char *raw_sig_data = ssh_string_data(sig->raw_sig);
|
||||||
|
size_t raw_sig_len = ssh_string_len(sig->raw_sig);
|
||||||
|
|
||||||
|
DSA_SIG *dsa_sig;
|
||||||
|
|
||||||
|
if (sig == NULL || sig->raw_sig == NULL || raw_sig_data == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsa_sig = d2i_DSA_SIG(NULL, &raw_sig_data, raw_sig_len);
|
||||||
|
if (dsa_sig == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DSA_SIG_get0(dsa_sig, &pr, &ps);
|
||||||
|
if (pr == NULL || ps == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
r = ssh_make_bignum_string((BIGNUM *)pr);
|
r = ssh_make_bignum_string((BIGNUM *)pr);
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = ssh_make_bignum_string((BIGNUM *)ps);
|
s = ssh_make_bignum_string((BIGNUM *)ps);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
ssh_string_free(r);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r_len = ssh_string_len(r);
|
r_len = ssh_string_len(r);
|
||||||
@@ -1459,6 +1476,7 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
|
|||||||
((char *)ssh_string_data(s)) + s_offset_in,
|
((char *)ssh_string_data(s)) + s_offset_in,
|
||||||
s_len - s_offset_in);
|
s_len - s_offset_in);
|
||||||
|
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
ssh_string_free(r);
|
ssh_string_free(r);
|
||||||
ssh_string_free(s);
|
ssh_string_free(s);
|
||||||
|
|
||||||
@@ -1470,6 +1488,12 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
|
|||||||
ssh_string_fill(sig_blob, buffer, 40);
|
ssh_string_fill(sig_blob, buffer, 40);
|
||||||
|
|
||||||
return sig_blob;
|
return sig_blob;
|
||||||
|
|
||||||
|
error:
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
|
ssh_string_free(r);
|
||||||
|
ssh_string_free(s);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssh_string pki_ecdsa_signature_to_blob(const ssh_signature sig)
|
static ssh_string pki_ecdsa_signature_to_blob(const ssh_signature sig)
|
||||||
@@ -1624,6 +1648,7 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
|
|||||||
const ssh_string sig_blob,
|
const ssh_string sig_blob,
|
||||||
ssh_signature sig)
|
ssh_signature sig)
|
||||||
{
|
{
|
||||||
|
DSA_SIG *dsa_sig = NULL;
|
||||||
BIGNUM *pr = NULL, *ps = NULL;
|
BIGNUM *pr = NULL, *ps = NULL;
|
||||||
|
|
||||||
ssh_string r;
|
ssh_string r;
|
||||||
@@ -1631,6 +1656,9 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
|
|||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
int raw_sig_len = 0;
|
||||||
|
unsigned char *raw_sig_data = NULL;
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
len = ssh_string_len(sig_blob);
|
len = ssh_string_len(sig_blob);
|
||||||
@@ -1648,11 +1676,6 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
|
|||||||
ssh_print_hexa("s", (unsigned char *)ssh_string_data(sig_blob) + 20, 20);
|
ssh_print_hexa("s", (unsigned char *)ssh_string_data(sig_blob) + 20, 20);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sig->dsa_sig = DSA_SIG_new();
|
|
||||||
if (sig->dsa_sig == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = ssh_string_new(20);
|
r = ssh_string_new(20);
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1660,6 +1683,7 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
|
|||||||
ssh_string_fill(r, ssh_string_data(sig_blob), 20);
|
ssh_string_fill(r, ssh_string_data(sig_blob), 20);
|
||||||
|
|
||||||
pr = ssh_make_string_bn(r);
|
pr = ssh_make_string_bn(r);
|
||||||
|
ssh_string_burn(r);
|
||||||
ssh_string_free(r);
|
ssh_string_free(r);
|
||||||
if (pr == NULL) {
|
if (pr == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1672,23 +1696,54 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
|
|||||||
ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
|
ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
|
||||||
|
|
||||||
ps = ssh_make_string_bn(s);
|
ps = ssh_make_string_bn(s);
|
||||||
|
ssh_string_burn(s);
|
||||||
ssh_string_free(s);
|
ssh_string_free(s);
|
||||||
if (ps == NULL) {
|
if (ps == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dsa_sig = DSA_SIG_new();
|
||||||
|
if (dsa_sig == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Memory management of pr and ps is transferred to DSA signature
|
/* Memory management of pr and ps is transferred to DSA signature
|
||||||
* object */
|
* object */
|
||||||
rc = DSA_SIG_set0(sig->dsa_sig, pr, ps);
|
rc = DSA_SIG_set0(dsa_sig, pr, ps);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
ps = NULL;
|
||||||
|
pr = NULL;
|
||||||
|
|
||||||
|
raw_sig_len = i2d_DSA_SIG(dsa_sig, &raw_sig_data);
|
||||||
|
if (raw_sig_len < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
sig->raw_sig = ssh_string_new(raw_sig_len);
|
||||||
|
if (sig->raw_sig == NULL) {
|
||||||
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_string_fill(sig->raw_sig, raw_sig_data, raw_sig_len);
|
||||||
|
if (rc < 0) {
|
||||||
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
|
SAFE_FREE(raw_sig_data);
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
bignum_safe_free(ps);
|
bignum_safe_free(ps);
|
||||||
bignum_safe_free(pr);
|
bignum_safe_free(pr);
|
||||||
|
SAFE_FREE(raw_sig_data);
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1922,17 +1977,34 @@ int pki_signature_verify(ssh_session session,
|
|||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
case SSH_KEYTYPE_DSS_CERT01:
|
case SSH_KEYTYPE_DSS_CERT01:
|
||||||
|
{
|
||||||
|
DSA_SIG *dsa_sig;
|
||||||
|
|
||||||
|
if (raw_sig_data == NULL) {
|
||||||
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
|
"NULL raw signature found in provided signature");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dsa_sig = d2i_DSA_SIG(NULL, &raw_sig_data, raw_sig_len);
|
||||||
|
if (dsa_sig == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
rc = DSA_do_verify(hash,
|
rc = DSA_do_verify(hash,
|
||||||
hlen,
|
hlen,
|
||||||
sig->dsa_sig,
|
dsa_sig,
|
||||||
key->dsa);
|
key->dsa);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
ssh_set_error(session,
|
ssh_set_error(session,
|
||||||
SSH_FATAL,
|
SSH_FATAL,
|
||||||
"DSA error: %s",
|
"DSA error: %s",
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
DSA_SIG_free(dsa_sig);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_RSA:
|
case SSH_KEYTYPE_RSA:
|
||||||
case SSH_KEYTYPE_RSA1:
|
case SSH_KEYTYPE_RSA1:
|
||||||
@@ -1996,6 +2068,9 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
|||||||
ssh_signature sig;
|
ssh_signature sig;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
unsigned char *raw_sig_data = NULL;
|
||||||
|
size_t raw_sig_len;
|
||||||
|
|
||||||
sig = ssh_signature_new();
|
sig = ssh_signature_new();
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2007,21 +2082,44 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
|
|||||||
|
|
||||||
switch(privkey->type) {
|
switch(privkey->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
sig->dsa_sig = DSA_do_sign(hash, hlen, privkey->dsa);
|
{
|
||||||
if (sig->dsa_sig == NULL) {
|
DSA_SIG *dsa;
|
||||||
|
dsa = DSA_do_sign(hash, hlen, privkey->dsa);
|
||||||
|
if (dsa == NULL) {
|
||||||
ssh_signature_free(sig);
|
ssh_signature_free(sig);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = i2d_DSA_SIG(dsa, &raw_sig_data);
|
||||||
|
if (rc < 0) {
|
||||||
|
DSA_SIG_free(dsa);
|
||||||
|
ssh_signature_free(sig);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
raw_sig_len = rc;
|
||||||
|
|
||||||
|
sig->raw_sig = ssh_string_new(raw_sig_len);
|
||||||
|
if (sig->raw_sig == NULL) {
|
||||||
|
DSA_SIG_free(dsa);
|
||||||
|
ssh_signature_free(sig);
|
||||||
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
|
SAFE_FREE(raw_sig_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_string_fill(sig->raw_sig, raw_sig_data, raw_sig_len);
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
{
|
{
|
||||||
const BIGNUM *pr, *ps;
|
const BIGNUM *pr, *ps;
|
||||||
DSA_SIG_get0(sig->dsa_sig, &pr, &ps);
|
DSA_SIG_get0(dsa, &pr, &ps);
|
||||||
ssh_print_bignum("r", (BIGNUM *) pr);
|
ssh_print_bignum("r", (BIGNUM *) pr);
|
||||||
ssh_print_bignum("s", (BIGNUM *) ps);
|
ssh_print_bignum("s", (BIGNUM *) ps);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
DSA_SIG_free(dsa);
|
||||||
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
|
SAFE_FREE(raw_sig_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_RSA:
|
case SSH_KEYTYPE_RSA:
|
||||||
case SSH_KEYTYPE_RSA1:
|
case SSH_KEYTYPE_RSA1:
|
||||||
|
|||||||
Reference in New Issue
Block a user