[openssh-commits] [openssh] 08/11: upstream: refactor sshkey_sign() and sshkey_verify()

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 28 12:47:33 AEDT 2022


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 3fbc58bb249d967cc43ebdc554f6781bb73d4a58
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Oct 28 00:43:08 2022 +0000

    upstream: refactor sshkey_sign() and sshkey_verify()
    
    feedback/ok markus@
    
    OpenBSD-Commit-ID: 368e662c128c99d05cc043b1308d2b6c71a4d3cc
---
 ssh-dss.c        | 39 ++++++++++++++------------
 ssh-ecdsa-sk.c   | 28 ++++++++++---------
 ssh-ecdsa.c      | 53 +++++++++++++++++++----------------
 ssh-ed25519-sk.c | 16 ++++++-----
 ssh-ed25519.c    | 33 ++++++++++++----------
 ssh-rsa.c        | 37 +++++++++++++-----------
 ssh-xmss.c       | 33 ++++++++++++----------
 sshkey.c         | 85 ++++++++++++--------------------------------------------
 sshkey.h         | 43 +++++-----------------------
 9 files changed, 158 insertions(+), 209 deletions(-)

diff --git a/ssh-dss.c b/ssh-dss.c
index baf3cfb1..58c66c7d 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.45 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.46 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -217,9 +217,11 @@ ssh_dss_deserialize_public(const char *ktype, struct sshbuf *b,
 	return ret;
 }
 
-int
-ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat)
+static int
+ssh_dss_sign(struct sshkey *key,
+    u_char **sigp, size_t *lenp,
+    const u_char *data, size_t datalen,
+    const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
 {
 	DSA_SIG *sig = NULL;
 	const BIGNUM *sig_r, *sig_s;
@@ -285,28 +287,29 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	return ret;
 }
 
-int
+static int
 ssh_dss_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat)
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
+    struct sshkey_sig_details **detailsp)
 {
-	DSA_SIG *sig = NULL;
+	DSA_SIG *dsig = 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);
+	size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 	int ret = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *b = NULL;
 	char *ktype = NULL;
 
 	if (key == NULL || key->dsa == NULL ||
 	    sshkey_type_plain(key->type) != KEY_DSA ||
-	    signature == NULL || signaturelen == 0)
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
-	if (dlen == 0)
+	if (hlen == 0)
 		return SSH_ERR_INTERNAL_ERROR;
 
 	/* fetch signature */
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
 	    sshbuf_get_string(b, &sigblob, &len) != 0) {
@@ -328,7 +331,7 @@ ssh_dss_verify(const struct sshkey *key,
 	}
 
 	/* parse signature */
-	if ((sig = DSA_SIG_new()) == NULL ||
+	if ((dsig = DSA_SIG_new()) == NULL ||
 	    (sig_r = BN_new()) == NULL ||
 	    (sig_s = BN_new()) == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
@@ -339,18 +342,18 @@ ssh_dss_verify(const struct sshkey *key,
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
-	if (!DSA_SIG_set0(sig, sig_r, sig_s)) {
+	if (!DSA_SIG_set0(dsig, 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,
+	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen,
 	    digest, sizeof(digest))) != 0)
 		goto out;
 
-	switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
+	switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) {
 	case 1:
 		ret = 0;
 		break;
@@ -364,7 +367,7 @@ ssh_dss_verify(const struct sshkey *key,
 
  out:
 	explicit_bzero(digest, sizeof(digest));
-	DSA_SIG_free(sig);
+	DSA_SIG_free(dsig);
 	BN_clear_free(sig_r);
 	BN_clear_free(sig_s);
 	sshbuf_free(b);
@@ -383,6 +386,8 @@ static const struct sshkey_impl_funcs sshkey_dss_funcs = {
 	/* .ssh_deserialize_public = */ ssh_dss_deserialize_public,
 	/* .generate = */	ssh_dss_generate,
 	/* .copy_public = */	ssh_dss_copy_public,
+	/* .sign = */		ssh_dss_sign,
+	/* .verify = */		ssh_dss_verify,
 };
 
 const struct sshkey_impl sshkey_dss_impl = {
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index cb8bcef1..6e08d869 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.14 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.15 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -197,13 +197,13 @@ webauthn_check_prepare_hash(const u_char *data, size_t datalen,
 }
 
 /* ARGSUSED */
-int
+static int
 ssh_ecdsa_sk_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat,
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
     struct sshkey_sig_details **detailsp)
 {
-	ECDSA_SIG *sig = NULL;
+	ECDSA_SIG *esig = NULL;
 	BIGNUM *sig_r = NULL, *sig_s = NULL;
 	u_char sig_flags;
 	u_char msghash[32], apphash[32], sighash[32];
@@ -221,14 +221,14 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
 		*detailsp = NULL;
 	if (key == NULL || key->ecdsa == NULL ||
 	    sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
-	    signature == NULL || signaturelen == 0)
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
 
 	if (key->ecdsa_nid != NID_X9_62_prime256v1)
 		return SSH_ERR_INTERNAL_ERROR;
 
 	/* fetch signature */
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((details = calloc(1, sizeof(*details))) == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
@@ -290,11 +290,11 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
 		sshbuf_dump(webauthn_wrapper, stderr);
 	}
 #endif
-	if ((sig = ECDSA_SIG_new()) == NULL) {
+	if ((esig = ECDSA_SIG_new()) == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
-	if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+	if (!ECDSA_SIG_set0(esig, sig_r, sig_s)) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
@@ -306,11 +306,11 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
 		goto out;
 	}
 	if (is_webauthn) {
-		if ((ret = webauthn_check_prepare_hash(data, datalen,
+		if ((ret = webauthn_check_prepare_hash(data, dlen,
 		    webauthn_origin, webauthn_wrapper, sig_flags, webauthn_exts,
 		    msghash, sizeof(msghash))) != 0)
 			goto out;
-	} else if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+	} else if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, data, dlen,
 	    msghash, sizeof(msghash))) != 0)
 		goto out;
 	/* Application value is hashed before signature */
@@ -344,7 +344,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
 #endif
 
 	/* Verify it */
-	switch (ECDSA_do_verify(sighash, sizeof(sighash), sig, key->ecdsa)) {
+	switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) {
 	case 1:
 		ret = 0;
 		break;
@@ -373,7 +373,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
 	sshbuf_free(original_signed);
 	sshbuf_free(sigbuf);
 	sshbuf_free(b);
-	ECDSA_SIG_free(sig);
+	ECDSA_SIG_free(esig);
 	BN_clear_free(sig_r);
 	BN_clear_free(sig_s);
 	free(ktype);
@@ -389,6 +389,8 @@ static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = {
 	/* .ssh_deserialize_public = */ ssh_ecdsa_sk_deserialize_public,
 	/* .generate = */	NULL,
 	/* .copy_public = */	ssh_ecdsa_sk_copy_public,
+	/* .sign = */		NULL,
+	/* .verify = */		ssh_ecdsa_sk_verify,
 };
 
 const struct sshkey_impl sshkey_ecdsa_sk_impl = {
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index e584cb79..a7b1b7b2 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.22 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.23 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -188,15 +188,17 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b,
 }
 
 /* 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)
+static int
+ssh_ecdsa_sign(struct sshkey *key,
+    u_char **sigp, size_t *lenp,
+    const u_char *data, size_t dlen,
+    const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
 {
-	ECDSA_SIG *sig = NULL;
+	ECDSA_SIG *esig = NULL;
 	const BIGNUM *sig_r, *sig_s;
 	int hash_alg;
 	u_char digest[SSH_DIGEST_MAX_LENGTH];
-	size_t len, dlen;
+	size_t len, hlen;
 	struct sshbuf *b = NULL, *bb = NULL;
 	int ret = SSH_ERR_INTERNAL_ERROR;
 
@@ -210,13 +212,13 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 		return SSH_ERR_INVALID_ARGUMENT;
 
 	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
-	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
+	    (hlen = ssh_digest_bytes(hash_alg)) == 0)
 		return SSH_ERR_INTERNAL_ERROR;
-	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+	if ((ret = ssh_digest_memory(hash_alg, data, dlen,
 	    digest, sizeof(digest))) != 0)
 		goto out;
 
-	if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
+	if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
@@ -225,7 +227,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
-	ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+	ECDSA_SIG_get0(esig, &sig_r, &sig_s);
 	if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
 	    (ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
 		goto out;
@@ -247,36 +249,37 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	explicit_bzero(digest, sizeof(digest));
 	sshbuf_free(b);
 	sshbuf_free(bb);
-	ECDSA_SIG_free(sig);
+	ECDSA_SIG_free(esig);
 	return ret;
 }
 
 /* ARGSUSED */
-int
+static int
 ssh_ecdsa_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat)
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
+    struct sshkey_sig_details **detailsp)
 {
-	ECDSA_SIG *sig = NULL;
+	ECDSA_SIG *esig = NULL;
 	BIGNUM *sig_r = NULL, *sig_s = NULL;
 	int hash_alg;
 	u_char digest[SSH_DIGEST_MAX_LENGTH];
-	size_t dlen;
+	size_t hlen;
 	int ret = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *b = NULL, *sigbuf = NULL;
 	char *ktype = NULL;
 
 	if (key == NULL || key->ecdsa == NULL ||
 	    sshkey_type_plain(key->type) != KEY_ECDSA ||
-	    signature == NULL || signaturelen == 0)
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
 
 	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
-	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
+	    (hlen = ssh_digest_bytes(hash_alg)) == 0)
 		return SSH_ERR_INTERNAL_ERROR;
 
 	/* fetch signature */
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
 	    sshbuf_froms(b, &sigbuf) != 0) {
@@ -298,11 +301,11 @@ ssh_ecdsa_verify(const struct sshkey *key,
 		ret = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
-	if ((sig = ECDSA_SIG_new()) == NULL) {
+	if ((esig = ECDSA_SIG_new()) == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
-	if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+	if (!ECDSA_SIG_set0(esig, sig_r, sig_s)) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
@@ -312,11 +315,11 @@ ssh_ecdsa_verify(const struct sshkey *key,
 		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 		goto out;
 	}
-	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+	if ((ret = ssh_digest_memory(hash_alg, data, dlen,
 	    digest, sizeof(digest))) != 0)
 		goto out;
 
-	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
+	switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {
 	case 1:
 		ret = 0;
 		break;
@@ -332,7 +335,7 @@ ssh_ecdsa_verify(const struct sshkey *key,
 	explicit_bzero(digest, sizeof(digest));
 	sshbuf_free(sigbuf);
 	sshbuf_free(b);
-	ECDSA_SIG_free(sig);
+	ECDSA_SIG_free(esig);
 	BN_clear_free(sig_r);
 	BN_clear_free(sig_s);
 	free(ktype);
@@ -349,6 +352,8 @@ const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
 	/* .ssh_deserialize_public = */ ssh_ecdsa_deserialize_public,
 	/* .generate = */	ssh_ecdsa_generate,
 	/* .copy_public = */	ssh_ecdsa_copy_public,
+	/* .sign = */		ssh_ecdsa_sign,
+	/* .verify = */		ssh_ecdsa_verify,
 };
 
 const struct sshkey_impl sshkey_ecdsa_nistp256_impl = {
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index eba835d9..1eef5424 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.12 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.13 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2019 Markus Friedl.  All rights reserved.
  *
@@ -94,10 +94,10 @@ ssh_ed25519_sk_deserialize_public(const char *ktype, struct sshbuf *b,
 	return 0;
 }
 
-int
+static int
 ssh_ed25519_sk_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat,
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
     struct sshkey_sig_details **detailsp)
 {
 	struct sshbuf *b = NULL;
@@ -122,10 +122,10 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
 	if (key == NULL ||
 	    sshkey_type_plain(key->type) != KEY_ED25519_SK ||
 	    key->ed25519_pk == NULL ||
-	    signature == NULL || signaturelen == 0)
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
 
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
 	    sshbuf_get_string_direct(b, &sigblob, &len) != 0 ||
@@ -156,7 +156,7 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
 	}
 	if (ssh_digest_memory(SSH_DIGEST_SHA256, key->sk_application,
 	    strlen(key->sk_application), apphash, sizeof(apphash)) != 0 ||
-	    ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+	    ssh_digest_memory(SSH_DIGEST_SHA256, data, dlen,
 	    msghash, sizeof(msghash)) != 0) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
@@ -230,6 +230,8 @@ static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = {
 	/* .ssh_deserialize_public = */ ssh_ed25519_sk_deserialize_public,
 	/* .generate = */	NULL,
 	/* .copy_public = */	ssh_ed25519_sk_copy_public,
+	/* .sign = */		NULL,
+	/* .verify = */		ssh_ed25519_sk_verify,
 };
 
 const struct sshkey_impl sshkey_ed25519_sk_impl = {
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 1556641d..8e6fabed 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.16 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.17 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2013 Markus Friedl <markus at openbsd.org>
  *
@@ -104,9 +104,11 @@ ssh_ed25519_deserialize_public(const char *ktype, struct sshbuf *b,
 	return 0;
 }
 
-int
-ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat)
+static int
+ssh_ed25519_sign(struct sshkey *key,
+    u_char **sigp, size_t *lenp,
+    const u_char *data, size_t datalen,
+    const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
 {
 	u_char *sig = NULL;
 	size_t slen = 0, len;
@@ -161,10 +163,11 @@ ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	return r;
 }
 
-int
+static int
 ssh_ed25519_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat)
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
+    struct sshkey_sig_details **detailsp)
 {
 	struct sshbuf *b = NULL;
 	char *ktype = NULL;
@@ -177,11 +180,11 @@ ssh_ed25519_verify(const struct sshkey *key,
 	if (key == NULL ||
 	    sshkey_type_plain(key->type) != KEY_ED25519 ||
 	    key->ed25519_pk == NULL ||
-	    datalen >= INT_MAX - crypto_sign_ed25519_BYTES ||
-	    signature == NULL || signaturelen == 0)
+	    dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
 
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||
 	    (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)
@@ -198,23 +201,23 @@ ssh_ed25519_verify(const struct sshkey *key,
 		r = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
-	if (datalen >= SIZE_MAX - len) {
+	if (dlen >= SIZE_MAX - len) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	smlen = len + datalen;
+	smlen = len + dlen;
 	mlen = smlen;
 	if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
 	memcpy(sm, sigblob, len);
-	memcpy(sm+len, data, datalen);
+	memcpy(sm+len, data, dlen);
 	if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
 	    key->ed25519_pk)) != 0) {
 		debug2_f("crypto_sign_ed25519_open failed: %d", ret);
 	}
-	if (ret != 0 || mlen != datalen) {
+	if (ret != 0 || mlen != dlen) {
 		r = SSH_ERR_SIGNATURE_INVALID;
 		goto out;
 	}
@@ -241,6 +244,8 @@ const struct sshkey_impl_funcs sshkey_ed25519_funcs = {
 	/* .ssh_deserialize_public = */ ssh_ed25519_deserialize_public,
 	/* .generate = */	ssh_ed25519_generate,
 	/* .copy_public = */	ssh_ed25519_copy_public,
+	/* .sign = */		ssh_ed25519_sign,
+	/* .verify = */		ssh_ed25519_verify,
 };
 
 const struct sshkey_impl sshkey_ed25519_impl = {
diff --git a/ssh-rsa.c b/ssh-rsa.c
index cbea0d29..07620a8d 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.74 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.75 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2000, 2003 Markus Friedl <markus at openbsd.org>
  *
@@ -328,14 +328,16 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
 }
 
 /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
-int
-ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, const char *alg_ident)
+static int
+ssh_rsa_sign(struct sshkey *key,
+    u_char **sigp, size_t *lenp,
+    const u_char *data, size_t datalen,
+    const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
 {
 	const BIGNUM *rsa_n;
 	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
 	size_t slen = 0;
-	u_int dlen, len;
+	u_int hlen, len;
 	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *b = NULL;
 
@@ -344,10 +346,10 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	if (sigp != NULL)
 		*sigp = NULL;
 
-	if (alg_ident == NULL || strlen(alg_ident) == 0)
+	if (alg == NULL || strlen(alg) == 0)
 		hash_alg = SSH_DIGEST_SHA1;
 	else
-		hash_alg = rsa_hash_id_from_keyname(alg_ident);
+		hash_alg = rsa_hash_id_from_keyname(alg);
 	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
 	    sshkey_type_plain(key->type) != KEY_RSA)
 		return SSH_ERR_INVALID_ARGUMENT;
@@ -360,7 +362,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 
 	/* hash the data */
 	nid = rsa_hash_alg_nid(hash_alg);
-	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
+	if ((hlen = ssh_digest_bytes(hash_alg)) == 0)
 		return SSH_ERR_INTERNAL_ERROR;
 	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 	    digest, sizeof(digest))) != 0)
@@ -371,7 +373,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 		goto out;
 	}
 
-	if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
+	if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
@@ -409,15 +411,16 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	return ret;
 }
 
-int
+static int
 ssh_rsa_verify(const struct sshkey *key,
-    const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
-    const char *alg)
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
+    struct sshkey_sig_details **detailsp)
 {
 	const BIGNUM *rsa_n;
 	char *sigtype = NULL;
 	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
-	size_t len = 0, diff, modlen, dlen;
+	size_t len = 0, diff, modlen, hlen;
 	struct sshbuf *b = NULL;
 	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
 
@@ -478,15 +481,15 @@ ssh_rsa_verify(const struct sshkey *key,
 		explicit_bzero(sigblob, diff);
 		len = modlen;
 	}
-	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
+	if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {
 		ret = SSH_ERR_INTERNAL_ERROR;
 		goto out;
 	}
-	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+	if ((ret = ssh_digest_memory(hash_alg, data, dlen,
 	    digest, sizeof(digest))) != 0)
 		goto out;
 
-	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
+	ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,
 	    key->rsa);
  out:
 	freezero(sigblob, len);
@@ -624,6 +627,8 @@ static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
 	/* .ssh_deserialize_public = */ ssh_rsa_deserialize_public,
 	/* .generate = */	ssh_rsa_generate,
 	/* .copy_public = */	ssh_rsa_copy_public,
+	/* .sign = */		ssh_rsa_sign,
+	/* .verify = */		ssh_rsa_verify,
 };
 
 const struct sshkey_impl sshkey_rsa_impl = {
diff --git a/ssh-xmss.c b/ssh-xmss.c
index 039436b4..2193aaab 100644
--- a/ssh-xmss.c
+++ b/ssh-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-xmss.c,v 1.11 2022/10/28 00:41:52 djm Exp $*/
+/* $OpenBSD: ssh-xmss.c,v 1.12 2022/10/28 00:43:08 djm Exp $*/
 /*
  * Copyright (c) 2017 Stefan-Lukas Gazdag.
  * Copyright (c) 2017 Markus Friedl.
@@ -138,9 +138,11 @@ ssh_xmss_deserialize_public(const char *ktype, struct sshbuf *b,
 	return ret;
 }
 
-int
-ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat)
+static int
+ssh_xmss_sign(struct sshkey *key,
+    u_char **sigp, size_t *lenp,
+    const u_char *data, size_t datalen,
+    const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
 {
 	u_char *sig = NULL;
 	size_t slen = 0, len = 0, required_siglen;
@@ -212,10 +214,11 @@ ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 	return r;
 }
 
-int
+static int
 ssh_xmss_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat)
+    const u_char *sig, size_t siglen,
+    const u_char *data, size_t dlen, const char *alg, u_int compat,
+    struct sshkey_sig_details **detailsp)
 {
 	struct sshbuf *b = NULL;
 	char *ktype = NULL;
@@ -229,14 +232,14 @@ ssh_xmss_verify(const struct sshkey *key,
 	    sshkey_type_plain(key->type) != KEY_XMSS ||
 	    key->xmss_pk == NULL ||
 	    sshkey_xmss_params(key) == NULL ||
-	    signature == NULL || signaturelen == 0)
+	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
 	if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0)
 		return r;
-	if (datalen >= INT_MAX - required_siglen)
+	if (dlen >= INT_MAX - required_siglen)
 		return SSH_ERR_INVALID_ARGUMENT;
 
-	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||
 	    (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)
@@ -253,23 +256,23 @@ ssh_xmss_verify(const struct sshkey *key,
 		r = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
-	if (datalen >= SIZE_MAX - len) {
+	if (dlen >= SIZE_MAX - len) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	smlen = len + datalen;
+	smlen = len + dlen;
 	mlen = smlen;
 	if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
 	memcpy(sm, sigblob, len);
-	memcpy(sm+len, data, datalen);
+	memcpy(sm+len, data, dlen);
 	if ((ret = xmss_sign_open(m, &mlen, sm, smlen,
 	    key->xmss_pk, sshkey_xmss_params(key))) != 0) {
 		debug2_f("xmss_sign_open failed: %d", ret);
 	}
-	if (ret != 0 || mlen != datalen) {
+	if (ret != 0 || mlen != dlen) {
 		r = SSH_ERR_SIGNATURE_INVALID;
 		goto out;
 	}
@@ -295,6 +298,8 @@ static const struct sshkey_impl_funcs sshkey_xmss_funcs = {
 	/* .ssh_deserialize_public = */ ssh_xmss_deserialize_public,
 	/* .generate = */	sshkey_xmss_generate_private_key,
 	/* .copy_public = */	ssh_xmss_copy_public,
+	/* .sign = */		ssh_xmss_sign,
+	/* .verify = */		ssh_xmss_verify,
 };
 
 const struct sshkey_impl sshkey_xmss_impl = {
diff --git a/sshkey.c b/sshkey.c
index 69b993b0..00da6bfb 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.129 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.130 2022/10/28 00:43:08 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -2042,6 +2042,7 @@ sshkey_sign(struct sshkey *key,
 {
 	int was_shielded = sshkey_is_shielded(key);
 	int r2, r = SSH_ERR_INTERNAL_ERROR;
+	const struct sshkey_impl *impl;
 
 	if (sigp != NULL)
 		*sigp = NULL;
@@ -2049,45 +2050,20 @@ sshkey_sign(struct sshkey *key,
 		*lenp = 0;
 	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
+	if ((impl = sshkey_impl_from_key(key)) == NULL)
+		return SSH_ERR_KEY_TYPE_UNKNOWN;
 	if ((r = sshkey_unshield_private(key)) != 0)
 		return r;
-	switch (key->type) {
-#ifdef WITH_OPENSSL
-	case KEY_DSA_CERT:
-	case KEY_DSA:
-		r = ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
-		break;
-# ifdef OPENSSL_HAS_ECC
-	case KEY_ECDSA_CERT:
-	case KEY_ECDSA:
-		r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
-		break;
-# endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA_CERT:
-	case KEY_RSA:
-		r = ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
-		break;
-#endif /* WITH_OPENSSL */
-	case KEY_ED25519:
-	case KEY_ED25519_CERT:
-		r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
-		break;
-	case KEY_ED25519_SK:
-	case KEY_ED25519_SK_CERT:
-	case KEY_ECDSA_SK_CERT:
-	case KEY_ECDSA_SK:
+	if (sshkey_is_sk(key)) {
 		r = sshsk_sign(sk_provider, key, sigp, lenp, data,
 		    datalen, compat, sk_pin);
-		break;
-#ifdef WITH_XMSS
-	case KEY_XMSS:
-	case KEY_XMSS_CERT:
-		r = ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
-		break;
-#endif /* WITH_XMSS */
-	default:
-		r = SSH_ERR_KEY_TYPE_UNKNOWN;
-		break;
+	} else {
+		if (impl->funcs->sign == NULL)
+			r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
+		else {
+			r = impl->funcs->sign(key, sigp, lenp, data, datalen,
+			    alg, sk_provider, sk_pin, compat);
+		 }
 	}
 	if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
 		return r2;
@@ -2104,43 +2080,16 @@ sshkey_verify(const struct sshkey *key,
     const u_char *data, size_t dlen, const char *alg, u_int compat,
     struct sshkey_sig_details **detailsp)
 {
+	const struct sshkey_impl *impl;
+
 	if (detailsp != NULL)
 		*detailsp = NULL;
 	if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
-	switch (key->type) {
-#ifdef WITH_OPENSSL
-	case KEY_DSA_CERT:
-	case KEY_DSA:
-		return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
-# ifdef OPENSSL_HAS_ECC
-	case KEY_ECDSA_CERT:
-	case KEY_ECDSA:
-		return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
-	case KEY_ECDSA_SK_CERT:
-	case KEY_ECDSA_SK:
-		return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen,
-		    compat, detailsp);
-# endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA_CERT:
-	case KEY_RSA:
-		return ssh_rsa_verify(key, sig, siglen, data, dlen, alg);
-#endif /* WITH_OPENSSL */
-	case KEY_ED25519:
-	case KEY_ED25519_CERT:
-		return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
-	case KEY_ED25519_SK:
-	case KEY_ED25519_SK_CERT:
-		return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
-		    compat, detailsp);
-#ifdef WITH_XMSS
-	case KEY_XMSS:
-	case KEY_XMSS_CERT:
-		return ssh_xmss_verify(key, sig, siglen, data, dlen, compat);
-#endif /* WITH_XMSS */
-	default:
+	if ((impl = sshkey_impl_from_key(key)) == NULL)
 		return SSH_ERR_KEY_TYPE_UNKNOWN;
-	}
+	return impl->funcs->verify(key, sig, siglen, data, dlen,
+	    alg, compat, detailsp);
 }
 
 /* Convert a plain key to their _CERT equivalent */
diff --git a/sshkey.h b/sshkey.h
index 5d9e9df3..d740c20b 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.58 2022/10/28 00:41:52 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.59 2022/10/28 00:43:08 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -175,6 +175,12 @@ struct sshkey_impl_funcs {
 	    struct sshkey *);
 	int (*generate)(struct sshkey *, int);	/* optional */
 	int (*copy_public)(const struct sshkey *, struct sshkey *);
+	int (*sign)(struct sshkey *, u_char **, size_t *,
+	    const u_char *, size_t, const char *,
+	    const char *, const char *, u_int); /* optional */
+	int (*verify)(const struct sshkey *, const u_char *, size_t,
+	    const u_char *, size_t, const char *, u_int,
+	    struct sshkey_sig_details **);
 };
 
 struct sshkey_impl {
@@ -321,41 +327,6 @@ int	sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key);
 #ifdef WITH_OPENSSL
 int	check_rsa_length(const RSA *rsa); /* XXX remove */
 #endif
-
-int ssh_rsa_sign(const struct sshkey *key,
-    u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
-    const char *ident);
-int ssh_rsa_verify(const struct sshkey *key,
-    const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
-    const char *alg);
-int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_dss_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_sk_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat,
-    struct sshkey_sig_details **detailsp);
-int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_ed25519_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_ed25519_sk_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat,
-    struct sshkey_sig_details **detailsp);
-int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat);
-int ssh_xmss_verify(const struct sshkey *key,
-    const u_char *signature, size_t signaturelen,
-    const u_char *data, size_t datalen, u_int compat);
 #endif
 
 #if !defined(WITH_OPENSSL)

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list