import openssh-8.7p1-24.el9_1

This commit is contained in:
CentOS Sources 2022-11-15 02:03:34 -05:00 committed by Stepan Oksanichenko
parent f2566ea532
commit a8a912bd43
15 changed files with 1568 additions and 156 deletions

View File

@ -101,22 +101,6 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
return idx; return idx;
} }
diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c
--- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100
+++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100
@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha
return p;
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
+ /* coverity[overwrite_var : FALSE] */
if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
fatal("match_filter_denylist failed");
if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
+ /* coverity[overwrite_var : FALSE] */
if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c
--- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 --- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 +++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100
@ -392,10 +376,9 @@ diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c
} }
/* SSH_CLIENT deprecated */ /* SSH_CLIENT deprecated */
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c --- a/sftp.c 2022-06-30 10:43:13.914058913 +0200
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ b/sftp.c 2022-06-30 10:48:17.243997888 +0200
+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100 @@ -222,7 +222,7 @@ killchild(int signo)
@@ -224,7 +224,7 @@ killchild(int signo)
pid = sshpid; pid = sshpid;
if (pid > 1) { if (pid > 1) {
kill(pid, SIGTERM); kill(pid, SIGTERM);
@ -404,7 +387,7 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
} }
_exit(1); _exit(1);
@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons @@ -768,6 +768,8 @@ process_put(struct sftp_conn *conn, cons
fflag || global_fflag, 0) == -1) fflag || global_fflag, 0) == -1)
err = -1; err = -1;
} }
@ -413,7 +396,7 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
} }
out: out:
@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co @@ -991,6 +993,7 @@ do_globbed_ls(struct sftp_conn *conn, co
if (lflag & LS_LONG_VIEW) { if (lflag & LS_LONG_VIEW) {
if (g.gl_statv[i] == NULL) { if (g.gl_statv[i] == NULL) {
error("no stat information for %s", fname); error("no stat information for %s", fname);
@ -514,15 +497,6 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
} }
/* /*
@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh)
if (options.rekey_limit || options.rekey_interval)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
-
+ /* coverity[leaked_storage : FALSE]*/
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
ssh, list_hostkey_types());
@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) @@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh)
if (newstr) if (newstr)

View File

@ -1,16 +1,3 @@
diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c
--- openssh-8.6p1/cipher-ctr.c.fips 2021-05-06 12:08:36.423926297 +0200
+++ openssh-8.6p1/cipher-ctr.c 2021-05-06 12:08:36.497926869 +0200
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
aes_ctr.do_cipher = ssh_aes_ctr;
#ifndef SSH_OLD_EVP
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |
+ EVP_CIPH_FLAG_FIPS;
#endif
return (&aes_ctr);
}
diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 --- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 +++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200
@ -19,7 +6,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
struct dhgroup dhg; struct dhgroup dhg;
+ if (FIPS_mode()) { + if (FIPS_mode()) {
+ logit("Using arbitrary primes is not allowed in FIPS mode." + verbose("Using arbitrary primes is not allowed in FIPS mode."
+ " Falling back to known groups."); + " Falling back to known groups.");
+ return (dh_new_group_fallback(max)); + return (dh_new_group_fallback(max));
+ } + }
@ -117,7 +104,7 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 --- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 +++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200
@@ -57,6 +57,20 @@ @@ -57,6 +57,18 @@
"rsa-sha2-256," \ "rsa-sha2-256," \
"ssh-rsa" "ssh-rsa"
@ -127,13 +114,11 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "rsa-sha2-512-cert-v01@openssh.com," \ + "rsa-sha2-512-cert-v01@openssh.com," \
+ "rsa-sha2-256-cert-v01@openssh.com," \ + "rsa-sha2-256-cert-v01@openssh.com," \
+ "ssh-rsa-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256," \ + "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \ + "ecdsa-sha2-nistp521," \
+ "rsa-sha2-512," \ + "rsa-sha2-512," \
+ "rsa-sha2-256," \ + "rsa-sha2-256"
+ "ssh-rsa"
+ +
#define KEX_SERVER_ENCRYPT \ #define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \ "chacha20-poly1305@openssh.com," \
@ -359,6 +344,20 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac; saved_argc = ac;
rexec_argc = ac; rexec_argc = ac;
@@ -1931,6 +1931,13 @@ main(int ac, char **av)
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
+ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK
+ || sshkey_type_plain(key->type) == KEY_ED25519)) {
+ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]);
+ sshkey_free(key);
+ key = NULL;
+ continue;
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2110,6 +2113,10 @@ main(int ac, char **av) @@ -2110,6 +2113,10 @@ main(int ac, char **av)
/* Reinitialize the log (because of the fork above). */ /* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr); log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -408,15 +407,78 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
#include "ssh-sk.h" #include "ssh-sk.h"
#ifdef WITH_XMSS #ifdef WITH_XMSS
@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA @@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
for (kt = keytypes; kt->type != -1; kt++) {
if (kt->name == NULL || kt->type == KEY_NULL)
continue;
+ if (FIPS_mode()) {
+ switch (kt->type) {
+ case KEY_ED25519:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
if (!include_sigonly && kt->sigonly)
continue;
if ((certs_only && !kt->cert) || (plain_only && kt->cert))
@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
return SSH_ERR_EC_CURVE_MISMATCH;
} }
if (!BN_set_word(f4, RSA_F4) ||
!RSA_generate_key_ex(private, bits, f4, NULL)) { + switch (type) {
+ if (FIPS_mode()) + case KEY_ED25519:
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); + case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ sshkey_free(k);
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ break;
+ default:
+ break;
+ }
/* Fill in ret from parsed key */
ret->type = type;
if (sshkey_is_cert(ret)) {
@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA
goto out;
if (EVP_PKEY_keygen(ctx, &res) <= 0) {
+ if (FIPS_mode())
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,
break;
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
case KEY_ECDSA_SK_CERT:
case KEY_ECDSA_SK:
r = sshsk_sign(sk_provider, key, sigp, lenp, data,
@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key,
return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
compat, detailsp);
#ifdef WITH_XMSS
diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200 --- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200
+++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 +++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200
@ -427,7 +489,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
+ if (FIPS_mode()) { + if (FIPS_mode()) {
+ if (type == KEY_DSA) + if (type == KEY_DSA)
+ fatal("DSA keys are not allowed in FIPS mode"); + fatal("DSA keys are not allowed in FIPS mode");
+ if (type == KEY_ED25519) + if (type == KEY_ED25519 || type == KEY_ED25519_SK)
+ fatal("ED25519 keys are not allowed in FIPS mode"); + fatal("ED25519 keys are not allowed in FIPS mode");
+ } + }
switch (type) { switch (type) {
@ -452,3 +514,122 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
if ((fd = mkstemp(prv_tmp)) == -1) { if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s", error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno)); prv_tmp, strerror(errno));
diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c
--- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200
+++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <signal.h>
+#include <openssl/crypto.h>
#include "sshkey.h"
#include "kex.h"
@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh)
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_keypair(kex);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_keypair(kex);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_dec(kex, server_blob,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
+ &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
- &server_pubkey, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c
--- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200
+++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200
@@ -24,6 +24,7 @@
#include <string.h>
#include <stdarg.h>
+#include <openssl/crypto.h>
#include "log.h"
#include "sshbuf.h"
@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke
key->ed25519_sk == NULL ||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey *
datalen >= INT_MAX - crypto_sign_ed25519_BYTES ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((b = sshbuf_from(signature, signaturelen)) == NULL)
return SSH_ERR_ALLOC_FAIL;

View File

@ -5,9 +5,9 @@ diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL); cfg, &includes, NULL);
+ /* 'UsePAM no' is not supported in Fedora */ + /* 'UsePAM no' is not supported in RHEL */
+ if (! options.use_pam) + if (! options.use_pam)
+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); + logit("WARNING: 'UsePAM no' is not supported in RHEL and may cause several problems.");
+ +
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
if (options.moduli_file != NULL) if (options.moduli_file != NULL)
@ -19,7 +19,7 @@ diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config
# If you just want the PAM account and session checks to run without # If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication # PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'. # and KbdInteractiveAuthentication to 'no'.
+# WARNING: 'UsePAM no' is not supported in Fedora and may cause several +# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
+# problems. +# problems.
#UsePAM no #UsePAM no

View File

@ -1,13 +1,13 @@
diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 diff --color -ru a/ssh_config.5 b/ssh_config.5
--- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 --- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200
+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 +++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200
@@ -373,17 +373,13 @@ or @@ -373,17 +373,13 @@
.Qq *.c.example.com .Qq *.c.example.com
domains. domains.
.It Cm CASignatureAlgorithms .It Cm CASignatureAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies which algorithms are allowed for signing of certificates Specifies which algorithms are allowed for signing of certificates
@ -24,13 +24,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
If the specified list begins with a If the specified list begins with a
.Sq + .Sq +
character, then the specified algorithms will be appended to the default set character, then the specified algorithms will be appended to the default set
@@ -445,20 +441,25 @@ If the option is set to @@ -445,20 +441,25 @@
(the default), (the default),
the check will not be executed. the check will not be executed.
.It Cm Ciphers .It Cm Ciphers
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the ciphers allowed and their order of preference. Specifies the ciphers allowed and their order of preference.
@ -54,7 +54,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The supported ciphers are: The supported ciphers are:
.Bd -literal -offset indent .Bd -literal -offset indent
@@ -474,13 +475,6 @@ aes256-gcm@openssh.com @@ -474,13 +475,6 @@
chacha20-poly1305@openssh.com chacha20-poly1305@openssh.com
.Ed .Ed
.Pp .Pp
@ -68,19 +68,19 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
The list of available ciphers may also be obtained using The list of available ciphers may also be obtained using
.Qq ssh -Q cipher . .Qq ssh -Q cipher .
.It Cm ClearAllForwardings .It Cm ClearAllForwardings
@@ -874,6 +868,11 @@ command line will be passed untouched to @@ -874,6 +868,11 @@
The default is The default is
.Dq no . .Dq no .
.It Cm GSSAPIKexAlgorithms .It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
The list of key exchange algorithms that are offered for GSSAPI The list of key exchange algorithms that are offered for GSSAPI
key exchange. Possible values are key exchange. Possible values are
.Bd -literal -offset 3n .Bd -literal -offset 3n
@@ -886,10 +885,8 @@ gss-nistp256-sha256-, @@ -886,10 +885,8 @@
gss-curve25519-sha256- gss-curve25519-sha256-
.Ed .Ed
.Pp .Pp
@ -92,13 +92,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.It Cm HashKnownHosts .It Cm HashKnownHosts
Indicates that Indicates that
.Xr ssh 1 .Xr ssh 1
@@ -1219,29 +1216,25 @@ it may be zero or more of: @@ -1219,29 +1216,25 @@
and and
.Cm pam . .Cm pam .
.It Cm KexAlgorithms .It Cm KexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available KEX (Key Exchange) algorithms. Specifies the available KEX (Key Exchange) algorithms.
@ -131,13 +131,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The list of available key exchange algorithms may also be obtained using The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex . .Qq ssh -Q kex .
@@ -1351,37 +1344,33 @@ function, and all code in the @@ -1351,37 +1344,33 @@
file. file.
This option is intended for debugging and no overrides are enabled by default. This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs .It Cm MACs
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the MAC (message authentication code) algorithms Specifies the MAC (message authentication code) algorithms
@ -178,13 +178,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
The list of available MAC algorithms may also be obtained using The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac . .Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost .It Cm NoHostAuthenticationForLocalhost
@@ -1553,37 +1542,25 @@ instead of continuing to execute and pas @@ -1553,37 +1542,25 @@
The default is The default is
.Cm no . .Cm no .
.It Cm PubkeyAcceptedAlgorithms .It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the signature algorithms that will be used for public key Specifies the signature algorithms that will be used for public key
@ -225,16 +225,16 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The list of available signature algorithms may also be obtained using The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms . .Qq ssh -Q PubkeyAcceptedAlgorithms .
diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 diff --color -ru a/sshd_config.5 b/sshd_config.5
--- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 --- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200
+++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 +++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200
@@ -373,17 +373,13 @@ If the argument is @@ -373,17 +373,13 @@
then no banner is displayed. then no banner is displayed.
By default, no banner is displayed. By default, no banner is displayed.
.It Cm CASignatureAlgorithms .It Cm CASignatureAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies which algorithms are allowed for signing of certificates Specifies which algorithms are allowed for signing of certificates
@ -251,13 +251,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
If the specified list begins with a If the specified list begins with a
.Sq + .Sq +
character, then the specified algorithms will be appended to the default set character, then the specified algorithms will be appended to the default set
@@ -450,20 +446,25 @@ The default is @@ -450,20 +446,25 @@
indicating not to indicating not to
.Xr chroot 2 . .Xr chroot 2 .
.It Cm Ciphers .It Cm Ciphers
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the ciphers allowed. Specifies the ciphers allowed.
@ -281,7 +281,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp .Pp
The supported ciphers are: The supported ciphers are:
.Pp .Pp
@@ -490,13 +491,6 @@ aes256-gcm@openssh.com @@ -490,13 +491,6 @@
chacha20-poly1305@openssh.com chacha20-poly1305@openssh.com
.El .El
.Pp .Pp
@ -295,13 +295,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available ciphers may also be obtained using The list of available ciphers may also be obtained using
.Qq ssh -Q cipher . .Qq ssh -Q cipher .
.It Cm ClientAliveCountMax .It Cm ClientAliveCountMax
@@ -685,21 +679,22 @@ For this to work @@ -685,21 +679,22 @@
.Cm GSSAPIKeyExchange .Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client. needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms .It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
The list of key exchange algorithms that are accepted by GSSAPI The list of key exchange algorithms that are accepted by GSSAPI
@ -328,13 +328,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
This option only applies to connections using GSSAPI. This option only applies to connections using GSSAPI.
.It Cm HostbasedAcceptedAlgorithms .It Cm HostbasedAcceptedAlgorithms
Specifies the signature algorithms that will be accepted for hostbased Specifies the signature algorithms that will be accepted for hostbased
@@ -799,26 +794,13 @@ is specified, the location of the socket @@ -799,26 +794,13 @@
.Ev SSH_AUTH_SOCK .Ev SSH_AUTH_SOCK
environment variable. environment variable.
.It Cm HostKeyAlgorithms .It Cm HostKeyAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the host key signature algorithms Specifies the host key signature algorithms
@ -360,13 +360,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available signature algorithms may also be obtained using The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms . .Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts .It Cm IgnoreRhosts
@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi @@ -965,20 +947,25 @@
The default is The default is
.Cm yes . .Cm yes .
.It Cm KexAlgorithms .It Cm KexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available KEX (Key Exchange) algorithms. Specifies the available KEX (Key Exchange) algorithms.
@ -390,7 +390,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The supported algorithms are: The supported algorithms are:
.Pp .Pp
.Bl -item -compact -offset indent .Bl -item -compact -offset indent
@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 @@ -1010,15 +997,6 @@
sntrup761x25519-sha512@openssh.com sntrup761x25519-sha512@openssh.com
.El .El
.Pp .Pp
@ -406,13 +406,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available key exchange algorithms may also be obtained using The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms . .Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress .It Cm ListenAddress
@@ -1104,21 +1082,26 @@ function, and all code in the @@ -1104,21 +1082,26 @@
file. file.
This option is intended for debugging and no overrides are enabled by default. This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs .It Cm MACs
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available MAC (message authentication code) algorithms. Specifies the available MAC (message authentication code) algorithms.
@ -437,7 +437,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp .Pp
The algorithms that contain The algorithms that contain
.Qq -etm .Qq -etm
@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com @@ -1161,15 +1144,6 @@
umac-128-etm@openssh.com umac-128-etm@openssh.com
.El .El
.Pp .Pp
@ -453,13 +453,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available MAC algorithms may also be obtained using The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac . .Qq ssh -Q mac .
.It Cm Match .It Cm Match
@@ -1548,37 +1522,25 @@ or equivalent.) @@ -1548,37 +1522,25 @@
The default is The default is
.Cm yes . .Cm yes .
.It Cm PubkeyAcceptedAlgorithms .It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the signature algorithms that will be accepted for public key Specifies the signature algorithms that will be accepted for public key

View File

@ -0,0 +1,110 @@
diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c
--- openssh-8.7p1/sshkey.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200
+++ openssh-8.7p1/sshkey.c 2022-06-30 15:24:31.499641196 +0200
@@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k)
static int
rsa_generate_private_key(u_int bits, RSA **rsap)
{
- RSA *private = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *res = NULL;
BIGNUM *f4 = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
@@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA
bits > SSHBUF_MAX_BIGNUM * 8)
return SSH_ERR_KEY_LENGTH;
*rsap = NULL;
- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
+ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (!BN_set_word(f4, RSA_F4) ||
- !RSA_generate_key_ex(private, bits, f4, NULL)) {
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
+ ret = SSH_ERR_KEY_LENGTH;
+ goto out;
+ }
+
+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0)
+ goto out;
+
+ if (EVP_PKEY_keygen(ctx, &res) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
+ *rsap = EVP_PKEY_get1_RSA(res);
+ if (*rsap) {
+ ret = 0;
+ } else {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- *rsap = private;
- private = NULL;
- ret = 0;
out:
- RSA_free(private);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(res);
BN_free(f4);
return ret;
}
@@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
static int
ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
{
- EC_KEY *private;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *res = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
if (nid == NULL || ecdsap == NULL)
@@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i
if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
return SSH_ERR_KEY_LENGTH;
*ecdsap = NULL;
- if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (EC_KEY_generate_key(private) != 1) {
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0
+ || EVP_PKEY_keygen(ctx, &res) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
+ *ecdsap = EVP_PKEY_get1_EC_KEY(res);
+ if (*ecdsap) {
+ EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE);
+ ret = 0;
+ } else {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
- *ecdsap = private;
- private = NULL;
- ret = 0;
out:
- EC_KEY_free(private);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(res);
return ret;
}
# endif /* OPENSSL_HAS_ECC */

View File

@ -0,0 +1,20 @@
diff --color -rup a/monitor.c b/monitor.c
--- a/monitor.c 2022-07-11 15:11:28.146863144 +0200
+++ b/monitor.c 2022-07-11 15:15:35.726655877 +0200
@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
auth_log(ssh, authenticated, partial,
auth_method, auth_submethod);
- if (!partial && !authenticated)
+ if (!partial && !authenticated) {
+#ifdef GSSAPI
+ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled.
+ * We have to reenable it to try again for gssapi-keyex */
+ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex)
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
+#endif
authctxt->failures++;
+ }
if (authenticated || partial) {
auth2_update_session_info(authctxt,
auth_method, auth_submethod);

View File

@ -0,0 +1,151 @@
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-11 17:00:02.618575727 +0200
+++ b/sshconnect2.c 2022-07-11 17:03:05.096085690 +0200
@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh)
if (authctxt->sensitive->keys[i] == NULL ||
authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
continue;
- if (match_pattern_list(
+ if (!sshkey_match_keyname_to_sigalgs(
sshkey_ssh_name(authctxt->sensitive->keys[i]),
- authctxt->active_ktype, 0) != 1)
+ authctxt->active_ktype))
continue;
/* we take and free the key */
private = authctxt->sensitive->keys[i];
@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh)
error_f("sshkey_fingerprint failed");
goto out;
}
- debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp);
+ debug_f("trying hostkey %s %s using sigalg %s",
+ sshkey_ssh_name(private), fp, authctxt->active_ktype);
/* figure out a name for the client host */
lname = get_local_name(ssh_packet_get_connection_in(ssh));
diff --color -rup a/sshkey.c b/sshkey.c
--- a/sshkey.c 2022-07-11 17:00:02.609575554 +0200
+++ b/sshkey.c 2022-07-11 17:12:30.905976443 +0200
@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n
return -1;
}
+int
+sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
+{
+ int ktype;
+
+ if (sigalgs == NULL || *sigalgs == '\0' ||
+ (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
+ return 0;
+ else if (ktype == KEY_RSA) {
+ return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
+ } else if (ktype == KEY_RSA_CERT) {
+ return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
+ sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
+ sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
+ sigalgs, 0) == 1;
+ } else
+ return match_pattern_list(keyname, sigalgs, 0) == 1;
+}
+
char *
sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
{
diff --color -rup a/sshkey.h b/sshkey.h
--- a/sshkey.h 2022-07-11 17:00:02.603575438 +0200
+++ b/sshkey.h 2022-07-11 17:13:01.052556879 +0200
@@ -194,6 +194,10 @@ int sshkey_is_cert(const struct sshkey
int sshkey_is_sk(const struct sshkey *);
int sshkey_type_is_cert(int);
int sshkey_type_plain(int);
+
+/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */
+int sshkey_match_keyname_to_sigalgs(const char *, const char *);
+
int sshkey_to_certified(struct sshkey *);
int sshkey_drop_cert(struct sshkey *);
int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
diff --color -rup a/ssh-keysign.c b/ssh-keysign.c
--- a/ssh-keysign.c 2021-08-20 06:03:49.000000000 +0200
+++ b/ssh-keysign.c 2022-07-11 17:00:23.306973667 +0200
@@ -62,7 +62,7 @@
extern char *__progname;
static int
-valid_request(struct passwd *pw, char *host, struct sshkey **ret,
+valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp,
u_char *data, size_t datalen)
{
struct sshbuf *b;
@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h
if (ret != NULL)
*ret = NULL;
+ if (pkalgp != NULL)
+ *pkalgp = NULL;
fail = 0;
if ((b = sshbuf_from(data, datalen)) == NULL)
@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h
fail++;
} else if (key->type != pktype)
fail++;
- free(pkalg);
- free(pkblob);
/* client host name, handle trailing dot */
if ((r = sshbuf_get_cstring(b, &p, &len)) != 0)
@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h
if (fail)
sshkey_free(key);
- else if (ret != NULL)
- *ret = key;
+ else {
+ if (ret != NULL) {
+ *ret = key;
+ key = NULL;
+ }
+ if (pkalgp != NULL) {
+ *pkalgp = pkalg;
+ pkalg = NULL;
+ }
+ }
+ sshkey_free(key);
+ free(pkalg);
+ free(pkblob);
return (fail ? -1 : 0);
}
@@ -170,7 +181,7 @@ main(int argc, char **argv)
struct passwd *pw;
int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
u_char *signature, *data, rver;
- char *host, *fp;
+ char *host, *fp, *pkalg;
size_t slen, dlen;
if (pledge("stdio rpath getpw dns id", NULL) != 0)
@@ -258,7 +269,7 @@ main(int argc, char **argv)
if ((r = sshbuf_get_string(b, &data, &dlen)) != 0)
fatal_r(r, "%s: buffer error", __progname);
- if (valid_request(pw, host, &key, data, dlen) < 0)
+ if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0)
fatal("%s: not a valid request", __progname);
free(host);
@@ -279,7 +290,7 @@ main(int argc, char **argv)
}
if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen,
- NULL, NULL, NULL, 0)) != 0)
+ pkalg, NULL, NULL, 0)) != 0)
fatal_r(r, "%s: sshkey_sign failed", __progname);
free(data);

View File

@ -0,0 +1,12 @@
--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200
+++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200
@@ -16,7 +16,7 @@
#include "includes.h"
-#ifndef HAVE_CLOSEFROM
+#if (!defined HAVE_CLOSEFROM) || (defined __s390__)
#include <sys/types.h>
#include <sys/param.h>

View File

@ -0,0 +1,156 @@
diff --color -rup a/compat.c b/compat.c
--- a/compat.c 2021-08-20 06:03:49.000000000 +0200
+++ b/compat.c 2022-07-14 17:39:23.770268440 +0200
@@ -157,11 +157,12 @@ compat_banner(struct ssh *ssh, const cha
debug_f("no match: %s", version);
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_cipher_proposal(struct ssh *ssh, char *cipher_prop)
{
if (!(ssh->compat & SSH_BUG_BIGENDIANAES))
- return cipher_prop;
+ return xstrdup(cipher_prop);
debug2_f("original cipher proposal: %s", cipher_prop);
if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL)
fatal("match_filter_denylist failed");
@@ -171,11 +172,12 @@ compat_cipher_proposal(struct ssh *ssh,
return cipher_prop;
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop)
{
if (!(ssh->compat & SSH_BUG_RSASIGMD5))
- return pkalg_prop;
+ return xstrdup(pkalg_prop);
debug2_f("original public key proposal: %s", pkalg_prop);
if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL)
fatal("match_filter_denylist failed");
@@ -185,21 +187,26 @@ compat_pkalg_proposal(struct ssh *ssh, c
return pkalg_prop;
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_kex_proposal(struct ssh *ssh, char *p)
{
+ char *cp = NULL;
+
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
- return p;
+ return xstrdup(p);
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
fatal("match_filter_denylist failed");
if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
+ cp = p;
if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
fatal("match_filter_denylist failed");
+ free(cp);
}
debug2_f("compat KEX proposal: %s", p);
if (*p == '\0')
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-14 17:38:43.241496549 +0200
+++ b/sshconnect2.c 2022-07-14 17:39:23.772268479 +0200
@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *s, *all_key;
+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -252,10 +253,9 @@ ssh_kex2(struct ssh *ssh, char *host, st
if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
fatal_f("kex_names_cat");
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s);
+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s);
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- compat_cipher_proposal(ssh, options.ciphers);
- myproposal[PROPOSAL_ENC_ALGS_STOC] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] =
@@ -264,12 +264,12 @@ ssh_kex2(struct ssh *ssh, char *host, st
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
if (use_known_hosts_order) {
/* Query known_hosts and prefer algorithms that appear there */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
compat_pkalg_proposal(ssh,
order_hostkeyalgs(host, hostaddr, port, cinfo));
} else {
/* Use specified HostkeyAlgorithms exactly */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
}
@@ -383,6 +383,10 @@ ssh_kex2(struct ssh *ssh, char *host, st
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send packet");
#endif
+ /* Free only parts of proposal that were dynamically allocated here. */
+ free(prop_kex);
+ free(prop_enc);
+ free(prop_hostkey);
}
/*
diff --color -rup a/sshd.c b/sshd.c
--- a/sshd.c 2022-07-14 17:38:43.242496568 +0200
+++ b/sshd.c 2022-07-14 17:42:07.616388978 +0200
@@ -2493,14 +2493,15 @@ do_ssh2_kex(struct ssh *ssh)
{
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
struct kex *kex;
+ char *hostkey_types = NULL;
+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r;
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh,
+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
options.kex_algorithms);
- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh,
- options.ciphers);
- myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh,
- options.ciphers);
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
+ compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
@@ -2513,8 +2514,10 @@ do_ssh2_kex(struct ssh *ssh)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
- ssh, list_hostkey_types());
+ hostkey_types = list_hostkey_types();
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
+ compat_pkalg_proposal(ssh, hostkey_types);
+ free(hostkey_types);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
{
@@ -2606,6 +2609,9 @@ do_ssh2_kex(struct ssh *ssh)
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send test");
#endif
+ free(prop_kex);
+ free(prop_enc);
+ free(prop_hostkey);
debug("KEX done");
}

View File

@ -1,102 +1,207 @@
diff -up openssh-8.7p1/kex.c.minsha1 openssh-8.7p1/kex.c diff --color -ru a/clientloop.c b/clientloop.c
--- openssh-8.7p1/kex.c.minsha1 2021-12-20 17:38:51.438294309 +0100 --- a/clientloop.c 2022-06-29 16:35:06.677597259 +0200
+++ openssh-8.7p1/kex.c 2021-12-21 11:02:48.379991319 +0100 +++ b/clientloop.c 2022-06-29 16:40:29.737926205 +0200
@@ -994,6 +994,35 @@ kex_choose_conf(struct ssh *ssh) @@ -116,6 +116,9 @@
#include "ssh-gss.h"
#endif
+/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
+#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"
+
/* import options */
extern Options options;
@@ -2110,8 +2113,10 @@
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
size_t i, ndone;
struct sshbuf *signdata;
- int r, kexsigtype, use_kexsigtype;
+ int r, plaintype;
const u_char *sig;
+ const char *rsa_kexalg = NULL;
+ char *alg = NULL;
size_t siglen;
if (ctx->nnew == 0)
@@ -2122,9 +2127,9 @@
hostkeys_update_ctx_free(ctx);
return;
}
- kexsigtype = sshkey_type_plain(
- sshkey_type_from_name(ssh->kex->hostkey_alg));
-
+ if (sshkey_type_plain(sshkey_type_from_name(
+ ssh->kex->hostkey_alg)) == KEY_RSA)
+ rsa_kexalg = ssh->kex->hostkey_alg;
if ((signdata = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/*
@@ -2135,6 +2140,7 @@
for (ndone = i = 0; i < ctx->nkeys; i++) {
if (ctx->keys_match[i])
continue;
+ plaintype = sshkey_type_plain(ctx->keys[i]->type);
/* Prepare data to be signed: session ID, unique string, key */
sshbuf_reset(signdata);
if ( (r = sshbuf_put_cstring(signdata,
@@ -2148,19 +2154,33 @@
error_fr(r, "parse sig");
goto out;
}
+ if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) {
+ error_fr(r, "server gave unintelligible signature "
+ "for %s key %zu", sshkey_type(ctx->keys[i]), i);
+ goto out;
+ }
/*
- * For RSA keys, prefer to use the signature type negotiated
- * during KEX to the default (SHA1).
+ * Special case for RSA keys: if a RSA hostkey was negotiated,
+ * then use its signature type for verification of RSA hostkey
+ * proofs. Otherwise, accept only RSA-SHA256/512 signatures.
*/
- use_kexsigtype = kexsigtype == KEY_RSA &&
- sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
- debug3_f("verify %s key %zu using %s sigalg",
- sshkey_type(ctx->keys[i]), i,
- use_kexsigtype ? ssh->kex->hostkey_alg : "default");
+ if (plaintype == KEY_RSA && rsa_kexalg == NULL &&
+ match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) {
+ debug_f("server used untrusted RSA signature algorithm "
+ "%s for key %zu, disregarding", alg, i);
+ free(alg);
+ /* zap the key from the list */
+ sshkey_free(ctx->keys[i]);
+ ctx->keys[i] = NULL;
+ ndone++;
+ continue;
+ }
+ debug3_f("verify %s key %zu using sigalg %s",
+ sshkey_type(ctx->keys[i]), i, alg);
+ free(alg);
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
sshbuf_ptr(signdata), sshbuf_len(signdata),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
- NULL)) != 0) {
+ plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) {
error_fr(r, "server gave bad signature for %s key %zu",
sshkey_type(ctx->keys[i]), i);
goto out;
diff --git a/hostfile.c b/hostfile.c
index a035b381..bd49e3ac 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -642,7 +642,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
/* Re-add the requested keys */
want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP);
for (i = 0; i < nkeys; i++) {
- if ((want & ctx.match_keys[i]) == want)
+ if (keys[i] == NULL || (want & ctx.match_keys[i]) == want)
continue;
if ((fp = sshkey_fingerprint(keys[i], hash_alg,
SSH_FP_DEFAULT)) == NULL) {
diff --color -ru a/kex.c b/kex.c
--- a/kex.c 2022-06-29 16:35:06.775599179 +0200
+++ b/kex.c 2022-06-29 16:42:00.839710940 +0200
@@ -959,6 +959,18 @@
return (1);
}
+/* returns non-zero if proposal contains any algorithm from algs */
+static int
+has_any_alg(const char *proposal, const char *algs)
+{
+ char *cp;
+
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
+ return 0;
+ free(cp);
+ return 1;
+}
+
static int
kex_choose_conf(struct ssh *ssh)
{
@@ -994,6 +1006,16 @@
free(ext); free(ext);
} }
+ /* Check whether client supports rsa-sha2 algorithms */ + /* Check whether client supports rsa-sha2 algorithms */
+ if (kex->server && (kex->flags & KEX_INITIAL)) { + if (kex->server && (kex->flags & KEX_INITIAL)) {
+ char *ext; + if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ + "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
+ ext = match_list("rsa-sha2-256", peer[PROPOSAL_SERVER_HOST_KEY_ALGS], NULL);
+ if (ext) {
+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED; + kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
+ free(ext); + if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ } + "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
+
+ ext = match_list("rsa-sha2-512", peer[PROPOSAL_SERVER_HOST_KEY_ALGS], NULL);
+ if (ext) {
+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED; + kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
+ free(ext);
+ }
+
+ ext = match_list("rsa-sha2-256-cert-v01@openssh.com", peer[PROPOSAL_SERVER_HOST_KEY_ALGS], NULL);
+ if (ext) {
+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
+ free(ext);
+ }
+
+ ext = match_list("rsa-sha2-512-cert-v01@openssh.com", peer[PROPOSAL_SERVER_HOST_KEY_ALGS], NULL);
+ if (ext) {
+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
+ free(ext);
+ }
+ } + }
+ +
/* Algorithm Negotiation */ /* Algorithm Negotiation */
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
sprop[PROPOSAL_KEX_ALGS])) != 0) { sprop[PROPOSAL_KEX_ALGS])) != 0) {
diff -up openssh-8.7p1/kex.h.minsha1 openssh-8.7p1/kex.h diff --color -ru a/kex.h b/kex.h
--- openssh-8.7p1/kex.h.minsha1 2021-12-20 17:38:51.430294240 +0100 --- a/kex.h 2022-06-29 16:35:06.766599003 +0200
+++ openssh-8.7p1/kex.h 2021-12-21 10:56:29.066735608 +0100 +++ b/kex.h 2022-06-29 16:42:24.199168567 +0200
@@ -116,6 +116,8 @@ enum kex_exchange { @@ -116,6 +116,8 @@
#define KEX_INIT_SENT 0x0001 #define KEX_INIT_SENT 0x0001
#define KEX_INITIAL 0x0002 #define KEX_INITIAL 0x0002
+#define KEX_RSA_SHA2_256_SUPPORTED 0x0004 +#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
+#define KEX_RSA_SHA2_512_SUPPORTED 0x0008 +#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
struct sshenc { struct sshenc {
char *name; char *name;
diff -up openssh-8.7p1/serverloop.c.minsha1 openssh-8.7p1/serverloop.c diff --color -ru a/serverloop.c b/serverloop.c
--- openssh-8.7p1/serverloop.c.minsha1 2021-08-20 06:03:49.000000000 +0200 --- a/serverloop.c 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/serverloop.c 2021-12-21 11:01:00.594047538 +0100 +++ b/serverloop.c 2022-06-29 16:45:05.902336428 +0200
@@ -684,7 +685,7 @@ server_input_hostkeys_prove(struct ssh * @@ -684,16 +684,18 @@
struct sshbuf *resp = NULL; struct sshbuf *resp = NULL;
struct sshbuf *sigbuf = NULL; struct sshbuf *sigbuf = NULL;
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
- int r, ndx, kexsigtype, use_kexsigtype, success = 0; - int r, ndx, kexsigtype, use_kexsigtype, success = 0;
+ int r, ndx, success = 0; + int r, ndx, success = 0;
const u_char *blob; const u_char *blob;
+ const char *sigalg, *kex_rsa_sigalg = NULL;
u_char *sig = 0; u_char *sig = 0;
size_t blen, slen; size_t blen, slen;
@@ -692,9 +693,11 @@ server_input_hostkeys_prove(struct ssh *
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new"); fatal_f("sshbuf_new");
- kexsigtype = sshkey_type_plain( - kexsigtype = sshkey_type_plain(
- sshkey_type_from_name(ssh->kex->hostkey_alg)); - sshkey_type_from_name(ssh->kex->hostkey_alg));
+ if (sshkey_type_plain(sshkey_type_from_name(
+ ssh->kex->hostkey_alg)) == KEY_RSA)
+ kex_rsa_sigalg = ssh->kex->hostkey_alg;
while (ssh_packet_remaining(ssh) > 0) { while (ssh_packet_remaining(ssh) > 0) {
+ const char *pkexstr = NULL;
+ const char *rsa_sha2_256 = "rsa-sha2-256";
+ const char *rsa_sha2_512 = "rsa-sha2-512";
+
sshkey_free(key); sshkey_free(key);
key = NULL; key = NULL;
if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 || @@ -726,16 +728,24 @@
@@ -726,8 +729,13 @@ server_input_hostkeys_prove(struct ssh *
* For RSA keys, prefer to use the signature type negotiated * For RSA keys, prefer to use the signature type negotiated
* during KEX to the default (SHA1). * during KEX to the default (SHA1).
*/ */
- use_kexsigtype = kexsigtype == KEY_RSA && - use_kexsigtype = kexsigtype == KEY_RSA &&
- sshkey_type_plain(key->type) == KEY_RSA; - sshkey_type_plain(key->type) == KEY_RSA;
+ sigalg = NULL;
+ if (sshkey_type_plain(key->type) == KEY_RSA) { + if (sshkey_type_plain(key->type) == KEY_RSA) {
+ if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED) + if (kex_rsa_sigalg != NULL)
+ pkexstr = rsa_sha2_512; + sigalg = kex_rsa_sigalg;
+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) + else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
+ pkexstr = rsa_sha2_256; + sigalg = "rsa-sha2-512";
+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
+ sigalg = "rsa-sha2-256";
+ } + }
+ + debug3_f("sign %s key (index %d) using sigalg %s",
+ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf, if ((r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove-00@openssh.com")) != 0 || "hostkeys-prove-00@openssh.com")) != 0 ||
(r = sshbuf_put_stringb(sigbuf, (r = sshbuf_put_stringb(sigbuf,
@@ -735,7 +743,7 @@ server_input_hostkeys_prove(struct ssh * ssh->kex->session_id)) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0 ||
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen, (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), - sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 || - use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
+ pkexstr)) != 0 || + sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
(r = sshbuf_put_string(resp, sig, slen)) != 0) { (r = sshbuf_put_string(resp, sig, slen)) != 0) {
error_fr(r, "assemble signature"); error_fr(r, "assemble signature");
goto out; goto out;

View File

@ -0,0 +1,446 @@
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 36b9d2f5..6b517db4 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key,
+ options.required_rsa_size)) != 0) {
+ logit_r(r, "refusing %s key", sshkey_type(key));
+ goto done;
+ }
if (!authctxt->valid || authctxt->user == NULL) {
debug2_f("disabled because of invalid user");
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 962fd342..5d59febc 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key,
+ options.required_rsa_size)) != 0) {
+ logit_r(r, "refusing %s key", sshkey_type(key));
+ goto done;
+ }
key_s = format_key(key);
if (sshkey_is_cert(key))
ca_s = format_key(key->cert->signature_key);
diff --git a/readconf.c b/readconf.c
index 7f26c680..42be690b 100644
--- a/readconf.c
+++ b/readconf.c
@@ -174,7 +174,7 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
- oSecurityKeyProvider, oKnownHostsCommand,
+ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -320,6 +320,8 @@ static struct {
{ "proxyjump", oProxyJump },
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
+ { "requiredrsasize", oRequiredRSASize },
+ { "rsaminsize", oRequiredRSASize }, /* alias */
{ NULL, oBadOption }
};
@@ -2176,6 +2177,10 @@ parse_pubkey_algos:
*charptr = xstrdup(arg);
break;
+ case oRequiredRSASize:
+ intptr = &options->required_rsa_size;
+ goto parse_int;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -2423,6 +2428,7 @@ initialize_options(Options * options)
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
+ options->required_rsa_size = -1;
}
/*
@@ -2619,6 +2625,8 @@ fill_default_options(Options * options)
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
#endif
+ if (options->required_rsa_size == -1)
+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
+ dump_cfg_int(oRequiredRSASize, o->required_rsa_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
diff --git a/readconf.h b/readconf.h
index f647bd42..ffb5ec4f 100644
--- a/readconf.h
+++ b/readconf.h
@@ -176,6 +176,8 @@ typedef struct {
char *known_hosts_command;
+ int required_rsa_size; /* minimum size of RSA keys */
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
diff --git a/servconf.c b/servconf.c
index 29df0463..423772b1 100644
--- a/servconf.c
+++ b/servconf.c
@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options)
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
options->expose_userauth_info = -1;
+ options->required_rsa_size = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options)
options->expose_userauth_info = 0;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
+ if (options->required_rsa_size == -1)
+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
assemble_algorithms(options);
@@ -517,6 +520,7 @@ typedef enum {
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
+ sRequiredRSASize,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -676,6 +680,8 @@ static struct {
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
+ { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ NULL, sBadOption, 0 }
};
@@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
*charptr = xstrdup(arg);
break;
+ case sRequiredRSASize:
+ intptr = &options->required_rsa_size;
+ goto parse_int;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
+ M_CP_INTOPT(required_rsa_size);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o)
dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
+ dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
/* formatted integer arguments */
diff --git a/servconf.h b/servconf.h
index 8a04463e..9346155c 100644
--- a/servconf.h
+++ b/servconf.h
@@ -229,6 +229,7 @@ typedef struct {
int expose_userauth_info;
u_int64_t timing_secret;
char *sk_provider;
+ int required_rsa_size; /* minimum size of RSA keys */
} ServerOptions;
/* Information about the incoming connection as used by Match */
diff --git a/ssh.c b/ssh.c
index 559bf2af..25be53d5 100644
--- a/ssh.c
+++ b/ssh.c
@@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port)
}
/*
- * Check the result of hostkey loading, ignoring some errors and
- * fatal()ing for others.
+ * Check the result of hostkey loading, ignoring some errors and either
+ * discarding the key or fatal()ing for others.
*/
static void
-check_load(int r, const char *path, const char *message)
+check_load(int r, struct sshkey **k, const char *path, const char *message)
{
switch (r) {
case 0:
+ /* Check RSA keys size and discard if undersized */
+ if (k != NULL && *k != NULL &&
+ (r = sshkey_check_rsa_length(*k,
+ options.required_rsa_size)) != 0) {
+ error_r(r, "load %s \"%s\"", message, path);
+ free(*k);
+ *k = NULL;
+ }
break;
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
@@ -1578,7 +1586,7 @@ main(int ac, char **av)
if ((o) >= sensitive_data.nkeys) \
fatal_f("pubkey out of array bounds"); \
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
- p, "pubkey"); \
+ &(sensitive_data.keys[o]), p, "pubkey"); \
} while (0)
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
@@ -1586,7 +1594,8 @@ main(int ac, char **av)
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
fatal_f("cert out of array bounds"); \
- check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
+ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
+ &(sensitive_data.keys[o]), p, "cert"); \
} while (0)
if (options.hostbased_authentication == 1) {
@@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", filename,
public ? public->type : -1);
free(options.identity_files[i]);
@@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
continue;
xasprintf(&cp, "%s-cert", filename);
check_load(sshkey_load_public(cp, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", cp,
public ? public->type : -1);
if (public == NULL) {
@@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "certificate");
+ &public, filename, "certificate");
debug("certificate file %s type %d", filename,
public ? public->type : -1);
free(options.certificate_files[i]);
diff --git a/sshconnect2.c b/sshconnect2.c
index f9bd19ea..58fe98db 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info;
static int
verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
+ int r;
+
+ if ((r = sshkey_check_rsa_length(hostkey,
+ options.required_rsa_size)) != 0)
+ fatal_r(r, "Bad server host key");
if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
xxx_conn_info) == -1)
fatal("Host key verification failed.");
@@ -1606,6 +1611,13 @@ load_identity_file(Identity *id)
private = NULL;
quit = 1;
}
+ if (!quit && (r = sshkey_check_rsa_length(private,
+ options.required_rsa_size)) != 0) {
+ debug_fr(r, "Skipping key %s", id->filename);
+ sshkey_free(private);
+ private = NULL;
+ quit = 1;
+ }
if (!quit && private != NULL && id->agent_fd == -1 &&
!(id->key && id->isprivate))
maybe_add_key_to_agent(id->filename, private, comment,
@@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
close(agent_fd);
} else {
for (j = 0; j < idlist->nkeys; j++) {
+ if ((r = sshkey_check_rsa_length(idlist->keys[j],
+ options.required_rsa_size)) != 0) {
+ debug_fr(r, "ignoring %s agent key",
+ sshkey_ssh_name(idlist->keys[j]));
+ continue;
+ }
found = 0;
TAILQ_FOREACH(id, &files, next) {
/*
diff --git a/sshd.c b/sshd.c
index 17eee9d8..395ef493 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1870,6 +1870,13 @@ main(int ac, char **av)
fatal_r(r, "Could not demote key: \"%s\"",
options.host_key_files[i]);
}
+ if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,
+ options.required_rsa_size)) != 0) {
+ error_fr(r, "Host key %s", options.host_key_files[i]);
+ sshkey_free(pubkey);
+ sshkey_free(key);
+ continue;
+ }
sensitive_data.host_keys[i] = key;
sensitive_data.host_pubkeys[i] = pubkey;
diff --git a/sshkey.c b/sshkey.c
index ed2b5dff..77093235 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
return ret;
}
-#ifdef WITH_OPENSSL
-static int
-check_rsa_length(const RSA *rsa)
+int
+sshkey_check_rsa_length(const struct sshkey *k, int min_size)
{
+#ifdef WITH_OPENSSL
const BIGNUM *rsa_n;
+ int nbits;
- RSA_get0_key(rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ 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;
}
-#endif
static int
sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
@@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
goto out;
}
rsa_n = rsa_e = NULL; /* transferred */
- if ((ret = check_rsa_length(key->rsa)) != 0)
+ if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
goto out;
#ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8);
@@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
goto out;
}
rsa_p = rsa_q = NULL; /* transferred */
- if ((r = check_rsa_length(k->rsa)) != 0)
+ if ((r = sshkey_check_rsa_length(k, 0)) != 0)
goto out;
if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
goto out;
@@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if ((r = check_rsa_length(prv->rsa)) != 0)
+ if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
goto out;
} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
(type == KEY_UNSPEC || type == KEY_DSA)) {
diff --git a/sshkey.h b/sshkey.h
index 094815e0..be254e6b 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -273,6 +273,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
int type, struct sshkey **pubkeyp);
+int sshkey_check_rsa_length(const struct sshkey *, int);
/* XXX should be internal, but used by ssh-keygen */
int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
diff --git a/ssh.1 b/ssh.1
index b4956aec..e255b9b9 100644
--- a/ssh.1
+++ b/ssh.1
@@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
diff --git a/ssh_config.5 b/ssh_config.5
index 24a46460..d1ede18e 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1634,6 +1634,17 @@ and
.Fl T
flags for
.Xr ssh 1 .
+.It Cm RequiredRSASize
+Specifies the minimum RSA key size (in bits) that
+.Xr ssh 1
+will accept.
+User authentication keys smaller than this limit will be ignored.
+Servers that present host keys smaller than this limit will cause the
+connection to be terminated.
+The default is
+.Cm 1024
+bits.
+Note that this limit may only be raised from the default.
.It Cm RevokedHostKeys
Specifies revoked host public keys.
Keys listed in this file will be refused for host authentication.
diff --git a/sshd_config.5 b/sshd_config.5
index 867a747d..f5a06637 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1596,6 +1596,16 @@ is
.Cm default none ,
which means that rekeying is performed after the cipher's default amount
of data has been sent or received and no time based rekeying is done.
+.It Cm RequiredRSASize
+Specifies the minimum RSA key size (in bits) that
+.Xr sshd 8
+will accept.
+User and host-based authentication keys smaller than this limit will be
+refused.
+The default is
+.Cm 1024
+bits.
+Note that this limit may only be raised from the default.
.It Cm RevokedKeys
Specifies revoked public keys file, or
.Cm none

View File

@ -0,0 +1,63 @@
diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
--- a/regress/hostkey-agent.sh 2021-08-20 06:03:49.000000000 +0200
+++ b/regress/hostkey-agent.sh 2022-07-14 11:58:12.172786060 +0200
@@ -13,8 +13,12 @@ r=$?
grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig
echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig
+PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
+ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
+SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
+
trace "load hostkeys"
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
(
printf 'localhost-with-alias,127.0.0.1,::1 '
@@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host
unset SSH_AUTH_SOCK
for ps in yes; do
- for k in $SSH_KEYTYPES ; do
+ for k in $SSH_ACCEPTED_KEYTYPES ; do
verbose "key type $k privsep=$ps"
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-14 10:10:07.262975710 +0200
+++ b/sshconnect2.c 2022-07-14 10:10:32.068452067 +0200
@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *s, *all_key;
+ char *hostkeyalgs = NULL, *pkalg = NULL;
char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r, use_known_hosts_order = 0;
@@ -264,14 +265,19 @@ ssh_kex2(struct ssh *ssh, char *host, st
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
if (use_known_hosts_order) {
/* Query known_hosts and prefer algorithms that appear there */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
- compat_pkalg_proposal(ssh,
- order_hostkeyalgs(host, hostaddr, port, cinfo));
+ if ((hostkeyalgs = order_hostkeyalgs(host, hostaddr, port, cinfo)) == NULL)
+ fatal_f("order_hostkeyalgs");
+ pkalg = match_filter_allowlist(hostkeyalgs, options.pubkey_accepted_algos);
+ free(hostkeyalgs);
} else {
- /* Use specified HostkeyAlgorithms exactly */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
- compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
+ /* Use specified HostkeyAlgorithms */
+ pkalg = match_filter_allowlist(options.hostkeyalgorithms, options.pubkey_accepted_algos);
}
+ if (pkalg == NULL)
+ fatal_f("match_filter_allowlist");
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
+ compat_pkalg_proposal(ssh, pkalg);
+ free(pkalg);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {

View File

@ -0,0 +1,53 @@
diff --color -ru a/ssh.1 b/ssh.1
--- a/ssh.1 2022-07-12 11:47:51.307295880 +0200
+++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200
@@ -493,6 +493,7 @@
.It AddressFamily
.It BatchMode
.It BindAddress
+.It BindInterface
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
@@ -510,6 +511,7 @@
.It ControlPath
.It ControlPersist
.It DynamicForward
+.It EnableSSHKeysign
.It EscapeChar
.It ExitOnForwardFailure
.It FingerprintHash
@@ -538,6 +540,8 @@
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
+.It IgnoreUnknown
+.It Include
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
@@ -546,6 +550,7 @@
.It LocalCommand
.It LocalForward
.It LogLevel
+.It LogVerbose
.It MACs
.It Match
.It NoHostAuthenticationForLocalhost
@@ -566,6 +571,8 @@
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RevokedHostKeys
+.It SecurityKeyProvider
.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
@@ -575,6 +582,7 @@
.It StreamLocalBindMask
.It StreamLocalBindUnlink
.It StrictHostKeyChecking
+.It SyslogFacility
.It TCPKeepAlive
.It Tunnel
.It TunnelDevice

View File

@ -0,0 +1,19 @@
diff -up openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
--- openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 2022-07-15 15:08:12.865585410 +0200
+++ openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c 2022-07-15 15:16:25.164282372 +0200
@@ -87,8 +87,13 @@ userauth_pubkey_from_id(const char *ruse
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
- goto user_auth_clean_exit;
+ if (sshkey_type_plain(id->key->type) == KEY_RSA
+ && ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), "rsa-sha2-256", 0) == 0) {
+ /* Do nothing */
+ } else {
+ if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
+ goto user_auth_clean_exit;
+ }
/* test for correct signature */
if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)

View File

@ -51,9 +51,9 @@
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
%global openssh_ver 8.7p1 %global openssh_ver 8.7p1
%global openssh_rel 10 %global openssh_rel 24
%global pam_ssh_agent_ver 0.10.4 %global pam_ssh_agent_ver 0.10.4
%global pam_ssh_agent_rel 4 %global pam_ssh_agent_rel 5
Summary: An open source implementation of SSH protocol version 2 Summary: An open source implementation of SSH protocol version 2
Name: openssh Name: openssh
@ -102,6 +102,8 @@ Patch306: pam_ssh_agent_auth-0.10.2-compat.patch
# Fix NULL dereference from getpwuid() return value # Fix NULL dereference from getpwuid() return value
# https://sourceforge.net/p/pamsshagentauth/bugs/22/ # https://sourceforge.net/p/pamsshagentauth/bugs/22/
Patch307: pam_ssh_agent_auth-0.10.2-dereference.patch Patch307: pam_ssh_agent_auth-0.10.2-dereference.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2070113
Patch308: pam_ssh_agent_auth-0.10.4-rsasha2.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch400: openssh-7.8p1-role-mls.patch Patch400: openssh-7.8p1-role-mls.patch
@ -212,12 +214,49 @@ Patch980: openssh-8.7p1-sftpscp-dir-create.patch
# https://github.com/openssh/openssh-portable/pull/299 # https://github.com/openssh/openssh-portable/pull/299
# downstream only # downstream only
Patch981: openssh-8.7p1-recursive-scp.patch Patch981: openssh-8.7p1-recursive-scp.patch
# https://github.com/djmdjm/openssh-wip/pull/13
Patch982: openssh-8.7p1-minrsabits.patch
# downstream only
Patch983: openssh-8.7p1-evpgenkey.patch
# downstream only, IBMCA tentative fix
# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14
Patch984: openssh-8.7p1-ibmca.patch
# Minimize the use of SHA1 as a proof of possession for RSA key (#2031868)
# upstream commits:
# 291721bc7c840d113a49518f3fca70e86248b8e8
# 0fa33683223c76289470a954404047bc762be84c
# Avoid dubious diagnostics on update known hosts (#2115246)
# 8832402bd500d1661ccc80a476fd563335ef6cdc
Patch1000: openssh-8.7p1-minimize-sha1-use.patch Patch1000: openssh-8.7p1-minimize-sha1-use.patch
# Fix for scp clearing file when src and dest are the same (#2108409) # Fix for scp clearing file when src and dest are the same (#2056884)
# upstream commits: # upstream commits:
# 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee # 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
Patch1001: openssh-8.7p1-scp-clears-file.patch Patch1001: openssh-8.7p1-scp-clears-file.patch
# Add missing options from ssh_config into ssh manpage
# upstream bug:
# https://bugzilla.mindrot.org/show_bug.cgi?id=3455
Patch1002: openssh-8.7p1-ssh-manpage.patch
# Always return allocated strings from the kex filtering so that we can free them
# upstream commits:
# 486c4dc3b83b4b67d663fb0fa62bc24138ec3946
# 6c31ba10e97b6953c4f325f526f3e846dfea647a
# 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b
Patch1003: openssh-8.7p1-mem-leak.patch
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch1004: openssh-8.7p1-gssapi-auth.patch
# Fix host-based authentication with rsa keys
# upstream commits:
# 7aa7b096cf2bafe2777085abdeed5ce00581f641
# d9dbb5d9a0326e252d3c7bc13beb9c2434f59409
# fdb1d58d0d3888b042e5a500f6ce524486aaf782
Patch1005: openssh-8.7p1-host-based-auth.patch
# Don't propose disallowed algorithms during hostkey negotiation
# upstream MR:
# https://github.com/openssh/openssh-portable/pull/323
Patch1006: openssh-8.7p1-negotiate-supported-algs.patch
License: BSD License: BSD
Requires: /sbin/nologin Requires: /sbin/nologin
@ -345,6 +384,7 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%patch306 -p2 -b .psaa-compat %patch306 -p2 -b .psaa-compat
%patch305 -p2 -b .psaa-agent %patch305 -p2 -b .psaa-agent
%patch307 -p2 -b .psaa-deref %patch307 -p2 -b .psaa-deref
%patch308 -p2 -b .rsasha2
# Remove duplicate headers and library files # Remove duplicate headers and library files
rm -f $(cat %{SOURCE5}) rm -f $(cat %{SOURCE5})
popd popd
@ -399,13 +439,21 @@ popd
%patch979 -p1 -b .find-principals %patch979 -p1 -b .find-principals
%patch980 -p1 -b .sftpdirs %patch980 -p1 -b .sftpdirs
%patch981 -p1 -b .scp-sftpdirs %patch981 -p1 -b .scp-sftpdirs
%patch982 -p1 -b .minrsabits
%patch983 -p1 -b .evpgenrsa
%patch984 -p1 -b .ibmca
%patch200 -p1 -b .audit %patch200 -p1 -b .audit
%patch201 -p1 -b .audit-race %patch201 -p1 -b .audit-race
%patch700 -p1 -b .fips %patch700 -p1 -b .fips
%patch1000 -p1 -b .minsha1 %patch1000 -p1 -b .minimize-sha1-use
%patch1001 -p1 -b .scp-clears-file %patch1001 -p1 -b .scp-clears-file
%patch1002 -p1 -b .ssh-manpage
%patch1003 -p1 -b .mem-leak
%patch1004 -p1 -b .gssapi-auth
%patch1005 -p1 -b .host-based-auth
%patch1006 -p1 -b .negotiate-supported-algs
%patch100 -p1 -b .coverity %patch100 -p1 -b .coverity
@ -686,13 +734,87 @@ test -f %{sysconfig_anaconda} && \
%endif %endif
%changelog %changelog
* Tue Jul 26 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-10 * Fri Sep 23 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-24
- Fix openssh-8.7p1-scp-clears-file.patch - Set minimal value of RSA key length via configuration option - support both names
Related: rhbz#2108409 Resolves: rhbz#2128352
* Thu Jul 21 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-9 * Thu Sep 22 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-23
- Set minimal value of RSA key length via configuration option
Resolves: rhbz#2128352
* Tue Aug 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-22
- Avoid spirous message on connecting to the machine with ssh-rsa keys
Related: rhbz#2115246
- Set minimal value of RSA key length via configuration option
Related: rhbz#2066882
* Thu Aug 04 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-21
- IBMCA workaround
Related: rhbz#1976202
* Tue Jul 26 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-20 + 0.10.4-5
- Fix openssh-8.7p1-scp-clears-file.patch
Related: rhbz#2056884
* Fri Jul 15 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-19 + 0.10.4-5
- FIX pam_ssh_agent_auth auth for RSA keys
Related: rhbz#2070113
* Thu Jul 14 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-18
- Fix new coverity issues
Related: rhbz#2068423
* Thu Jul 14 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-17
- Disable ed25519 and ed25519-sk keys in FIPS mode
Related: rhbz#2087915
* Thu Jul 14 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-16
- Don't propose disallowed algorithms during hostkey negotiation
Resolves: rhbz#2068423
* Thu Jul 14 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-15
- Disable ed25519 and ed25519-sk keys in FIPS mode
Related: rhbz#2087915
* Wed Jul 13 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-14
- Disable ed25519 and ed25519-sk keys in FIPS mode
Related: rhbz#2087915
* Tue Jul 12 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-13
- Add reference for policy customization in ssh/sshd_config manpages
Resolves: rhbz#1984575
* Mon Jul 11 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-12
- Disable sntrup761x25519-sha512 in FIPS mode
Related: rhbz#2070628
- Disable ed25519 and ed25519-sk keys in FIPS mode
Related: rhbz#2087915
* Mon Jul 11 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-11
- Fix scp clearing file when src and dest are the same - Fix scp clearing file when src and dest are the same
Resolves: rhbz#2108409 Resolves: rhbz#2056884
- Add missing options from ssh_config into ssh manpage
Resolves: rhbz#2033372
- Fix several memory leaks
Related: rhbz#2068423
- Fix gssapi authentication failures
Resolves: rhbz#2091023
- Fix host-based authentication with rsa keys
Resolves: rhbz#2088916
* Wed Jun 29 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-10
- Set minimal value of RSA key length via configuration option
Related: rhbz#2066882
- Use EVP functions for RSA key generation
Related: rhbz#2087121
* Wed Jun 29 2022 Zoltan Fridrich <zfridric@redhat.com> - 8.7p1-9
- Update minimize-sha1-use.patch to use upstream code
Related: rhbz#2031868
- Change product name from Fedora to RHEL in openssh-7.8p1-UsePAM-warning.patch
Resolves: rhbz#2064338
- Change log level of FIPS specific log message to verbose
Resolves: rhbz#2102201
* Mon Feb 21 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-8 * Mon Feb 21 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-8
- Workaround for RHEL 8 incompatibility in scp utility in SFTP mode - Workaround for RHEL 8 incompatibility in scp utility in SFTP mode