#49 [DRAFT] Rebasing OpenSSH from 9.0 to 9.3
Closed a year ago by dbelyavs. Opened a year ago by dbelyavs.

file modified
+2
@@ -56,3 +56,5 @@ 

  /openssh-8.8p1.tar.gz.asc

  /openssh-9.0p1.tar.gz

  /openssh-9.0p1.tar.gz.asc

+ /openssh-9.3p1.tar.gz

+ /openssh-9.3p1.tar.gz.asc

@@ -1,101 +0,0 @@ 

- diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c

- --- openssh-5.9p1/cipher-ctr.c.ctr-evp	2012-01-11 09:24:06.000000000 +0100

- +++ openssh-5.9p1/cipher-ctr.c	2012-01-11 15:54:04.675956600 +0100

- @@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in

-  

-  struct ssh_aes_ctr_ctx

-  {

- -	AES_KEY		aes_ctx;

- +	EVP_CIPHER_CTX	ecbctx;

-  	u_char		aes_counter[AES_BLOCK_SIZE];

-  };

-  

- @@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char

-  {

-  	struct ssh_aes_ctr_ctx *c;

-  	size_t n = 0;

- -	u_char buf[AES_BLOCK_SIZE];

- +	u_char ctrbuf[AES_BLOCK_SIZE*256];

- +	u_char buf[AES_BLOCK_SIZE*256];

-  

-  	if (len == 0)

-  		return (1);

-  	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)

-  		return (0);

-  

- -	while ((len--) > 0) {

- +	for (; len > 0; len -= sizeof(u_int)) {

- +		u_int r,a,b;

- +

-  		if (n == 0) {

- -			AES_encrypt(c->aes_counter, buf, &c->aes_ctx);

- -			ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);

- +			int outl, i, buflen;

- +

- +			buflen = MIN(len, sizeof(ctrbuf));

- +

- +			for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {

- +				memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);

- +				ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);

- +			}

- +

- +			EVP_EncryptUpdate(&c->ecbctx, buf, &outl,

- +				ctrbuf, buflen);

-  		}

- -		*(dest++) = *(src++) ^ buf[n];

- -		n = (n + 1) % AES_BLOCK_SIZE;

- +

- +		memcpy(&a, src, sizeof(a));

- +		memcpy(&b, &buf[n], sizeof(b));

- +		r = a ^ b;

- +		memcpy(dest, &r, sizeof(r));

- +		src += sizeof(a);

- +		dest += sizeof(r);

- +

- +		n = (n + sizeof(b)) % sizeof(buf);

-  	}

- +	memset(ctrbuf, '\0', sizeof(ctrbuf));

- +	memset(buf, '\0', sizeof(buf));

-  	return (1);

-  }

-  

- @@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co

-  		c = xmalloc(sizeof(*c));

-  		EVP_CIPHER_CTX_set_app_data(ctx, c);

-  	}

- -	if (key != NULL)

- -		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,

- -		    &c->aes_ctx);

- +

- +	EVP_CIPHER_CTX_init(&c->ecbctx);

- +

- +	if (key != NULL) {

- +		const EVP_CIPHER *cipher;

- +		switch(EVP_CIPHER_CTX_key_length(ctx)*8) {

- +			case 128:

- +				cipher = EVP_aes_128_ecb();

- +				break;

- +			case 192:

- +				cipher = EVP_aes_192_ecb();

- +				break;

- +			case 256:

- +				cipher = EVP_aes_256_ecb();

- +				break;

- +			default:

- +				fatal("ssh_aes_ctr_init: wrong aes key length");

- +		}

- +		if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))

- +			fatal("ssh_aes_ctr_init: cannot initialize aes encryption");

- +		EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);

- +	}

-  	if (iv != NULL)

-  		memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);

-  	return (1);

- @@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)

-  	struct ssh_aes_ctr_ctx *c;

-  

-  	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {

- +		EVP_CIPHER_CTX_cleanup(&c->ecbctx);

-  		memset(c, 0, sizeof(*c));

-  		free(c);

-  		EVP_CIPHER_CTX_set_app_data(ctx, NULL);

file modified
+2 -2
@@ -61,13 +61,13 @@ 

   	ssh-xmss.o \

  @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)

   ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)

-  	$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2)

+  	$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)

   

  +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o

  +	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)

  +

   ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)

-  	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)

+  	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)

   

  @@ -321,6 +325,7 @@ install-files:

   	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)

@@ -28,17 +28,6 @@ 

   	return 0;

   }

   

- 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	2021-03-24 12:03:33.783968166 +0100

- @@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname

- 		    &hostkey_digest, &hostkey_digest_len, hostkey)) {

- 			error("Error calculating key fingerprint.");

- 			freerrset(fingerprints);

- +				free(dnskey_digest);

- 			return -1;

- 		}

- 

  diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c

  --- openssh-8.5p1/gss-genr.c.coverity	2021-03-26 11:52:46.613942552 +0100

  +++ openssh-8.5p1/gss-genr.c	2021-03-26 11:54:37.881726318 +0100
@@ -154,17 +143,6 @@ 

   	return ret;

   }

   

- diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c

- --- openssh-8.5p1/moduli.c.coverity	2021-03-02 11:31:47.000000000 +0100

- +++ openssh-8.5p1/moduli.c	2021-03-24 12:03:33.784968173 +0100

- @@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t

-  	else

-  		logit("failed to write to checkpoint file '%s': %s", cpfile,

-  		    strerror(errno));

- +	/* coverity[leaked_storage : FALSE] */

-  }

-  

-  static unsigned long

  diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c

  --- openssh-7.4p1/monitor.c.coverity	2016-12-23 16:40:26.888788688 +0100

  +++ openssh-7.4p1/monitor.c	2016-12-23 16:40:26.900788691 +0100
@@ -300,24 +278,6 @@ 

   		if (tun != SSH_TUNID_ANY &&

   		    auth_opts->force_tun_device != (int)tun)

   			goto done;

- diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c

- --- openssh-8.5p1/session.c.coverity	2021-03-24 12:03:33.777968124 +0100

- +++ openssh-8.5p1/session.c	2021-03-24 12:03:33.786968187 +0100

- @@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s

-  	/* Environment specified by admin */

-  	for (i = 0; i < options.num_setenv; i++) {

-  		cp = xstrdup(options.setenv[i]);

- +		/* coverity[overwrite_var : FALSE] */

-  		if ((value = strchr(cp, '=')) == NULL) {

-  			/* shouldn't happen; vars are checked in servconf.c */

-  			fatal("Invalid config SetEnv: %s", options.setenv[i]);

-  		}

-  		*value++ = '\0';

-  		child_set_env(&env, &envsize, cp, value);

- +		free(cp);

-  	}

-  

-  	/* SSH_CLIENT deprecated */

  diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c

  --- openssh-7.4p1/sftp.c.coverity	2016-12-19 05:59:41.000000000 +0100

  +++ openssh-7.4p1/sftp.c	2016-12-23 16:40:26.903788691 +0100
@@ -330,25 +290,6 @@ 

   	}

   

   	_exit(1);

- @@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co

-  		if (lflag & LS_LONG_VIEW) {

-  			if (g.gl_statv[i] == NULL) {

-  				error("no stat information for %s", fname);

- +				free(fname);

-  				continue;

-  			}

-  			lname = ls_file(fname, g.gl_statv[i], 1,

- diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c

- --- openssh-8.5p1/sk-usbhid.c.coverity	2021-03-02 11:31:47.000000000 +0100

- +++ openssh-8.5p1/sk-usbhid.c	2021-03-24 12:03:33.786968187 +0100

- @@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s

-  		freezero(rks[i], sizeof(*rks[i]));

-  	}

-  	free(rks);

- +	free(device);

-  	return ret;

-  }

-  

  diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c

  --- openssh-7.4p1/ssh-agent.c.coverity	2016-12-19 05:59:41.000000000 +0100

  +++ openssh-7.4p1/ssh-agent.c	2016-12-23 16:40:26.903788691 +0100
@@ -423,32 +364,3 @@ 

   		} else {

   			if (strncasecmp(cp, "key:", 4) == 0) {

   				cp += 4;

- @@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c

-  		} else if (strncmp(opts[i], "start-line=", 11) == 0) {

-  			start_lineno = strtoul(opts[i]+11, NULL, 10);

-  		} else if (strncmp(opts[i], "checkpoint=", 11) == 0) {

- +			free(checkpoint);

-  			checkpoint = xstrdup(opts[i]+11);

-  		} else if (strncmp(opts[i], "generator=", 10) == 0) {

-  			generator_wanted = (u_int32_t)strtonum(

- @@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c

-  #else /* WITH_OPENSSL */

-  	fatal("Moduli screening is not supported");

-  #endif /* WITH_OPENSSL */

- +	free(checkpoint);

- +	if (in != stdin)

- +		fclose(in);

-  }

-  

-  static char *

- diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c

- --- openssh-8.5p1/sshsig.c.coverity	2021-03-02 11:31:47.000000000 +0100

- +++ openssh-8.5p1/sshsig.c	2021-03-24 12:03:33.787968194 +0100

- @@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s

-  			oerrno = errno;

-  			error_f("read: %s", strerror(errno));

-  			ssh_digest_free(ctx);

- +			ctx = NULL;

-  			errno = oerrno;

-  			r = SSH_ERR_SYSTEM_ERROR;

-  			goto out;

@@ -82,7 +82,7 @@ 

  +++ openssh-7.4p1/channels.h	2016-12-23 15:46:32.139506636 +0100

  @@ -293,7 +293,7 @@ int	 permitopen_port(const char *);

   

-  void	 channel_set_x11_refuse_time(struct ssh *, u_int);

+  void	 channel_set_x11_refuse_time(struct ssh *, time_t);

   int	 x11_connect_display(struct ssh *);

  -int	 x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);

  +int	 x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
@@ -191,8 +191,8 @@ 

  --- openssh-7.4p1/sshd_config.5.x11max	2016-12-23 15:46:32.134506635 +0100

  +++ openssh-7.4p1/sshd_config.5	2016-12-23 15:46:32.141506636 +0100

  @@ -1133,6 +1133,7 @@ Available keywords are

-  .Cm StreamLocalBindUnlink ,

   .Cm TrustedUserCAKeys ,

+  .Cm UnusedConnectionTimeout ,

   .Cm X11DisplayOffset ,

  +.Cm X11MaxDisplays ,

   .Cm X11Forwarding

file modified
+1 -1
@@ -9,8 +9,8 @@ 

  --- a/configure.ac

  +++ b/configure.ac

  @@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5],

-  AC_SUBST([GSSLIBS])

   AC_SUBST([K5LIBS])

+  AC_SUBST([CHANNELLIBS])

   

  +# Check whether user wants systemd support

  +SYSTEMD_MSG="no"

file modified
+1 -1
@@ -21,7 +21,7 @@ 

  +	SC_ALLOW(__NR_flock),

  +#endif

   #ifdef __NR_futex

-  	SC_ALLOW(__NR_futex),

+  	SC_FUTEX(__NR_futex),

   #endif

  @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {

   #ifdef __NR_gettimeofday

file modified
+13 -13
@@ -802,8 +802,8 @@ 

  +}

  +

   static int

-  match_principals_option(const char *principal_list, struct sshkey_cert *cert)

-  {

+  match_principals_file(struct passwd *pw, char *file,

+      struct sshkey_cert *cert, struct sshauthopt **authoptsp)

  diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c

  --- openssh-8.6p1/auth.c.audit	2021-04-19 16:47:35.681061553 +0200

  +++ openssh-8.6p1/auth.c	2021-04-19 16:47:35.754062114 +0200
@@ -820,15 +820,6 @@ 

  diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h

  --- openssh-8.6p1/auth.h.audit	2021-04-19 16:47:35.697061676 +0200

  +++ openssh-8.6p1/auth.h	2021-04-19 16:47:35.754062114 +0200

- @@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh

-  

-  char	*expand_authorized_keys(const char *, struct passwd *pw);

-  char	*authorized_principals_file(struct passwd *);

- +int	 user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t,

- +    const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);

-  

-  FILE	*auth_openkeyfile(const char *, struct passwd *, int);

-  FILE	*auth_openprincipals(const char *, struct passwd *, int);

  @@ -212,6 +214,8 @@ struct sshkey	*get_hostkey_private_by_ty

   int	 get_hostkey_index(struct sshkey *, int, struct ssh *);

   int	 sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
@@ -838,6 +829,15 @@ 

   

   /* Key / cert options linkage to auth layer */

   const struct sshauthopt *auth_options(struct ssh *);

+ @@ -239,6 +241,8 @@ struct passwd * getpwnamallow(struct ssh

+      char *, const char *, const char *, const char *, struct sshauthopt **);

+  int	 auth_check_authkeys_file(struct passwd *, FILE *, char *,

+      struct sshkey *, const char *, const char *, struct sshauthopt **);

+ +int	 user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t,

+ +    const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);

+  FILE	*auth_openkeyfile(const char *, struct passwd *, int);

+  FILE	*auth_openprincipals(const char *, struct passwd *, int);

+  

  diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c

  --- openssh-8.6p1/cipher.c.audit	2021-04-16 05:55:25.000000000 +0200

  +++ openssh-8.6p1/cipher.c	2021-04-19 16:47:35.755062122 +0200
@@ -910,9 +910,9 @@ 

  --- openssh-8.6p1/kex.c.audit	2021-04-19 16:47:35.743062030 +0200

  +++ openssh-8.6p1/kex.c	2021-04-19 16:47:35.755062122 +0200

  @@ -65,6 +65,7 @@

-  #include "ssherr.h"

   #include "sshbuf.h"

   #include "digest.h"

+  #include "xmalloc.h"

  +#include "audit.h"

   

   #ifdef GSSAPI
@@ -2006,7 +2006,7 @@ 

  @@ -71,10 +77,12 @@ void	 session_unused(int);

   int	 session_input_channel_req(struct ssh *, Channel *, const char *);

   void	 session_close_by_pid(struct ssh *ssh, pid_t, int);

-  void	 session_close_by_channel(struct ssh *, int, void *);

+  void	 session_close_by_channel(struct ssh *, int, int, void *);

  -void	 session_destroy_all(struct ssh *, void (*)(Session *));

  +void	 session_destroy_all(struct ssh *, void (*)(struct ssh*, Session *));

   void	 session_pty_cleanup2(Session *);

file modified
+36 -41
@@ -368,14 +368,6 @@ 

   #include "openbsd-compat/openssl-compat.h"

   #endif

   

- @@ -1619,6 +1621,7 @@ main(int ac, char **av)

-  #endif

-  	__progname = ssh_get_progname(av[0]);

-  

- +	OpenSSL_add_all_algorithms();

-  	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */

-  	saved_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\"",
@@ -440,11 +432,11 @@ 

   

   #ifdef WITH_XMSS

  @@ -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)

+  		impl = keyimpls[i];

+  		if (impl->name == NULL || impl->type == KEY_NULL)

   			continue;

  +		if (FIPS_mode()) {

- +			switch (kt->type) {

+ +			switch (impl->type) {

  +			case KEY_ED25519:

  +			case KEY_ED25519_SK:

  +			case KEY_ED25519_CERT:
@@ -455,9 +447,9 @@ 

  +			     break;

  +			}

  +		}

-  		if (!include_sigonly && kt->sigonly)

+  		if (!include_sigonly && impl->sigonly)

   			continue;

-  		if ((certs_only && !kt->cert) || (plain_only && kt->cert))

+  		if ((certs_only && !impl->cert) || (plain_only && impl->cert))

  @@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c

   		return SSH_ERR_EC_CURVE_MISMATCH;

   	}
@@ -477,40 +469,31 @@ 

  +		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;

-  		goto out;

-  	}

+  	sshkey_free_contents(ret);

+  	*ret = *k;

  @@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,

-  		break;

-  	case KEY_ED25519_SK:

-  	case KEY_ED25519_SK_CERT:

- +		if (FIPS_mode()) {

+  		*lenp = 0;

+  	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)

+  		return SSH_ERR_INVALID_ARGUMENT;

+ +		if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {

  +		    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,

+  	if ((impl = sshkey_impl_from_key(key)) == NULL)

+  		return SSH_ERR_KEY_TYPE_UNKNOWN;

+  	if ((r = sshkey_unshield_private(key)) != 0)

  @@ -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()) {

+  		*detailsp = NULL;

+  	if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)

+  		return SSH_ERR_INVALID_ARGUMENT;

+ +		if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {

  +		    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

+ 	if ((impl = sshkey_impl_from_key(key)) == NULL)

+ 		return SSH_ERR_KEY_TYPE_UNKNOWN;

+ 	return impl->funcs->verify(key, sig, siglen, data, dlen,

  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
@@ -554,6 +537,18 @@ 

   		if ((fd = mkstemp(prv_tmp)) == -1) {

   			error("Could not save your private key in %s: %s",

   			    prv_tmp, strerror(errno));

+ diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c

+ --- openssh-9.3p1/ssh-rsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200

+ +++ openssh-9.3p1/ssh-rsa.c	2022-06-30 15:24:31.499641196 +0200

+ @@ -1705,6 +1707,8 @@ ssh_rsa_generate(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;

+  		goto out;

+  	}

  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
@@ -663,13 +658,13 @@ 

   	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)

+  	    dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||

+  	    sig == NULL || siglen == 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)

+  	if ((b = sshbuf_from(sig, siglen)) == NULL)

   		return SSH_ERR_ALLOC_FAIL;

file modified
+139 -44
@@ -12,13 +12,76 @@ 

   

  @@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \

   	auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \

-  	auth2-none.o auth2-passwd.o auth2-pubkey.o \

+  	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \

   	monitor.o monitor_wrap.o auth-krb5.o \

  -	auth2-gss.o gss-serv.o gss-serv-krb5.o \

  +	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \

   	loginrec.o auth-pam.o auth-shadow.o auth-sia.o \

   	srclimit.o sftp-server.o sftp-common.o \

   	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \

+ @@ -213,41 +213,41 @@ sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(S

+  	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)

+  

+  scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)

+ -	$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)

+ +	$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS)

+  

+  ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS)

+ -	$(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHAGENT_OBJS)

+ -	$(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYGEN_OBJS)

+ -	$(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSIGN_OBJS)

+ -	$(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)

+ -	$(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)

+ -	$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) $(GSSLIBS)

+  

+  ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o

+ -	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)

+ +	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) $(GSSLIBS)

+  

+  ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)

+ -	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)

+ +	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS)

+ -	$(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)

+ +	$(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(GSSLIBS)

+  

+  sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS)

+ -	$(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)

+ +	$(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) $(GSSLIBS)

+  

+  # test driver for the loginrec code - not built by default

+  logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o

+ -	$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)

+ +	$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) $(GSSLIBS)

+  

+  $(MANPAGES): $(MANPAGES_IN)

+  	if test "$(MANTYPE)" = "cat"; then \

+ @@ -523,7 +523,7 @@ regress-prep:

+  	    ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile

+  

+  REGRESSLIBS=libssh.a $(LIBCOMPAT)

+ -TESTLIBS=$(LIBS) $(CHANNELLIBS)

+ +TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS)

+  

+  regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS)

+  	$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \

  diff -up a/auth.c.gsskex b/auth.c

  --- a/auth.c.gsskex	2021-08-20 06:03:49.000000000 +0200

  +++ b/auth.c	2021-08-27 12:41:51.262788953 +0200
@@ -378,13 +441,9 @@ 

   /* Permitted RSA signature algorithms for UpdateHostkeys proofs */

   #define HOSTKEY_PROOF_RSA_ALGS	"rsa-sha2-512,rsa-sha2-256"

   

- @@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,

-  			break;

-  

-  		/* Do channel operations unless rekeying in progress. */

- -		if (!ssh_packet_is_rekeying(ssh))

- +		if (!ssh_packet_is_rekeying(ssh)) {

- 			channel_after_poll(ssh, pfd, npfd_active);

+ @@ -1379,6 +1383,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,

+  		/* Do channel operations. */

+  		channel_after_poll(ssh, pfd, npfd_active);

   

  +#ifdef GSSAPI

  +			if (options.gss_renewal_rekey &&
@@ -393,7 +452,6 @@ 

  +				need_rekeying = 1;

  +			}

  +#endif

- +		}

  +

   		/* Buffer input from the connection.  */

  		if (conn_in_ready)
@@ -1254,15 +1312,9 @@ 

  index ce85f043..574c7609 100644

  --- a/kex.c

  +++ b/kex.c

- @@ -57,11 +57,16 @@

-  #include "misc.h"

-  #include "dispatch.h"

-  #include "monitor.h"

- +#include "xmalloc.h"

-  

-  #include "ssherr.h"

-  #include "sshbuf.h"

+ @@ -57,6 +57,10 @@

   #include "digest.h"

+  #include "xmalloc.h"

   

  +#ifdef GSSAPI

  +#include "ssh-gss.h"
@@ -1360,9 +1412,9 @@ 

  +	return 1;

  +}

  +

-  /* put algorithm proposal into buffer */

-  int

-  kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])

+  /*

+   * Fill out a proposal array with dynamically allocated values, which may

+   * be modified as required for compatibility reasons.

  @@ -698,6 +755,9 @@ kex_free(struct kex *kex)

   	sshbuf_free(kex->server_version);

   	sshbuf_free(kex->client_pub);
@@ -1414,9 +1466,9 @@ 

   char	*kex_names_cat(const char *, const char *);

   int	 kex_assemble_names(char **, const char *, const char *);

  +int	 kex_gss_names_valid(const char *);

-  

-  int	 kex_exchange_identification(struct ssh *, int, const char *);

-  

+  void	 kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX],

+      const char *, const char *, const char *, const char *, const char *);

+  void	 kex_proposal_free_entries(char *prop[PROPOSAL_MAX]);

  @@ -202,6 +219,12 @@ int	 kexgex_client(struct ssh *);

   int	 kexgex_server(struct ssh *);

   int	 kex_gen_client(struct ssh *);
@@ -1489,7 +1541,7 @@ 

  index 00000000..f6e1405e

  --- /dev/null

  +++ b/kexgssc.c

- @@ -0,0 +1,599 @@

+ @@ -0,0 +1,629 @@

  +/*

  + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.

  + *
@@ -2088,6 +2140,36 @@ 

  +	sshbuf_free(server_host_key_blob);

  +	return r;

  +}

+ +

+ +/* FIXME */

+ +#if 0

+ +static const struct sshkey_impl_funcs sshkey_gss_funcs = {

+ +	/* .size = */		ssh_gss_size,

+ +	/* .alloc = */		ssh_gss_alloc,

+ +	/* .cleanup = */	ssh_gss_cleanup,

+ +	/* .equal = */		ssh_gss_equal,

+ +	/* .ssh_serialize_public = */ ssh_gss_serialize_public,

+ +	/* .ssh_deserialize_public = */ ssh_gss_deserialize_public,

+ +	/* .ssh_serialize_private = */ ssh_gss_serialize_private,

+ +	/* .ssh_deserialize_private = */ ssh_gss_deserialize_private,

+ +	/* .generate = */	ssh_gss_generate,

+ +	/* .copy_public = */	ssh_gss_copy_public,

+ +	/* .sign = */		ssh_gss_sign,

+ +	/* .verify = */		ssh_gss_verify,

+ +};

+ +#endif

+ +

+ +const struct sshkey_impl sshkey_gss_kex_impl = {

+ +	/* .name = */		"null",

+ +	/* .shortname = */	"null",

+ +	/* .sigalg = */		NULL,

+ +	/* .type = */		KEY_NULL,

+ +	/* .nid = */		0,

+ +	/* .cert = */		0,

+ +	/* .sigonly = */	0,

+ +	/* .keybits = */	0, /* FIXME */

+ +	/* .funcs = */		NULL, /*FIXME &sshkey_gss_funcs,*/

+ +};

  +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */

  diff --git a/kexgsss.c b/kexgsss.c

  new file mode 100644
@@ -3496,7 +3578,7 @@ 

   

   /*

  @@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)

-  	char *s, *all_key;

+  	char *s, *all_key, *hkalgs = NULL;

   	int r, use_known_hosts_order = 0;

   

  +#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -3508,8 +3590,8 @@ 

   	xxx_hostaddr = hostaddr;

   	xxx_conn_info = cinfo;

  @@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)

-  		    compat_pkalg_proposal(ssh, options.hostkeyalgorithms);

-  	}

+  	if (use_known_hosts_order)

+  		hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);

   

  +#if defined(GSSAPI) && defined(WITH_OPENSSL)

  +	if (options.gss_keyex) {
@@ -3547,10 +3629,10 @@ 

  +	}

  +#endif

  +

-  	if (options.rekey_limit || options.rekey_interval)

-  		ssh_packet_set_rekey_limits(ssh, options.rekey_limit,

-  		    options.rekey_interval);

- @@ -224,16 +256,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)

+  	kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,

+  	    options.macs, compression_alg_list(options.compression),

+  	    hkalgs ? hkalgs : options.hostkeyalgorithms);

+ @@ -224,17 +256,47 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)

   # ifdef OPENSSL_HAS_ECC

   	ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;

   # endif
@@ -3583,6 +3665,7 @@ 

   	ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);

   

   	/* remove ext-info from the KEX proposals for rekeying */

+  	free(myproposal[PROPOSAL_KEX_ALGS]);

   	myproposal[PROPOSAL_KEX_ALGS] =

   	    compat_kex_proposal(ssh, options.kex_algorithms);

  +#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -3751,8 +3834,8 @@ 

   		exit(1);

   	}

  @@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh)

-  	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(

-  	    ssh, list_hostkey_types());

+  

+  	free(hkalgs);

   

  +#if defined(GSSAPI) && defined(WITH_OPENSSL)

  +	{
@@ -3885,22 +3968,34 @@ 

  index 57995ee6..fd5b7724 100644

  --- a/sshkey.c

  +++ b/sshkey.c

- @@ -154,6 +154,7 @@ static const struct keytype keytypes[] = {

-  #  endif /* ENABLE_SK */

-  # endif /* OPENSSL_HAS_ECC */

-  #endif /* WITH_OPENSSL */

- +	{ "null", "null", NULL, KEY_NULL, 0, 0, 0 },

-  	{ NULL, NULL, NULL, -1, -1, 0, 0 }

+ @@ -127,6 +127,9 @@ static const struct keytype keytypes[] = {

+  extern const struct sshkey_impl sshkey_xmss_impl;

+  extern const struct sshkey_impl sshkey_xmss_cert_impl;

+  #endif

+ +#ifdef GSSAPI

+ +extern const struct sshkey_impl sshkey_gss_kex_impl;

+ +#endif

+  

+  const struct sshkey_impl * const keyimpls[] = {

+  	&sshkey_ed25519_impl,

+ @@ -154,6 +154,9 @@ static const struct keytype keytypes[] = {

+  	&sshkey_xmss_impl,

+  	&sshkey_xmss_cert_impl,

+  #endif

+ +#ifdef GSSAPI

+ +	&sshkey_gss_kex_impl,

+ +#endif

+  	NULL

   };

   

  @@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)

-  	const struct keytype *kt;

   

-  	for (kt = keytypes; kt->type != -1; kt++) {

- -		if (kt->name == NULL)

- +		if (kt->name == NULL || kt->type == KEY_NULL)

+  	for (i = 0; keyimpls[i] != NULL; i++) {

+  		impl = keyimpls[i];

+ -		if (impl->name == NULL)

+ +		if (impl->name == NULL || impl->type == KEY_NULL)

   			continue;

-  		if (!include_sigonly && kt->sigonly)

+  		if (!include_sigonly && impl->sigonly)

   			continue;

  diff --git a/sshkey.h b/sshkey.h

  index 71a3fddc..37a43a67 100644

file modified
+51 -51
@@ -62,8 +62,8 @@ 

  --- a/ssh-dss.c

  +++ b/ssh-dss.c

  @@ -52,11 +52,15 @@ int

-  ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,

-      const u_char *data, size_t datalen, u_int compat)

+      const u_char *data, size_t datalen,

+      const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)

   {

  +	EVP_PKEY *pkey = NULL;

   	DSA_SIG *sig = NULL;
@@ -119,14 +119,14 @@ 

   	sshbuf_free(b);

   	return ret;

  @@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,

-      const u_char *signature, size_t signaturelen,

-      const u_char *data, size_t datalen, u_int compat)

+      const u_char *data, size_t dlen, const char *alg, u_int compat,

+      struct sshkey_sig_details **detailsp)

   {

  +	EVP_PKEY *pkey = NULL;

-  	DSA_SIG *sig = NULL;

+  	DSA_SIG *dsig = NULL;

   	BIGNUM *sig_r = NULL, *sig_s = NULL;

  -	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;

- -	size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);

+ -	size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1);

  +	u_char *sigblob = NULL;

  +	size_t len, slen;

   	int ret = SSH_ERR_INTERNAL_ERROR;
@@ -136,25 +136,25 @@ 

   

   	if (key == NULL || key->dsa == NULL ||

   	    sshkey_type_plain(key->type) != KEY_DSA ||

-  	    signature == NULL || signaturelen == 0)

+  	    sig == NULL || siglen == 0)

   		return SSH_ERR_INVALID_ARGUMENT;

- -	if (dlen == 0)

+ -	if (hlen == 0)

  -		return SSH_ERR_INTERNAL_ERROR;

   

   	/* fetch signature */

-  	if ((b = sshbuf_from(signature, signaturelen)) == NULL)

+  	if ((b = sshbuf_from(sig, siglen)) == NULL)

  @@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,

   	}

   	sig_r = sig_s = NULL; /* transferred */

   

  -	/* sha1 the data */

- -	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,

+ -	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen,

  -	    digest, sizeof(digest))) != 0)

  +	if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {

  +		ret = SSH_ERR_LIBCRYPTO_ERROR;

   		goto out;

  -

- -	switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {

+ -	switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) {

  -	case 1:

  -		ret = 0;

  -		break;
@@ -177,14 +177,14 @@ 

  +		ret = SSH_ERR_ALLOC_FAIL;

  +		goto out;

  +	}

- +	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,

+ +	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen,

  +	    sigb, slen);

  +	EVP_PKEY_free(pkey);

  +

    out:

  -	explicit_bzero(digest, sizeof(digest));

  +	free(sigb);

-  	DSA_SIG_free(sig);

+  	DSA_SIG_free(dsig);

   	BN_clear_free(sig_r);

   	BN_clear_free(sig_s);

  diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
@@ -192,17 +192,17 @@ 

  --- a/ssh-ecdsa.c

  +++ b/ssh-ecdsa.c

  @@ -50,11 +50,13 @@ int

-  ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,

-      const u_char *data, size_t datalen, u_int compat)

+      const u_char *data, size_t dlen,

+      const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)

   {

  +	EVP_PKEY *pkey = NULL;

-  	ECDSA_SIG *sig = NULL;

+  	ECDSA_SIG *esig = NULL;

  +	unsigned char *sigb = NULL;

  +	const unsigned char *psig;

   	const BIGNUM *sig_r, *sig_s;

   	int hash_alg;

  -	u_char digest[SSH_DIGEST_MAX_LENGTH];

- -	size_t len, dlen;

+ -	size_t len, hlen;

  +	int len;

   	struct sshbuf *b = NULL, *bb = NULL;

   	int ret = SSH_ERR_INTERNAL_ERROR;
@@ -212,25 +212,25 @@ 

   		return SSH_ERR_INVALID_ARGUMENT;

   

  -	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||

- -	    (dlen = ssh_digest_bytes(hash_alg)) == 0)

+ -	    (hlen = ssh_digest_bytes(hash_alg)) == 0)

  +	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)

   		return SSH_ERR_INTERNAL_ERROR;

- -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,

+ -	if ((ret = ssh_digest_memory(hash_alg, data, dlen,

  -	    digest, sizeof(digest))) != 0)

  +

  +	if ((pkey = EVP_PKEY_new()) == NULL ||

  +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)

  +		return SSH_ERR_ALLOC_FAIL;

  +	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,

- +	    datalen);

+ +	    dlen);

  +	EVP_PKEY_free(pkey);

  +	if (ret < 0) {

   		goto out;

  +	}

   

- -	if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {

+ -	if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) {

  +	psig = sigb;

- +	if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {

+ +	if (d2i_ECDSA_SIG(&esig, &psig, len) == NULL) {

   		ret = SSH_ERR_LIBCRYPTO_ERROR;

   		goto out;

   	}
@@ -246,17 +246,17 @@ 

  +	free(sigb);

   	sshbuf_free(b);

   	sshbuf_free(bb);

-  	ECDSA_SIG_free(sig);

+  	ECDSA_SIG_free(esig);

  @@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,

-      const u_char *signature, size_t signaturelen,

-      const u_char *data, size_t datalen, u_int compat)

+      const u_char *data, size_t dlen, const char *alg, u_int compat,

+      struct sshkey_sig_details **detailsp)

   {

  +	EVP_PKEY *pkey = NULL;

-  	ECDSA_SIG *sig = NULL;

+  	ECDSA_SIG *esig = NULL;

   	BIGNUM *sig_r = NULL, *sig_s = NULL;

  -	int hash_alg;

  -	u_char digest[SSH_DIGEST_MAX_LENGTH];

- -	size_t dlen;

+ -	size_t hlen;

  +	int hash_alg, len;

   	int ret = SSH_ERR_INTERNAL_ERROR;

   	struct sshbuf *b = NULL, *sigbuf = NULL;
@@ -265,11 +265,11 @@ 

   

   	if (key == NULL || key->ecdsa == NULL ||

   	    sshkey_type_plain(key->type) != KEY_ECDSA ||

-  	    signature == NULL || signaturelen == 0)

+  	    sig == NULL || siglen == 0)

   		return SSH_ERR_INVALID_ARGUMENT;

   

  -	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||

- -	    (dlen = ssh_digest_bytes(hash_alg)) == 0)

+ -	    (hlen = ssh_digest_bytes(hash_alg)) == 0)

  +	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)

   		return SSH_ERR_INTERNAL_ERROR;

   
@@ -281,7 +281,7 @@ 

  -	if (sshbuf_len(sigbuf) != 0) {

  -		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;

  +	/* Figure out the length */

- +	if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {

+ +	if ((len = i2d_ECDSA_SIG(esig, NULL)) == 0) {

  +		ret = SSH_ERR_LIBCRYPTO_ERROR;

  +		goto out;

  +	}
@@ -289,15 +289,15 @@ 

  +		ret = SSH_ERR_ALLOC_FAIL;

   		goto out;

   	}

- -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,

+ -	if ((ret = ssh_digest_memory(hash_alg, data, dlen,

  -	    digest, sizeof(digest))) != 0)

  +	psig = sigb;

- +	if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {

+ +	if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) {

  +		ret = SSH_ERR_LIBCRYPTO_ERROR;

   		goto out;

  +	}

   

- -	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {

+ -	switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {

  -	case 1:

  -		ret = 0;

  -		break;
@@ -315,7 +315,7 @@ 

  +		ret =  SSH_ERR_ALLOC_FAIL;

   		goto out;

   	}

- +	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);

+ +	ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len);

  +	EVP_PKEY_free(pkey);

   

    out:
@@ -323,7 +323,7 @@ 

  +	free(sigb);

   	sshbuf_free(sigbuf);

   	sshbuf_free(b);

-  	ECDSA_SIG_free(sig);

+  	ECDSA_SIG_free(esig);

  diff --git a/ssh-rsa.c b/ssh-rsa.c

  index 9b14f9a9a..8ef3a6aca 100644

  --- a/ssh-rsa.c
@@ -335,8 +335,8 @@ 

  -static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);

  +static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);

   

-  static const char *

-  rsa_hash_alg_ident(int hash_alg)

+  static u_int

+  ssh_rsa_size(const struct sshkey *key)

  @@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)

   	return -1;

   }
@@ -360,13 +360,13 @@ 

   ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)

   {

  @@ -164,11 +149,10 @@ int

-  ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,

-      const u_char *data, size_t datalen, const char *alg_ident)

+      const u_char *data, size_t datalen,

+      const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)

   {

  -	const BIGNUM *rsa_n;

  -	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;

  -	size_t slen = 0;

- -	u_int dlen, len;

+ -	u_int hlen, len;

  -	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;

  +	EVP_PKEY *pkey = NULL;

  +	u_char *sig = NULL;
@@ -378,7 +378,7 @@ 

  @@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,

   		hash_alg = SSH_DIGEST_SHA1;

   	else

-  		hash_alg = rsa_hash_id_from_keyname(alg_ident);

+  		hash_alg = rsa_hash_id_from_keyname(alg);

  +

   	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||

   	    sshkey_type_plain(key->type) != KEY_RSA)
@@ -392,7 +392,7 @@ 

  -

  -	/* hash the data */

  -	nid = rsa_hash_alg_nid(hash_alg);

- -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)

+ -	if ((hlen = ssh_digest_bytes(hash_alg)) == 0)

  -		return SSH_ERR_INTERNAL_ERROR;

  -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,

  -	    digest, sizeof(digest))) != 0)
@@ -412,7 +412,7 @@ 

   		goto out;

   	}

   

- -	if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {

+ -	if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {

  -		ret = SSH_ERR_LIBCRYPTO_ERROR;

  -		goto out;

  -	}
@@ -436,14 +436,14 @@ 

   	sshbuf_free(b);

   	return ret;

  @@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,

-      const u_char *sig, size_t siglen, const u_char *data, size_t datalen,

-      const char *alg)

+      const u_char *data, size_t dlen, const char *alg, u_int compat,

+      struct sshkey_sig_details **detailsp)

   {

  -	const BIGNUM *rsa_n;

  +	EVP_PKEY *pkey = NULL;

   	char *sigtype = NULL;

   	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;

- -	size_t len = 0, diff, modlen, dlen;

+ -	size_t len = 0, diff, modlen, hlen;

  +	size_t len = 0, diff, modlen;

   	struct sshbuf *b = NULL;

   	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
@@ -462,7 +462,7 @@ 

   		explicit_bzero(sigblob, diff);

   		len = modlen;

   	}

- -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {

+ -	if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {

  -		ret = SSH_ERR_INTERNAL_ERROR;

  +

  +	if ((pkey = EVP_PKEY_new()) == NULL ||
@@ -470,13 +470,13 @@ 

  +		ret = SSH_ERR_ALLOC_FAIL;

   		goto out;

   	}

- -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,

+ -	if ((ret = ssh_digest_memory(hash_alg, data, dlen,

  -	    digest, sizeof(digest))) != 0)

  -		goto out;

- +	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);

+ +	ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey);

  +	EVP_PKEY_free(pkey);

   

- -	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,

+ -	ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,

  -	    key->rsa);

    out:

   	freezero(sigblob, len);
@@ -613,7 +613,7 @@ 

  -	freezero(decrypted, rsasize);

   	return ret;

   }

-  #endif /* WITH_OPENSSL */

+  

  diff --git a/sshkey.c b/sshkey.c

  index ad1957762..b95ed0b10 100644

  --- a/sshkey.c

@@ -76,7 +76,7 @@ 

  +	ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \

   	poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \

   	ssh-ed25519.o digest-openssl.o digest-libc.o \

-  	hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \

+  	hmac.o ed25519.o hash.o \

  @@ -302,6 +302,8 @@ clean:	regressclean

   	rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT)

   	rm -f regress/unittests/utf8/*.o
@@ -105,7 +105,7 @@ 

   	    ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile

  @@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT

   	    regress/unittests/test_helper/libtest_helper.a \

-  	    -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)

+  	    -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)

   

  +UNITTESTS_TEST_PKCS11_OBJS=\

  +	regress/unittests/pkcs11/tests.o
@@ -115,7 +115,7 @@ 

  +    regress/unittests/test_helper/libtest_helper.a libssh.a

  +	$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \

  +	    regress/unittests/test_helper/libtest_helper.a \

- +	    -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)

+ +	    -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lcrypto $(LIBS)

  +

   # These all need to be compiled -fPIC, so they are treated differently.

   SK_DUMMY_OBJS=\

file modified
+37 -38
@@ -1,9 +1,9 @@ 

- 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

+ diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c

+ --- openssh-9.3p1/ssh-rsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200

+ +++ openssh-9.3p1/ssh-rsa.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)

+  ssh_rsa_generate(struct sshkey *k, int bits)

   {

  -	RSA *private = NULL;

  +	EVP_PKEY_CTX *ctx = NULL;
@@ -11,10 +11,10 @@ 

   	BIGNUM *f4 = NULL;

   	int ret = SSH_ERR_INTERNAL_ERROR;

   

- @@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA

+ @@ -1667,20 +1668,42 @@ ssh_rsa_generate(u_int bits, RSA

+ 	if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||

   	    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
@@ -44,14 +44,14 @@ 

  +	}

  +

  +	/* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/

- +	*rsap = EVP_PKEY_get1_RSA(res);

- +	if (*rsap) {

+ +	k->rsa = EVP_PKEY_get1_RSA(res);

+ +	if (k->rsa) {

  +		ret = 0;

  +	} else {

   		ret = SSH_ERR_LIBCRYPTO_ERROR;

   		goto out;

   	}

- -	*rsap = private;

+ -	k->rsa = private;

  -	private = NULL;

  -	ret = 0;

    out:
@@ -61,50 +61,49 @@ 

   	BN_free(f4);

   	return ret;

   }

+ diff -up openssh-9.3p1/ssh-ecdsa.c.evpgenrsa openssh-9.3p1/ssh-ecdsa.c

+ --- openssh-9.3p1/ssh-ecdsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200

+ +++ openssh-9.3p1/ssh-ecdsa.c	2022-06-30 15:24:31.499641196 +0200

  @@ -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)

+  ssh_ecdsa_generate(struct sshkey *k, int bits)

   {

  -	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)

+  	if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)

+  		return SSH_ERR_KEY_LENGTH;

+ @@ -1828,15 +1829,24 @@ ssh_ecdsa_generate(u_int bits, i

+ 

+  	if ((k->ecdsa_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 ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)

  +

- +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) {

-  		ret = SSH_ERR_ALLOC_FAIL;

-  		goto out;

-  	}

+ +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL)

+  		return SSH_ERR_ALLOC_FAIL;

  -	if (EC_KEY_generate_key(private) != 1) {

+ -		EC_KEY_free(private);

+ -		return SSH_ERR_LIBCRYPTO_ERROR;

+ -	}

  +

- +	if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0

+ +	if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0

  +	   || EVP_PKEY_keygen(ctx, &res) <= 0) {

- +		ret = SSH_ERR_LIBCRYPTO_ERROR;

- +		goto out;

+ +		EVP_PKEY_CTX_free(ctx);

+ +		EVP_PKEY_free(res);

+ +		return SSH_ERR_LIBCRYPTO_ERROR;

  +	}

  +	/* 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;

-  	}

+ +	k->ecdsa = EVP_PKEY_get1_EC_KEY(res);

+ +	if (k->ecdsa)

+ +		EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE);

+ +

  -	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);

- -	*ecdsap = private;

- -	private = NULL;

- -	ret = 0;

-   out:

- -	EC_KEY_free(private);

+ -	k->ecdsa = private;

+ -	return 0;

  +	EVP_PKEY_CTX_free(ctx);

  +	EVP_PKEY_free(res);

-  	return ret;

+ + 	return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR;

   }

-  # endif /* OPENSSL_HAS_ECC */

+  

+  static int

@@ -1,156 +0,0 @@ 

- 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");

-  }

-  

file modified
+7 -429
@@ -1,446 +1,24 @@ 

- diff --git a/auth2-hostbased.c b/auth2-hostbased.c

- index 36b9d2f5..6b517db4 100644

- --- a/auth2-hostbased.c

- +++ b/auth2-hostbased.c

- @@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method)

-  		    "(null)" : key->cert->signature_type);

-  		goto done;

-  	}

- +	if ((r = sshkey_check_rsa_length(key,

- +	    options.required_rsa_size)) != 0) {

- +		logit_r(r, "refusing %s key", sshkey_type(key));

- +		goto done;

- +	}

-  

-  	if (!authctxt->valid || authctxt->user == NULL) {

-  		debug2_f("disabled because of invalid user");

- diff --git a/auth2-pubkey.c b/auth2-pubkey.c

- index 962fd342..5d59febc 100644

- --- a/auth2-pubkey.c

- +++ b/auth2-pubkey.c

- @@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method)

-  		    "(null)" : key->cert->signature_type);

-  		goto done;

-  	}

- +	if ((r = sshkey_check_rsa_length(key,

- +	    options.required_rsa_size)) != 0) {

- +		logit_r(r, "refusing %s key", sshkey_type(key));

- +		goto done;

- +	}

-  	key_s = format_key(key);

-  	if (sshkey_is_cert(key))

-  		ca_s = format_key(key->cert->signature_key);

  diff --git a/readconf.c b/readconf.c

  index 7f26c680..42be690b 100644

  --- a/readconf.c

  +++ b/readconf.c

- @@ -174,7 +174,7 @@ typedef enum {

-  	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,

-  	oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,

-  	oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,

- -	oSecurityKeyProvider, oKnownHostsCommand,

- +	oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,

-  	oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported

-  } OpCodes;

-  

- @@ -320,6 +320,8 @@ static struct {

-  	{ "proxyjump", oProxyJump },

+ @@ -320,6 +320,7 @@ static struct {

   	{ "securitykeyprovider", oSecurityKeyProvider },

   	{ "knownhostscommand", oKnownHostsCommand },

- +	{ "requiredrsasize", oRequiredRSASize },

+ 	{ "requiredrsasize", oRequiredRSASize },

  +	{ "rsaminsize", oRequiredRSASize }, /* alias */

+  	{ "enableescapecommandline", oEnableEscapeCommandline },

   

   	{ NULL, oBadOption }

-  };

- @@ -2176,6 +2177,10 @@ parse_pubkey_algos:

-  			*charptr = xstrdup(arg);

-  		break;

-  

- +	case oRequiredRSASize:

- +		intptr = &options->required_rsa_size;

- +		goto parse_int;

- +

-  	case oDeprecated:

-  		debug("%s line %d: Deprecated option \"%s\"",

-  		    filename, linenum, keyword);

- @@ -2423,6 +2428,7 @@ initialize_options(Options * options)

-  	options->hostbased_accepted_algos = NULL;

-  	options->pubkey_accepted_algos = NULL;

-  	options->known_hosts_command = NULL;

- +	options->required_rsa_size = -1;

-  }

-  

-  /*

- @@ -2619,6 +2625,8 @@ fill_default_options(Options * options)

-  	if (options->sk_provider == NULL)

-  		options->sk_provider = xstrdup("$SSH_SK_PROVIDER");

-  #endif

- +	if (options->required_rsa_size == -1)

- +		options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;

-  

-  	/* Expand KEX name lists */

-  	all_cipher = cipher_alg_list(',', 0);

- @@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host)

-  	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);

-  	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);

-  	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);

- +	dump_cfg_int(oRequiredRSASize, o->required_rsa_size);

-  

-  	/* String options */

-  	dump_cfg_string(oBindAddress, o->bind_address);

- diff --git a/readconf.h b/readconf.h

- index f647bd42..ffb5ec4f 100644

- --- a/readconf.h

- +++ b/readconf.h

- @@ -176,6 +176,8 @@ typedef struct {

-  

-  	char   *known_hosts_command;

-  

- +	int	required_rsa_size;	/* minimum size of RSA keys */

- +

-  	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */

-  }       Options;

-  

  diff --git a/servconf.c b/servconf.c

  index 29df0463..423772b1 100644

  --- a/servconf.c

  +++ b/servconf.c

- @@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options)

-  	options->fingerprint_hash = -1;

-  	options->disable_forwarding = -1;

-  	options->expose_userauth_info = -1;

- +	options->required_rsa_size = -1;

-  }

-  

-  /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */

- @@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options)

-  		options->expose_userauth_info = 0;

-  	if (options->sk_provider == NULL)

-  		options->sk_provider = xstrdup("internal");

- +	if (options->required_rsa_size == -1)

- +		options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;

-  

-  	assemble_algorithms(options);

-  

- @@ -517,6 +520,7 @@ typedef enum {

-  	sStreamLocalBindMask, sStreamLocalBindUnlink,

-  	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,

-  	sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,

- +	sRequiredRSASize,

-  	sDeprecated, sIgnore, sUnsupported

-  } ServerOpCodes;

-  

- @@ -676,6 +680,8 @@ static struct {

-  	{ "rdomain", sRDomain, SSHCFG_ALL },

+ @@ -676,6 +680,7 @@ static struct {

   	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },

   	{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },

- +	{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },

+ 	{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },

  +	{ "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */

+  	{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },

+  	{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },

   	{ NULL, sBadOption, 0 }

-  };

-  

- @@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,

-  			*charptr = xstrdup(arg);

-  		break;

-  

- +	case sRequiredRSASize:

- +		intptr = &options->required_rsa_size;

- +		goto parse_int;

- +

-  	case sDeprecated:

-  	case sIgnore:

-  	case sUnsupported:

- @@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)

-  	M_CP_INTOPT(rekey_limit);

-  	M_CP_INTOPT(rekey_interval);

-  	M_CP_INTOPT(log_level);

- +	M_CP_INTOPT(required_rsa_size);

-  

-  	/*

-  	 * The bind_mask is a mode_t that may be unsigned, so we can't use

- @@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o)

-  	dump_cfg_int(sMaxSessions, o->max_sessions);

-  	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);

-  	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);

- +	dump_cfg_int(sRequiredRSASize, o->required_rsa_size);

-  	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);

-  

-  	/* formatted integer arguments */

- diff --git a/servconf.h b/servconf.h

- index 8a04463e..9346155c 100644

- --- a/servconf.h

- +++ b/servconf.h

- @@ -229,6 +229,7 @@ typedef struct {

-  	int	expose_userauth_info;

-  	u_int64_t timing_secret;

-  	char   *sk_provider;

- +	int	required_rsa_size;	/* minimum size of RSA keys */

-  }       ServerOptions;

-  

-  /* Information about the incoming connection as used by Match */

- diff --git a/ssh.c b/ssh.c

- index 559bf2af..25be53d5 100644

- --- a/ssh.c

- +++ b/ssh.c

- @@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port)

-  }

-  

-  /*

- - * Check the result of hostkey loading, ignoring some errors and

- - * fatal()ing for others.

- + * Check the result of hostkey loading, ignoring some errors and either

- + * discarding the key or fatal()ing for others.

-   */

-  static void

- -check_load(int r, const char *path, const char *message)

- +check_load(int r, struct sshkey **k, const char *path, const char *message)

-  {

-  	switch (r) {

-  	case 0:

- +		/* Check RSA keys size and discard if undersized */

- +		if (k != NULL && *k != NULL &&

- +		    (r = sshkey_check_rsa_length(*k,

- +		    options.required_rsa_size)) != 0) {

- +			error_r(r, "load %s \"%s\"", message, path);

- +			free(*k);

- +			*k = NULL;

- +		}

-  		break;

-  	case SSH_ERR_INTERNAL_ERROR:

-  	case SSH_ERR_ALLOC_FAIL:

- @@ -1578,7 +1586,7 @@ main(int ac, char **av)

-  	if ((o) >= sensitive_data.nkeys) \

-  		fatal_f("pubkey out of array bounds"); \

-  	check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \

- -	    p, "pubkey"); \

- +	    &(sensitive_data.keys[o]), p, "pubkey"); \

-  	if (sensitive_data.keys[o] != NULL) \

-  		debug2("hostbased key %d: %s key from \"%s\"", o, \

-  		    sshkey_ssh_name(sensitive_data.keys[o]), p); \

- @@ -1586,7 +1594,8 @@ main(int ac, char **av)

-  #define L_CERT(p,o) do { \

-  	if ((o) >= sensitive_data.nkeys) \

-  		fatal_f("cert out of array bounds"); \

- -	check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \

- +	check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \

- +	    &(sensitive_data.keys[o]), p, "cert"); \

-  	if (sensitive_data.keys[o] != NULL) \

-  		debug2("hostbased key %d: %s cert from \"%s\"", o, \

-  		    sshkey_ssh_name(sensitive_data.keys[o]), p); \

- @@ -2265,7 +2274,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)

-  		filename = default_client_percent_dollar_expand(cp, cinfo);

-  		free(cp);

-  		check_load(sshkey_load_public(filename, &public, NULL),

- -		    filename, "pubkey");

- +		    &public, filename, "pubkey");

-  		debug("identity file %s type %d", filename,

-  		    public ? public->type : -1);

-  		free(options.identity_files[i]);

- @@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)

-  			continue;

-  		xasprintf(&cp, "%s-cert", filename);

-  		check_load(sshkey_load_public(cp, &public, NULL),

- -		    filename, "pubkey");

- +		    &public, filename, "pubkey");

-  		debug("identity file %s type %d", cp,

-  		    public ? public->type : -1);

-  		if (public == NULL) {

- @@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)

-  		free(cp);

-  

-  		check_load(sshkey_load_public(filename, &public, NULL),

- -		    filename, "certificate");

- +		    &public, filename, "certificate");

-  		debug("certificate file %s type %d", filename,

-  		    public ? public->type : -1);

-  		free(options.certificate_files[i]);

- diff --git a/sshconnect2.c b/sshconnect2.c

- index f9bd19ea..58fe98db 100644

- --- a/sshconnect2.c

- +++ b/sshconnect2.c

- @@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info;

-  static int

-  verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)

-  {

- +	int r;

- +

- +	if ((r = sshkey_check_rsa_length(hostkey,

- +	    options.required_rsa_size)) != 0)

- +		fatal_r(r, "Bad server host key");

-  	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,

-  	    xxx_conn_info) == -1)

-  		fatal("Host key verification failed.");

- @@ -1606,6 +1611,13 @@ load_identity_file(Identity *id)

-  			private = NULL;

-  			quit = 1;

-  		}

- +		if (!quit && (r = sshkey_check_rsa_length(private,

- +		    options.required_rsa_size)) != 0) {

- +			debug_fr(r, "Skipping key %s", id->filename);

- +			sshkey_free(private);

- +			private = NULL;

- +			quit = 1;

- +		}

-  		if (!quit && private != NULL && id->agent_fd == -1 &&

-  		    !(id->key && id->isprivate))

-  			maybe_add_key_to_agent(id->filename, private, comment,

- @@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)

-  	/* list of keys supported by the agent */

-  	if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) {

-  		for (j = 0; j < idlist->nkeys; j++) {

- +			if ((r = sshkey_check_rsa_length(idlist->keys[j],

- +			    options.required_rsa_size)) != 0) {

- +				debug_fr(r, "ignoring %s agent key",

- +				    sshkey_ssh_name(idlist->keys[j]));

- +				continue;

- +			}

-  			found = 0;

-  			TAILQ_FOREACH(id, &files, next) {

-  				/*

- diff --git a/sshd.c b/sshd.c

- index 17eee9d8..395ef493 100644

- --- a/sshd.c

- +++ b/sshd.c

- @@ -1870,6 +1870,13 @@ main(int ac, char **av)

-  				fatal_r(r, "Could not demote key: \"%s\"",

-  				    options.host_key_files[i]);

-  		}

- +		if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,

- +		    options.required_rsa_size)) != 0) {

- +			error_fr(r, "Host key %s", options.host_key_files[i]);

- +			sshkey_free(pubkey);

- +			sshkey_free(key);

- +			continue;

- +		}

-  		sensitive_data.host_keys[i] = key;

-  		sensitive_data.host_pubkeys[i] = pubkey;

-  

- diff --git a/sshkey.c b/sshkey.c

- index ed2b5dff..77093235 100644

- --- a/sshkey.c

- +++ b/sshkey.c

- @@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)

-  	return ret;

-  }

-  

- -#ifdef WITH_OPENSSL

- -static int

- -check_rsa_length(const RSA *rsa)

- +int

- +sshkey_check_rsa_length(const struct sshkey *k, int min_size)

-  {

- +#ifdef WITH_OPENSSL

-  	const BIGNUM *rsa_n;

- +	int nbits;

-  

- -	RSA_get0_key(rsa, &rsa_n, NULL, NULL);

- -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)

- +	if (k == NULL || k->rsa == NULL ||

- +	    (k->type != KEY_RSA && k->type != KEY_RSA_CERT))

- +		return 0;

- +	RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);

- +	nbits = BN_num_bits(rsa_n);

- +	if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||

- +	    (min_size > 0 && nbits < min_size))

-  		return SSH_ERR_KEY_LENGTH;

- +#endif /* WITH_OPENSSL */

-  	return 0;

-  }

- -#endif

-  

-  static int

-  sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,

- @@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,

-  			goto out;

-  		}

-  		rsa_n = rsa_e = NULL; /* transferred */

- -		if ((ret = check_rsa_length(key->rsa)) != 0)

- +		if ((ret = sshkey_check_rsa_length(key, 0)) != 0)

-  			goto out;

-  #ifdef DEBUG_PK

-  		RSA_print_fp(stderr, key->rsa, 8);

- @@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)

-  			goto out;

-  		}

-  		rsa_p = rsa_q = NULL; /* transferred */

- -		if ((r = check_rsa_length(k->rsa)) != 0)

- +		if ((r = sshkey_check_rsa_length(k, 0)) != 0)

-  			goto out;

-  		if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)

-  			goto out;

- @@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,

-  			r = SSH_ERR_LIBCRYPTO_ERROR;

-  			goto out;

-  		}

- -		if ((r = check_rsa_length(prv->rsa)) != 0)

- +		if ((r = sshkey_check_rsa_length(prv, 0)) != 0)

-  			goto out;

-  	} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&

-  	    (type == KEY_UNSPEC || type == KEY_DSA)) {

- diff --git a/sshkey.h b/sshkey.h

- index 094815e0..be254e6b 100644

- --- a/sshkey.h

- +++ b/sshkey.h

- @@ -273,6 +273,7 @@ int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,

-  int	sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,

-      int type, struct sshkey **pubkeyp);

-  

- +int sshkey_check_rsa_length(const struct sshkey *, int);

-  /* XXX should be internal, but used by ssh-keygen */

-  int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);

-  

- diff --git a/ssh.1 b/ssh.1

- index b4956aec..e255b9b9 100644

- --- a/ssh.1

- +++ b/ssh.1

- @@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see

-  .It RemoteCommand

-  .It RemoteForward

-  .It RequestTTY

- +.It RequiredRSASize

-  .It SendEnv

-  .It ServerAliveInterval

-  .It ServerAliveCountMax

- diff --git a/ssh_config.5 b/ssh_config.5

- index 24a46460..d1ede18e 100644

- --- a/ssh_config.5

- +++ b/ssh_config.5

- @@ -1634,6 +1634,17 @@ and

-  .Fl T

-  flags for

-  .Xr ssh 1 .

- +.It Cm RequiredRSASize

- +Specifies the minimum RSA key size (in bits) that

- +.Xr ssh 1

- +will accept.

- +User authentication keys smaller than this limit will be ignored.

- +Servers that present host keys smaller than this limit will cause the

- +connection to be terminated.

- +The default is

- +.Cm 1024

- +bits.

- +Note that this limit may only be raised from the default.

-  .It Cm RevokedHostKeys

-  Specifies revoked host public keys.

-  Keys listed in this file will be refused for host authentication.

- diff --git a/sshd_config.5 b/sshd_config.5

- index 867a747d..f5a06637 100644

- --- a/sshd_config.5

- +++ b/sshd_config.5

- @@ -1596,6 +1596,16 @@ is

-  .Cm default none ,

-  which means that rekeying is performed after the cipher's default amount

-  of data has been sent or received and no time based rekeying is done.

- +.It Cm RequiredRSASize

- +Specifies the minimum RSA key size (in bits) that

- +.Xr sshd 8

- +will accept.

- +User and host-based authentication keys smaller than this limit will be

- +refused.

- +The default is

- +.Cm 1024

- +bits.

- +Note that this limit may only be raised from the default.

-  .It Cm RevokedKeys

-  Specifies revoked public keys file, or

-  .Cm none

@@ -1,63 +1,117 @@ 

- 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=$?

+ diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh

+ --- openssh-9.3p1/regress/hostkey-agent.sh.xxx	2023-05-29 18:15:56.311236887 +0200

+ +++ openssh-9.3p1/regress/hostkey-agent.sh	2023-05-29 18:16:07.598503551 +0200

+ @@ -17,8 +17,21 @@ trace "make CA key"

   

   ${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"

   

  +PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \

  +    grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`

  +SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`

+ +echo $PUBKEY_ACCEPTED_ALGOS | grep "rsa"

+ +r=$?

+ +if [ $r == 0 ]; then

+ +echo $SSH_ACCEPTED_KEYTYPES | grep "rsa"

+ +r=$?

+ +if [ $r -ne 0 ]; then

+ +SSH_ACCEPTED_KEYTYPES="$SSH_ACCEPTED_KEYTYPES ssh-rsa"

+ +fi

+ +fi

  +

   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"

- 	${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \

- 		-I localhost-with-alias $OBJ/agent-key.$k.pub || \

- @@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host

+  	${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"

+  	${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \

+  		-I localhost-with-alias $OBJ/agent-key.$k.pub || \

+ @@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private

   

   unset SSH_AUTH_SOCK

   

  -for k in $SSH_KEYTYPES ; do

  +for k in $SSH_ACCEPTED_KEYTYPES ; do

- 	verbose "key type $k"

- 	cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy

- 	echo "HostKeyAlgorithms $k" >> $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

+  	verbose "key type $k"

+ +	hka=$k

+ +	if [ $k = "ssh-rsa" ]; then

+ +	   hka="rsa-sha2-512"

+ +	fi

+  	cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy

+ -	echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy

+ +	echo "HostKeyAlgorithms $hka" >> $OBJ/sshd_proxy

+  	echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy

+ -	opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"

+ +	opts="-oHostKeyAlgorithms=$hka -F $OBJ/ssh_proxy"

+  	( printf 'localhost-with-alias,127.0.0.1,::1 ' ;

+  	  cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts

+  	SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`

+ @@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do

+  done

+  

+  SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'`

+ +SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`

+  

+  # Prepare sshd_proxy for certificates.

+  cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy

+  HOSTKEYALGS=""

+ -for k in $SSH_CERTTYPES ; do

+ +for k in $SSH_ACCEPTED_CERTTYPES ; do

+  	test -z "$HOSTKEYALGS" || HOSTKEYALGS="${HOSTKEYALGS},"

+  	HOSTKEYALGS="${HOSTKEYALGS}${k}"

+  done

+ -for k in $SSH_KEYTYPES ; do

+ +for k in $SSH_ACCEPTED_KEYTYPES ; do

+  	echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy

+  	echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy

+  	test -f $OBJ/agent-key.${k}.pub || fatal "no $k key"

+ @@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >>

+  ( printf '@cert-authority localhost-with-alias ' ;

+    cat $OBJ/agent-ca.pub) > $OBJ/known_hosts

+  

+ -for k in $SSH_CERTTYPES ; do

+ +for k in $SSH_ACCEPTED_CERTTYPES ; do

+  	verbose "cert type $k"

+  	opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"

+  	SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`

+ diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c

+ --- openssh-9.3p1/sshconnect2.c.xxx	2023-04-26 17:37:35.100827792 +0200

+ +++ openssh-9.3p1/sshconnect2.c	2023-04-26 17:50:31.860748877 +0200

+ @@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st

+      const struct ssh_conn_info *cinfo)

   {

-  	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;

+  	char *myproposal[PROPOSAL_MAX];

+ -	char *s, *all_key, *hkalgs = NULL;

+ +	char *s, *all_key, *hkalgs = NULL, *filtered_algs = 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)

+ @@ -260,6 +260,18 @@ ssh_kex2(struct ssh *ssh, char *host, st

+  	if (use_known_hosts_order)

+  		hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);

   

+ +	filtered_algs = hkalgs ? match_filter_allowlist(hkalgs, options.pubkey_accepted_algos)

+ +		               : match_filter_allowlist(options.hostkeyalgorithms,

+ +				 options.pubkey_accepted_algos);

+ +	if (filtered_algs == NULL) {

+ +		if (hkalgs)

+ +			fatal_f("No match between algorithms for %s (host %s) and pubkey accepted algorithms %s",

+ +			       hkalgs, host, options.pubkey_accepted_algos);

+ +		else

+ +			fatal_f("No match between host key algorithms %s and pubkey accepted algorithms %s",

+ +			        options.hostkeyalgorithms, options.pubkey_accepted_algos);

+ +	}

+ +

   #if defined(GSSAPI) && defined(WITH_OPENSSL)

   	if (options.gss_keyex) {

+  		if (FIPS_mode()) {

+ @@ -303,9 +315,10 @@ ssh_kex2(struct ssh *ssh, char *host, st

+  

+  	kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,

+  	    options.macs, compression_alg_list(options.compression),

+ -	    hkalgs ? hkalgs : options.hostkeyalgorithms);

+ +	    filtered_algs);

+  

+  	free(hkalgs);

+ +	free(filtered_algs);

+  

+  	/* start key exchange */

+  	if ((r = kex_setup(ssh, myproposal)) != 0)

@@ -295,6 +295,14 @@ 

  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

+ @@ -80,6 +80,7 @@

+  #include "auth-options.h"

+  #include "serverloop.h"

+  #include "ssherr.h"

+ +#include "compat.h"

+  

+  extern ServerOptions options;

+  

  @@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *

   			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)

   				sigalg = "rsa-sha2-256";
@@ -328,9 +336,9 @@ 

  --- 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;

+  	sigset_t sigmask;

  +	int forbid_ssh_rsa = 0;

   

   #ifdef HAVE_SECUREWARE
@@ -379,38 +387,6 @@ 

   	/* Prepare the channels layer */

   	channel_init_channels(ssh);

   	channel_set_af(ssh, options.address_family);

- diff -Nur openssh-8.7p1/ssh-keygen.c openssh-8.7p1_patched/ssh-keygen.c

- --- openssh-8.7p1/ssh-keygen.c	2023-01-18 17:41:47.894515779 +0100

- +++ openssh-8.7p1_patched/ssh-keygen.c	2023-01-18 17:41:44.500488818 +0100

- @@ -491,6 +491,8 @@

-  	BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;

-  	BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;

-  	BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;

- +	char rsa_safe_alg[] = "rsa-sha2-256";

- +	char *alg = NULL;

-  

-  	if ((r = sshbuf_get_u32(b, &magic)) != 0)

-  		fatal_fr(r, "parse magic");

- @@ -590,6 +592,7 @@ do_convert_private_ssh2(struct sshbuf *b

-  		if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)

-  			fatal_fr(r, "generate RSA parameters");

-  		BN_clear_free(rsa_iqmp);

- +		alg = rsa_safe_alg;

-  		break;

-  	}

-  	rlen = sshbuf_len(b);

- @@ -598,9 +601,9 @@ do_convert_private_ssh2(struct sshbuf *b

-  

-  	/* try the key */

-  	if (sshkey_sign(key, &sig, &slen, data, sizeof(data),

- -	    NULL, NULL, NULL, 0) != 0 ||

- +	    alg, NULL, NULL, 0) != 0 ||

-  	    sshkey_verify(key, sig, slen, data, sizeof(data),

- -	    NULL, 0, NULL) != 0) {

- +	    alg, 0, NULL) != 0) {

-  		sshkey_free(key);

-  		free(sig);

-  		return NULL;

  diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c

  --- openssh-8.7p1/ssh-rsa.c.sshrsacheck	2023-01-20 13:07:54.180676144 +0100

  +++ openssh-8.7p1/ssh-rsa.c	2023-01-20 13:07:54.290677074 +0100

@@ -5,8 +5,8 @@ 

   

   	if (src_is_dir && iamrecursive) {

   		if (upload_dir(conn, src, abs_dst, pflag,

- -		    SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {

- +		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {

+ -		    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, targ);

  			errs = 1;

  		}
@@ -108,8 +108,8 @@ 

   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 follow_link_flag, int create_dir)

+ -    int follow_link_flag, int inplace_flag)

+ +    int follow_link_flag, int inplace_flag, int create_dir)

   {

   	char *dst_canon;

   	int ret;
@@ -143,9 +143,9 @@ 

  @@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const

    * times if 'pflag' is set

    */

-  int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,

- -    int, int);

- +    int, int, int);

+  int upload_dir(struct sftp_conn *, const char *, const char *,

+ -    int, int, int, int, int, int);

+ +    int, int, int, int, int, int, int);

   

   /*

    * Download a 'from_path' from the 'from' connection and upload it to
@@ -156,8 +156,8 @@ 

   		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) == -1)

- +			    fflag || global_fflag, 0, 0) == -1)

+ -			    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,

@@ -1,303 +0,0 @@ 

- 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,11 +1324,11 @@ 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, targ);

- 			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, targ);

- 		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("open local \"%s\": %s", local_path, strerror(errno));

- 		goto fail;

- @@ -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("close local \"%s\": %s", local_path, strerror(errno));

- 		status = SSH2_FX_FAILURE;

- @@ -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("upload \"%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

@@ -13,8 +13,8 @@ 

  --- openssh-8.7p1/scp.1.kill-scp	2021-09-16 12:09:02.646714578 +0200

  +++ openssh-8.7p1/scp.1	2021-09-16 12:26:49.978628226 +0200

  @@ -278,6 +278,13 @@ to print debugging messages about their

-  This is helpful in

-  debugging connection, authentication, and configuration problems.

+  By default a 32KB buffer is used.

+  .El

   .El

  +.Pp

  +Usage of SCP protocol can be blocked by creating a world-readable

@@ -14,9 +14,9 @@ 

   .It ControlPersist

   .It DynamicForward

  +.It EnableSSHKeysign

+  .It EnableEscapeCommandline

   .It EscapeChar

   .It ExitOnForwardFailure

-  .It FingerprintHash

  @@ -538,6 +540,8 @@

   .It IdentitiesOnly

   .It IdentityAgent

@@ -1,41 +0,0 @@ 

- diff -up openssh-8.8p1/regress/hostkey-agent.sh.redhat openssh-8.8p1/regress/hostkey-agent.sh

- --- openssh-8.8p1/regress/hostkey-agent.sh.redhat	2022-08-10 15:54:42.084777662 +0200

- +++ openssh-8.8p1/regress/hostkey-agent.sh	2022-08-10 17:01:25.651269994 +0200

- @@ -36,6 +36,8 @@ unset SSH_AUTH_SOCK

-  unset SSH_AUTH_SOCK

-  

-  for k in $SSH_ACCEPTED_KEYTYPES ; do

- +	[ "$k" == "ssh-rsa" ] && continue

- +	[ "$k" == "ssh-dss" ] && continue

- 	verbose "key type $k"

- 	cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy

- 	echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy

- diff -up openssh-8.8p1/regress/hostkey-rotate.sh.redhat openssh-8.8p1/regress/hostkey-rotate.sh

- --- openssh-8.8p1/regress/hostkey-rotate.sh.redhat	2022-08-10 16:57:12.720029146 +0200

- +++ openssh-8.8p1/regress/hostkey-rotate.sh	2022-08-10 17:15:48.274923865 +0200

- @@ -40,6 +40,8 @@ trace "prepare hostkeys"

-  nkeys=0

-  all_algs=""

-  for k in $SSH_HOSTKEY_TYPES; do

- +	[ "$k" == "ssh-rsa" ] && continue

- +	[ "$k" == "ssh-dss" ] && continue

-  	${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"

-  	echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig

-  	nkeys=`expr $nkeys + 1`

- @@ -87,11 +89,15 @@ dossh -oStrictHostKeyChecking=yes -oHost

-  # Check that other keys learned

-  expect_nkeys $nkeys "learn hostkeys"

-  for k in $SSH_HOSTKEY_TYPES; do

- +	[ "$k" == "ssh-rsa" ] && continue

- +	[ "$k" == "ssh-dss" ] && continue

-  	check_key_present $k || fail "didn't learn keytype $k"

-  done

-  

-  # Check each key type

-  for k in $SSH_HOSTKEY_TYPES; do

- +	[ "$k" == "ssh-rsa" ] && continue

- +	[ "$k" == "ssh-dss" ] && continue

-  	verbose "learn additional hostkeys, type=$k"

-  	dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs

-  	expect_nkeys $nkeys "learn hostkeys $k"

- 

@@ -1,6 +1,6 @@ 

- diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-dss.c ./ssh-dss.c

- --- ../../openssh-8.7p1/ssh-dss.c	2023-03-08 15:35:14.669943335 +0100

- +++ ./ssh-dss.c	2023-03-08 15:34:33.508578129 +0100

+ diff -up openssh-9.3p1/ssh-dss.c.evp-fips-sign openssh-9.3p1/ssh-dss.c

+ --- openssh-9.3p1/ssh-dss.c.evp-fips-sign	2023-04-27 16:46:17.115809116 +0200

+ +++ openssh-9.3p1/ssh-dss.c	2023-04-27 17:07:40.117253665 +0200

  @@ -32,6 +32,8 @@

   #include <openssl/bn.h>

   #include <openssl/dsa.h>
@@ -10,7 +10,7 @@ 

   

   #include <stdarg.h>

   #include <string.h>

- @@ -72,9 +74,8 @@

+ @@ -281,9 +283,8 @@ ssh_dss_sign(struct sshkey *key,

   	    sshkey_type_plain(key->type) != KEY_DSA)

   		return SSH_ERR_INVALID_ARGUMENT;

   
@@ -22,7 +22,7 @@ 

   	ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,

   	    data, datalen);

   	EVP_PKEY_free(pkey);

- @@ -201,11 +202,8 @@

+ @@ -411,11 +412,8 @@ ssh_dss_verify(const struct sshkey *key,

   		goto out;

   	}

   
@@ -32,14 +32,13 @@ 

  +  	if ((ret = ssh_create_evp_dss(key, &pkey)) != 0)

   		goto out;

  -	}

-  	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,

+  	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen,

   	    sigb, slen);

   	EVP_PKEY_free(pkey);

- @@ -221,4 +219,63 @@

-  		freezero(sigblob, len);

+ @@ -432,6 +430,65 @@ ssh_dss_verify(const struct sshkey *key,

   	return ret;

   }

- +

+  

  +int

  +ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey)

  +{
@@ -98,10 +97,13 @@ 

  +  	EVP_PKEY_CTX_free(ctx);

  +  	return ret;

  +}

-  #endif /* WITH_OPENSSL */

- diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-ecdsa.c ./ssh-ecdsa.c

- --- ../../openssh-8.7p1/ssh-ecdsa.c	2023-03-08 15:35:14.669943335 +0100

- +++ ./ssh-ecdsa.c	2023-03-08 15:40:52.628201267 +0100

+ +

+  static const struct sshkey_impl_funcs sshkey_dss_funcs = {

+  	/* .size = */		ssh_dss_size,

+  	/* .alloc = */		ssh_dss_alloc,

+ diff -up openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign openssh-9.3p1/ssh-ecdsa.c

+ --- openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign	2023-04-27 16:46:17.127809401 +0200

+ +++ openssh-9.3p1/ssh-ecdsa.c	2023-04-27 17:08:28.557396513 +0200

  @@ -34,6 +34,8 @@

   #include <openssl/ec.h>

   #include <openssl/ecdsa.h>
@@ -111,7 +113,7 @@ 

   

   #include <string.h>

   

- @@ -72,9 +74,8 @@

+ @@ -260,9 +262,8 @@ ssh_ecdsa_sign(struct sshkey *key,

   	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)

   		return SSH_ERR_INTERNAL_ERROR;

   
@@ -121,9 +123,9 @@ 

  +  	if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)

  +		return ret;

   	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,

-  	    datalen);

+  	    dlen);

   	EVP_PKEY_free(pkey);

- @@ -193,11 +194,8 @@

+ @@ -381,11 +382,8 @@ ssh_ecdsa_verify(const struct sshkey *ke

   		goto out;

   	}

   
@@ -133,10 +135,10 @@ 

  +  	if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0)

   		goto out;

  -	}

-  	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);

+  	ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len);

   	EVP_PKEY_free(pkey);

   

- @@ -212,4 +210,76 @@

+ @@ -400,6 +398,79 @@ ssh_ecdsa_verify(const struct sshkey *ke

   	return ret;

   }

   
@@ -212,10 +214,13 @@ 

  +  	free(pub_ser);

  +  	return ret;

  +}

-  #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */

- diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.c ./sshkey.c

- --- ../../openssh-8.7p1/sshkey.c	2023-03-08 15:35:14.702943628 +0100

- +++ ./sshkey.c	2023-03-08 15:39:03.354082015 +0100

+ +

+  /* NB. not static; used by ECDSA-SK */

+  const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {

+  	/* .size = */		ssh_ecdsa_size,

+ diff -up openssh-9.3p1/sshkey.c.evp-fips-sign openssh-9.3p1/sshkey.c

+ --- openssh-9.3p1/sshkey.c.evp-fips-sign	2023-04-27 16:46:17.139809686 +0200

+ +++ openssh-9.3p1/sshkey.c	2023-04-27 16:46:17.144809804 +0200

  @@ -35,6 +35,8 @@

   #include <openssl/err.h>

   #include <openssl/pem.h>
@@ -225,7 +230,7 @@ 

   #endif

   

   #include "crypto_api.h"

- @@ -492,13 +494,14 @@

+ @@ -527,13 +529,14 @@ sshkey_calculate_signature(EVP_PKEY *pke

   {

   	EVP_MD_CTX *ctx = NULL;

   	u_char *sig = NULL;
@@ -242,7 +247,7 @@ 

   	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)

   		return SSH_ERR_INVALID_ARGUMENT;

   

- @@ -511,9 +514,10 @@

+ @@ -546,9 +549,10 @@ sshkey_calculate_signature(EVP_PKEY *pke

   		ret = SSH_ERR_ALLOC_FAIL;

   		goto error;

   	}
@@ -256,7 +261,7 @@ 

   		ret = SSH_ERR_LIBCRYPTO_ERROR;

   		goto error;

   	}

- @@ -540,12 +544,13 @@

+ @@ -575,12 +579,13 @@ sshkey_verify_signature(EVP_PKEY *pkey,

   	if ((ctx = EVP_MD_CTX_new()) == NULL) {

   		return SSH_ERR_ALLOC_FAIL;

   	}
@@ -273,7 +278,7 @@ 

   	switch (ret) {

   	case 1:

   		ret = 0;

- @@ -5038,3 +5043,27 @@

+ @@ -3809,3 +3814,27 @@ sshkey_set_filename(struct sshkey *k, co

   	return 0;

   }

   #endif /* WITH_XMSS */
@@ -301,9 +306,9 @@ 

  +  	return ret;

  +}

  +#endif /* WITH_OPENSSL */

- diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.h ./sshkey.h

- --- ../../openssh-8.7p1/sshkey.h	2023-03-08 15:35:14.702943628 +0100

- +++ ./sshkey.h	2023-03-08 15:34:33.509578138 +0100

+ diff -up openssh-9.3p1/sshkey.h.evp-fips-sign openssh-9.3p1/sshkey.h

+ --- openssh-9.3p1/sshkey.h.evp-fips-sign	2023-04-27 16:46:17.133809543 +0200

+ +++ openssh-9.3p1/sshkey.h	2023-04-27 16:46:17.144809804 +0200

  @@ -31,6 +31,9 @@

   #ifdef WITH_OPENSSL

   #include <openssl/rsa.h>
@@ -314,7 +319,7 @@ 

   # ifdef OPENSSL_HAS_ECC

   #  include <openssl/ec.h>

   #  include <openssl/ecdsa.h>

- @@ -293,6 +295,13 @@

+ @@ -328,6 +331,13 @@ int	 sshkey_private_serialize_maxsign(st

   

   void	 sshkey_sig_details_free(struct sshkey_sig_details *);

   
@@ -326,11 +331,11 @@ 

  +#endif /* WITH_OPENSSL */

  +

   #ifdef SSHKEY_INTERNAL

-  int ssh_rsa_sign(const struct sshkey *key,

-      u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,

- diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-rsa.c ./ssh-rsa.c

- --- ../../openssh-8.7p1/ssh-rsa.c	2023-03-08 15:35:14.669943335 +0100

- +++ ./ssh-rsa.c	2023-03-08 15:34:33.509578138 +0100

+  int	sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b);

+  void	sshkey_sk_cleanup(struct sshkey *k);

+ diff -up openssh-9.3p1/ssh-rsa.c.evp-fips-sign openssh-9.3p1/ssh-rsa.c

+ --- openssh-9.3p1/ssh-rsa.c.evp-fips-sign	2023-04-27 16:46:17.139809686 +0200

+ +++ openssh-9.3p1/ssh-rsa.c	2023-04-27 17:10:30.376270565 +0200

  @@ -23,6 +23,8 @@

   

   #include <openssl/evp.h>
@@ -340,7 +345,7 @@ 

   

   #include <stdarg.h>

   #include <string.h>

- @@ -172,9 +174,8 @@

+ @@ -426,9 +428,8 @@ ssh_rsa_sign(struct sshkey *key,

   	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)

   		return SSH_ERR_KEY_LENGTH;

   
@@ -352,7 +357,7 @@ 

   	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,

   	    datalen);

   	EVP_PKEY_free(pkey);

- @@ -285,11 +286,8 @@

+ @@ -540,11 +541,9 @@ ssh_rsa_verify(const struct sshkey *key,

   		len = modlen;

   	}

   
@@ -362,10 +367,11 @@ 

  +  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)

   		goto out;

  -	}

-  	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);

+ +

+  	ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey);

   	EVP_PKEY_free(pkey);

   

- @@ -306,11 +304,9 @@

+ @@ -561,11 +560,9 @@ openssh_RSA_verify(int hash_alg, const u

       u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)

   {

   	size_t rsasize = 0;
@@ -378,11 +384,10 @@ 

   	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||

   	    siglen == 0 || siglen > rsasize) {

   		ret = SSH_ERR_INVALID_ARGUMENT;

- @@ -323,4 +319,87 @@

-  done:

+ @@ -579,6 +576,89 @@ done:

   	return ret;

   }

- +

+  

  +int

  +ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey)

  +{
@@ -465,4 +470,7 @@ 

  +  	EVP_PKEY_CTX_free(ctx);

  +  	return ret;

  +}

-  #endif /* WITH_OPENSSL */

+ +

+  static const struct sshkey_impl_funcs sshkey_rsa_funcs = {

+  	/* .size = */		ssh_rsa_size,

+  	/* .alloc = */		ssh_rsa_alloc,

@@ -1,26 +0,0 @@ 

- commit 40b0a5eb6e3edfa2886b60c09c7803353b0cc7f5

- Author: Sam James <sam@gentoo.org>

- Date:   Sun Nov 6 04:47:35 2022 +0000

- 

-     configure.ac: Add <pty.h> include for openpty

-     

-     Another Clang 16ish fix (which makes -Wimplicit-function-declaration

-     an error by default).  github PR#355.

-     

-     See: 2efd71da49b9cfeab7987058cf5919e473ff466b

-     See: be197635329feb839865fdc738e34e24afd1fca8

- 

- diff --git a/configure.ac b/configure.ac

- index 1e77ecfc..1866aea5 100644

- --- a/configure.ac

- +++ b/configure.ac

- @@ -2373,6 +2373,9 @@ if test ! -z "$check_for_openpty_ctty_bug"; then

-  #include <stdio.h>

-  #include <stdlib.h>

-  #include <unistd.h>

- +#ifdef HAVE_PTY_H

- +# include <pty.h>

- +#endif

-  #include <sys/fcntl.h>

-  #include <sys/types.h>

-  #include <sys/wait.h>

@@ -1,47 +0,0 @@ 

- commit 32fddb982fd61b11a2f218a115975a87ab126d43

- Author: Darren Tucker <dtucker@dtucker.net>

- Date:   Mon Nov 7 10:39:01 2022 +1100

- 

-     Fix setres*id checks to work with clang-16.

-     

-     glibc has the prototypes for setresuid and setresgid behind _GNU_SOURCE,

-     and clang 16 will error out on implicit function definitions, so add

-     _GNU_SOURCE and the required headers to the configure checks.  From

-     sam at @gentoo.org via bz#3497.

- 

- diff --git a/configure.ac b/configure.ac

- index 4bf758ac..e172540a 100644

- --- a/configure.ac

- +++ b/configure.ac

- @@ -863,7 +863,8 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))

-  	check_for_openpty_ctty_bug=1

-  	dnl Target SUSv3/POSIX.1-2001 plus BSD specifics.

-  	dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE

- -	CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE"

- +	dnl _GNU_SOURCE is needed for setres*id prototypes.

- +	CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE"

-  	AC_DEFINE([BROKEN_CLOSEFROM], [1], [broken in chroots on older kernels])

-  	AC_DEFINE([PAM_TTY_KLUDGE], [1],

-  		[Work around problematic Linux PAM modules handling of PAM_TTY])

- @@ -2168,8 +2169,9 @@ AC_CHECK_FUNCS([setresuid], [

-  	AC_MSG_CHECKING([if setresuid seems to work])

-  	AC_RUN_IFELSE(

-  		[AC_LANG_PROGRAM([[

- -#include <stdlib.h>

-  #include <errno.h>

- +#include <stdlib.h>

- +#include <unistd.h>

-  		]], [[

-  	errno=0;

-  	setresuid(0,0,0);

- @@ -2191,8 +2193,9 @@ AC_CHECK_FUNCS([setresgid], [

-  	AC_MSG_CHECKING([if setresgid seems to work])

-  	AC_RUN_IFELSE(

-  		[AC_LANG_PROGRAM([[

- -#include <stdlib.h>

-  #include <errno.h>

- +#include <stdlib.h>

- +#include <unistd.h>

-  		]], [[

-  	errno=0;

-  	setresgid(0,0,0);

@@ -1,41 +0,0 @@ 

- commit 5eb796a369c64f18d55a6ae9b1fa9b35eea237fb

- Author: Harmen Stoppels <harmenstoppels@gmail.com>

- Date:   Thu Oct 13 16:08:46 2022 +0200

- 

-     Fix snprintf configure test for clang 15

-     

-     Clang 15 -Wimplicit-int defaults to an error in C99 mode and above.

-     A handful of tests have "main(..." and not "int main(..." which caused

-     the tests to produce incorrect results.

- 

- diff --git a/configure.ac b/configure.ac

- index de60a1b1..165c49de 100644

- --- a/configure.ac

- +++ b/configure.ac

- @@ -713,7 +713,7 @@ case "$host" in

-  	AC_RUN_IFELSE([AC_LANG_SOURCE([[

-  #include <mach-o/dyld.h>

-  #include <stdlib.h>

- -main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))

- +int main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))

-  		exit(0);

-  	else

-  		exit(1);

- @@ -4259,7 +4259,7 @@ dnl test snprintf (broken on SCO w/gcc)

-  #include <stdlib.h>

-  #include <string.h>

-  #ifdef HAVE_SNPRINTF

- -main()

- +int main()

-  {

-  	char buf[50];

-  	char expected_out[50];

- @@ -4276,7 +4276,7 @@ main()

-  	exit(0);

-  }

-  #else

- -main() { exit(0); }

- +int main() { exit(0); }

-  #endif

-  		]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ],

-  		AC_MSG_WARN([cross compiling: Assuming working snprintf()])

file modified
+6 -29
@@ -46,10 +46,10 @@ 

  %{?static_openssl:%global static_libcrypto 1}

  

  # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1

- %global openssh_ver 9.0p1

- %global openssh_rel 17

+ %global openssh_ver 9.3p1

+ %global openssh_rel 1

  %global pam_ssh_agent_ver 0.10.4

- %global pam_ssh_agent_rel 8

+ %global pam_ssh_agent_rel 9

  

  Summary: An open source implementation of SSH protocol version 2

  Name: openssh
@@ -134,8 +134,6 @@ 

  Patch707: openssh-7.7p1-redhat.patch

  # warn users for unsupported UsePAM=no (#757545)

  Patch711: openssh-7.8p1-UsePAM-warning.patch

- # make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL

- Patch712: openssh-6.3p1-ctr-evp-fast.patch

  

  # GSSAPI Key Exchange (RFC 4462 + RFC 8732)

  # from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
@@ -213,20 +211,10 @@ 

  # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14

  Patch984: openssh-8.7p1-ibmca.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
@@ -237,12 +225,6 @@ 

  # https://github.com/openssh/openssh-portable/pull/323

  Patch1006: openssh-8.7p1-negotiate-supported-algs.patch

  

- Patch1007: openssh-configure-c99-1.patch

- Patch1008: openssh-configure-c99-2.patch

- Patch1009: openssh-configure-c99-3.patch

- 

- Patch1010: openssh-8.7p1-CVE-2023-25136.patch

- 

  Patch1011: openssh-9.0p1-evp-fips-sign.patch

  Patch1012: openssh-9.0p1-evp-fips-dh.patch

  Patch1013: openssh-9.0p1-evp-fips-ecdh.patch
@@ -402,7 +384,6 @@ 

  %patch703 -p1 -b .grab-info

  %patch707 -p1 -b .redhat

  %patch711 -p1 -b .log-usepam-no

- %patch712 -p1 -b .evp-ctr

  # 

  %patch800 -p1 -b .gsskex

  %patch801 -p1 -b .force_krb
@@ -444,18 +425,11 @@ 

  %patch202 -p1 -b .audit-log

  %patch700 -p1 -b .fips

  

- %patch1001 -p1 -b .scp-clears-file

  %patch1002 -p1 -b .ssh-manpage

- %patch1003 -p1 -b .mem-leak

  %patch1004 -p1 -b .gssapi-auth

  

  %patch1006 -p1 -b .negotiate-supported-algs

  

- %patch1007 -p1 -b .configure-c99-1

- %patch1008 -p1 -b .configure-c99-2

- %patch1009 -p1 -b .configure-c99-3

- %patch1010 -p1 -b .cve-2023-25136

- 

  %patch1011 -p1 -b .evp-fips-sign

  %patch1012 -p1 -b .evp-fips-dh

  %patch1013 -p1 -b .evp-fips-ecdh
@@ -767,6 +741,9 @@ 

  %endif

  

  %changelog

+ * Fri Apr 21 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.3p1-1 + 0.10.4-9

+ - Rebase OpenSSH to 9.3p1

+ 

  * Fri Apr 14 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.0p1-17

  - In case when sha1 signatures are not supported, fallback to sha2 in hostproof

  - Audit logging patch was not applied (rhbz#2177471)

@@ -150,15 +150,17 @@ 

  diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in

  --- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build	2016-11-13 04:24:32.000000000 +0100

  +++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in	2017-02-07 14:40:14.407566921 +0100

- @@ -52,7 +52,7 @@ PATHS=

+ @@ -52,8 +52,8 @@ PATHS=

   CC=@CC@

   LD=@LD@

   CFLAGS=@CFLAGS@

  -CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@

+ -LIBS=@LIBS@

  +CPPFLAGS=-I.. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@

-  LIBS=@LIBS@

+ +LIBS=@LIBS@ -lgssapi_krb5 -lz

   AR=@AR@

   AWK=@AWK@

+  RANLIB=@RANLIB@

  @@ -61,8 +61,8 @@ INSTALL=@INSTALL@

   PERL=@PERL@

   SED=@SED@

file modified
+2 -2
@@ -1,4 +1,4 @@ 

- SHA512 (openssh-9.0p1.tar.gz) = 613ae95317e734868c6a60d9cc5af47a889baa3124bbdd2b31bb51dd6b57b136f4cfcb5604cca78a03bd500baab9b9b45eaf77e038b1ed776c86dce0437449a9

- SHA512 (openssh-9.0p1.tar.gz.asc) = 7b1445764058435d2fa8a9c7553643983650d4232036c088e46e44beeb538d32cba88f775b1be9da5f21a01d6caea59b3dc4714507781e9cb946546fa54f169f

+ SHA512 (openssh-9.3p1.tar.gz) = 087ff6fe5f6caab4c6c3001d906399e02beffad7277280f11187420c2939fd4befdcb14643862a657ce4cad2f115b82a0a1a2c99df6ee54dcd76b53647637c19

+ SHA512 (openssh-9.3p1.tar.gz.asc) = 6222378eb24a445c6c1db255392b405f5369b1af0e92f558d4ba05b0d83ab0d084cb8f4b91d7ae8636f333d970638a6635e2bc7af885135dd34992d87f2ef1f4

  SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2

  SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21

Phase I - making patches apply

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci
https://fedora.softwarefactory-project.io/zuul/buildset/406f271df7c84b60a19630dabdf65b6b

2 new commits added

  • Phase III
  • Get rid of compilation errors.
a year ago

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci
https://fedora.softwarefactory-project.io/zuul/buildset/8a454596fc64466a9c3a8a9d2fecbddd

1 new commit added

  • Making 9.3 build linking
a year ago

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci
https://fedora.softwarefactory-project.io/zuul/buildset/d13c8cd6a7de447b97c69de9101fdf54

4 new commits added

  • Making native test suite passing
  • Make hostkey-agent test passing
  • Removing unused patch
  • Proper ECDSA signature parsing
a year ago

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging src.fedoraproject.org/rpms/openssh for 49,75b94bb

Pull-Request has been closed by dbelyavs

a year ago