summaryrefslogtreecommitdiff
path: root/ssh-ecdsa.c
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2020-08-20 16:14:23 -0700
committerAlistair Delva <adelva@google.com>2020-08-20 16:53:18 -0700
commitd9da10d147d633fdb6ec65e17ff4b8447419d83e (patch)
tree8f93e8fdc2907f141e0924910bfec26669819f0b /ssh-ecdsa.c
parent22246b08952d746a7cc5a292570636cf4277598f (diff)
parentecb2c02d994b3e21994f31a70ff911667c262f1f (diff)
Merge upstream-master into master
Commit ecb2c02d994b3e21994f31a70ff911667c262f1f upstream This nearly (but not quite) corresponds to V_8_3_P1; subsequent cherry-picks will correct this. Bug: 162492243 Change-Id: I3c079d86435b7c25aefff4538dc89a3002b1e25b
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r--ssh-ecdsa.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 2c76f8b4..599c7199 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.11 2014/06/24 01:13:21 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.16 2019/01/21 09:54:11 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -43,12 +43,15 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
+#include "openbsd-compat/openssl-compat.h"
+
/* ARGSUSED */
int
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
ECDSA_SIG *sig = NULL;
+ const BIGNUM *sig_r, *sig_s;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
size_t len, dlen;
@@ -80,8 +83,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
- (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
+ ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+ if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
+ (ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
goto out;
if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
(ret = sshbuf_put_stringb(b, bb)) != 0)
@@ -99,12 +103,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = 0;
out:
explicit_bzero(digest, sizeof(digest));
- if (b != NULL)
- sshbuf_free(b);
- if (bb != NULL)
- sshbuf_free(bb);
- if (sig != NULL)
- ECDSA_SIG_free(sig);
+ sshbuf_free(b);
+ sshbuf_free(bb);
+ ECDSA_SIG_free(sig);
return ret;
}
@@ -115,6 +116,7 @@ ssh_ecdsa_verify(const struct sshkey *key,
const u_char *data, size_t datalen, u_int compat)
{
ECDSA_SIG *sig = NULL;
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
size_t dlen;
@@ -123,7 +125,8 @@ ssh_ecdsa_verify(const struct sshkey *key,
char *ktype = NULL;
if (key == NULL || key->ecdsa == NULL ||
- sshkey_type_plain(key->type) != KEY_ECDSA)
+ sshkey_type_plain(key->type) != KEY_ECDSA ||
+ signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
@@ -148,15 +151,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
}
/* parse signature */
+ if (sshbuf_get_bignum2(sigbuf, &sig_r) != 0 ||
+ sshbuf_get_bignum2(sigbuf, &sig_s) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
if ((sig = ECDSA_SIG_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
- sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
+ if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ sig_r = sig_s = NULL; /* transferred */
+
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
@@ -179,12 +188,11 @@ ssh_ecdsa_verify(const struct sshkey *key,
out:
explicit_bzero(digest, sizeof(digest));
- if (sigbuf != NULL)
- sshbuf_free(sigbuf);
- if (b != NULL)
- sshbuf_free(b);
- if (sig != NULL)
- ECDSA_SIG_free(sig);
+ sshbuf_free(sigbuf);
+ sshbuf_free(b);
+ ECDSA_SIG_free(sig);
+ BN_clear_free(sig_r);
+ BN_clear_free(sig_s);
free(ktype);
return ret;
}