[openssh-commits] [openssh] 03/11: upstream: factor out public key serialization
git+noreply at mindrot.org
git+noreply at mindrot.org
Fri Oct 28 12:47:28 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 591fed94e66a016acf87f4b7cd416ce812f2abe8
Author: djm at openbsd.org <djm at openbsd.org>
Date: Fri Oct 28 00:37:24 2022 +0000
upstream: factor out public key serialization
feedback/ok markus@
OpenBSD-Commit-ID: a3570c4b97290c5662890aea7328d87f55939033
---
ssh-dss.c | 27 ++++++++++++-
ssh-ecdsa-sk.c | 18 ++++++++-
ssh-ecdsa.c | 21 +++++++++-
ssh-ed25519-sk.c | 18 ++++++++-
ssh-ed25519.c | 18 ++++++++-
ssh-rsa.c | 21 +++++++++-
ssh-xmss.c | 22 ++++++++++-
sshkey.c | 117 ++++++++++++-------------------------------------------
sshkey.h | 5 ++-
9 files changed, 166 insertions(+), 101 deletions(-)
diff --git a/ssh-dss.c b/ssh-dss.c
index 15d6cea3..e955fdd5 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.41 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.42 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -102,6 +102,30 @@ ssh_dss_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_dss_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+
+ if (key->dsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
+ if (dsa_p == NULL || dsa_q == NULL ||
+ dsa_g == NULL || dsa_pub_key == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
+ return r;
+
+ return 0;
+}
+
int
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
@@ -264,6 +288,7 @@ static const struct sshkey_impl_funcs sshkey_dss_funcs = {
/* .alloc = */ ssh_dss_alloc,
/* .cleanup = */ ssh_dss_cleanup,
/* .equal = */ ssh_dss_equal,
+ /* .ssh_serialize_public = */ ssh_dss_serialize_public,
};
const struct sshkey_impl sshkey_dss_impl = {
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index 77a57767..228e1b09 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.10 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.11 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -81,6 +81,21 @@ ssh_ecdsa_sk_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_ecdsa_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshkey_ecdsa_funcs.serialize_public(key, b,
+ typename, opts)) != 0)
+ return r;
+ if ((r = sshkey_serialize_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
/*
* Check FIDO/W3C webauthn signatures clientData field against the expected
* format and prepare a hash of it for use in signature verification.
@@ -346,6 +361,7 @@ static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = {
/* .alloc = */ NULL,
/* .cleanup = */ ssh_ecdsa_sk_cleanup,
/* .equal = */ ssh_ecdsa_sk_equal,
+ /* .ssh_serialize_public = */ ssh_ecdsa_sk_serialize_public,
};
const struct sshkey_impl sshkey_ecdsa_sk_impl = {
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 85fa15c4..24f66bdc 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.18 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.19 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -87,9 +87,27 @@ ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b)
return 0;
if (EC_POINT_cmp(grp_a, pub_a, pub_b, NULL) != 0)
return 0;
+
return 1;
}
+static int
+ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->ecdsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
+ (r = sshbuf_put_cstring(b,
+ sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
+ (r = sshbuf_put_eckey(b, key->ecdsa)) != 0)
+ return r;
+
+ return 0;
+}
+
/* ARGSUSED */
int
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
@@ -248,6 +266,7 @@ const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
/* .alloc = */ NULL,
/* .cleanup = */ ssh_ecdsa_cleanup,
/* .equal = */ ssh_ecdsa_equal,
+ /* .ssh_serialize_public = */ ssh_ecdsa_serialize_public,
};
const struct sshkey_impl sshkey_ecdsa_nistp256_impl = {
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index 4c0fc707..b95227c0 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.8 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.9 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
@@ -55,6 +55,21 @@ ssh_ed25519_sk_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_ed25519_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.serialize_public(key, b,
+ typename, opts)) != 0)
+ return r;
+ if ((r = sshkey_serialize_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
int
ssh_ed25519_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
@@ -187,6 +202,7 @@ static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = {
/* .alloc = */ NULL,
/* .cleanup = */ ssh_ed25519_sk_cleanup,
/* .equal = */ ssh_ed25519_sk_equal,
+ /* .ssh_serialize_public = */ ssh_ed25519_sk_serialize_public,
};
const struct sshkey_impl sshkey_ed25519_sk_impl = {
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 712cc402..72c85000 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.12 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.13 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2013 Markus Friedl <markus at openbsd.org>
*
@@ -51,6 +51,21 @@ ssh_ed25519_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_ed25519_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->ed25519_pk == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
+ (r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0)
+ return r;
+
+ 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)
@@ -184,6 +199,7 @@ const struct sshkey_impl_funcs sshkey_ed25519_funcs = {
/* .alloc = */ NULL,
/* .cleanup = */ ssh_ed25519_cleanup,
/* .equal = */ ssh_ed25519_equal,
+ /* .ssh_serialize_public = */ ssh_ed25519_serialize_public,
};
const struct sshkey_impl sshkey_ed25519_impl = {
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 345d9a8d..4ece09f7 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.70 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.71 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus at openbsd.org>
*
@@ -86,6 +86,24 @@ ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *rsa_n, *rsa_e;
+
+ if (key->rsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
+ if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_n)) != 0)
+ return r;
+
+ return 0;
+}
+
static const char *
rsa_hash_alg_ident(int hash_alg)
{
@@ -499,6 +517,7 @@ static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
/* .alloc = */ ssh_rsa_alloc,
/* .cleanup = */ ssh_rsa_cleanup,
/* .equal = */ ssh_rsa_equal,
+ /* .ssh_serialize_public = */ ssh_rsa_serialize_public,
};
const struct sshkey_impl sshkey_rsa_impl = {
diff --git a/ssh-xmss.c b/ssh-xmss.c
index 2bc31979..7031baf9 100644
--- a/ssh-xmss.c
+++ b/ssh-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-xmss.c,v 1.7 2022/10/28 00:36:31 djm Exp $*/
+/* $OpenBSD: ssh-xmss.c,v 1.8 2022/10/28 00:37:24 djm Exp $*/
/*
* Copyright (c) 2017 Stefan-Lukas Gazdag.
* Copyright (c) 2017 Markus Friedl.
@@ -63,6 +63,25 @@ ssh_xmss_equal(const struct sshkey *a, const struct sshkey *b)
return 1;
}
+static int
+ssh_xmss_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ const char *typename, enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->xmss_name == NULL || key->xmss_pk == NULL ||
+ sshkey_xmss_pklen(key) == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
+ (r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
+ (r = sshbuf_put_string(b, key->xmss_pk,
+ sshkey_xmss_pklen(key))) != 0 ||
+ (r = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
+ return r;
+
+ return 0;
+}
+
int
ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
@@ -216,6 +235,7 @@ static const struct sshkey_impl_funcs sshkey_xmss_funcs = {
/* .alloc = */ NULL,
/* .cleanup = */ ssh_xmss_cleanup,
/* .equal = */ ssh_xmss_equal,
+ /* .ssh_serialize_public = */ ssh_xmss_serialize_public,
};
const struct sshkey_impl sshkey_xmss_impl = {
diff --git a/sshkey.c b/sshkey.c
index 76bab4f9..b4130f2a 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.124 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.125 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -679,116 +679,47 @@ sshkey_equal(const struct sshkey *a, const struct sshkey *b)
return sshkey_equal_public(a, b);
}
+
+/* Serialise common FIDO key parts */
+int
+sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b)
+{
+ int r;
+
+ if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0)
+ return r;
+
+ return 0;
+}
+
static int
to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
enum sshkey_serialize_rep opts)
{
int type, ret = SSH_ERR_INTERNAL_ERROR;
const char *typename;
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
if (key == NULL)
return SSH_ERR_INVALID_ARGUMENT;
- if (sshkey_is_cert(key)) {
+ type = force_plain ? sshkey_type_plain(key->type) : key->type;
+
+ if (sshkey_type_is_cert(type)) {
if (key->cert == NULL)
return SSH_ERR_EXPECTED_CERT;
if (sshbuf_len(key->cert->certblob) == 0)
return SSH_ERR_KEY_LACKS_CERTBLOB;
- }
- type = force_plain ? sshkey_type_plain(key->type) : key->type;
- typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
-
- switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA_CERT:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK_CERT:
- case KEY_RSA_CERT:
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK_CERT:
-#ifdef WITH_XMSS
- case KEY_XMSS_CERT:
-#endif /* WITH_XMSS */
/* Use the existing blob */
- /* XXX modified flag? */
if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
return ret;
- break;
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- if (key->dsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
- DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
- return ret;
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- case KEY_ECDSA_SK:
- if (key->ecdsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_cstring(b,
- sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
- (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
- return ret;
- if (type == KEY_ECDSA_SK) {
- if ((ret = sshbuf_put_cstring(b,
- key->sk_application)) != 0)
- return ret;
- }
- break;
-# endif
- case KEY_RSA:
- if (key->rsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
- (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
- return ret;
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_SK:
- if (key->ed25519_pk == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_string(b,
- key->ed25519_pk, ED25519_PK_SZ)) != 0)
- return ret;
- if (type == KEY_ED25519_SK) {
- if ((ret = sshbuf_put_cstring(b,
- key->sk_application)) != 0)
- return ret;
- }
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- if (key->xmss_name == NULL || key->xmss_pk == NULL ||
- sshkey_xmss_pklen(key) == 0)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
- (ret = sshbuf_put_string(b,
- key->xmss_pk, sshkey_xmss_pklen(key))) != 0 ||
- (ret = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
- return ret;
- break;
-#endif /* WITH_XMSS */
- default:
- return SSH_ERR_KEY_TYPE_UNKNOWN;
+ return 0;
}
- return 0;
+ if ((impl = sshkey_impl_from_type(type)) == NULL)
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+
+ typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
+ return impl->funcs->serialize_public(key, b, typename, opts);
}
int
diff --git a/sshkey.h b/sshkey.h
index b94e332e..03d82aed 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.54 2022/10/28 00:36:31 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.55 2022/10/28 00:37:24 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -169,6 +169,8 @@ struct sshkey_impl_funcs {
int (*alloc)(struct sshkey *); /* optional */
void (*cleanup)(struct sshkey *); /* optional */
int (*equal)(const struct sshkey *, const struct sshkey *);
+ int (*serialize_public)(const struct sshkey *, struct sshbuf *,
+ const char *, enum sshkey_serialize_rep);
};
struct sshkey_impl {
@@ -309,6 +311,7 @@ void sshkey_sig_details_free(struct sshkey_sig_details *);
#ifdef SSHKEY_INTERNAL
int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b);
void sshkey_sk_cleanup(struct sshkey *k);
+int sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b);
int ssh_rsa_sign(const struct sshkey *key,
u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list