diff options
author | djm@openbsd.org <djm@openbsd.org> | 2022-10-28 02:41:52 +0200 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2022-10-28 03:46:59 +0200 |
commit | a1deb6cdbbe6afaab74ecb08fcb62db5739267be (patch) | |
tree | c5fcd10bde2ab9bdc6cc00da41f5e495bf865021 /ssh-rsa.c | |
parent | upstream: refactor sshkey_from_private() (diff) | |
download | openssh-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.c | 58 |
1 files changed, 54 insertions, 4 deletions
@@ -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, }; |