=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-dss.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- src/usr.bin/ssh/ssh-dss.c 2018/02/07 02:06:51 1.37 +++ src/usr.bin/ssh/ssh-dss.c 2018/09/13 02:08:33 1.38 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.37 2018/02/07 02:06:51 jsing Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.38 2018/09/13 02:08:33 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -45,6 +45,7 @@ const u_char *data, size_t datalen, u_int compat) { DSA_SIG *sig = NULL; + const BIGNUM *sig_r, *sig_s; u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; @@ -70,15 +71,16 @@ goto out; } - rlen = BN_num_bytes(sig->r); - slen = BN_num_bytes(sig->s); + DSA_SIG_get0(sig, &sig_r, &sig_s); + rlen = BN_num_bytes(sig_r); + slen = BN_num_bytes(sig_s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } explicit_bzero(sigblob, SIGBLOB_LEN); - BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); - BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); + BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); + BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen); if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -112,6 +114,7 @@ const u_char *data, size_t datalen, u_int compat) { DSA_SIG *sig = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); int ret = SSH_ERR_INTERNAL_ERROR; @@ -149,16 +152,21 @@ /* parse signature */ if ((sig = DSA_SIG_new()) == NULL || - (sig->r = BN_new()) == NULL || - (sig->s = BN_new()) == NULL) { + (sig_r = BN_new()) == NULL || + (sig_s = BN_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || - (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { + if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) || + (BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + if (!DSA_SIG_set0(sig, sig_r, sig_s)) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + sig_r = sig_s = NULL; /* transferred */ /* sha1 the data */ if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, @@ -180,6 +188,8 @@ out: explicit_bzero(digest, sizeof(digest)); DSA_SIG_free(sig); + BN_clear_free(sig_r); + BN_clear_free(sig_s); sshbuf_free(b); free(ktype); if (sigblob != NULL) {