From 7f53c0e13378491b703ef0dc06b1938c9bb4bd46 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 28 Mar 2023 09:20:54 +0000 Subject: [PATCH] import openssh-8.7p1-28.el9 --- SOURCES/openssh-7.7p1-fips.patch | 54 ++++- SOURCES/openssh-8.7p1-minrsabits.patch | 237 ++++++++++---------- SOURCES/openssh-8.7p1-nohostsha1proof.patch | 100 +++++++++ SOURCES/openssh-8.7p1-ssh-manpage.patch | 4 +- SOURCES/openssh-9.1p1-sshbanner.patch | 57 +++++ SPECS/openssh.spec | 50 ++++- 6 files changed, 378 insertions(+), 124 deletions(-) create mode 100644 SOURCES/openssh-8.7p1-nohostsha1proof.patch create mode 100644 SOURCES/openssh-9.1p1-sshbanner.patch diff --git a/SOURCES/openssh-7.7p1-fips.patch b/SOURCES/openssh-7.7p1-fips.patch index 1466b40..05b2907 100644 --- a/SOURCES/openssh-7.7p1-fips.patch +++ b/SOURCES/openssh-7.7p1-fips.patch @@ -1,6 +1,14 @@ 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 2021-05-06 12:12:10.107634472 +0200 +@@ -36,6 +36,7 @@ + + #include + #include ++#include + + #include "dh.h" + #include "pathnames.h" @@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -67,6 +75,14 @@ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c --- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200 +++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200 +@@ -39,6 +39,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + # ifdef HAVE_EVP_KDF_CTX_NEW_ID + # include @@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { @@ -86,7 +102,7 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c #ifdef WITH_OPENSSL -+#include ++#include #include #include @@ -154,6 +170,14 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c --- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 +++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #ifdef USE_SYSTEM_GLOB + # include + #else @@ -2538,11 +2538,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -192,6 +216,14 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c --- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 +++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #ifdef HAVE_UTIL_H + #include + #endif @@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); @@ -221,7 +253,7 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c #include #include #endif -+#include ++#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" @@ -243,7 +275,7 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c #include #endif -+#include ++#include + #include "openbsd-compat/sys-queue.h" @@ -332,7 +364,7 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c #include #include #include -+#include ++#include #include "openbsd-compat/openssl-compat.h" #endif @@ -395,7 +427,7 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #include #include #include -+#include ++#include #endif #include "crypto_api.h" @@ -482,6 +514,14 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.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 2021-05-06 12:08:36.503926916 +0200 +@@ -20,6 +20,7 @@ + + #ifdef WITH_OPENSSL + #include ++#include + #include + #include "openbsd-compat/openssl-compat.h" + #endif @@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } @@ -521,7 +561,7 @@ diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c #include #include #include -+#include ++#include #include "sshkey.h" #include "kex.h" @@ -607,7 +647,7 @@ diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c #include #include -+#include ++#include #include "log.h" #include "sshbuf.h" diff --git a/SOURCES/openssh-8.7p1-minrsabits.patch b/SOURCES/openssh-8.7p1-minrsabits.patch index 107fe70..b53c383 100644 --- a/SOURCES/openssh-8.7p1-minrsabits.patch +++ b/SOURCES/openssh-8.7p1-minrsabits.patch @@ -1,184 +1,188 @@ diff --git a/auth2-hostbased.c b/auth2-hostbased.c -index 2ab222ed6..4e9437912 100644 +index 36b9d2f5..6b517db4 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c -@@ -118,6 +118,10 @@ userauth_hostbased(struct ssh *ssh, const char *method) +@@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method) "(null)" : key->cert->signature_type); goto done; } -+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { -+ logit("refusing %s key", sshkey_type(key)); ++ if ((r = sshkey_check_rsa_length(key, ++ options.required_rsa_size)) != 0) { ++ logit_r(r, "refusing %s key", sshkey_type(key)); + goto done; + } if (!authctxt->valid || authctxt->user == NULL) { debug2_f("disabled because of invalid user"); diff --git a/auth2-pubkey.c b/auth2-pubkey.c -index daa756a01..68e7dea1f 100644 +index 962fd342..5d59febc 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c -@@ -172,6 +172,10 @@ userauth_pubkey(struct ssh *ssh, const char *method) +@@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method) "(null)" : key->cert->signature_type); goto done; } -+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) { -+ logit("refusing %s key", sshkey_type(key)); ++ if ((r = sshkey_check_rsa_length(key, ++ options.required_rsa_size)) != 0) { ++ logit_r(r, "refusing %s key", sshkey_type(key)); + goto done; + } key_s = format_key(key); if (sshkey_is_cert(key)) ca_s = format_key(key->cert->signature_key); diff --git a/readconf.c b/readconf.c -index 5b5afa8e3..5e17abd41 100644 +index 7f26c680..42be690b 100644 --- a/readconf.c +++ b/readconf.c -@@ -160,7 +160,7 @@ typedef enum { +@@ -174,7 +174,7 @@ typedef enum { oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, - oSecurityKeyProvider, oKnownHostsCommand, -+ oSecurityKeyProvider, oKnownHostsCommand, oRSAMinSize, ++ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; -@@ -306,6 +306,7 @@ static struct { +@@ -320,6 +320,8 @@ static struct { { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, -+ { "rsaminsize", oRSAMinSize }, ++ { "requiredrsasize", oRequiredRSASize }, ++ { "rsaminsize", oRequiredRSASize }, /* alias */ { NULL, oBadOption } }; -@@ -2162,6 +2163,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, +@@ -2176,6 +2177,10 @@ parse_pubkey_algos: *charptr = xstrdup(arg); break; -+ case oRSAMinSize: -+ intptr = &options->rsa_min_size; ++ case oRequiredRSASize: ++ intptr = &options->required_rsa_size; + goto parse_int; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); -@@ -2409,6 +2414,7 @@ initialize_options(Options * options) +@@ -2423,6 +2428,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; ++ options->required_rsa_size = -1; } /* -@@ -2598,6 +2604,8 @@ fill_default_options(Options * options) +@@ -2619,6 +2625,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; ++ if (options->required_rsa_size == -1) ++ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; /* Expand KEX name lists */ all_cipher = cipher_alg_list(',', 0); -@@ -3287,6 +3295,7 @@ dump_client_config(Options *o, const char *host) +@@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); dump_cfg_int(oServerAliveInterval, o->server_alive_interval); -+ dump_cfg_int(oRSAMinSize, o->rsa_min_size); ++ dump_cfg_int(oRequiredRSASize, o->required_rsa_size); /* String options */ dump_cfg_string(oBindAddress, o->bind_address); diff --git a/readconf.h b/readconf.h -index f647bd42a..29db353ab 100644 +index f647bd42..ffb5ec4f 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 */ ++ int required_rsa_size; /* minimum size of RSA keys */ + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; diff --git a/servconf.c b/servconf.c -index f7317a5cb..362ff5b67 100644 +index 29df0463..423772b1 100644 --- a/servconf.c +++ b/servconf.c -@@ -177,6 +177,7 @@ initialize_server_options(ServerOptions *options) +@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options) options->fingerprint_hash = -1; options->disable_forwarding = -1; options->expose_userauth_info = -1; -+ options->rsa_min_size = -1; ++ options->required_rsa_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) +@@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options) options->expose_userauth_info = 0; if (options->sk_provider == NULL) options->sk_provider = xstrdup("internal"); -+ if (options->rsa_min_size == -1) -+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE; ++ if (options->required_rsa_size == -1) ++ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; assemble_algorithms(options); -@@ -489,6 +492,7 @@ typedef enum { +@@ -517,6 +520,7 @@ typedef enum { sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, -+ sRSAMinSize, ++ sRequiredRSASize, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; -@@ -632,6 +636,7 @@ static struct { +@@ -676,6 +680,8 @@ static struct { { "rdomain", sRDomain, SSHCFG_ALL }, { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, -+ { "rsaminsize", sRSAMinSize, SSHCFG_ALL }, ++ { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, ++ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */ { NULL, sBadOption, 0 } }; -@@ -2377,6 +2382,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; -+ case sRSAMinSize: -+ intptr = &options->rsa_min_size; ++ case sRequiredRSASize: ++ intptr = &options->required_rsa_size; + goto parse_int; + case sDeprecated: case sIgnore: case sUnsupported: -@@ -2549,6 +2558,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) +@@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); M_CP_INTOPT(log_level); -+ M_CP_INTOPT(rsa_min_size); ++ M_CP_INTOPT(required_rsa_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) +@@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o) dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); -+ dump_cfg_int(sRSAMinSize, o->rsa_min_size); ++ dump_cfg_int(sRequiredRSASize, o->required_rsa_size); dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); /* formatted integer arguments */ diff --git a/servconf.h b/servconf.h -index 115db1e79..2e3486906 100644 +index 8a04463e..9346155c 100644 --- a/servconf.h +++ b/servconf.h -@@ -227,6 +227,7 @@ typedef struct { +@@ -229,6 +229,7 @@ typedef struct { int expose_userauth_info; u_int64_t timing_secret; char *sk_provider; -+ int rsa_min_size; /* minimum size of RSA keys */ ++ int required_rsa_size; /* minimum size of RSA keys */ } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/ssh.c b/ssh.c -index a926cc007..cd13fb879 100644 +index 559bf2af..25be53d5 100644 --- a/ssh.c +++ b/ssh.c -@@ -500,14 +500,22 @@ resolve_canonicalize(char **hostp, int port) +@@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port) } /* @@ -196,7 +200,7 @@ index a926cc007..cd13fb879 100644 + /* Check RSA keys size and discard if undersized */ + if (k != NULL && *k != NULL && + (r = sshkey_check_rsa_length(*k, -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + error_r(r, "load %s \"%s\"", message, path); + free(*k); + *k = NULL; @@ -204,13 +208,16 @@ index a926cc007..cd13fb879 100644 break; case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: -@@ -1557,12 +1565,13 @@ main(int ac, char **av) +@@ -1578,7 +1586,7 @@ main(int ac, char **av) if ((o) >= sensitive_data.nkeys) \ fatal_f("pubkey out of array bounds"); \ check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ - p, "pubkey"); \ + &(sensitive_data.keys[o]), p, "pubkey"); \ } while (0) + #define L_CERT(p,o) do { \ + if ((o) >= sensitive_data.nkeys) \ +@@ -1586,7 +1594,8 @@ main(int ac, char **av) #define L_CERT(p,o) do { \ if ((o) >= sensitive_data.nkeys) \ fatal_f("cert out of array bounds"); \ @@ -229,7 +236,7 @@ index a926cc007..cd13fb879 100644 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) +@@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) continue; xasprintf(&cp, "%s-cert", filename); check_load(sshkey_load_public(cp, &public, NULL), @@ -238,7 +245,7 @@ index a926cc007..cd13fb879 100644 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) +@@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) free(cp); check_load(sshkey_load_public(filename, &public, NULL), @@ -248,25 +255,27 @@ index a926cc007..cd13fb879 100644 public ? public->type : -1); free(options.certificate_files[i]); diff --git a/sshconnect2.c b/sshconnect2.c -index 67f8e0309..d050c1656 100644 +index f9bd19ea..58fe98db 100644 --- a/sshconnect2.c +++ b/sshconnect2.c -@@ -91,6 +91,10 @@ static const struct ssh_conn_info *xxx_conn_info; +@@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info; static int verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) { + int r; + -+ if ((r = sshkey_check_rsa_length(hostkey, options.rsa_min_size)) != 0) ++ if ((r = sshkey_check_rsa_length(hostkey, ++ options.required_rsa_size)) != 0) + fatal_r(r, "Bad server host key"); if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_conn_info) == -1) fatal("Host key verification failed."); -@@ -1762,6 +1762,12 @@ load_identity_file(Identity *id) +@@ -1606,6 +1611,13 @@ load_identity_file(Identity *id) private = NULL; quit = 1; } -+ if (r = sshkey_check_rsa_length(private, options.rsa_min_size) != 0) { ++ if (!quit && (r = sshkey_check_rsa_length(private, ++ options.required_rsa_size)) != 0) { + debug_fr(r, "Skipping key %s", id->filename); + sshkey_free(private); + private = NULL; @@ -275,12 +284,12 @@ index 67f8e0309..d050c1656 100644 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) +@@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) close(agent_fd); } else { for (j = 0; j < idlist->nkeys; j++) { + if ((r = sshkey_check_rsa_length(idlist->keys[j], -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + debug_fr(r, "ignoring %s agent key", + sshkey_ssh_name(idlist->keys[j])); + continue; @@ -289,15 +298,15 @@ index 67f8e0309..d050c1656 100644 TAILQ_FOREACH(id, &files, next) { /* diff --git a/sshd.c b/sshd.c -index d26eb86ae..5f36905a1 100644 +index 17eee9d8..395ef493 100644 --- a/sshd.c +++ b/sshd.c -@@ -1746,6 +1746,13 @@ main(int ac, char **av) +@@ -1870,6 +1870,13 @@ main(int ac, char **av) fatal_r(r, "Could not demote key: \"%s\"", options.host_key_files[i]); } + if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey, -+ options.rsa_min_size)) != 0) { ++ options.required_rsa_size)) != 0) { + error_fr(r, "Host key %s", options.host_key_files[i]); + sshkey_free(pubkey); + sshkey_free(key); @@ -307,10 +316,10 @@ index d26eb86ae..5f36905a1 100644 sensitive_data.host_pubkeys[i] = pubkey; diff --git a/sshkey.c b/sshkey.c -index 47864e6d8..8bad6bd99 100644 +index ed2b5dff..77093235 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -2319,18 +2319,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) +@@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) return ret; } @@ -341,7 +350,7 @@ index 47864e6d8..8bad6bd99 100644 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, +@@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, goto out; } rsa_n = rsa_e = NULL; /* transferred */ @@ -350,7 +359,7 @@ index 47864e6d8..8bad6bd99 100644 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) +@@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) goto out; } rsa_p = rsa_q = NULL; /* transferred */ @@ -359,7 +368,7 @@ index 47864e6d8..8bad6bd99 100644 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, +@@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -369,10 +378,10 @@ index 47864e6d8..8bad6bd99 100644 } 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 +index 094815e0..be254e6b 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -267,6 +267,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, +@@ -273,6 +273,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, struct sshkey **pubkeyp); @@ -381,57 +390,57 @@ index 125cadb64..52e879456 100644 int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); diff --git a/ssh.1 b/ssh.1 -index b4956aec..b1a40ebd 100644 +index b4956aec..e255b9b9 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 +@@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see + .It RemoteCommand + .It RemoteForward + .It RequestTTY ++.It RequiredRSASize + .It SendEnv + .It ServerAliveInterval + .It ServerAliveCountMax diff --git a/ssh_config.5 b/ssh_config.5 -index 24a46460..68771e4b 100644 +index 24a46460..d1ede18e 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. +@@ -1634,6 +1634,17 @@ and + .Fl T + flags for + .Xr ssh 1 . ++.It Cm RequiredRSASize ++Specifies the minimum RSA key size (in bits) that ++.Xr ssh 1 ++will accept. ++User authentication keys smaller than this limit will be ignored. ++Servers that present host keys smaller than this limit will cause the ++connection to be terminated. ++The default is ++.Cm 1024 ++bits. ++Note that this limit may only be raised from the default. + .It Cm RevokedHostKeys + Specifies revoked host public keys. + Keys listed in this file will be refused for host authentication. diff --git a/sshd_config.5 b/sshd_config.5 -index 867a747d..e08811ca 100644 +index 867a747d..f5a06637 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, +@@ -1596,6 +1596,16 @@ is + .Cm default none , + which means that rekeying is performed after the cipher's default amount + of data has been sent or received and no time based rekeying is done. ++.It Cm RequiredRSASize ++Specifies the minimum RSA key size (in bits) that ++.Xr sshd 8 ++will accept. ++User and host-based authentication keys smaller than this limit will be ++refused. ++The default is ++.Cm 1024 ++bits. ++Note that this limit may only be raised from the default. + .It Cm RevokedKeys + Specifies revoked public keys file, or + .Cm none diff --git a/SOURCES/openssh-8.7p1-nohostsha1proof.patch b/SOURCES/openssh-8.7p1-nohostsha1proof.patch new file mode 100644 index 0000000..a5323e4 --- /dev/null +++ b/SOURCES/openssh-8.7p1-nohostsha1proof.patch @@ -0,0 +1,100 @@ +diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c +--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100 ++++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100 +@@ -43,6 +43,7 @@ void + compat_banner(struct ssh *ssh, const char *version) + { + int i; ++ int forbid_ssh_rsa = 0; + static struct { + char *pat; + int bugs; +@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha + }; + + /* process table, return first match */ ++ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA); + ssh->compat = 0; + for (i = 0; check[i].pat; i++) { + if (match_pattern_list(version, check[i].pat, 0) == 1) { + debug_f("match: %s pat %s compat 0x%08x", + version, check[i].pat, check[i].bugs); + ssh->compat = check[i].bugs; ++ if (forbid_ssh_rsa) ++ ssh->compat |= SSH_RH_RSASIGSHA; + return; + } + } + debug_f("no match: %s", version); ++ if (forbid_ssh_rsa) ++ ssh->compat |= SSH_RH_RSASIGSHA; + } + + /* Always returns pointer to allocated memory, caller must free. */ +diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h +--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100 +@@ -30,7 +30,7 @@ + #define SSH_BUG_UTF8TTYMODE 0x00000001 + #define SSH_BUG_SIGTYPE 0x00000002 + #define SSH_BUG_SIGTYPE74 0x00000004 +-/* #define unused 0x00000008 */ ++#define SSH_RH_RSASIGSHA 0x00000008 + #define SSH_OLD_SESSIONID 0x00000010 + /* #define unused 0x00000020 */ + #define SSH_BUG_DEBUG 0x00000040 +diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c +--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100 ++++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100 +@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * + else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) + sigalg = "rsa-sha2-256"; + } ++ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) { ++ sigalg = "rsa-sha2-512"; ++ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg); ++ } + debug3_f("sign %s key (index %d) using sigalg %s", + sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); + if ((r = sshbuf_put_cstring(sigbuf, +diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c +--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100 ++++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100 +@@ -1640,6 +1651,7 @@ main(int ac, char **av) + int keytype; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; ++ int forbid_ssh_rsa = 0; + + #ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +@@ -1938,6 +1950,19 @@ main(int ac, char **av) + key = NULL; + continue; + } ++ if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) { ++ size_t sign_size = 0; ++ u_char *tmp = NULL; ++ u_char data[] = "Test SHA1 vector"; ++ int res; ++ ++ res = ssh_rsa_sign(key, &tmp, &sign_size, data, sizeof(data), NULL); ++ free(tmp); ++ if (res == SSH_ERR_LIBCRYPTO_ERROR) { ++ logit_f("sshd: ssh-rsa algorithm is disabled"); ++ forbid_ssh_rsa = 1; ++ } ++ } + if (sshkey_is_sk(key) && + key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { + debug("host key %s requires user presence, ignoring", +@@ -2275,6 +2306,9 @@ main(int ac, char **av) + + check_ip_options(ssh); + ++ if (forbid_ssh_rsa) ++ ssh->compat |= SSH_RH_RSASIGSHA; ++ + /* Prepare the channels layer */ + channel_init_channels(ssh); + channel_set_af(ssh, options.address_family); diff --git a/SOURCES/openssh-8.7p1-ssh-manpage.patch b/SOURCES/openssh-8.7p1-ssh-manpage.patch index bd0bdb7..04e4c06 100644 --- a/SOURCES/openssh-8.7p1-ssh-manpage.patch +++ b/SOURCES/openssh-8.7p1-ssh-manpage.patch @@ -33,16 +33,16 @@ diff --color -ru a/ssh.1 b/ssh.1 +.It LogVerbose .It MACs .It Match - .It RSAMinSize + .It NoHostAuthenticationForLocalhost @@ -566,6 +571,8 @@ .It RemoteCommand .It RemoteForward .It RequestTTY +.It RevokedHostKeys +.It SecurityKeyProvider + .It RequiredRSASize .It SendEnv .It ServerAliveInterval - .It ServerAliveCountMax @@ -575,6 +582,7 @@ .It StreamLocalBindMask .It StreamLocalBindUnlink diff --git a/SOURCES/openssh-9.1p1-sshbanner.patch b/SOURCES/openssh-9.1p1-sshbanner.patch new file mode 100644 index 0000000..57112be --- /dev/null +++ b/SOURCES/openssh-9.1p1-sshbanner.patch @@ -0,0 +1,57 @@ +diff --git a/ssh-keyscan.c b/ssh-keyscan.c +index d29a03b4..d7283136 100644 +--- a/ssh-keyscan.c ++++ b/ssh-keyscan.c +@@ -490,6 +490,15 @@ congreet(int s) + return; + } + ++ /* ++ * Read the server banner as per RFC4253 section 4.2. The "SSH-" ++ * protocol identification string may be preceeded by an arbitarily ++ * large banner which we must read and ignore. Loop while reading ++ * newline-terminated lines until we have one starting with "SSH-". ++ * The ID string cannot be longer than 255 characters although the ++ * preceeding banner lines may (in which case they'll be discarded ++ * in multiple iterations of the outer loop). ++ */ + for (;;) { + memset(buf, '\0', sizeof(buf)); + bufsiz = sizeof(buf); +@@ -517,6 +526,11 @@ congreet(int s) + conrecycle(s); + return; + } ++ if (cp >= buf + sizeof(buf)) { ++ error("%s: greeting exceeds allowable length", c->c_name); ++ confree(s); ++ return; ++ } + if (*cp != '\n' && *cp != '\r') { + error("%s: bad greeting", c->c_name); + confree(s); +diff --git a/sshsig.c b/sshsig.c +index 1e3b6398..eb2a931e 100644 +--- a/sshsig.c ++++ b/sshsig.c +@@ -491,7 +491,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) + { + char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH]; + ssize_t n, total = 0; +- struct ssh_digest_ctx *ctx; ++ struct ssh_digest_ctx *ctx = NULL; + int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR; + struct sshbuf *b = NULL; + +@@ -549,9 +548,11 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) + /* success */ + r = 0; + out: ++ oerrno = errno; + sshbuf_free(b); + ssh_digest_free(ctx); + explicit_bzero(hash, sizeof(hash)); ++ errno = oerrno; + return r; + } + diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec index 4ce3542..93f2613 100644 --- a/SPECS/openssh.spec +++ b/SPECS/openssh.spec @@ -51,7 +51,7 @@ # 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_rel 22 +%global openssh_rel 28 %global pam_ssh_agent_ver 0.10.4 %global pam_ssh_agent_rel 5 @@ -221,6 +221,8 @@ 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 +# Upstream ff89b1bed80721295555bd083b173247a9c0484e, 5062ad48814b06162511c4f5924a33d97b6b2566 +Patch986: openssh-9.1p1-sshbanner.patch # Minimize the use of SHA1 as a proof of possession for RSA key (#2031868) # upstream commits: @@ -257,6 +259,8 @@ Patch1005: openssh-8.7p1-host-based-auth.patch # upstream MR: # https://github.com/openssh/openssh-portable/pull/323 Patch1006: openssh-8.7p1-negotiate-supported-algs.patch +# +Patch1007: openssh-8.7p1-nohostsha1proof.patch License: BSD Requires: /sbin/nologin @@ -324,6 +328,10 @@ Requires: openssh = %{version}-%{release} Summary: A passphrase dialog for OpenSSH and X Requires: openssh = %{version}-%{release} +%package sk-dummy +Summary: OpenSSH SK driver for test purposes +Requires: openssh = %{version}-%{release} + %package -n pam_ssh_agent_auth Summary: PAM module for authentication with ssh-agent Version: %{pam_ssh_agent_ver} @@ -364,6 +372,9 @@ OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains an X11 passphrase dialog for OpenSSH. +%description sk-dummy +This package contains a test SK driver used for OpenSSH test purposes + %description -n pam_ssh_agent_auth This package contains a PAM module which can be used to authenticate users using ssh keys stored in a ssh-agent. Through the use of the @@ -442,6 +453,7 @@ popd %patch982 -p1 -b .minrsabits %patch983 -p1 -b .evpgenrsa %patch984 -p1 -b .ibmca +%patch986 -p1 -b .91cleanup %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -457,6 +469,8 @@ popd %patch100 -p1 -b .coverity +%patch1007 -p1 -b .sshrsacheck + autoreconf pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} autoreconf @@ -532,6 +546,7 @@ perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile %endif %make_build +make regress/misc/sk-dummy/sk-dummy.so # Define a variable to toggle gnome1/gtk2 building. This is necessary # because RPM doesn't handle nested %%if statements. @@ -623,6 +638,10 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} %make_install popd %endif + +install -m 755 -d $RPM_BUILD_ROOT%{_libdir}/sshtest/ +install -m 755 regress/misc/sk-dummy/sk-dummy.so $RPM_BUILD_ROOT%{_libdir}/sshtest + %pre getent group ssh_keys >/dev/null || groupadd -r ssh_keys || : @@ -726,6 +745,9 @@ test -f %{sysconfig_anaconda} && \ %attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass %endif +%files sk-dummy +%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so + %if %{pam_ssh_agent} %files -n pam_ssh_agent_auth %license pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE @@ -734,6 +756,32 @@ test -f %{sysconfig_anaconda} && \ %endif %changelog +* Thu Jan 12 2023 Dmitry Belyavskiy - 8.7p1-28 +- Do not try to use SHA1 for host key ownership proof when we don't support it server-side + Resolves: rhbz#2088750 + +* Thu Jan 12 2023 Zoltan Fridrich - 8.7p1-27 +- Add sk-dummy subpackage for test purposes + Resolves: rhbz#2092780 + +* Fri Jan 06 2023 Dmitry Belyavskiy - 8.7p1-26 +- Fix one-byte overflow in SSH banner processing + Resolves: rhbz#2138345 +- Fix double free() in error path + Resolves: rhbz#2138347 + +* Fri Dec 16 2022 Dmitry Belyavskiy - 8.7p1-25 +- Build fix after OpenSSL rebase + Resolves: rhbz#2153626 + +* Fri Sep 23 2022 Dmitry Belyavskiy - 8.7p1-24 +- Set minimal value of RSA key length via configuration option - support both names + Resolves: rhbz#2128352 + +* Thu Sep 22 2022 Dmitry Belyavskiy - 8.7p1-23 +- Set minimal value of RSA key length via configuration option + Resolves: rhbz#2128352 + * Tue Aug 16 2022 Dmitry Belyavskiy - 8.7p1-22 - Avoid spirous message on connecting to the machine with ssh-rsa keys Related: rhbz#2115246