summaryrefslogtreecommitdiffstats
path: root/ssh-ecdsa-sk.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2024-08-15 02:51:51 +0200
committerDamien Miller <djm@mindrot.org>2024-08-15 04:07:59 +0200
commit7bdfc20516e288b58c8c847958059c7b141eeff9 (patch)
treec2058c785fc099f0e8741feeb6916e793c2792bc /ssh-ecdsa-sk.c
parentupstream: Reorder calloc arguments (diff)
downloadopenssh-7bdfc20516e288b58c8c847958059c7b141eeff9.tar.xz
openssh-7bdfc20516e288b58c8c847958059c7b141eeff9.zip
upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API.
DSA remains unconverted as it will be removed within six months. Based on patches originally from Dmitry Belyavskiy, but significantly reworked based on feedback from Bob Beck, Joel Sing and especially Theo Buehler (apologies to anyone I've missed). ok tb@ OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5
Diffstat (limited to 'ssh-ecdsa-sk.c')
-rw-r--r--ssh-ecdsa-sk.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index 5dcd3c13d..27ddf904b 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.18 2023/03/08 04:43:12 guenther Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.19 2024/08/15 00:51:51 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -237,11 +237,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
struct sshkey_sig_details **detailsp)
{
ECDSA_SIG *esig = NULL;
+ EVP_MD_CTX *md_ctx = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
u_char sig_flags;
- u_char msghash[32], apphash[32], sighash[32];
+ u_char msghash[32], apphash[32];
u_int sig_counter;
- int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR;
+ u_char *sigb = NULL, *cp;
+ int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR, len = 0;
struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL;
char *ktype = NULL, *webauthn_origin = NULL;
@@ -252,7 +254,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
if (detailsp != NULL)
*detailsp = NULL;
- if (key == NULL || key->ecdsa == NULL ||
+ if (key == NULL || key->pkey == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
@@ -363,21 +365,43 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
(ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 ||
(ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0)
goto out;
- /* Signature is over H(original_signed) */
- if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
- sighash, sizeof(sighash))) != 0)
- goto out;
details->sk_counter = sig_counter;
details->sk_flags = sig_flags;
#ifdef DEBUG_SK
fprintf(stderr, "%s: signed buf:\n", __func__);
sshbuf_dump(original_signed, stderr);
- fprintf(stderr, "%s: signed hash:\n", __func__);
- sshbuf_dump_data(sighash, sizeof(sighash), stderr);
#endif
+ if ((md_ctx = EVP_MD_CTX_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) {
+ len = 0;
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((sigb = calloc(1, len)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ cp = sigb; /* ASN1_item_i2d increments the pointer past the object */
+ if (i2d_ECDSA_SIG(esig, &cp) != len) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+#ifdef DEBUG_SK
+ fprintf(stderr, "%s: signed hash:\n", __func__);
+ sshbuf_dump_data(sigb, len, stderr);
+#endif
/* Verify it */
- switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) {
+ if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL,
+ key->pkey) != 1) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ switch (EVP_DigestVerify(md_ctx, sigb, len,
+ sshbuf_ptr(original_signed), sshbuf_len(original_signed))) {
case 1:
ret = 0;
break;
@@ -397,7 +421,6 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
explicit_bzero(&sig_flags, sizeof(sig_flags));
explicit_bzero(&sig_counter, sizeof(sig_counter));
explicit_bzero(msghash, sizeof(msghash));
- explicit_bzero(sighash, sizeof(msghash));
explicit_bzero(apphash, sizeof(apphash));
sshkey_sig_details_free(details);
sshbuf_free(webauthn_wrapper);
@@ -410,6 +433,8 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
BN_clear_free(sig_r);
BN_clear_free(sig_s);
free(ktype);
+ freezero(sigb, len);
+ EVP_MD_CTX_free(md_ctx);
return ret;
}