-/* $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.
*
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)
/* .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 = {
-/* $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.
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.
/* .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 = {
-/* $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.
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,
/* .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 = {
-/* $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.
*
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,
/* .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 = {
-/* $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@openbsd.org>
*
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)
/* .alloc = */ NULL,
/* .cleanup = */ ssh_ed25519_cleanup,
/* .equal = */ ssh_ed25519_equal,
+ /* .ssh_serialize_public = */ ssh_ed25519_serialize_public,
};
const struct sshkey_impl sshkey_ed25519_impl = {
-/* $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@openbsd.org>
*
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)
{
/* .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 = {
-/* $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.
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)
/* .alloc = */ NULL,
/* .cleanup = */ ssh_xmss_cleanup,
/* .equal = */ ssh_xmss_equal,
+ /* .ssh_serialize_public = */ ssh_xmss_serialize_public,
};
const struct sshkey_impl sshkey_xmss_impl = {
-/* $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.
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;
- 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;
- 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
-/* $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.
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 {
#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,