summaryrefslogtreecommitdiffstats
path: root/ssh-rsa.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2022-10-28 02:41:52 +0200
committerDamien Miller <djm@mindrot.org>2022-10-28 03:46:59 +0200
commita1deb6cdbbe6afaab74ecb08fcb62db5739267be (patch)
treec5fcd10bde2ab9bdc6cc00da41f5e495bf865021 /ssh-rsa.c
parentupstream: refactor sshkey_from_private() (diff)
downloadopenssh-a1deb6cdbbe6afaab74ecb08fcb62db5739267be.tar.xz
openssh-a1deb6cdbbe6afaab74ecb08fcb62db5739267be.zip
upstream: refactor sshkey_from_blob_internal()
feedback/ok markus@ OpenBSD-Commit-ID: 1f46c0cbb8060ee9666a02749594ad6658c8e283
Diffstat (limited to 'ssh-rsa.c')
-rw-r--r--ssh-rsa.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 10585387e..cbea0d299 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.73 2022/10/28 00:41:17 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.74 2022/10/28 00:41:52 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
*
@@ -39,6 +39,26 @@
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
+int
+sshkey_check_rsa_length(const struct sshkey *k, int min_size)
+{
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n;
+ int nbits;
+
+ if (k == NULL || k->rsa == NULL ||
+ (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
+ return 0;
+ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
+ nbits = BN_num_bits(rsa_n);
+ if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+ (min_size > 0 && nbits < min_size))
+ return SSH_ERR_KEY_LENGTH;
+#endif /* WITH_OPENSSL */
+ return 0;
+}
+
+
static u_int
ssh_rsa_size(const struct sshkey *key)
{
@@ -88,7 +108,7 @@ ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b)
static int
ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
- const char *typename, enum sshkey_serialize_rep opts)
+ enum sshkey_serialize_rep opts)
{
int r;
const BIGNUM *rsa_n, *rsa_e;
@@ -96,8 +116,7 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
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 ||
+ if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
(r = sshbuf_put_bignum2(b, rsa_n)) != 0)
return r;
@@ -158,6 +177,36 @@ ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to)
return r;
}
+static int
+ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int ret = SSH_ERR_INTERNAL_ERROR;
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL;
+
+ if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||
+ sshbuf_get_bignum2(b, &rsa_n) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_n = rsa_e = NULL; /* transferred */
+ if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ RSA_print_fp(stderr, key->rsa, 8);
+#endif
+ /* success */
+ ret = 0;
+ out:
+ BN_clear_free(rsa_n);
+ BN_clear_free(rsa_e);
+ return ret;
+}
+
static const char *
rsa_hash_alg_ident(int hash_alg)
{
@@ -572,6 +621,7 @@ static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
/* .cleanup = */ ssh_rsa_cleanup,
/* .equal = */ ssh_rsa_equal,
/* .ssh_serialize_public = */ ssh_rsa_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_rsa_deserialize_public,
/* .generate = */ ssh_rsa_generate,
/* .copy_public = */ ssh_rsa_copy_public,
};