import openssh-8.7p1-22.el9

This commit is contained in:
CentOS Sources 2022-09-27 09:53:35 -04:00 committed by root
parent ab0d991457
commit 044f5935ef
16 changed files with 1863 additions and 151 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,8 +387,8 @@ 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) == -1) fflag || global_fflag, 0) == -1)
err = -1; err = -1;
} }
+ free(abs_dst); + free(abs_dst);
@ -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,437 @@
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 2ab222ed6..4e9437912 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -118,6 +118,10 @@ userauth_hostbased(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) {
+ logit("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 daa756a01..68e7dea1f 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -172,6 +172,10 @@ userauth_pubkey(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) {
+ logit("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 5b5afa8e3..5e17abd41 100644
--- a/readconf.c
+++ b/readconf.c
@@ -160,7 +160,7 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
- oSecurityKeyProvider, oKnownHostsCommand,
+ oSecurityKeyProvider, oKnownHostsCommand, oRSAMinSize,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -306,6 +306,7 @@ static struct {
{ "proxyjump", oProxyJump },
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
+ { "rsaminsize", oRSAMinSize },
{ NULL, oBadOption }
};
@@ -2162,6 +2163,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
*charptr = xstrdup(arg);
break;
+ case oRSAMinSize:
+ intptr = &options->rsa_min_size;
+ goto parse_int;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -2409,6 +2414,7 @@ initialize_options(Options * options)
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
+ options->rsa_min_size = -1;
}
/*
@@ -2598,6 +2604,8 @@ fill_default_options(Options * options)
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
#endif
+ if (options->rsa_min_size == -1)
+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -3287,6 +3295,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(oRSAMinSize, o->rsa_min_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
diff --git a/readconf.h b/readconf.h
index f647bd42a..29db353ab 100644
--- a/readconf.h
+++ b/readconf.h
@@ -176,6 +176,8 @@ typedef struct {
char *known_hosts_command;
+ int rsa_min_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 f7317a5cb..362ff5b67 100644
--- a/servconf.c
+++ b/servconf.c
@@ -177,6 +177,7 @@ initialize_server_options(ServerOptions *options)
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
options->expose_userauth_info = -1;
+ options->rsa_min_size = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -416,6 +417,8 @@ fill_default_server_options(ServerOptions *options)
options->expose_userauth_info = 0;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
+ if (options->rsa_min_size == -1)
+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
assemble_algorithms(options);
@@ -489,6 +492,7 @@ typedef enum {
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
+ sRSAMinSize,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -632,6 +636,7 @@ static struct {
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
+ { "rsaminsize", sRSAMinSize, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -2377,6 +2382,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
*charptr = xstrdup(arg);
break;
+ case sRSAMinSize:
+ intptr = &options->rsa_min_size;
+ goto parse_int;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -2549,6 +2558,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(rsa_min_size);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2810,6 +2820,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(sRSAMinSize, o->rsa_min_size);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
/* formatted integer arguments */
diff --git a/servconf.h b/servconf.h
index 115db1e79..2e3486906 100644
--- a/servconf.h
+++ b/servconf.h
@@ -227,6 +227,7 @@ typedef struct {
int expose_userauth_info;
u_int64_t timing_secret;
char *sk_provider;
+ int rsa_min_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 a926cc007..cd13fb879 100644
--- a/ssh.c
+++ b/ssh.c
@@ -500,14 +500,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.rsa_min_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:
@@ -1557,12 +1565,13 @@ 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) \
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]);
@@ -2263,7 +2272,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) {
@@ -2294,7 +2303,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 67f8e0309..d050c1656 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -91,6 +91,10 @@ 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.rsa_min_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.");
@@ -1762,6 +1762,12 @@ load_identity_file(Identity *id)
private = NULL;
quit = 1;
}
+ if (r = sshkey_check_rsa_length(private, options.rsa_min_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,
@@ -1747,6 +1751,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.rsa_min_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 d26eb86ae..5f36905a1 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1746,6 +1746,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.rsa_min_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 47864e6d8..8bad6bd99 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -2319,18 +2319,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,
@@ -2391,7 +2397,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);
@@ -3580,7 +3586,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;
@@ -4566,7 +4572,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 125cadb64..52e879456 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -267,6 +267,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..b1a40ebd 100644
--- a/ssh.1
+++ b/ssh.1
@@ -554,6 +554,7 @@ For full details of the options listed below, and their possible values, see
.It LogLevel
.It MACs
.It Match
+.It RSAMinSize
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
diff --git a/ssh_config.5 b/ssh_config.5
index 24a46460..68771e4b 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1322,6 +1322,10 @@ The argument to this keyword must be
or
.Cm no
(the default).
+.It Cm RSAMinSize
+Provides a minimal bits requirement for RSA keys when used for signature and
+verification but not for the key generation. The default value is 1024 and
+can't be reduced.
.It Cm NumberOfPasswordPrompts
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
diff --git a/sshd_config.5 b/sshd_config.5
index 867a747d..e08811ca 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1266,6 +1266,10 @@ will refuse connection attempts with a probability of rate/100 (30%)
if there are currently start (10) unauthenticated connections.
The probability increases linearly and all connection attempts
are refused if the number of unauthenticated connections reaches full (60).
+.It Cm RSAMinSize
+Provides a minimal bits requirement for RSA keys when used for signature and
+verification but not for the key generation. The default value is 1024 and
+can't be reduced.
.It Cm ModuliFile
Specifies the
.Xr moduli 5
diff --git a/sshkey.h b/sshkey.h
index 094815e0..2bb8cb90 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -286,6 +286,8 @@ int sshkey_private_serialize_maxsign(struct sshkey *key,
void sshkey_sig_details_free(struct sshkey_sig_details *);
+int ssh_set_rsa_min_bits(int minbits);
+
#ifdef SSHKEY_INTERNAL
int ssh_rsa_sign(const struct sshkey *key,
u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,

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,304 @@
diff --color -rup a/scp.c b/scp.c
--- a/scp.c 2022-07-26 14:51:40.560120817 +0200
+++ b/scp.c 2022-07-26 14:52:37.118213004 +0200
@@ -1324,12 +1324,12 @@ source_sftp(int argc, char *src, char *t
if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
error("failed to upload directory %s to %s",
src, abs_dst);
errs = 1;
}
- } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
+ } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
error("failed to upload file %s to %s", src, abs_dst);
errs = 1;
}
@@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1)
+ pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag, 0, 0) == -1)
+ pflag, 0, 0, 1) == -1)
err = -1;
}
free(abs_dst);
diff --color -rup a/sftp.c b/sftp.c
--- a/sftp.c 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp.c 2022-07-26 14:52:37.119213023 +0200
@@ -666,12 +666,12 @@ process_get(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0) == -1)
+ fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
}
free(abs_dst);
@@ -760,12 +760,12 @@ process_put(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0, 0) == -1)
+ fflag || global_fflag, 0, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
}
}
diff --color -rup a/sftp-client.c b/sftp-client.c
--- a/sftp-client.c 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp-client.c 2022-07-26 15:09:54.825295533 +0200
@@ -1454,7 +1454,7 @@ progress_meter_path(const char *path)
int
do_download(struct sftp_conn *conn, const char *remote_path,
const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
- int fsync_flag)
+ int fsync_flag, int inplace_flag)
{
struct sshbuf *msg;
u_char *handle;
@@ -1498,8 +1498,8 @@ do_download(struct sftp_conn *conn, cons
&handle, &handle_len) != 0)
return -1;
- local_fd = open(local_path,
- O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
+ local_fd = open(local_path, O_WRONLY | O_CREAT |
+ ((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR);
if (local_fd == -1) {
error("Couldn't open local file \"%s\" for writing: %s",
local_path, strerror(errno));
@@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons
/* Sanity check */
if (TAILQ_FIRST(&requests) != NULL)
fatal("Transfer complete, but requests still in queue");
- /* Truncate at highest contiguous point to avoid holes on interrupt */
- if (read_error || write_error || interrupted) {
+ /*
+ * Truncate at highest contiguous point to avoid holes on interrupt,
+ * or unconditionally if writing in place.
+ */
+ if (inplace_flag || read_error || write_error || interrupted) {
if (reordered && resume_flag) {
error("Unable to resume download of \"%s\": "
"server reordered requests", local_path);
@@ -1724,7 +1727,7 @@ do_download(struct sftp_conn *conn, cons
static int
download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
- int resume_flag, int fsync_flag, int follow_link_flag)
+ int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag)
{
int i, ret = 0;
SFTP_DIRENT **dir_entries;
@@ -1781,7 +1784,7 @@ download_dir_internal(struct sftp_conn *
if (download_dir_internal(conn, new_src, new_dst,
depth + 1, &(dir_entries[i]->a), preserve_flag,
print_flag, resume_flag,
- fsync_flag, follow_link_flag) == -1)
+ fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(dir_entries[i]->a.perm) ||
(follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
@@ -1793,7 +1796,8 @@ download_dir_internal(struct sftp_conn *
if (do_download(conn, new_src, new_dst,
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
&(dir_entries[i]->a),
- preserve_flag, resume_flag, fsync_flag) == -1) {
+ preserve_flag, resume_flag, fsync_flag,
+ inplace_flag) == -1) {
error("Download of file %s to %s failed",
new_src, new_dst);
ret = -1;
@@ -1831,7 +1835,7 @@ download_dir_internal(struct sftp_conn *
int
download_dir(struct sftp_conn *conn, const char *src, const char *dst,
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
- int fsync_flag, int follow_link_flag)
+ int fsync_flag, int follow_link_flag, int inplace_flag)
{
char *src_canon;
int ret;
@@ -1843,26 +1847,25 @@ download_dir(struct sftp_conn *conn, con
ret = download_dir_internal(conn, src_canon, dst, 0,
dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
- follow_link_flag);
+ follow_link_flag, inplace_flag);
free(src_canon);
return ret;
}
int
do_upload(struct sftp_conn *conn, const char *local_path,
- const char *remote_path, int preserve_flag, int resume, int fsync_flag)
+ const char *remote_path, int preserve_flag, int resume,
+ int fsync_flag, int inplace_flag)
{
int r, local_fd;
- u_int status = SSH2_FX_OK;
- u_int id;
- u_char type;
+ u_int openmode, id, status = SSH2_FX_OK, reordered = 0;
off_t offset, progress_counter;
- u_char *handle, *data;
+ u_char type, *handle, *data;
struct sshbuf *msg;
struct stat sb;
- Attrib a, *c = NULL;
- u_int32_t startid;
- u_int32_t ackid;
+ Attrib a, t, *c = NULL;
+ u_int32_t startid, ackid;
+ u_int64_t highwater = 0;
struct request *ack = NULL;
struct requests acks;
size_t handle_len;
@@ -1913,10 +1916,15 @@ do_upload(struct sftp_conn *conn, const
}
}
+ openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT;
+ if (resume)
+ openmode |= SSH2_FXF_APPEND;
+ else if (!inplace_flag)
+ openmode |= SSH2_FXF_TRUNC;
+
/* Send open request */
- if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT|
- (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC),
- &a, &handle, &handle_len) != 0) {
+ if (send_open(conn, remote_path, "dest", openmode, &a,
+ &handle, &handle_len) != 0) {
close(local_fd);
return -1;
}
@@ -1999,6 +2007,12 @@ do_upload(struct sftp_conn *conn, const
ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
progress_counter += ack->len;
+ if (!reordered && ack->offset <= highwater)
+ highwater = ack->offset + ack->len;
+ else if (!reordered && ack->offset > highwater) {
+ debug3_f("server reordered ACKs");
+ reordered = 1;
+ }
free(ack);
}
offset += len;
@@ -2017,6 +2031,14 @@ do_upload(struct sftp_conn *conn, const
status = SSH2_FX_FAILURE;
}
+ if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) {
+ debug("truncating at %llu", (unsigned long long)highwater);
+ attrib_clear(&t);
+ t.flags = SSH2_FILEXFER_ATTR_SIZE;
+ t.size = highwater;
+ do_fsetstat(conn, handle, handle_len, &t);
+ }
+
if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path,
strerror(errno));
@@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const
static int
upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int depth, int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag)
+ int follow_link_flag, int inplace_flag)
{
int ret = 0;
DIR *dirp;
@@ -2119,12 +2141,13 @@ upload_dir_internal(struct sftp_conn *co
if (upload_dir_internal(conn, new_src, new_dst,
depth + 1, preserve_flag, print_flag, resume,
- fsync_flag, follow_link_flag) == -1)
+ fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(sb.st_mode) ||
(follow_link_flag && S_ISLNK(sb.st_mode))) {
if (do_upload(conn, new_src, new_dst,
- preserve_flag, resume, fsync_flag) == -1) {
+ preserve_flag, resume, fsync_flag,
+ inplace_flag) == -1) {
error("Uploading of file %s to %s failed!",
new_src, new_dst);
ret = -1;
@@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co
int
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag, int create_dir)
+ int follow_link_flag, int create_dir, int inplace_flag)
{
char *dst_canon;
int ret;
@@ -2155,7 +2178,7 @@ upload_dir(struct sftp_conn *conn, const
}
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
- print_flag, resume, fsync_flag, follow_link_flag);
+ print_flag, resume, fsync_flag, follow_link_flag, inplace_flag);
free(dst_canon);
return ret;
diff --color -rup a/sftp-client.h b/sftp-client.h
--- a/sftp-client.h 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp-client.h 2022-07-26 14:52:37.120213042 +0200
@@ -138,28 +138,29 @@ int do_fsync(struct sftp_conn *conn, u_c
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(struct sftp_conn *, const char *, const char *,
- Attrib *, int, int, int);
+int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
+ int, int, int, int);
/*
* Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set
*/
-int download_dir(struct sftp_conn *, const char *, const char *,
- Attrib *, int, int, int, int, int);
+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
+ int, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
+int do_upload(struct sftp_conn *, const char *, const char *,
+ int, int, int, int);
/*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set
*/
-int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
- int, int, int);
+int upload_dir(struct sftp_conn *, const char *, const char *,
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to

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 RSAMinSize
@@ -566,6 +571,8 @@
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RevokedHostKeys
+.It SecurityKeyProvider
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
@@ -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 8 %global openssh_rel 22
%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,8 +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 (#2056884)
# upstream commits:
# 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
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
@ -341,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
@ -395,12 +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
%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
@ -681,6 +734,80 @@ test -f %{sysconfig_anaconda} && \
%endif %endif
%changelog %changelog
* 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
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
Related: rhbz#2038854 Related: rhbz#2038854