forked from rpms/openssh
		
	import openssh-8.0p1-3.el8
This commit is contained in:
		
							parent
							
								
									b830398e18
								
							
						
					
					
						commit
						0f83d08dcb
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,3 @@ | ||||
| SOURCES/DJM-GPG-KEY.gpg | ||||
| SOURCES/openssh-7.8p1.tar.gz | ||||
| SOURCES/openssh-8.0p1.tar.gz | ||||
| SOURCES/pam_ssh_agent_auth-0.10.3.tar.bz2 | ||||
|  | ||||
| @ -1,3 +1,3 @@ | ||||
| bed7240bb17840b451b8f8457791c33456814d93 SOURCES/DJM-GPG-KEY.gpg | ||||
| 27e267e370315561de96577fccae563bc2c37a60 SOURCES/openssh-7.8p1.tar.gz | ||||
| 756dbb99193f9541c9206a667eaa27b0fa184a4f SOURCES/openssh-8.0p1.tar.gz | ||||
| a4482a050fdad1d012427e45799564136708cf6b SOURCES/pam_ssh_agent_auth-0.10.3.tar.bz2 | ||||
|  | ||||
| @ -1,78 +0,0 @@ | ||||
| diff -up openssh-5.9p1/Makefile.in.wIm openssh-5.9p1/Makefile.in
 | ||||
| --- openssh-5.9p1/Makefile.in.wIm	2011-08-05 22:15:18.000000000 +0200
 | ||||
| +++ openssh-5.9p1/Makefile.in	2011-09-12 16:24:18.643674014 +0200
 | ||||
| @@ -66,7 +66,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
 | ||||
|  	cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ | ||||
|  	compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ | ||||
|  	log.o match.o md-sha256.o moduli.o nchan.o packet.o \ | ||||
| -	readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
 | ||||
| +	readpass.o rsa.o ttymodes.o whereIam.o xmalloc.o addrmatch.o \
 | ||||
|  	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ | ||||
|  	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ | ||||
|  	kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ | ||||
| diff -up openssh-5.9p1/log.h.wIm openssh-5.9p1/log.h
 | ||||
| --- openssh-5.9p1/log.h.wIm	2011-06-20 06:42:23.000000000 +0200
 | ||||
| +++ openssh-5.9p1/log.h	2011-09-12 16:34:52.984674326 +0200
 | ||||
| @@ -65,6 +65,8 @@ void     verbose(const char *, ...) __at
 | ||||
|  void     debug(const char *, ...) __attribute__((format(printf, 1, 2))); | ||||
|  void     debug2(const char *, ...) __attribute__((format(printf, 1, 2))); | ||||
|  void     debug3(const char *, ...) __attribute__((format(printf, 1, 2))); | ||||
| +void	 _debug_wIm_body(const char *, int, const char *, const char *, int);
 | ||||
| +#define	debug_wIm(a,b) _debug_wIm_body(a,b,__func__,__FILE__,__LINE__)
 | ||||
|   | ||||
|   | ||||
|  void	 set_log_handler(log_handler_fn *, void *); | ||||
| diff -up openssh-5.9p1/sshd.c.wIm openssh-5.9p1/sshd.c
 | ||||
| --- openssh-5.9p1/sshd.c.wIm	2011-06-23 11:45:51.000000000 +0200
 | ||||
| +++ openssh-5.9p1/sshd.c	2011-09-12 16:38:35.787816490 +0200
 | ||||
| @@ -140,6 +140,9 @@ int deny_severity;
 | ||||
|   | ||||
|  extern char *__progname; | ||||
|   | ||||
| +/* trace of fork processes */
 | ||||
| +extern int whereIam;
 | ||||
| +
 | ||||
|  /* Server configuration options. */ | ||||
|  ServerOptions options; | ||||
|   | ||||
| @@ -666,6 +669,7 @@ privsep_preauth(Authctxt *authctxt)
 | ||||
|  		return 1; | ||||
|  	} else { | ||||
|  		/* child */ | ||||
| +		whereIam = 1;
 | ||||
|  		close(pmonitor->m_sendfd); | ||||
|  		close(pmonitor->m_log_recvfd); | ||||
|   | ||||
| @@ -715,6 +719,7 @@ privsep_postauth(Authctxt *authctxt)
 | ||||
|   | ||||
|  	/* child */ | ||||
|   | ||||
| +	whereIam = 2;
 | ||||
|  	close(pmonitor->m_sendfd); | ||||
|  	pmonitor->m_sendfd = -1; | ||||
|   | ||||
| @@ -1325,6 +1330,8 @@ main(int ac, char **av)
 | ||||
|  	Key *key; | ||||
|  	Authctxt *authctxt; | ||||
|   | ||||
| +	whereIam = 0;
 | ||||
| +
 | ||||
|  #ifdef HAVE_SECUREWARE | ||||
|  	(void)set_auth_parameters(ac, av); | ||||
|  #endif | ||||
| diff -up openssh-5.9p1/whereIam.c.wIm openssh-5.9p1/whereIam.c
 | ||||
| --- openssh-5.9p1/whereIam.c.wIm	2011-09-12 16:24:18.722674167 +0200
 | ||||
| +++ openssh-5.9p1/whereIam.c	2011-09-12 16:24:18.724674418 +0200
 | ||||
| @@ -0,0 +1,12 @@
 | ||||
| +
 | ||||
| +int whereIam = -1;
 | ||||
| +
 | ||||
| +void _debug_wIm_body(const char *txt, int val, const char *func, const char *file, int line)
 | ||||
| +{
 | ||||
| +	if (txt)
 | ||||
| +		debug("%s=%d, %s(%s:%d) wIm = %d, uid=%d, euid=%d", txt, val, func, file, line, whereIam, getuid(), geteuid());
 | ||||
| +	else
 | ||||
| +		debug("%s(%s:%d) wIm = %d, uid=%d, euid=%d", func, file, line, whereIam, getuid(), geteuid());
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
| @ -1,21 +0,0 @@ | ||||
| diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c
 | ||||
| --- openssh-6.1p1/sshconnect2.c.canohost	2012-10-30 10:52:59.593301692 +0100
 | ||||
| +++ openssh-6.1p1/sshconnect2.c	2012-10-30 11:01:12.870301632 +0100
 | ||||
| @@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt)
 | ||||
|  	static u_int mech = 0; | ||||
|  	OM_uint32 min; | ||||
|  	int r, ok = 0; | ||||
| -	const char *gss_host;
 | ||||
| +	const char *gss_host = NULL;
 | ||||
|   | ||||
|  	if (options.gss_server_identity) | ||||
|  		gss_host = options.gss_server_identity; | ||||
| -	else if (options.gss_trust_dns)
 | ||||
| +	else if (options.gss_trust_dns) {
 | ||||
|  		gss_host = get_canonical_hostname(active_state, 1); | ||||
| +		if (strcmp(gss_host, "UNKNOWN") == 0)
 | ||||
| +			gss_host = authctxt->host;
 | ||||
| +	}
 | ||||
|  	else | ||||
|  		gss_host = authctxt->host; | ||||
|   | ||||
| @ -1,142 +0,0 @@ | ||||
| diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac
 | ||||
| --- openssh-7.4p1/configure.ac.vendor	2016-12-23 13:34:51.681253844 +0100
 | ||||
| +++ openssh-7.4p1/configure.ac	2016-12-23 13:34:51.694253847 +0100
 | ||||
| @@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog],
 | ||||
|  		fi | ||||
|  	] | ||||
|  ) | ||||
| +AC_ARG_ENABLE(vendor-patchlevel,
 | ||||
| +  [  --enable-vendor-patchlevel=TAG  specify a vendor patch level],
 | ||||
| +  [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.])
 | ||||
| +   SSH_VENDOR_PATCHLEVEL="$enableval"],
 | ||||
| +  [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.])
 | ||||
| +   SSH_VENDOR_PATCHLEVEL=none])
 | ||||
|   | ||||
|  dnl lastlog, [uw]tmpx? detection | ||||
|  dnl  NOTE: set the paths in the platform section to avoid the | ||||
| @@ -5194,6 +5200,7 @@ echo "           Translate v4 in v6 hack
 | ||||
|  echo "                  BSD Auth support: $BSD_AUTH_MSG" | ||||
|  echo "              Random number source: $RAND_MSG" | ||||
|  echo "             Privsep sandbox style: $SANDBOX_STYLE" | ||||
| +echo "                Vendor patch level: $SSH_VENDOR_PATCHLEVEL"
 | ||||
|   | ||||
|  echo "" | ||||
|   | ||||
| diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c
 | ||||
| --- openssh-7.4p1/servconf.c.vendor	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 13:36:07.555268628 +0100
 | ||||
| @@ -143,6 +143,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->max_authtries = -1; | ||||
|  	options->max_sessions = -1; | ||||
|  	options->banner = NULL; | ||||
| +	options->show_patchlevel = -1;
 | ||||
|  	options->use_dns = -1; | ||||
|  	options->client_alive_interval = -1; | ||||
|  	options->client_alive_count_max = -1; | ||||
| @@ -325,6 +326,8 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->ip_qos_bulk = IPTOS_DSCP_CS1; | ||||
|  	if (options->version_addendum == NULL) | ||||
|  		options->version_addendum = xstrdup(""); | ||||
| +	if (options->show_patchlevel == -1)
 | ||||
| +		options->show_patchlevel = 0;
 | ||||
|  	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) | ||||
|  		options->fwd_opts.streamlocal_bind_mask = 0177; | ||||
|  	if (options->fwd_opts.streamlocal_bind_unlink == -1) | ||||
| @@ -402,7 +405,7 @@ typedef enum {
 | ||||
|  	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, | ||||
|  	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, | ||||
|  	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, | ||||
| -	sBanner, sUseDNS, sHostbasedAuthentication,
 | ||||
| +	sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
 | ||||
|  	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, | ||||
|  	sHostKeyAlgorithms, | ||||
|  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | ||||
| @@ -528,6 +531,7 @@ static struct {
 | ||||
|  	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, | ||||
|  	{ "maxsessions", sMaxSessions, SSHCFG_ALL }, | ||||
|  	{ "banner", sBanner, SSHCFG_ALL }, | ||||
| +	{ "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL },
 | ||||
|  	{ "usedns", sUseDNS, SSHCFG_GLOBAL }, | ||||
|  	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, | ||||
|  	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, | ||||
| @@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions
 | ||||
|  		intptr = &options->disable_forwarding; | ||||
|  		goto parse_flag; | ||||
|   | ||||
| +	case sShowPatchLevel:
 | ||||
| +		intptr = &options->show_patchlevel;
 | ||||
| +		goto parse_flag;
 | ||||
| +
 | ||||
|  	case sAllowUsers: | ||||
|  		while ((arg = strdelim(&cp)) && *arg != '\0') { | ||||
|  			if (match_user(NULL, NULL, NULL, arg) == -1) | ||||
| @@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o)
 | ||||
|  	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); | ||||
|  	dump_cfg_fmtint(sCompression, o->compression); | ||||
|  	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); | ||||
| +	dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel);
 | ||||
|  	dump_cfg_fmtint(sUseDNS, o->use_dns); | ||||
|  	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); | ||||
|  	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); | ||||
| diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h
 | ||||
| --- openssh-7.4p1/servconf.h.vendor	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/servconf.h	2016-12-23 13:34:51.694253847 +0100
 | ||||
| @@ -149,6 +149,7 @@ typedef struct {
 | ||||
|  	int	max_authtries; | ||||
|  	int	max_sessions; | ||||
|  	char   *banner;			/* SSH-2 banner message */ | ||||
| +	int	show_patchlevel;	/* Show vendor patch level to clients */
 | ||||
|  	int	use_dns; | ||||
|  	int	client_alive_interval;	/* | ||||
|  					 * poke the client this often to | ||||
| diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5
 | ||||
| --- openssh-7.4p1/sshd_config.5.vendor	2016-12-23 13:34:51.695253847 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config.5	2016-12-23 13:37:17.482282253 +0100
 | ||||
| @@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as
 | ||||
|  .Cm AcceptEnv | ||||
|  or | ||||
|  .Cm PermitUserEnvironment . | ||||
| +.It Cm ShowPatchLevel 
 | ||||
| +Specifies whether 
 | ||||
| +.Nm sshd 
 | ||||
| +will display the patch level of the binary in the identification string. 
 | ||||
| +The patch level is set at compile-time. 
 | ||||
| +The default is 
 | ||||
| +.Dq no . 
 | ||||
|  .It Cm StreamLocalBindMask | ||||
|  Sets the octal file creation mode mask | ||||
|  .Pq umask | ||||
| diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config
 | ||||
| --- openssh-7.4p1/sshd_config.vendor	2016-12-23 13:34:51.690253846 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config	2016-12-23 13:34:51.695253847 +0100
 | ||||
| @@ -105,6 +105,7 @@ X11Forwarding yes
 | ||||
|  #Compression delayed | ||||
|  #ClientAliveInterval 0 | ||||
|  #ClientAliveCountMax 3 | ||||
| +#ShowPatchLevel no
 | ||||
|  #UseDNS no | ||||
|  #PidFile /var/run/sshd.pid | ||||
|  #MaxStartups 10:30:100 | ||||
| diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c
 | ||||
| --- openssh-7.4p1/sshd.c.vendor	2016-12-23 13:34:51.682253844 +0100
 | ||||
| +++ openssh-7.4p1/sshd.c	2016-12-23 13:38:32.434296856 +0100
 | ||||
| @@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh
 | ||||
|  	char remote_version[256];	/* Must be at least as big as buf. */ | ||||
|   | ||||
|  	xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", | ||||
| -	    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
 | ||||
| +	    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
 | ||||
| +	    (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
 | ||||
|  	    *options.version_addendum == '\0' ? "" : " ", | ||||
|  	    options.version_addendum); | ||||
|   | ||||
| @@ -1650,7 +1651,8 @@ main(int ac, char **av)
 | ||||
|  		exit(1); | ||||
|  	} | ||||
|   | ||||
| -	debug("sshd version %s, %s", SSH_VERSION,
 | ||||
| +	debug("sshd version %s, %s", 
 | ||||
| +		(options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
 | ||||
|  #ifdef WITH_OPENSSL | ||||
|  	    SSLeay_version(SSLEAY_VERSION) | ||||
|  #else | ||||
| @ -46,7 +46,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c | ||||
|   | ||||
| +	pmonitor->m_state = "preauth";
 | ||||
| +
 | ||||
|  	authctxt = _authctxt; | ||||
|  	authctxt = (Authctxt *)ssh->authctxt; | ||||
|  	memset(authctxt, 0, sizeof(*authctxt)); | ||||
|  	ssh->authctxt = authctxt; | ||||
| @@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p
 | ||||
| @ -113,7 +113,7 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h | ||||
| +void monitor_reinit(struct monitor *, const char *);
 | ||||
|   | ||||
|  struct Authctxt; | ||||
|  void monitor_child_preauth(struct Authctxt *, struct monitor *); | ||||
|  void monitor_child_preauth(struct ssh *, struct monitor *); | ||||
| diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c
 | ||||
| --- openssh-7.4p1/session.c.log-in-chroot	2016-12-23 15:14:33.319168086 +0100
 | ||||
| +++ openssh-7.4p1/session.c	2016-12-23 15:18:18.742211853 +0100
 | ||||
|  | ||||
| @ -19,7 +19,7 @@ index 8f32464..18a2ca4 100644 | ||||
|   | ||||
|  	if (!sshd_selinux_enabled()) | ||||
|  		return; | ||||
| @@ -461,6 +462,58 @@ sshd_selinux_copy_context(void)
 | ||||
| @@ -461,6 +462,72 @@ sshd_selinux_copy_context(void)
 | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @ -30,46 +30,60 @@ index 8f32464..18a2ca4 100644 | ||||
| +	char line[1024], *preauth_context = NULL, *cp, *arg;
 | ||||
| +	const char *contexts_path;
 | ||||
| +	FILE *contexts_file;
 | ||||
| +	struct stat sb;
 | ||||
| +
 | ||||
| +	contexts_path = selinux_openssh_contexts_path();
 | ||||
| +	if (contexts_path != NULL) {
 | ||||
| +		if ((contexts_file = fopen(contexts_path, "r")) != NULL) {
 | ||||
| +			struct stat sb;
 | ||||
| +
 | ||||
| +			if (fstat(fileno(contexts_file), &sb) == 0 && ((sb.st_uid == 0) && ((sb.st_mode & 022) == 0))) {
 | ||||
| +				while (fgets(line, sizeof(line), contexts_file)) {
 | ||||
| +					/* Strip trailing whitespace */
 | ||||
| +					for (len = strlen(line) - 1; len > 0; len--) {
 | ||||
| +						if (strchr(" \t\r\n", line[len]) == NULL)
 | ||||
| +							break;
 | ||||
| +						line[len] = '\0';
 | ||||
| +					}
 | ||||
| +
 | ||||
| +					if (line[0] == '\0')
 | ||||
| +						continue;
 | ||||
| +
 | ||||
| +					cp = line;
 | ||||
| +					arg = strdelim(&cp);
 | ||||
| +					if (arg && *arg == '\0')
 | ||||
| +						arg = strdelim(&cp);
 | ||||
| +
 | ||||
| +					if (arg && strcmp(arg, "privsep_preauth") == 0) {
 | ||||
| +						arg = strdelim(&cp);
 | ||||
| +						if (!arg || *arg == '\0') {
 | ||||
| +							debug("%s: privsep_preauth is empty", __func__);
 | ||||
| +							fclose(contexts_file);
 | ||||
| +							return;
 | ||||
| +						}
 | ||||
| +						preauth_context = xstrdup(arg);
 | ||||
| +					}
 | ||||
| +				}
 | ||||
| +			}
 | ||||
| +			fclose(contexts_file);
 | ||||
| +		}
 | ||||
| +	if (contexts_path == NULL) {
 | ||||
| +		debug3("%s: Failed to get the path to SELinux context", __func__);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (preauth_context == NULL)
 | ||||
| +		preauth_context = xstrdup("sshd_net_t");
 | ||||
| +	if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
 | ||||
| +		debug("%s: Failed to open SELinux context file", __func__);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (fstat(fileno(contexts_file), &sb) != 0 ||
 | ||||
| +	    sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
 | ||||
| +		logit("%s: SELinux context file needs to be owned by root"
 | ||||
| +		    " and not writable by anyone else", __func__);
 | ||||
| +		fclose(contexts_file);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	while (fgets(line, sizeof(line), contexts_file)) {
 | ||||
| +		/* Strip trailing whitespace */
 | ||||
| +		for (len = strlen(line) - 1; len > 0; len--) {
 | ||||
| +			if (strchr(" \t\r\n", line[len]) == NULL)
 | ||||
| +				break;
 | ||||
| +			line[len] = '\0';
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if (line[0] == '\0')
 | ||||
| +			continue;
 | ||||
| +
 | ||||
| +		cp = line;
 | ||||
| +		arg = strdelim(&cp);
 | ||||
| +		if (arg && *arg == '\0')
 | ||||
| +			arg = strdelim(&cp);
 | ||||
| +
 | ||||
| +		if (arg && strcmp(arg, "privsep_preauth") == 0) {
 | ||||
| +			arg = strdelim(&cp);
 | ||||
| +			if (!arg || *arg == '\0') {
 | ||||
| +				debug("%s: privsep_preauth is empty", __func__);
 | ||||
| +				fclose(contexts_file);
 | ||||
| +				return;
 | ||||
| +			}
 | ||||
| +			preauth_context = xstrdup(arg);
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	fclose(contexts_file);
 | ||||
| +
 | ||||
| +	if (preauth_context == NULL) {
 | ||||
| +		debug("%s: Unable to find 'privsep_preauth' option in"
 | ||||
| +		    " SELinux context file", __func__);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ssh_selinux_change_context(preauth_context);
 | ||||
| +	free(preauth_context);
 | ||||
| @ -82,14 +96,6 @@ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c | ||||
| index 22ea8ef..1fc963d 100644
 | ||||
| --- a/openbsd-compat/port-linux.c
 | ||||
| +++ b/openbsd-compat/port-linux.c
 | ||||
| @@ -26,6 +26,7 @@
 | ||||
|  #include <stdarg.h> | ||||
|  #include <string.h> | ||||
|  #include <stdio.h> | ||||
| +#include <stdlib.h>
 | ||||
|   | ||||
|  #include "log.h" | ||||
|  #include "xmalloc.h" | ||||
| @@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname)
 | ||||
|  	strlcpy(newctx + len, newname, newlen - len); | ||||
|  	if ((cx = index(cx + 1, ':'))) | ||||
|  | ||||
| @ -22,15 +22,15 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c | ||||
| --- openssh-7.4p1/servconf.c.GSSAPIEnablek5users	2016-12-23 15:18:40.615216100 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 15:35:36.354401156 +0100
 | ||||
| @@ -168,6 +168,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->gss_strict_acceptor = -1; | ||||
|  	options->gss_store_rekey = -1; | ||||
|  	options->gss_kex_algorithms = NULL; | ||||
|  	options->use_kuserok = -1; | ||||
| +	options->enable_k5users = -1;
 | ||||
|  	options->password_authentication = -1; | ||||
|  	options->kbd_interactive_authentication = -1; | ||||
|  	options->challenge_response_authentication = -1; | ||||
| @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->gss_store_rekey = 0; | ||||
|  #endif | ||||
|  	if (options->use_kuserok == -1) | ||||
|  		options->use_kuserok = 1; | ||||
| +	if (options->enable_k5users == -1)
 | ||||
| @ -44,20 +44,22 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c | ||||
|  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | ||||
| -	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
 | ||||
| +	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
 | ||||
|  	sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, | ||||
|  	sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, | ||||
|  	sAcceptEnv, sSetEnv, sPermitTunnel, | ||||
|  	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | ||||
|  	sUsePrivilegeSeparation, sAllowAgentForwarding, | ||||
| @@ -497,12 +500,14 @@ static struct {
 | ||||
|  	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, | ||||
| @@ -497,14 +500,16 @@ static struct {
 | ||||
|  	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, | ||||
| +	{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
 | ||||
|  #else | ||||
|  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, | ||||
|  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, | ||||
| +	{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
 | ||||
|  #endif | ||||
|  	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  | ||||
| @ -187,7 +187,7 @@ diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c | ||||
| +                usage();
 | ||||
| +        }
 | ||||
| +
 | ||||
| +	SSLeay_add_all_algorithms();
 | ||||
| +	OpenSSL_add_all_algorithms();
 | ||||
| +
 | ||||
| +	c = cipher_by_name(algo);
 | ||||
| +	if (c == NULL) {
 | ||||
|  | ||||
| @ -235,9 +235,9 @@ index 28659ec..9c94d8e 100644 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  	s->forced = 0; | ||||
|  	if (forced != NULL) { | ||||
|  		if (IS_INTERNAL_SFTP(command)) { | ||||
|  			s->is_subsystem = s->is_subsystem ? | ||||
|  		s->forced = 1; | ||||
| diff --git a/ssh-gss.h b/ssh-gss.h
 | ||||
| index 0374c88..509109a 100644
 | ||||
| --- a/ssh-gss.h
 | ||||
|  | ||||
| @ -176,17 +176,17 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c | ||||
| --- openssh-7.4p1/servconf.c.kuserok	2016-12-23 14:36:07.630465944 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 15:11:52.278133344 +0100
 | ||||
| @@ -116,6 +116,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->gss_cleanup_creds = -1; | ||||
|  	options->gss_strict_acceptor = -1; | ||||
|  	options->gss_store_rekey = -1; | ||||
|  	options->gss_kex_algorithms = NULL; | ||||
| +	options->use_kuserok = -1;
 | ||||
|  	options->password_authentication = -1; | ||||
|  	options->kbd_interactive_authentication = -1; | ||||
|  	options->challenge_response_authentication = -1; | ||||
| @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->gss_strict_acceptor = 1; | ||||
|  	if (options->gss_store_rekey == -1) | ||||
|  		options->gss_store_rekey = 0; | ||||
|  	if (options->gss_kex_algorithms == NULL) | ||||
|  		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); | ||||
|  #endif | ||||
| +	if (options->use_kuserok == -1)
 | ||||
| +		options->use_kuserok = 1;
 | ||||
|  	if (options->password_authentication == -1) | ||||
|  | ||||
| @ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- | ||||
| +		return;
 | ||||
| +
 | ||||
| +	if (getexeccon((security_context_t *)&ctx) != 0) {
 | ||||
| +		logit("%s: getcon failed with %s", __func__, strerror (errno));
 | ||||
| +		logit("%s: getexeccon failed with %s", __func__, strerror(errno));
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +	if (ctx != NULL) {
 | ||||
| +		/* unset exec context before we will lose this capabililty */
 | ||||
| +		if (setexeccon(NULL) != 0)
 | ||||
| +			fatal("%s: setexeccon failed with %s", __func__, strerror (errno));
 | ||||
| +			fatal("%s: setexeccon failed with %s", __func__, strerror(errno));
 | ||||
| +		if (setcon(ctx) != 0)
 | ||||
| +			fatal("%s: setcon failed with %s", __func__, strerror (errno));
 | ||||
| +			fatal("%s: setcon failed with %s", __func__, strerror(errno));
 | ||||
| +		freecon(ctx);
 | ||||
| +	}
 | ||||
| +}
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ 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
 | ||||
| @@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx
 | ||||
|  	mm_get_keystate(pmonitor); | ||||
|  	mm_get_keystate(ssh, pmonitor); | ||||
|   | ||||
|  	/* Drain any buffered messages from the child */ | ||||
| -	while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
 | ||||
| @ -124,14 +124,14 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c | ||||
|  } | ||||
|   | ||||
| @@ -518,7 +518,7 @@ server_request_tun(void)
 | ||||
|  		debug("%s: invalid tun", __func__); | ||||
|  		goto done; | ||||
|  	} | ||||
|   | ||||
|  	tun = packet_get_int(); | ||||
| -	if (auth_opts->force_tun_device != -1) {
 | ||||
| +	if (auth_opts->force_tun_device >= 0) {
 | ||||
|  		if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) | ||||
|  		if (tun != SSH_TUNID_ANY && | ||||
|  		    auth_opts->force_tun_device != (int)tun) | ||||
|  			goto done; | ||||
|  		tun = auth_opts->force_tun_device; | ||||
| 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
 | ||||
| @ -163,7 +163,7 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c | ||||
| +++ openssh-7.4p1/sshd.c	2016-12-23 16:40:26.904788692 +0100
 | ||||
| @@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
 | ||||
|   | ||||
|  		privsep_preauth_child(); | ||||
|  		privsep_preauth_child(ssh); | ||||
|  		setproctitle("%s", "[net]"); | ||||
| -		if (box != NULL)
 | ||||
| +		if (box != NULL) {
 | ||||
| @ -174,8 +174,8 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c | ||||
|  		return 0; | ||||
|  	} | ||||
| @@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
 | ||||
|  		if (num_listen_socks < 0) | ||||
|  			break; | ||||
|  			explicit_bzero(rnd, sizeof(rnd)); | ||||
|  		} | ||||
|  	} | ||||
| +
 | ||||
| +	if (fdset != NULL)
 | ||||
|  | ||||
| @ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in | ||||
| diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
 | ||||
| --- openssh-6.8p1/ssh-cavs.c.kdf-cavs	2015-03-18 11:23:46.348049354 +0100
 | ||||
| +++ openssh-6.8p1/ssh-cavs.c	2015-03-18 11:23:46.348049354 +0100
 | ||||
| @@ -0,0 +1,377 @@
 | ||||
| @@ -0,0 +1,387 @@
 | ||||
| +/*
 | ||||
| + * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
 | ||||
| + *
 | ||||
| @ -208,6 +208,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c | ||||
| +{
 | ||||
| +	int ret = 0;
 | ||||
| +	struct kex kex;
 | ||||
| +	struct sshbuf *Kb = NULL;
 | ||||
| +	BIGNUM *Kbn = NULL;
 | ||||
| +	int mode = 0;
 | ||||
| +	struct newkeys *ctoskeys;
 | ||||
| @ -222,10 +223,17 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c | ||||
| +	Kbn = BN_new();
 | ||||
| +	BN_bin2bn(test->K, test->Klen, Kbn);
 | ||||
| +	if (!Kbn) {
 | ||||
| +		printf("cannot convert K into BIGNUM\n");
 | ||||
| +		printf("cannot convert K into bignum\n");
 | ||||
| +		ret = 1;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	Kb = sshbuf_new();
 | ||||
| +	if (!Kb) {
 | ||||
| +		printf("cannot convert K into sshbuf\n");
 | ||||
| +		ret = 1;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	sshbuf_put_bignum2(Kb, Kbn);
 | ||||
| +
 | ||||
| +	kex.session_id = test->session_id;
 | ||||
| +	kex.session_id_len = test->session_id_len;
 | ||||
| @ -285,7 +293,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	ssh->kex = &kex;
 | ||||
| +	kex_derive_keys_bn(ssh, test->H, test->Hlen, Kbn);
 | ||||
| +	kex_derive_keys(ssh, test->H, test->Hlen, Kb);
 | ||||
| +
 | ||||
| +	ctoskeys = kex.newkeys[0];
 | ||||
| +	stockeys = kex.newkeys[1];
 | ||||
| @ -321,6 +329,8 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c | ||||
| +out:
 | ||||
| +	if (Kbn)
 | ||||
| +		BN_free(Kbn);
 | ||||
| +	if (Kb)
 | ||||
| +		sshbuf_free(Kb);
 | ||||
| +	if (ssh)
 | ||||
| +		ssh_packet_close(ssh);
 | ||||
| +	return ret;
 | ||||
|  | ||||
| @ -331,7 +331,7 @@ diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac | ||||
| +					[ac_cv_ldap_set_rebind_proc=3],
 | ||||
| +					[ac_cv_ldap_set_rebind_proc=2])
 | ||||
| +				AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
 | ||||
| +				AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
 | ||||
| +				AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
 | ||||
| +			)
 | ||||
| +			LIBS="$saved_LIBS"
 | ||||
| +		fi
 | ||||
| @ -646,7 +646,7 @@ diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf | ||||
| diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c
 | ||||
| --- openssh-6.8p1/ldapbody.c.ldap	2015-03-18 11:11:29.031801462 +0100
 | ||||
| +++ openssh-6.8p1/ldapbody.c	2015-03-18 11:11:29.031801462 +0100
 | ||||
| @@ -0,0 +1,494 @@
 | ||||
| @@ -0,0 +1,499 @@
 | ||||
| +/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 | ||||
| +/*
 | ||||
| + * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
 | ||||
| @ -708,7 +708,11 @@ diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c | ||||
| +
 | ||||
| +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
 | ||||
| +static int
 | ||||
| +#if LDAP_API_VERSION > 3000
 | ||||
| +_rebind_proc (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params)
 | ||||
| +#else
 | ||||
| +_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
 | ||||
| +#endif
 | ||||
| +{
 | ||||
| +	struct timeval timeout;
 | ||||
| +	int rc;
 | ||||
|  | ||||
| @ -10,18 +10,3 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c | ||||
|  	dump_cfg_string(sForceCommand, o->adm_forced_command); | ||||
|  	dump_cfg_string(sChrootDirectory, o->chroot_directory); | ||||
|  	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); | ||||
| diff -up openssh/ssh.1.sshdt openssh/ssh.1
 | ||||
| --- openssh/ssh.1.sshdt	2015-06-24 11:42:19.565102807 +0200
 | ||||
| +++ openssh/ssh.1	2015-06-24 11:42:29.042078701 +0200
 | ||||
| @@ -441,7 +441,11 @@ For full details of the options listed b
 | ||||
|  .It GatewayPorts | ||||
|  .It GlobalKnownHostsFile | ||||
|  .It GSSAPIAuthentication | ||||
| +.It GSSAPIKeyExchange
 | ||||
| +.It GSSAPIClientIdentity
 | ||||
|  .It GSSAPIDelegateCredentials | ||||
| +.It GSSAPIRenewalForcesRekey
 | ||||
| +.It GSSAPITrustDNS
 | ||||
|  .It HashKnownHosts | ||||
|  .It Host | ||||
|  .It HostbasedAuthentication | ||||
|  | ||||
| @ -1,431 +0,0 @@ | ||||
| diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c
 | ||||
| --- openssh-7.0p1/gss-genr.c.gsskexalg	2015-08-19 12:28:38.024518959 +0200
 | ||||
| +++ openssh-7.0p1/gss-genr.c	2015-08-19 12:28:38.078518839 +0200
 | ||||
| @@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() {
 | ||||
|   */ | ||||
|   | ||||
|  char * | ||||
| -ssh_gssapi_client_mechanisms(const char *host, const char *client) {
 | ||||
| +ssh_gssapi_client_mechanisms(const char *host, const char *client,
 | ||||
| +    const char *kex) {
 | ||||
|  	gss_OID_set gss_supported; | ||||
|  	OM_uint32 min_status; | ||||
|   | ||||
| @@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char
 | ||||
|  		return NULL; | ||||
|   | ||||
|  	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, | ||||
| -	    host, client));
 | ||||
| +	    host, client, kex));
 | ||||
|  } | ||||
|   | ||||
|  char * | ||||
|  ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, | ||||
| -    const char *host, const char *client) {
 | ||||
| +    const char *host, const char *client, const char *kex) {
 | ||||
|  	struct sshbuf *buf; | ||||
|  	size_t i; | ||||
|  	int oidpos, enclen, r; | ||||
| @@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
 | ||||
|  	char deroid[2]; | ||||
|  	const EVP_MD *evp_md = EVP_md5(); | ||||
|  	EVP_MD_CTX md; | ||||
| +	char *s, *cp, *p;
 | ||||
|   | ||||
|  	if (gss_enc2oid != NULL) { | ||||
|  		for (i = 0; gss_enc2oid[i].encoded != NULL; i++) | ||||
| @@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
 | ||||
|  		fatal("%s: sshbuf_new failed", __func__); | ||||
|   | ||||
|  	oidpos = 0; | ||||
| +	s = cp = xstrdup(kex);
 | ||||
|  	for (i = 0; i < gss_supported->count; i++) { | ||||
|  		if (gss_supported->elements[i].length < 128 && | ||||
|  		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) { | ||||
| @@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
 | ||||
|  			enclen = __b64_ntop(digest, EVP_MD_size(evp_md), | ||||
|  			    encoded, EVP_MD_size(evp_md) * 2); | ||||
|   | ||||
| -			if (oidpos != 0)
 | ||||
| -				if ((r = sshbuf_put_u8(buf, ',')) != 0)
 | ||||
| -					fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
| -
 | ||||
| -			if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID,
 | ||||
| -			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 ||
 | ||||
| -			    (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
 | ||||
| -			    (r = sshbuf_put_u8(buf, ',')) != 0 ||
 | ||||
| -			    (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, 
 | ||||
| -			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 ||
 | ||||
| -			    (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
 | ||||
| -			    (r = sshbuf_put_u8(buf, ',')) != 0 ||
 | ||||
| -			    (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID,
 | ||||
| -			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 ||
 | ||||
| -			    (r = sshbuf_put(buf, encoded, enclen)) != 0)
 | ||||
| -		 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
| +			cp = strncpy(s, kex, strlen(kex));
 | ||||
| +			for ((p = strsep(&cp, ",")); p && *p != '\0';
 | ||||
| +				(p = strsep(&cp, ","))) {
 | ||||
| +				if (sshbuf_len(buf) != 0)
 | ||||
| +					if ((r = sshbuf_put_u8(buf, ',')) != 0)
 | ||||
| +			 			fatal("%s: buffer error: %s",
 | ||||
| +						    __func__, ssh_err(r));
 | ||||
| +				if ((r = sshbuf_put(buf, p, strlen(p))) != 0 ||
 | ||||
| +				    (r = sshbuf_put(buf, encoded, enclen)) != 0)
 | ||||
| +			 		fatal("%s: buffer error: %s",
 | ||||
| +					    __func__, ssh_err(r));
 | ||||
| +			}
 | ||||
|   | ||||
|  			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); | ||||
|  			gss_enc2oid[oidpos].encoded = encoded; | ||||
|  			oidpos++; | ||||
|  		} | ||||
|  	} | ||||
| +	free(s);
 | ||||
|  	gss_enc2oid[oidpos].oid = NULL; | ||||
|  	gss_enc2oid[oidpos].encoded = NULL; | ||||
|   | ||||
| diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c
 | ||||
| --- openssh-7.0p1/gss-serv.c.gsskexalg	2015-08-19 12:28:38.024518959 +0200
 | ||||
| +++ openssh-7.0p1/gss-serv.c	2015-08-19 12:28:38.078518839 +0200
 | ||||
| @@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() {
 | ||||
|  	if (supported_oids == NULL) | ||||
|  		ssh_gssapi_prepare_supported_oids(); | ||||
|  	return (ssh_gssapi_kex_mechs(supported_oids, | ||||
| -	    &ssh_gssapi_server_check_mech, NULL, NULL));
 | ||||
| +	    &ssh_gssapi_server_check_mech, NULL, NULL,
 | ||||
| +	    options.gss_kex_algorithms));
 | ||||
|  } | ||||
|   | ||||
|  /* Unprivileged */ | ||||
| diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c
 | ||||
| --- openssh-7.0p1/kex.c.gsskexalg	2015-08-19 12:28:38.078518839 +0200
 | ||||
| +++ openssh-7.0p1/kex.c	2015-08-19 12:30:13.249306371 +0200
 | ||||
| @@ -50,6 +50,7 @@
 | ||||
|  #include "misc.h" | ||||
|  #include "dispatch.h" | ||||
|  #include "monitor.h" | ||||
| +#include "xmalloc.h"
 | ||||
|   | ||||
|  #include "ssherr.h" | ||||
|  #include "sshbuf.h" | ||||
| @@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char
 | ||||
|  	return r; | ||||
|  } | ||||
|   | ||||
| +/* Validate GSS KEX method name list */
 | ||||
| +int
 | ||||
| +gss_kex_names_valid(const char *names)
 | ||||
| +{
 | ||||
| +	char *s, *cp, *p;
 | ||||
| +
 | ||||
| +	if (names == NULL || *names == '\0')
 | ||||
| +		return 0;
 | ||||
| +	s = cp = xstrdup(names);
 | ||||
| +	for ((p = strsep(&cp, ",")); p && *p != '\0';
 | ||||
| +	    (p = strsep(&cp, ","))) {
 | ||||
| +		if (strncmp(p, "gss-", 4) != 0
 | ||||
| +		  || kex_alg_by_name(p) == NULL) {
 | ||||
| +			error("Unsupported KEX algorithm \"%.100s\"", p);
 | ||||
| +			free(s);
 | ||||
| +			return 0;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	debug3("gss kex names ok: [%s]", names);
 | ||||
| +	free(s);
 | ||||
| +	return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* put algorithm proposal into buffer */ | ||||
|  int | ||||
|  kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) | ||||
| diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h
 | ||||
| --- openssh-7.0p1/kex.h.gsskexalg	2015-08-19 12:28:38.078518839 +0200
 | ||||
| +++ openssh-7.0p1/kex.h	2015-08-19 12:30:52.404218958 +0200
 | ||||
| @@ -173,6 +173,7 @@ int	 kex_names_valid(const char *);
 | ||||
|  char	*kex_alg_list(char); | ||||
|  char	*kex_names_cat(const char *, const char *); | ||||
|  int	 kex_assemble_names(char **, const char *, const char *); | ||||
| +int	 gss_kex_names_valid(const char *);
 | ||||
|   | ||||
|  int	 kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); | ||||
|  int	 kex_setup(struct ssh *, char *[PROPOSAL_MAX]); | ||||
| diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c
 | ||||
| --- openssh-7.0p1/readconf.c.gsskexalg	2015-08-19 12:28:38.026518955 +0200
 | ||||
| +++ openssh-7.0p1/readconf.c	2015-08-19 12:31:28.333138747 +0200
 | ||||
| @@ -61,6 +61,7 @@
 | ||||
|  #include "uidswap.h" | ||||
|  #include "myproposal.h" | ||||
|  #include "digest.h" | ||||
| +#include "ssh-gss.h"
 | ||||
|   | ||||
|  /* Format of the configuration file: | ||||
|   | ||||
| @@ -148,7 +149,7 @@ typedef enum {
 | ||||
|  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, | ||||
|  	oAddressFamily, oGssAuthentication, oGssDelegateCreds, | ||||
|  	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, | ||||
| -	oGssServerIdentity, 
 | ||||
| +	oGssServerIdentity, oGssKexAlgorithms,
 | ||||
|  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, | ||||
|  	oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, | ||||
|  	oHashKnownHosts, | ||||
| @@ -200,6 +201,7 @@ static struct {
 | ||||
|  	{ "gssapiclientidentity", oGssClientIdentity }, | ||||
|  	{ "gssapiserveridentity", oGssServerIdentity }, | ||||
|  	{ "gssapirenewalforcesrekey", oGssRenewalRekey }, | ||||
| +	{ "gssapikexalgorithms", oGssKexAlgorithms },
 | ||||
|  # else | ||||
|  	{ "gssapiauthentication", oUnsupported }, | ||||
|  	{ "gssapikeyexchange", oUnsupported }, | ||||
| @@ -207,6 +209,7 @@ static struct {
 | ||||
|  	{ "gssapitrustdns", oUnsupported }, | ||||
|  	{ "gssapiclientidentity", oUnsupported }, | ||||
|  	{ "gssapirenewalforcesrekey", oUnsupported }, | ||||
| +	{ "gssapikexalgorithms", oUnsupported },
 | ||||
|  #endif | ||||
|  #ifdef ENABLE_PKCS11 | ||||
|  	{ "smartcarddevice", oPKCS11Provider }, | ||||
| @@ -929,6 +932,18 @@ parse_time:
 | ||||
|  		intptr = &options->gss_renewal_rekey; | ||||
|  		goto parse_flag; | ||||
|   | ||||
| +	case oGssKexAlgorithms:
 | ||||
| +		arg = strdelim(&s);
 | ||||
| +		if (!arg || *arg == '\0')
 | ||||
| +			fatal("%.200s line %d: Missing argument.",
 | ||||
| +			    filename, linenum);
 | ||||
| +		if (!gss_kex_names_valid(arg))
 | ||||
| +			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
 | ||||
| +			    filename, linenum, arg ? arg : "<NONE>");
 | ||||
| +		if (*activep && options->gss_kex_algorithms == NULL)
 | ||||
| +			options->gss_kex_algorithms = xstrdup(arg);
 | ||||
| +		break;
 | ||||
| +
 | ||||
|  	case oBatchMode: | ||||
|  		intptr = &options->batch_mode; | ||||
|  		goto parse_flag; | ||||
| @@ -1638,6 +1653,7 @@ initialize_options(Options * options)
 | ||||
|  	options->gss_renewal_rekey = -1; | ||||
|  	options->gss_client_identity = NULL; | ||||
|  	options->gss_server_identity = NULL; | ||||
| +	options->gss_kex_algorithms = NULL;
 | ||||
|  	options->password_authentication = -1; | ||||
|  	options->kbd_interactive_authentication = -1; | ||||
|  	options->kbd_interactive_devices = NULL; | ||||
| @@ -1773,6 +1789,10 @@ fill_default_options(Options * options)
 | ||||
|  		options->gss_trust_dns = 0; | ||||
|  	if (options->gss_renewal_rekey == -1) | ||||
|  		options->gss_renewal_rekey = 0; | ||||
| +#ifdef GSSAPI
 | ||||
| +	if (options->gss_kex_algorithms == NULL)
 | ||||
| +		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
 | ||||
| +#endif
 | ||||
|  	if (options->password_authentication == -1) | ||||
|  		options->password_authentication = 1; | ||||
|  	if (options->kbd_interactive_authentication == -1) | ||||
| @@ -2651,6 +2671,8 @@ dump_client_config(Options *o, const cha
 | ||||
|  	dump_cfg_string(oGssClientIdentity, o->gss_client_identity); | ||||
|  	dump_cfg_string(oGssServerIdentity, o->gss_client_identity); | ||||
|  	dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); | ||||
| +	dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ?
 | ||||
| +		o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX);
 | ||||
|  #endif /* GSSAPI */ | ||||
|  	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); | ||||
|  	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); | ||||
| diff -up openssh-7.9p1/readconf.h.gsskexalg openssh-7.9p1/readconf.h
 | ||||
| --- openssh-7.9p1/readconf.h.gsskexalg	2018-11-14 09:20:06.616350574 +0100
 | ||||
| +++ openssh-7.9p1/readconf.h	2018-11-14 09:20:06.647350828 +0100
 | ||||
| @@ -46,6 +46,7 @@ typedef struct {
 | ||||
|  	int	gss_renewal_rekey;	/* Credential renewal forces rekey */ | ||||
|  	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */ | ||||
|  	char    *gss_server_identity;   /* GSSAPI target principal */ | ||||
| +	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
 | ||||
|  	int     password_authentication;	/* Try password | ||||
|  						 * authentication. */ | ||||
|  	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */ | ||||
| diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c
 | ||||
| --- openssh-7.0p1/servconf.c.gsskexalg	2015-08-19 12:28:38.074518847 +0200
 | ||||
| +++ openssh-7.0p1/servconf.c	2015-08-19 12:33:13.599902732 +0200
 | ||||
| @@ -57,6 +57,7 @@
 | ||||
|  #include "auth.h" | ||||
|  #include "myproposal.h" | ||||
|  #include "digest.h" | ||||
| +#include "ssh-gss.h"
 | ||||
|   | ||||
|  static void add_listen_addr(ServerOptions *, const char *, | ||||
|      const char *, int); | ||||
| @@ -121,6 +122,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->gss_cleanup_creds = -1; | ||||
|  	options->gss_strict_acceptor = -1; | ||||
|  	options->gss_store_rekey = -1; | ||||
| +	options->gss_kex_algorithms = NULL;
 | ||||
|  	options->use_kuserok = -1; | ||||
|  	options->enable_k5users = -1; | ||||
|  	options->password_authentication = -1; | ||||
| @@ -288,6 +290,10 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->gss_strict_acceptor = 1; | ||||
|  	if (options->gss_store_rekey == -1) | ||||
|  		options->gss_store_rekey = 0; | ||||
| +#ifdef GSSAPI
 | ||||
| +	if (options->gss_kex_algorithms == NULL)
 | ||||
| +		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
 | ||||
| +#endif
 | ||||
|  	if (options->use_kuserok == -1) | ||||
|  		options->use_kuserok = 1; | ||||
|  	if (options->enable_k5users == -1) | ||||
| @@ -427,7 +431,7 @@ typedef enum {
 | ||||
|  	sHostKeyAlgorithms, | ||||
|  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | ||||
|  	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, | ||||
| -	sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
 | ||||
| +	sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel,
 | ||||
|  	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | ||||
|  	sUsePrivilegeSeparation, sAllowAgentForwarding, | ||||
|  	sHostCertificate, | ||||
| @@ -506,6 +510,7 @@ static struct {
 | ||||
|  	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, | ||||
| +	{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
 | ||||
|  #else | ||||
|  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, | ||||
|  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, | ||||
| @@ -513,6 +518,7 @@ static struct {
 | ||||
|  	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapienablek5users", sUnsupported, SSHCFG_ALL }, | ||||
| +	{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
 | ||||
|  #endif | ||||
|  	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, | ||||
| @@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions
 | ||||
|  		intptr = &options->gss_store_rekey; | ||||
|  		goto parse_flag; | ||||
|   | ||||
| +	case sGssKexAlgorithms:
 | ||||
| +		arg = strdelim(&cp);
 | ||||
| +		if (!arg || *arg == '\0')
 | ||||
| +			fatal("%.200s line %d: Missing argument.",
 | ||||
| +			    filename, linenum);
 | ||||
| +		if (!gss_kex_names_valid(arg))
 | ||||
| +			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
 | ||||
| +			    filename, linenum, arg ? arg : "<NONE>");
 | ||||
| +		if (*activep && options->gss_kex_algorithms == NULL)
 | ||||
| +			options->gss_kex_algorithms = xstrdup(arg);
 | ||||
| +		break;
 | ||||
| +
 | ||||
|  	case sPasswordAuthentication: | ||||
|  		intptr = &options->password_authentication; | ||||
|  		goto parse_flag; | ||||
| @@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o)
 | ||||
|  	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); | ||||
|  	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); | ||||
|  	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); | ||||
| +	dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
 | ||||
|  #endif | ||||
|  	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); | ||||
|  	dump_cfg_fmtint(sKbdInteractiveAuthentication, | ||||
| diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h
 | ||||
| --- openssh-7.0p1/servconf.h.gsskexalg	2015-08-19 12:28:38.080518834 +0200
 | ||||
| +++ openssh-7.0p1/servconf.h	2015-08-19 12:34:46.328693944 +0200
 | ||||
| @@ -122,6 +122,7 @@ typedef struct {
 | ||||
|  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ | ||||
|  	int     gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */ | ||||
|  	int 	gss_store_rekey; | ||||
| +	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
 | ||||
|  	int     password_authentication;	/* If true, permit password | ||||
|  						 * authentication. */ | ||||
|  	int     kbd_interactive_authentication;	/* If true, permit */ | ||||
| diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1
 | ||||
| --- openssh-7.0p1/ssh.1.gsskexalg	2015-08-19 12:28:38.081518832 +0200
 | ||||
| +++ openssh-7.0p1/ssh.1	2015-08-19 12:35:31.741591692 +0200
 | ||||
| @@ -496,6 +496,7 @@ For full details of the options listed b
 | ||||
|  .It GSSAPIDelegateCredentials | ||||
|  .It GSSAPIRenewalForcesRekey | ||||
|  .It GSSAPITrustDNS | ||||
| +.It GSSAPIKexAlgorithms
 | ||||
|  .It HashKnownHosts | ||||
|  .It Host | ||||
|  .It HostbasedAuthentication | ||||
| diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5
 | ||||
| --- openssh-7.0p1/ssh_config.5.gsskexalg	2015-08-19 12:28:38.028518950 +0200
 | ||||
| +++ openssh-7.0p1/ssh_config.5	2015-08-19 12:28:38.082518830 +0200
 | ||||
| @@ -786,6 +786,18 @@ command line will be passed untouched to
 | ||||
|  command line will be passed untouched to the GSSAPI library. | ||||
|  The default is | ||||
|  .Dq no . | ||||
| +.It Cm GSSAPIKexAlgorithms
 | ||||
| +The list of key exchange algorithms that are offered for GSSAPI
 | ||||
| +key exchange. Possible values are
 | ||||
| +.Bd -literal -offset 3n
 | ||||
| +gss-gex-sha1-,
 | ||||
| +gss-group1-sha1-,
 | ||||
| +gss-group14-sha1-
 | ||||
| +.Ed
 | ||||
| +.Pp
 | ||||
| +The default is
 | ||||
| +.Dq gss-gex-sha1-,gss-group14-sha1- .
 | ||||
| +This option only applies to protocol version 2 connections using GSSAPI.
 | ||||
|  .It Cm HashKnownHosts | ||||
|  Indicates that | ||||
|  .Xr ssh 1 | ||||
| diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c
 | ||||
| --- openssh-7.0p1/sshconnect2.c.gsskexalg	2015-08-19 12:28:38.045518912 +0200
 | ||||
| +++ openssh-7.0p1/sshconnect2.c	2015-08-19 12:28:38.081518832 +0200
 | ||||
| @@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho
 | ||||
|  		else | ||||
|  			gss_host = host; | ||||
|   | ||||
| -		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
 | ||||
| +		gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||
| +		    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||
|  		if (gss) { | ||||
|  			debug("Offering GSSAPI proposal: %s", gss); | ||||
|  			xasprintf(&options.kex_algorithms, | ||||
| --- openssh-7.1p1/sshd_config.5.gsskexalg	2015-12-10 15:32:48.105418092 +0100
 | ||||
| +++ openssh-7.1p1/sshd_config.5	2015-12-10 15:33:47.771279548 +0100
 | ||||
| @@ -663,6 +663,18 @@ or updated credentials from a compatible
 | ||||
|  For this to work | ||||
|  .Cm GSSAPIKeyExchange | ||||
|  needs to be enabled in the server and also used by the client. | ||||
| +.It Cm GSSAPIKexAlgorithms
 | ||||
| +The list of key exchange algorithms that are accepted by GSSAPI
 | ||||
| +key exchange. Possible values are
 | ||||
| +.Bd -literal -offset 3n
 | ||||
| +gss-gex-sha1-,
 | ||||
| +gss-group1-sha1-,
 | ||||
| +gss-group14-sha1-
 | ||||
| +.Ed
 | ||||
| +.Pp
 | ||||
| +The default is
 | ||||
| +.Dq gss-gex-sha1-,gss-group14-sha1- .
 | ||||
| +This option only applies to protocol version 2 connections using GSSAPI.
 | ||||
|  .It Cm HostbasedAcceptedKeyTypes | ||||
|  Specifies the key types that will be accepted for hostbased authentication | ||||
|  as a list of comma-separated patterns. | ||||
| diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h
 | ||||
| --- openssh-7.0p1/ssh-gss.h.gsskexalg	2015-08-19 12:28:38.031518944 +0200
 | ||||
| +++ openssh-7.0p1/ssh-gss.h	2015-08-19 12:28:38.081518832 +0200
 | ||||
| @@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds;
 | ||||
|  #define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-" | ||||
|  #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-" | ||||
|   | ||||
| +#define        GSS_KEX_DEFAULT_KEX \
 | ||||
| +	KEX_GSS_GEX_SHA1_ID "," \
 | ||||
| +	KEX_GSS_GRP14_SHA1_ID
 | ||||
| +
 | ||||
|  typedef struct { | ||||
|  	char *envvar; | ||||
|  	char *envval; | ||||
| @@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct
 | ||||
|  /* In the server */ | ||||
|  typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *,  | ||||
|      const char *); | ||||
| -char *ssh_gssapi_client_mechanisms(const char *, const char *);
 | ||||
| +char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
 | ||||
|  char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, | ||||
| -    const char *);
 | ||||
| +    const char *, const char *);
 | ||||
|  gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); | ||||
|  int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,  | ||||
|      const char *); | ||||
| @ -1,52 +0,0 @@ | ||||
| diff -up openssh-7.4p1/ssh_config.5.gss-docs openssh-7.4p1/ssh_config.5
 | ||||
| --- openssh-7.4p1/ssh_config.5.gss-docs	2016-12-23 14:28:34.051714486 +0100
 | ||||
| +++ openssh-7.4p1/ssh_config.5	2016-12-23 14:34:24.568522417 +0100
 | ||||
| @@ -765,10 +765,19 @@ The default is
 | ||||
|  If set to  | ||||
|  .Dq yes | ||||
|  then renewal of the client's GSSAPI credentials will force the rekeying of the | ||||
| -ssh connection. With a compatible server, this can delegate the renewed 
 | ||||
| +ssh connection. With a compatible server, this will delegate the renewed 
 | ||||
|  credentials to a session on the server. | ||||
| +.Pp
 | ||||
| +Checks are made to ensure that credentials are only propagated when the new
 | ||||
| +credentials match the old ones on the originating client and where the
 | ||||
| +receiving server still has the old set in its cache.
 | ||||
| +.Pp
 | ||||
|  The default is | ||||
|  .Dq no . | ||||
| +.Pp
 | ||||
| +For this to work
 | ||||
| +.Cm GSSAPIKeyExchange
 | ||||
| +needs to be enabled in the server and also used by the client.
 | ||||
|  .It Cm GSSAPIServerIdentity | ||||
|  If set, specifies the GSSAPI server identity that ssh should expect when  | ||||
|  connecting to the server. The default is unset, which means that the | ||||
| @@ -776,9 +785,11 @@ expected GSSAPI server identity will be
 | ||||
|  hostname. | ||||
|  .It Cm GSSAPITrustDns | ||||
|  Set to  | ||||
| -.Dq yes to indicate that the DNS is trusted to securely canonicalize
 | ||||
| +.Dq yes
 | ||||
| +to indicate that the DNS is trusted to securely canonicalize
 | ||||
|  the name of the host being connected to. If  | ||||
| -.Dq no, the hostname entered on the
 | ||||
| +.Dq no ,
 | ||||
| +the hostname entered on the
 | ||||
|  command line will be passed untouched to the GSSAPI library. | ||||
|  The default is | ||||
|  .Dq no . | ||||
| diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5
 | ||||
| --- openssh-7.4p1/sshd_config.5.gss-docs	2016-12-23 14:28:34.043714490 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config.5	2016-12-23 14:28:34.051714486 +0100
 | ||||
| @@ -652,6 +652,10 @@ Controls whether the user's GSSAPI crede
 | ||||
|  successful connection rekeying. This option can be used to accepted renewed  | ||||
|  or updated credentials from a compatible client. The default is | ||||
|  .Dq no . | ||||
| +.Pp
 | ||||
| +For this to work
 | ||||
| +.Cm GSSAPIKeyExchange
 | ||||
| +needs to be enabled in the server and also used by the client.
 | ||||
|  .It Cm HostbasedAcceptedKeyTypes | ||||
|  Specifies the key types that will be accepted for hostbased authentication | ||||
|  as a list of comma-separated patterns. | ||||
| @ -56,9 +56,9 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h | ||||
| --- openssh-7.4p1/monitor_wrap.h.audit-race	2016-12-23 16:35:52.694685771 +0100
 | ||||
| +++ openssh-7.4p1/monitor_wrap.h	2016-12-23 16:35:52.698685772 +0100
 | ||||
| @@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int);
 | ||||
|  void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); | ||||
|  void mm_audit_session_key_free_body(int, pid_t, uid_t); | ||||
|  void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); | ||||
|  void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); | ||||
|  void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t); | ||||
|  void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); | ||||
| +int mm_forward_audit_messages(int);
 | ||||
| +void mm_set_monitor_pipe(int);
 | ||||
|  #endif | ||||
| @ -82,7 +82,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
|  	return 1; | ||||
|  } | ||||
|   | ||||
| +void child_destory_sensitive_data();
 | ||||
| +void child_destory_sensitive_data(struct ssh *ssh);
 | ||||
| +
 | ||||
|  #define USE_PIPES 1 | ||||
|  /* | ||||
| @ -91,7 +91,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
|  		close(err[0]); | ||||
|  #endif | ||||
|   | ||||
| +		child_destory_sensitive_data();
 | ||||
| +		child_destory_sensitive_data(ssh);
 | ||||
| +
 | ||||
|  		/* Do processing for the child (exec command etc). */ | ||||
|  		do_child(ssh, s, command); | ||||
| @ -101,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
|  		close(ttyfd); | ||||
|   | ||||
| +		/* Do this early, so we will not block large MOTDs */
 | ||||
| +		child_destory_sensitive_data();
 | ||||
| +		child_destory_sensitive_data(ssh);
 | ||||
| +
 | ||||
|  		/* record login, etc. similar to login(1) */ | ||||
|  #ifndef HAVE_OSF_SIA | ||||
| @ -109,7 +109,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
| @@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
 | ||||
|  	} | ||||
|  	if (s->command != NULL && s->ptyfd == -1) | ||||
|  		s->command_handle = PRIVSEP(audit_run_command(s->command)); | ||||
|  		s->command_handle = PRIVSEP(audit_run_command(ssh, s->command)); | ||||
| +	if (pipe(paudit) < 0)
 | ||||
| +		fatal("pipe: %s", strerror(errno));
 | ||||
|  #endif | ||||
| @ -141,7 +141,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
|  } | ||||
|   | ||||
| +void
 | ||||
| +child_destory_sensitive_data()
 | ||||
| +child_destory_sensitive_data(struct ssh *ssh)
 | ||||
| +{
 | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +	int pparent = paudit[1];
 | ||||
| @ -152,15 +152,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
| +#endif
 | ||||
| +
 | ||||
| +	/* remove hostkey from the child's memory */
 | ||||
| +	destroy_sensitive_data(use_privsep);
 | ||||
| +	destroy_sensitive_data(ssh, use_privsep);
 | ||||
| +	/*
 | ||||
| +	 * We can audit this, because we hacked the pipe to direct the
 | ||||
| +	 * messages over postauth child. But this message requires answer
 | ||||
| +	 * which we can't do using one-way pipe.
 | ||||
| +	 */
 | ||||
| +	packet_destroy_all(0, 1);
 | ||||
| +	packet_destroy_all(ssh, 0, 1);
 | ||||
| +	/* XXX this will clean the rest but should not audit anymore */
 | ||||
| +	/* packet_clear_keys(); */
 | ||||
| +	/* packet_clear_keys(ssh); */
 | ||||
| +
 | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +	/* Notify parent that we are done */
 | ||||
| @ -172,15 +172,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | ||||
|   * Performs common processing for the child, such as setting up the | ||||
|   * environment, closing extra file descriptors, setting the user and group | ||||
| @@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
 | ||||
|  	struct passwd *pw = s->pw; | ||||
|  	int r = 0; | ||||
|   | ||||
|  	sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); | ||||
|   | ||||
| -	/* remove hostkey from the child's memory */
 | ||||
| -	destroy_sensitive_data(1);
 | ||||
| -	packet_clear_keys();
 | ||||
| -	destroy_sensitive_data(ssh, 1);
 | ||||
| -	ssh_packet_clear_keys(ssh);
 | ||||
| -	/* Don't audit this - both us and the parent would be talking to the
 | ||||
| -	   monitor over a single socket, with no synchronization. */
 | ||||
| -	packet_destroy_all(0, 1);
 | ||||
| -	packet_destroy_all(ssh, 0, 1);
 | ||||
| -
 | ||||
|  	/* Force a password change */ | ||||
|  	if (s->authctxt->force_pwchange) { | ||||
|  | ||||
| @ -2,10 +2,11 @@ diff --git a/auth-krb5.c b/auth-krb5.c | ||||
| index 2b02a04..19b9364 100644
 | ||||
| --- a/auth-krb5.c
 | ||||
| +++ b/auth-krb5.c
 | ||||
| @@ -375,6 +375,22 @@ cleanup:
 | ||||
|  	return -1; | ||||
| @@ -375,5 +375,21 @@ cleanup:
 | ||||
|  		return (krb5_cc_resolve(ctx, ccname, ccache)); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| +
 | ||||
| +/*
 | ||||
| + * Reads  k5login_directory  option from the  krb5.conf
 | ||||
| + */
 | ||||
| @ -21,10 +22,8 @@ index 2b02a04..19b9364 100644 | ||||
| +	return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL,
 | ||||
| +		k5login_directory);
 | ||||
| +}
 | ||||
| +
 | ||||
|  krb5_error_code | ||||
|  ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { | ||||
|  	profile_t p; | ||||
|  #endif /* !HEIMDAL */ | ||||
|  #endif /* KRB5 */ | ||||
| diff --git a/auth.h b/auth.h
 | ||||
| index f9d191c..c432d2f 100644
 | ||||
| --- a/auth.h
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -20,8 +20,8 @@ index ca75cc7..6e7de31 100644 | ||||
| +#if defined(__NR_flock) && defined(__s390__)
 | ||||
| +	SC_ALLOW(__NR_flock),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_geteuid | ||||
|  	SC_ALLOW(__NR_geteuid), | ||||
|  #ifdef __NR_futex | ||||
|  	SC_ALLOW(__NR_futex), | ||||
|  #endif | ||||
| @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {
 | ||||
|  #ifdef __NR_gettimeofday | ||||
| @ -106,3 +106,41 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se | ||||
|  #ifdef __NR_getrandom | ||||
|  	SC_ALLOW(__NR_getrandom), | ||||
|  #endif | ||||
| 
 | ||||
| 
 | ||||
| From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001 | ||||
| From: Harald Freudenberger <freude@linux.ibm.com> | ||||
| Date: Fri, 24 May 2019 10:11:15 +0200 | ||||
| Subject: [PATCH] allow s390 specific ioctl for ecc hardware support | ||||
| 
 | ||||
| Adding another s390 specific ioctl to be able to support ECC hardware acceleration | ||||
| to the sandbox seccomp filter rules. | ||||
| 
 | ||||
| Now the ibmca openssl engine provides elliptic curve cryptography support with the | ||||
| help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt | ||||
| device driver and so there is a need to enable this on the openssl sandbox. | ||||
| 
 | ||||
| Code is s390 specific and has been tested, verified and reviewed. | ||||
| 
 | ||||
| Please note that I am also the originator of the previous changes in that area. | ||||
| I posted these changes to Eduardo and he forwarded the patches to the openssl | ||||
| community. | ||||
| 
 | ||||
| Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> | ||||
| Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com> | ||||
| ---
 | ||||
|  sandbox-seccomp-filter.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
| 
 | ||||
| diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
 | ||||
| index 5edbc6946..56eb9317f 100644
 | ||||
| --- a/sandbox-seccomp-filter.c
 | ||||
| +++ b/sandbox-seccomp-filter.c
 | ||||
| @@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = {
 | ||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), | ||||
|  	/* Allow ioctls for EP11 crypto card on s390 */ | ||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), | ||||
| +	SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB),
 | ||||
|  #endif | ||||
|  #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) | ||||
|  	/* | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,6 +1,6 @@ | ||||
| diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
 | ||||
| --- openssh/auth2-pubkey.c.refactor	2017-09-27 13:10:19.556830609 +0200
 | ||||
| +++ openssh/auth2-pubkey.c	2017-09-27 13:10:19.677831274 +0200
 | ||||
| --- openssh/auth2-pubkey.c.refactor	2019-04-04 13:19:12.188821236 +0200
 | ||||
| +++ openssh/auth2-pubkey.c	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -72,6 +72,9 @@
 | ||||
|  extern ServerOptions options; | ||||
|  extern u_char *session_id2; | ||||
| @ -11,7 +11,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c | ||||
|   | ||||
|  static char * | ||||
|  format_key(const struct sshkey *key) | ||||
| @@ -432,7 +435,8 @@ match_principals_command(struct passwd *
 | ||||
| @@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
 | ||||
|   | ||||
|  	if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command, | ||||
|  	    ac, av, &f, | ||||
| @ -21,7 +21,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c | ||||
|  		goto out; | ||||
|   | ||||
|  	uid_swapped = 1; | ||||
| @@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd
 | ||||
| @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
 | ||||
|   | ||||
|  	if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, | ||||
|  	    ac, av, &f, | ||||
| @ -32,9 +32,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c | ||||
|   | ||||
|  	uid_swapped = 1; | ||||
| diff -up openssh/auth.c.refactor openssh/auth.c
 | ||||
| --- openssh/auth.c.refactor	2017-09-27 13:10:19.640831071 +0200
 | ||||
| +++ openssh/auth.c	2017-09-27 13:10:19.678831279 +0200
 | ||||
| @@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv)
 | ||||
| --- openssh/auth.c.refactor	2019-04-04 13:19:12.235821686 +0200
 | ||||
| +++ openssh/auth.c	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
 | ||||
|   */ | ||||
|  pid_t | ||||
|  subprocess(const char *tag, struct passwd *pw, const char *command, | ||||
| @ -44,7 +44,7 @@ diff -up openssh/auth.c.refactor openssh/auth.c | ||||
|  { | ||||
|  	FILE *f = NULL; | ||||
|  	struct stat st; | ||||
| @@ -1551,7 +1552,7 @@ subprocess(const char *tag, struct passw
 | ||||
| @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
 | ||||
|  		} | ||||
|   | ||||
|  #ifdef WITH_SELINUX | ||||
| @ -54,9 +54,9 @@ diff -up openssh/auth.c.refactor openssh/auth.c | ||||
|  			    strerror(errno)); | ||||
|  			_exit(127); | ||||
| diff -up openssh/auth.h.refactor openssh/auth.h
 | ||||
| --- openssh/auth.h.refactor	2017-09-25 01:48:10.000000000 +0200
 | ||||
| +++ openssh/auth.h	2017-09-27 13:10:19.678831279 +0200
 | ||||
| @@ -144,7 +144,7 @@ int	 exited_cleanly(pid_t, const char *,
 | ||||
| --- openssh/auth.h.refactor	2019-04-04 13:19:12.251821839 +0200
 | ||||
| +++ openssh/auth.h	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -235,7 +235,7 @@ struct passwd *fakepw(void);
 | ||||
|  #define	SSH_SUBPROCESS_STDOUT_CAPTURE  (1<<1)  /* Redirect stdout */ | ||||
|  #define	SSH_SUBPROCESS_STDERR_DISCARD  (1<<2)  /* Discard stderr */ | ||||
|  pid_t	subprocess(const char *, struct passwd *, | ||||
| @ -66,8 +66,8 @@ diff -up openssh/auth.h.refactor openssh/auth.h | ||||
|  int	 sys_auth_passwd(struct ssh *, const char *); | ||||
|   | ||||
| diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
 | ||||
| --- openssh/openbsd-compat/port-linux.h.refactor	2017-09-27 13:10:19.634831038 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux.h	2017-09-27 13:10:54.954025248 +0200
 | ||||
| --- openssh/openbsd-compat/port-linux.h.refactor	2019-04-04 13:19:12.256821887 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux.h	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch
 | ||||
|   | ||||
|  int sshd_selinux_enabled(void); | ||||
| @ -80,9 +80,9 @@ diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/por | ||||
|  #endif | ||||
|   | ||||
| diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c
 | ||||
| --- openssh/openbsd-compat/port-linux-sshd.c.refactor	2017-09-27 13:10:19.634831038 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux-sshd.c	2017-09-27 13:12:06.811420371 +0200
 | ||||
| @@ -48,11 +48,6 @@
 | ||||
| --- openssh/openbsd-compat/port-linux-sshd.c.refactor	2019-04-04 13:19:12.256821887 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux-sshd.c	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -49,11 +49,6 @@
 | ||||
|  #include <unistd.h> | ||||
|  #endif | ||||
|   | ||||
| @ -94,7 +94,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  /* Wrapper around is_selinux_enabled() to log its return value once only */ | ||||
|  int | ||||
|  sshd_selinux_enabled(void) | ||||
| @@ -222,7 +217,8 @@ get_user_context(const char *sename, con
 | ||||
| @@ -223,7 +218,8 @@ get_user_context(const char *sename, con
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| @ -104,7 +104,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  { | ||||
|  	*role = NULL; | ||||
|  	*level = NULL; | ||||
| @@ -240,8 +236,8 @@ ssh_selinux_get_role_level(char **role,
 | ||||
| @@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
 | ||||
|   | ||||
|  /* Return the default security context for the given username */ | ||||
|  static int | ||||
| @ -115,7 +115,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  { | ||||
|  	char *sename, *lvl; | ||||
|  	char *role; | ||||
| @@ -249,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
| @@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|  	int r = 0; | ||||
|  	context_t con = NULL; | ||||
|   | ||||
| @ -124,7 +124,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|   | ||||
|  #ifdef HAVE_GETSEUSERBYNAME | ||||
|  	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { | ||||
| @@ -271,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
| @@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|   | ||||
|  	if (r == 0) { | ||||
|  		/* If launched from xinetd, we must use current level */ | ||||
| @ -133,7 +133,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  			security_context_t sshdsc=NULL; | ||||
|   | ||||
|  			if (getcon_raw(&sshdsc) < 0) | ||||
| @@ -332,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
| @@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|   | ||||
|  /* Setup environment variables for pam_selinux */ | ||||
|  static int | ||||
| @ -143,7 +143,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  { | ||||
|  	const char *reqlvl; | ||||
|  	char *role; | ||||
| @@ -341,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
| @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
|   | ||||
|  	debug3("%s: setting execution context", __func__); | ||||
|   | ||||
| @ -157,7 +157,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  		use_current = "1"; | ||||
|  	} else { | ||||
|  		use_current = ""; | ||||
| @@ -361,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
| @@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @ -170,7 +170,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @@ -373,25 +371,28 @@ do_setenv(char *name, const char *value)
 | ||||
| @@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| @ -204,7 +204,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  			switch (security_getenforce()) { | ||||
|  			case -1: | ||||
|  				fatal("%s: security_getenforce() failed", __func__); | ||||
| @@ -409,7 +410,7 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||
| @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||
|   | ||||
|  	debug3("%s: setting execution context", __func__); | ||||
|   | ||||
| @ -214,9 +214,9 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | ||||
|  		r = setexeccon(user_ctx); | ||||
|  		if (r < 0) { | ||||
| diff -up openssh/platform.c.refactor openssh/platform.c
 | ||||
| --- openssh/platform.c.refactor	2017-09-27 13:10:19.574830708 +0200
 | ||||
| +++ openssh/platform.c	2017-09-27 13:11:45.475303050 +0200
 | ||||
| @@ -33,6 +33,9 @@
 | ||||
| --- openssh/platform.c.refactor	2019-04-04 13:19:12.204821389 +0200
 | ||||
| +++ openssh/platform.c	2019-04-04 13:19:12.277822088 +0200
 | ||||
| @@ -32,6 +32,9 @@
 | ||||
|   | ||||
|  extern int use_privsep; | ||||
|  extern ServerOptions options; | ||||
| @ -226,7 +226,7 @@ diff -up openssh/platform.c.refactor openssh/platform.c | ||||
|   | ||||
|  void | ||||
|  platform_pre_listen(void) | ||||
| @@ -184,7 +187,9 @@ platform_setusercontext_post_groups(stru
 | ||||
| @@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
 | ||||
|  	} | ||||
|  #endif /* HAVE_SETPCRED */ | ||||
|  #ifdef WITH_SELINUX | ||||
| @ -238,9 +238,27 @@ diff -up openssh/platform.c.refactor openssh/platform.c | ||||
|  } | ||||
|   | ||||
| diff -up openssh/sshd.c.refactor openssh/sshd.c
 | ||||
| --- openssh/sshd.c.refactor	2017-09-27 13:10:19.674831257 +0200
 | ||||
| +++ openssh/sshd.c	2017-09-27 13:12:01.635391909 +0200
 | ||||
| @@ -2135,7 +2135,9 @@ main(int ac, char **av)
 | ||||
| --- openssh/sshd.c.refactor	2019-04-04 13:19:12.275822068 +0200
 | ||||
| +++ openssh/sshd.c	2019-04-04 13:19:51.270195262 +0200
 | ||||
| @@ -158,7 +158,7 @@ int debug_flag = 0;
 | ||||
|  static int test_flag = 0; | ||||
|   | ||||
|  /* Flag indicating that the daemon is being started from inetd. */ | ||||
| -static int inetd_flag = 0;
 | ||||
| +int inetd_flag = 0;
 | ||||
|   | ||||
|  /* Flag indicating that sshd should not detach and become a daemon. */ | ||||
|  static int no_daemon_flag = 0; | ||||
| @@ -171,7 +171,7 @@ static char **saved_argv;
 | ||||
|  static int saved_argc; | ||||
|   | ||||
|  /* re-exec */ | ||||
| -static int rexeced_flag = 0;
 | ||||
| +int rexeced_flag = 0;
 | ||||
|  static int rexec_flag = 1; | ||||
|  static int rexec_argc = 0; | ||||
|  static char **rexec_argv; | ||||
| @@ -2192,7 +2192,9 @@ main(int ac, char **av)
 | ||||
|  	} | ||||
|  #endif | ||||
|  #ifdef WITH_SELINUX | ||||
|  | ||||
| @ -1,801 +0,0 @@ | ||||
| diff -up openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-client.c
 | ||||
| --- openssh-7.6p1/ssh-pkcs11-client.c.pkcs11-ecdsa	2018-02-16 13:25:59.426469253 +0100
 | ||||
| +++ openssh-7.6p1/ssh-pkcs11-client.c	2018-02-16 13:25:59.428469265 +0100
 | ||||
| @@ -31,6 +31,15 @@
 | ||||
|  #include <errno.h> | ||||
|   | ||||
|  #include <openssl/rsa.h> | ||||
| +#ifdef OPENSSL_HAS_ECC
 | ||||
| +#include <openssl/ecdsa.h>
 | ||||
| +#if ((defined(LIBRESSL_VERSION_NUMBER) && \
 | ||||
| +	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
 | ||||
| +	(defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
 | ||||
| +	(OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +#define ENABLE_PKCS11_ECDSA 1
 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
|   | ||||
|  #include "pathnames.h" | ||||
|  #include "xmalloc.h" | ||||
| @@ -139,9 +147,9 @@ pkcs11_rsa_private_encrypt(int flen, con
 | ||||
|  	return (ret); | ||||
|  } | ||||
|   | ||||
| -/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
 | ||||
| +/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */
 | ||||
|  static int | ||||
| -wrap_key(RSA *rsa)
 | ||||
| +wrap_rsa_key(RSA *rsa)
 | ||||
|  { | ||||
|  	static RSA_METHOD helper_rsa; | ||||
|   | ||||
| @@ -152,6 +160,88 @@ wrap_key(RSA *rsa)
 | ||||
|  	return (0); | ||||
|  } | ||||
|   | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +static ECDSA_SIG *
 | ||||
| +pkcs11_ecdsa_private_sign(const unsigned char *from, int flen,
 | ||||
| +    const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa)
 | ||||
| +{
 | ||||
| +	struct sshkey *key = NULL;
 | ||||
| +	u_char *blob, *signature = NULL;
 | ||||
| +	size_t blen, slen = 0;
 | ||||
| +	struct sshbuf *msg = NULL;
 | ||||
| +	ECDSA_SIG *ret = NULL;
 | ||||
| +	BIGNUM *r = NULL, *s = NULL;
 | ||||
| +	int rv;
 | ||||
| +
 | ||||
| +	if ((key = sshkey_new(KEY_ECDSA)) == NULL)
 | ||||
| +		fatal("%s: sshkey_new failed", __func__);
 | ||||
| +	key->ecdsa = ecdsa;
 | ||||
| +	key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
 | ||||
| +	if (sshkey_to_blob(key, &blob, &blen) == 0)
 | ||||
| +		goto out;
 | ||||
| +	if ((msg = sshbuf_new()) == NULL)
 | ||||
| +		fatal("%s: sshbuf_new failed", __func__);
 | ||||
| +	if ((rv = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
 | ||||
| +	    (rv = sshbuf_put_string(msg, blob, blen)) != 0 ||
 | ||||
| +	    (rv = sshbuf_put_string(msg, from, flen)) != 0 ||
 | ||||
| +	    (rv = sshbuf_put_u32(msg, 0)) != 0)
 | ||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(rv));
 | ||||
| +	free(blob);
 | ||||
| +	send_msg(msg);
 | ||||
| +	sshbuf_reset(msg);
 | ||||
| +
 | ||||
| +	if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
 | ||||
| +		if ((rv = sshbuf_get_string(msg, &signature, &slen)) != 0)
 | ||||
| +			fatal("%s: buffer error: %s", __func__, ssh_err(rv));
 | ||||
| +		if (slen <= (size_t)ECDSA_size(ecdsa)) {
 | ||||
| +			int nlen = slen / 2;
 | ||||
| +			ret = ECDSA_SIG_new();
 | ||||
| +			r = BN_new();
 | ||||
| +			s = BN_new();
 | ||||
| +			BN_bin2bn(&signature[0], nlen, r);
 | ||||
| +			BN_bin2bn(&signature[nlen], nlen, s);
 | ||||
| +			ECDSA_SIG_set0(ret, r, s);
 | ||||
| +		}
 | ||||
| +		free(signature);
 | ||||
| +	}
 | ||||
| +out:
 | ||||
| +	sshkey_free(key);
 | ||||
| +	sshbuf_free(msg);
 | ||||
| +	return (ret);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */
 | ||||
| +static int
 | ||||
| +wrap_ecdsa_key(EC_KEY *ecdsa) {
 | ||||
| +#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +	static EC_KEY_METHOD *helper_ecdsa = NULL;
 | ||||
| +	if (helper_ecdsa == NULL) {
 | ||||
| +		const EC_KEY_METHOD *def = EC_KEY_get_default_method();
 | ||||
| +		helper_ecdsa = EC_KEY_METHOD_new(def);
 | ||||
| +		EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign);
 | ||||
| +	}
 | ||||
| +	EC_KEY_set_method(ecdsa, helper_ecdsa);
 | ||||
| +#else
 | ||||
| +	static ECDSA_METHOD *helper_ecdsa = NULL;
 | ||||
| +	if(helper_ecdsa == NULL) {
 | ||||
| +		const ECDSA_METHOD *def = ECDSA_get_default_method();
 | ||||
| +# ifdef ECDSA_F_ECDSA_METHOD_NEW
 | ||||
| +		helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def);
 | ||||
| +		ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa");
 | ||||
| +		ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign);
 | ||||
| +# else
 | ||||
| +		helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa));
 | ||||
| +		memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa));
 | ||||
| +		helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa";
 | ||||
| +		helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign;
 | ||||
| +# endif
 | ||||
| +	}
 | ||||
| +	ECDSA_set_method(ecdsa, helper_ecdsa);
 | ||||
| +#endif
 | ||||
| +	return (0);
 | ||||
| +}
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  static int | ||||
|  pkcs11_start_helper(void) | ||||
|  { | ||||
| @@ -212,7 +281,15 @@ pkcs11_add_provider(char *name, char *pi
 | ||||
|  				    __func__, ssh_err(r)); | ||||
|  			if ((r = sshkey_from_blob(blob, blen, &k)) != 0) | ||||
|  				fatal("%s: bad key: %s", __func__, ssh_err(r)); | ||||
| -			wrap_key(k->rsa);
 | ||||
| +			if(k->type == KEY_RSA) {
 | ||||
| +				 wrap_rsa_key(k->rsa);
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +			} else if(k->type == KEY_ECDSA) {
 | ||||
| +				 wrap_ecdsa_key(k->ecdsa);
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +			} else {
 | ||||
| +				/* Unsupported type */
 | ||||
| +			}
 | ||||
|  			(*keysp)[i] = k; | ||||
|  			free(blob); | ||||
|  		} | ||||
| diff -up openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.c
 | ||||
| --- openssh-7.6p1/ssh-pkcs11.c.pkcs11-ecdsa	2018-02-16 13:25:59.427469259 +0100
 | ||||
| +++ openssh-7.6p1/ssh-pkcs11.c	2018-02-16 13:44:51.270554797 +0100
 | ||||
| @@ -32,6 +32,16 @@
 | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
|  #include <openssl/x509.h> | ||||
| +#include <openssl/rsa.h>
 | ||||
| +#ifdef OPENSSL_HAS_ECC
 | ||||
| +#include <openssl/ecdsa.h>
 | ||||
| +#if ((defined(LIBRESSL_VERSION_NUMBER) && \
 | ||||
| +	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
 | ||||
| +	(defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
 | ||||
| +	(OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +#define ENABLE_PKCS11_ECDSA 1
 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
|   | ||||
|  #define CRYPTOKI_COMPAT | ||||
|  #include "pkcs11.h" | ||||
| @@ -67,6 +76,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro
 | ||||
|  struct pkcs11_key { | ||||
|  	struct pkcs11_provider	*provider; | ||||
|  	CK_ULONG		slotidx; | ||||
| +	CK_ULONG		key_type;
 | ||||
|  	int			(*orig_finish)(RSA *rsa); | ||||
|  	RSA_METHOD		rsa_method; | ||||
|  	char			*keyid; | ||||
| @@ -75,6 +85,9 @@ struct pkcs11_key {
 | ||||
|  }; | ||||
|   | ||||
|  int pkcs11_interactive = 0; | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +static int pkcs11_key_idx = -1;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|   | ||||
|  /* | ||||
|   * This can't be in the ssh-pkcs11-uri, becase we can not depend on | ||||
| @@ -289,6 +302,40 @@ pkcs11_find(struct pkcs11_provider *p, C
 | ||||
|  	return (ret); | ||||
|  } | ||||
|   | ||||
| +int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) {
 | ||||
| +	char			*pin = NULL, prompt[1024];
 | ||||
| +	CK_RV			rv;
 | ||||
| +	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
 | ||||
| +		if (!pkcs11_interactive) {
 | ||||
| +			error("need pin entry%s", (si->token.flags &
 | ||||
| +			    CKF_PROTECTED_AUTHENTICATION_PATH) ?
 | ||||
| +			    " on reader keypad" : "");
 | ||||
| +			return (-1);
 | ||||
| +		}
 | ||||
| +		if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
 | ||||
| +			verbose("Deferring PIN entry to reader keypad.");
 | ||||
| +		else {
 | ||||
| +			snprintf(prompt, sizeof(prompt),
 | ||||
| +			    "Enter PIN for '%s': ", si->token.label);
 | ||||
| +			pin = read_passphrase(prompt, RP_ALLOW_EOF);
 | ||||
| +			if (pin == NULL)
 | ||||
| +				return (-1);	/* bail out */
 | ||||
| +		}
 | ||||
| +		rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
 | ||||
| +		    (pin != NULL) ? strlen(pin) : 0);
 | ||||
| +		if (pin != NULL) {
 | ||||
| +			explicit_bzero(pin, strlen(pin));
 | ||||
| +			free(pin);
 | ||||
| +		}
 | ||||
| +		if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
 | ||||
| +			error("C_Login failed: %lu", rv);
 | ||||
| +			return (-1);
 | ||||
| +		}
 | ||||
| +		si->logged_in = 1;
 | ||||
| +	}
 | ||||
| +	return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* openssl callback doing the actual signing operation */ | ||||
|  static int | ||||
|  pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, | ||||
| @@ -310,7 +357,6 @@ pkcs11_rsa_private_encrypt(int flen, con
 | ||||
|  		{CKA_ID, NULL, 0}, | ||||
|  		{CKA_SIGN, NULL, sizeof(true_val) } | ||||
|  	}; | ||||
| -	char			*pin = NULL, prompt[1024];
 | ||||
|  	int			rval = -1; | ||||
|   | ||||
|  	key_filter[0].pValue = &private_key_class; | ||||
| @@ -326,33 +372,8 @@ pkcs11_rsa_private_encrypt(int flen, con
 | ||||
|  	} | ||||
|  	f = k11->provider->module->function_list; | ||||
|  	si = &k11->provider->module->slotinfo[k11->slotidx]; | ||||
| -	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
 | ||||
| -		if (!pkcs11_interactive) {
 | ||||
| -			error("need pin entry%s", (si->token.flags &
 | ||||
| -			    CKF_PROTECTED_AUTHENTICATION_PATH) ?
 | ||||
| -			    " on reader keypad" : "");
 | ||||
| -			return (-1);
 | ||||
| -		}
 | ||||
| -		if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
 | ||||
| -			verbose("Deferring PIN entry to reader keypad.");
 | ||||
| -		else {
 | ||||
| -			snprintf(prompt, sizeof(prompt),
 | ||||
| -			    "Enter PIN for '%s': ", si->token.label);
 | ||||
| -			pin = read_passphrase(prompt, RP_ALLOW_EOF);
 | ||||
| -			if (pin == NULL)
 | ||||
| -				return (-1);	/* bail out */
 | ||||
| -		}
 | ||||
| -		rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
 | ||||
| -		    (pin != NULL) ? strlen(pin) : 0);
 | ||||
| -		if (pin != NULL) {
 | ||||
| -			explicit_bzero(pin, strlen(pin));
 | ||||
| -			free(pin);
 | ||||
| -		}
 | ||||
| -		if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
 | ||||
| -			error("C_Login failed: %lu", rv);
 | ||||
| -			return (-1);
 | ||||
| -		}
 | ||||
| -		si->logged_in = 1;
 | ||||
| +	if(pkcs11_login(k11, f, si)) {
 | ||||
| +		return (-1);
 | ||||
|  	} | ||||
|  	key_filter[1].pValue = k11->keyid; | ||||
|  	key_filter[1].ulValueLen = k11->keyid_len; | ||||
| @@ -390,6 +411,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
 | ||||
|  	const RSA_METHOD	*def = RSA_get_default_method(); | ||||
|   | ||||
|  	k11 = xcalloc(1, sizeof(*k11)); | ||||
| +	k11->key_type = CKK_RSA;
 | ||||
|  	k11->provider = provider; | ||||
|  	provider->refcount++;	/* provider referenced by RSA key */ | ||||
|  	k11->slotidx = slotidx; | ||||
| @@ -415,6 +437,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
 | ||||
|  	return (0); | ||||
|  } | ||||
|   | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
 | ||||
| +                                    const BIGNUM *inv, const BIGNUM *rp,
 | ||||
| +                                    EC_KEY *ecdsa) {
 | ||||
| +	struct pkcs11_key	*k11;
 | ||||
| +	struct pkcs11_slotinfo	*si;
 | ||||
| +	CK_FUNCTION_LIST	*f;
 | ||||
| +	CK_OBJECT_HANDLE	obj;
 | ||||
| +	CK_ULONG		tlen = 0;
 | ||||
| +	CK_RV			rv;
 | ||||
| +	CK_OBJECT_CLASS	private_key_class = CKO_PRIVATE_KEY;
 | ||||
| +	CK_BBOOL		true_val = CK_TRUE;
 | ||||
| +	CK_MECHANISM		mech = {
 | ||||
| +		CKM_ECDSA, NULL_PTR, 0
 | ||||
| +	};
 | ||||
| +	CK_ATTRIBUTE		key_filter[] = {
 | ||||
| +		{CKA_CLASS, NULL, sizeof(private_key_class) },
 | ||||
| +		{CKA_ID, NULL, 0},
 | ||||
| +		{CKA_SIGN, NULL, sizeof(true_val) }
 | ||||
| +	};
 | ||||
| +	ECDSA_SIG  		*rval = NULL;
 | ||||
| +	key_filter[0].pValue = &private_key_class;
 | ||||
| +	key_filter[2].pValue = &true_val;
 | ||||
| +
 | ||||
| + #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +	if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
 | ||||
| +		error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa);
 | ||||
| + #else
 | ||||
| +	if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
 | ||||
| +		error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
 | ||||
| + #endif
 | ||||
| +		return NULL;
 | ||||
| +	}
 | ||||
| +	if (!k11->provider || !k11->provider->valid) {
 | ||||
| +		error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
 | ||||
| +		return NULL;
 | ||||
| +	}
 | ||||
| +	f = k11->provider->module->function_list;
 | ||||
| +	si = &k11->provider->module->slotinfo[k11->slotidx];
 | ||||
| +	if(pkcs11_login(k11, f, si)) {
 | ||||
| +		return NULL;
 | ||||
| +	}
 | ||||
| +	key_filter[1].pValue = k11->keyid;
 | ||||
| +	key_filter[1].ulValueLen = k11->keyid_len;
 | ||||
| +	/* try to find object w/CKA_SIGN first, retry w/o */
 | ||||
| +	if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
 | ||||
| +	    pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
 | ||||
| +		error("cannot find private key");
 | ||||
| +	} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
 | ||||
| +		error("C_SignInit failed: %lu", rv);
 | ||||
| +	} else {
 | ||||
| +		CK_BYTE_PTR buf = NULL;
 | ||||
| +		BIGNUM *r = NULL, *s = NULL;
 | ||||
| +		int nlen;
 | ||||
| +		/* Make a call to C_Sign to find out the size of the signature */
 | ||||
| +		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
 | ||||
| +		if (rv != CKR_OK) {
 | ||||
| +			error("C_Sign failed: %lu", rv);
 | ||||
| +			return NULL;
 | ||||
| +		}
 | ||||
| +		if ((buf = xmalloc(tlen)) == NULL) {
 | ||||
| +			error("failure to allocate signature buffer");
 | ||||
| +			return NULL;
 | ||||
| +		}
 | ||||
| +		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
 | ||||
| +		if (rv != CKR_OK) {
 | ||||
| +			error("C_Sign failed: %lu", rv);
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if ((rval = ECDSA_SIG_new()) == NULL ||
 | ||||
| +		    (r = BN_new()) == NULL ||
 | ||||
| +		    (s = BN_new()) == NULL) {
 | ||||
| +			error("failure to allocate ECDSA signature");
 | ||||
| +		} else {
 | ||||
| +			/*
 | ||||
| +			 * ECDSA signature is 2 large integers of same size returned
 | ||||
| +			 * concatenated by PKCS#11, we separate them to create an
 | ||||
| +			 * ECDSA_SIG for OpenSSL.
 | ||||
| +			 */
 | ||||
| +			nlen = tlen / 2;
 | ||||
| +			BN_bin2bn(&buf[0], nlen, r);
 | ||||
| +			BN_bin2bn(&buf[nlen], nlen, s);
 | ||||
| +			ECDSA_SIG_set0(rval, r, s);
 | ||||
| +		}
 | ||||
| +		free(buf);
 | ||||
| +	}
 | ||||
| +	return (rval);
 | ||||
| +}
 | ||||
| +
 | ||||
| +#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) {
 | ||||
| +	static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL;
 | ||||
| +	if(pkcs11_key_idx == -1) {
 | ||||
| +		pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
 | ||||
| +	}
 | ||||
| +	if (pkcs11_ecdsa_method == NULL) {
 | ||||
| +		const EC_KEY_METHOD *def = EC_KEY_get_default_method();
 | ||||
| +		pkcs11_ecdsa_method = EC_KEY_METHOD_new(def);
 | ||||
| +		EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign);
 | ||||
| +	}
 | ||||
| +#else
 | ||||
| +static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) {
 | ||||
| +	static ECDSA_METHOD *pkcs11_ecdsa_method = NULL;
 | ||||
| +	if(pkcs11_key_idx == -1) {
 | ||||
| +		pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
 | ||||
| +	}
 | ||||
| +	if(pkcs11_ecdsa_method == NULL) {
 | ||||
| +		const ECDSA_METHOD *def = ECDSA_get_default_method();
 | ||||
| + #ifdef ECDSA_F_ECDSA_METHOD_NEW
 | ||||
| +		pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def);
 | ||||
| +		ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11");
 | ||||
| +		ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign);
 | ||||
| + #else
 | ||||
| +		pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method));
 | ||||
| +		memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method));
 | ||||
| +		pkcs11_ecdsa_method->name = "pkcs11";
 | ||||
| +		pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign;
 | ||||
| + #endif
 | ||||
| +	}
 | ||||
| +#endif
 | ||||
| +	return pkcs11_ecdsa_method;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
 | ||||
| +                  CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa)
 | ||||
| +{
 | ||||
| +	struct pkcs11_key *k11;
 | ||||
| +	k11 = xcalloc(1, sizeof(*k11));
 | ||||
| +	k11->key_type = CKK_EC;
 | ||||
| +	k11->provider = provider;
 | ||||
| +	provider->refcount++; /* provider referenced by ECDSA key */
 | ||||
| +	k11->slotidx = slotidx;
 | ||||
| +	/* identify key object on smartcard */
 | ||||
| +	k11->keyid_len = keyid_attrib->ulValueLen;
 | ||||
| +	if (k11->keyid_len > 0) {
 | ||||
| +		k11->keyid = xmalloc(k11->keyid_len);
 | ||||
| +		memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
 | ||||
| +	}
 | ||||
| +	if (label_attrib->ulValueLen > 0 ) {
 | ||||
| +		k11->label = xmalloc(label_attrib->ulValueLen+1);
 | ||||
| +		memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen);
 | ||||
| +		k11->label[label_attrib->ulValueLen] = 0;
 | ||||
| +	}
 | ||||
| + #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +	EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method());
 | ||||
| +	EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11);
 | ||||
| + #else
 | ||||
| +	ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
 | ||||
| +	ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
 | ||||
| + #endif
 | ||||
| +	return (0);
 | ||||
| +}
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +
 | ||||
| +int pkcs11_del_key(struct sshkey *key) {
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +	if(key->type == KEY_ECDSA) {
 | ||||
| +		struct pkcs11_key *k11 = (struct pkcs11_key *)
 | ||||
| + #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +			EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx);
 | ||||
| + #else
 | ||||
| +			ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
 | ||||
| + #endif
 | ||||
| +		if (k11 == NULL) {
 | ||||
| +			error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa);
 | ||||
| +		} else {
 | ||||
| +			if (k11->provider)
 | ||||
| +				pkcs11_provider_unref(k11->provider);
 | ||||
| +			free(k11->keyid);
 | ||||
| +			free(k11);
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +	sshkey_free(key);
 | ||||
| +	return (0);
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* remove trailing spaces */ | ||||
|  static void | ||||
|  rmspace(u_char *buf, size_t len) | ||||
| @@ -482,11 +646,13 @@ static int
 | ||||
|  pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, | ||||
|      struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri) | ||||
|  { | ||||
| -	size_t filter_size = 1;
 | ||||
| +	size_t filter_size = 2;
 | ||||
| +	CK_KEY_TYPE pubkey_type = CKK_RSA;
 | ||||
|  	CK_OBJECT_CLASS	pubkey_class = CKO_PUBLIC_KEY; | ||||
|  	CK_OBJECT_CLASS	cert_class = CKO_CERTIFICATE; | ||||
|  	CK_ATTRIBUTE		pubkey_filter[] = { | ||||
|  		{ CKA_CLASS, NULL, sizeof(pubkey_class) }, | ||||
| +		{ CKA_KEY_TYPE, NULL, sizeof(pubkey_type) },
 | ||||
|  		{ CKA_ID, NULL, 0 }, | ||||
|  		{ CKA_LABEL, NULL, 0 } | ||||
|  	}; | ||||
| @@ -507,29 +673,60 @@ pkcs11_fetch_keys(struct pkcs11_provider
 | ||||
|  		{ CKA_SUBJECT, NULL, 0 }, | ||||
|  		{ CKA_VALUE, NULL, 0 } | ||||
|  	}; | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +	CK_KEY_TYPE	        ecdsa_type = CKK_EC;
 | ||||
| +	CK_ATTRIBUTE		ecdsa_filter[] = {
 | ||||
| +		{ CKA_CLASS, NULL, sizeof(pubkey_class) },
 | ||||
| +		{ CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) },
 | ||||
| +		{ CKA_ID, NULL, 0 },
 | ||||
| +		{ CKA_LABEL, NULL, 0 }
 | ||||
| +	};
 | ||||
| +	CK_ATTRIBUTE		ecdsa_attribs[] = {
 | ||||
| +		{ CKA_ID, NULL, 0 },
 | ||||
| +		{ CKA_LABEL, NULL, 0 },
 | ||||
| +		{ CKA_EC_PARAMS, NULL, 0 },
 | ||||
| +		{ CKA_EC_POINT, NULL, 0 }
 | ||||
| +	};
 | ||||
| +	ecdsa_filter[0].pValue = &pubkey_class;
 | ||||
| +	ecdsa_filter[1].pValue = &ecdsa_type;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|  	pubkey_filter[0].pValue = &pubkey_class; | ||||
| +	pubkey_filter[1].pValue = &pubkey_type;
 | ||||
|  	cert_filter[0].pValue = &cert_class; | ||||
|   | ||||
|  	if (uri->id != NULL) { | ||||
|  		pubkey_filter[filter_size].pValue = uri->id; | ||||
|  		pubkey_filter[filter_size].ulValueLen = uri->id_len; | ||||
| -		cert_filter[filter_size].pValue = uri->id;
 | ||||
| -		cert_filter[filter_size].ulValueLen = uri->id_len;
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +		ecdsa_filter[filter_size].pValue = uri->id;
 | ||||
| +		ecdsa_filter[filter_size].ulValueLen = uri->id_len;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +		cert_filter[filter_size-1].pValue = uri->id;
 | ||||
| +		cert_filter[filter_size-1].ulValueLen = uri->id_len;
 | ||||
|  		filter_size++; | ||||
|  	} | ||||
|  	if (uri->object != NULL) { | ||||
|  		pubkey_filter[filter_size].pValue = uri->object; | ||||
|  		pubkey_filter[filter_size].ulValueLen = strlen(uri->object); | ||||
|  		pubkey_filter[filter_size].type = CKA_LABEL; | ||||
| -		cert_filter[filter_size].pValue = uri->object;
 | ||||
| -		cert_filter[filter_size].ulValueLen = strlen(uri->object);
 | ||||
| -		cert_filter[filter_size].type = CKA_LABEL;
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +		ecdsa_filter[filter_size].pValue = uri->object;
 | ||||
| +		ecdsa_filter[filter_size].ulValueLen = strlen(uri->object);
 | ||||
| +		ecdsa_filter[filter_size].type = CKA_LABEL;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +		cert_filter[filter_size-1].pValue = uri->object;
 | ||||
| +		cert_filter[filter_size-1].ulValueLen = strlen(uri->object);
 | ||||
| +		cert_filter[filter_size-1].type = CKA_LABEL;
 | ||||
|  		filter_size++; | ||||
|  	} | ||||
|   | ||||
|  	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size, | ||||
|  	    pubkey_attribs, keysp, nkeys) < 0 || | ||||
| -	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size,
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +	    pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size,
 | ||||
| +	    ecdsa_attribs, keysp, nkeys) < 0||
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1,
 | ||||
|  	    cert_attribs, keysp, nkeys) < 0) | ||||
|  		return (-1); | ||||
|  	return (0); | ||||
| @@ -553,6 +746,11 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  { | ||||
|  	struct sshkey		*key; | ||||
|  	RSA			*rsa; | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +	EC_KEY			*ecdsa;
 | ||||
| +#else
 | ||||
| +	void			*ecdsa;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|  	X509 			*x509; | ||||
|  	EVP_PKEY		*evp = NULL; | ||||
|  	int			i; | ||||
| @@ -608,6 +806,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  		 * or ID, label, subject and value for certificates. | ||||
|  		 */ | ||||
|  		rsa = NULL; | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +		ecdsa = NULL;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|  		if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs)) | ||||
|  		    != CKR_OK) { | ||||
|  			error("C_GetAttributeValue failed: %lu", rv); | ||||
| @@ -620,6 +821,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  				rsa->e = BN_bin2bn(attribs[3].pValue, | ||||
|  				    attribs[3].ulValueLen, NULL); | ||||
|  			} | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +		} else if (attribs[2].type == CKA_EC_PARAMS ) {
 | ||||
| +			if ((ecdsa = EC_KEY_new()) == NULL) {
 | ||||
| +				error("EC_KEY_new failed");
 | ||||
| +			} else {
 | ||||
| +				const unsigned char *ptr1 = attribs[2].pValue;
 | ||||
| +				const unsigned char *ptr2 = attribs[3].pValue;
 | ||||
| +				CK_ULONG len1 = attribs[2].ulValueLen;
 | ||||
| +				CK_ULONG len2 = attribs[3].ulValueLen;
 | ||||
| +				ASN1_OCTET_STRING *point = NULL;
 | ||||
| +
 | ||||
| +				/*
 | ||||
| +				 * CKA_EC_PARAMS contains the curve parameters of the key
 | ||||
| +				 * either referenced as an OID or directly with all values.
 | ||||
| +				 * CKA_EC_POINT contains the point (public key) on the curve.
 | ||||
| +				 * The point is should be returned inside a DER-encoded
 | ||||
| +				 * ASN.1 OCTET STRING value (but some implementation).
 | ||||
| +				 */
 | ||||
| +				if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
 | ||||
| +					/* Pointing to OCTET STRING content */
 | ||||
| +					ptr2 = point->data;
 | ||||
| +					len2 = point->length;
 | ||||
| +				} else {
 | ||||
| +					/* No OCTET STRING */
 | ||||
| +					ptr2 = attribs[3].pValue;
 | ||||
| +				}
 | ||||
| +
 | ||||
| +				if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
 | ||||
| +				   (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
 | ||||
| +					EC_KEY_free(ecdsa);
 | ||||
| +					ecdsa = NULL;
 | ||||
| +					error("EC public key parsing failed");
 | ||||
| +				}
 | ||||
| +
 | ||||
| +				if(point) {
 | ||||
| +					ASN1_OCTET_STRING_free(point);
 | ||||
| +				}
 | ||||
| +			}
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|  		} else { | ||||
|  			cp = attribs[3].pValue; | ||||
|  			if ((x509 = X509_new()) == NULL) { | ||||
| @@ -639,13 +879,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  			X509_free(x509); | ||||
|  			EVP_PKEY_free(evp); | ||||
|  		} | ||||
| -		if (rsa && rsa->n && rsa->e &&
 | ||||
| -		    pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
 | ||||
| -			if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
 | ||||
| -				fatal("sshkey_new failed");
 | ||||
| -			key->rsa = rsa;
 | ||||
| -			key->type = KEY_RSA;
 | ||||
| -			key->flags |= SSHKEY_FLAG_EXT;
 | ||||
| +		key = NULL;
 | ||||
| +		if (rsa || ecdsa) {
 | ||||
| +			if (rsa && rsa->n && rsa->e &&
 | ||||
| +			    pkcs11_rsa_wrap(p, slotidx, &attribs[0], &attribs[1], rsa) == 0) {
 | ||||
| +				if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
 | ||||
| +					fatal("sshkey_new failed");
 | ||||
| +				key->rsa = rsa;
 | ||||
| +				key->type = KEY_RSA;
 | ||||
| +				key->flags |= SSHKEY_FLAG_EXT;
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +			} else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) {
 | ||||
| +				if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
 | ||||
| +					fatal("sshkey_new failed");
 | ||||
| +				key->ecdsa = ecdsa;
 | ||||
| +				key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
 | ||||
| +				key->type = KEY_ECDSA;
 | ||||
| +				key->flags |= SSHKEY_FLAG_EXT;
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if(key) {
 | ||||
|  			if (pkcs11_key_included(keysp, nkeys, key)) { | ||||
|  				sshkey_free(key); | ||||
|  			} else { | ||||
| @@ -658,6 +913,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  			} | ||||
|  		} else if (rsa) { | ||||
|  			RSA_free(rsa); | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +		} else if (ecdsa) {
 | ||||
| +			EC_KEY_free(ecdsa);
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
|  		} | ||||
|  		for (i = 0; i < nattribs; i++) | ||||
|  			free(attribs[i].pValue); | ||||
| diff -up openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11-helper.c
 | ||||
| --- openssh-7.6p1/ssh-pkcs11-helper.c.pkcs11-ecdsa	2017-10-02 21:34:26.000000000 +0200
 | ||||
| +++ openssh-7.6p1/ssh-pkcs11-helper.c	2018-02-16 13:25:59.428469265 +0100
 | ||||
| @@ -24,6 +24,17 @@
 | ||||
|   | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
| +#include <openssl/rsa.h>
 | ||||
| +#ifdef OPENSSL_HAS_ECC
 | ||||
| +#include <openssl/ecdsa.h>
 | ||||
| +#if ((defined(LIBRESSL_VERSION_NUMBER) && \
 | ||||
| +	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
 | ||||
| +	(defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
 | ||||
| +	(OPENSSL_VERSION_NUMBER >= 0x00010100L)
 | ||||
| +#define ENABLE_PKCS11_ECDSA 1
 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #include <stdarg.h> | ||||
|  #include <string.h> | ||||
|  #include <unistd.h> | ||||
| @@ -80,7 +90,7 @@ del_keys_by_name(char *name)
 | ||||
|  		if (!strcmp(ki->providername, name)) { | ||||
|  			TAILQ_REMOVE(&pkcs11_keylist, ki, next); | ||||
|  			free(ki->providername); | ||||
| -			sshkey_free(ki->key);
 | ||||
| +			pkcs11_del_key(ki->key);
 | ||||
|  			free(ki); | ||||
|  		} | ||||
|  	} | ||||
| @@ -164,6 +174,20 @@ process_del(void)
 | ||||
|  	sshbuf_free(msg); | ||||
|  } | ||||
|   | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +static u_int EC_KEY_order_size(EC_KEY *key)
 | ||||
| +{
 | ||||
| +	const EC_GROUP *group = EC_KEY_get0_group(key);
 | ||||
| +	BIGNUM *order = BN_new();
 | ||||
| +	u_int nbytes = 0;
 | ||||
| +	if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) {
 | ||||
| +		nbytes = BN_num_bytes(order);
 | ||||
| +	}
 | ||||
| +	BN_clear_free(order);
 | ||||
| +	return nbytes;
 | ||||
| +}
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +
 | ||||
|  static void | ||||
|  process_sign(void) | ||||
|  { | ||||
| @@ -180,14 +204,38 @@ process_sign(void)
 | ||||
|  	else { | ||||
|  		if ((found = lookup_key(key)) != NULL) { | ||||
|  #ifdef WITH_OPENSSL | ||||
| -			int ret;
 | ||||
| -
 | ||||
| -			slen = RSA_size(key->rsa);
 | ||||
| -			signature = xmalloc(slen);
 | ||||
| -			if ((ret = RSA_private_encrypt(dlen, data, signature,
 | ||||
| -			    found->rsa, RSA_PKCS1_PADDING)) != -1) {
 | ||||
| -				slen = ret;
 | ||||
| -				ok = 0;
 | ||||
| +			if(found->type == KEY_RSA) {
 | ||||
| +				int ret;
 | ||||
| +				slen = RSA_size(key->rsa);
 | ||||
| +				signature = xmalloc(slen);
 | ||||
| +				if ((ret = RSA_private_encrypt(dlen, data, signature,
 | ||||
| +											   found->rsa, RSA_PKCS1_PADDING)) != -1) {
 | ||||
| +					slen = ret;
 | ||||
| +					ok = 0;
 | ||||
| +				}
 | ||||
| +#ifdef ENABLE_PKCS11_ECDSA
 | ||||
| +			} else if(found->type == KEY_ECDSA) {
 | ||||
| +				ECDSA_SIG *sig;
 | ||||
| +				const BIGNUM *r = NULL, *s = NULL;
 | ||||
| +				if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
 | ||||
| +					/* PKCS11 2.3.1 recommends both r and s to have the order size for
 | ||||
| +					   backward compatiblity */
 | ||||
| +					ECDSA_SIG_get0(sig, &r, &s);
 | ||||
| +					u_int o_len = EC_KEY_order_size(found->ecdsa);
 | ||||
| +					u_int r_len = BN_num_bytes(r);
 | ||||
| +					u_int s_len = BN_num_bytes(s);
 | ||||
| +					if (o_len > 0 && r_len <= o_len && s_len <= o_len) {
 | ||||
| +						signature = xcalloc(2, o_len);
 | ||||
| +						BN_bn2bin(r, signature + o_len - r_len);
 | ||||
| +						BN_bn2bin(s, signature + (2 * o_len) - s_len);
 | ||||
| +						slen = 2 * o_len;
 | ||||
| +						ok = 0;
 | ||||
| +					}
 | ||||
| +					ECDSA_SIG_free(sig);
 | ||||
| +				}
 | ||||
| +#endif /* ENABLE_PKCS11_ECDSA */
 | ||||
| +			} else {
 | ||||
| +				/* Unsupported type */
 | ||||
|  			} | ||||
|  #endif /* WITH_OPENSSL */ | ||||
|  		} | ||||
| diff -up openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa openssh-7.6p1/ssh-pkcs11.h
 | ||||
| --- openssh-7.6p1/ssh-pkcs11.h.pkcs11-ecdsa	2018-02-16 13:25:59.429469272 +0100
 | ||||
| +++ openssh-7.6p1/ssh-pkcs11.h	2018-02-16 13:45:29.623800048 +0100
 | ||||
| @@ -20,6 +20,7 @@
 | ||||
|  int	pkcs11_init(int); | ||||
|  void	pkcs11_terminate(void); | ||||
|  int	pkcs11_add_provider(char *, char *, struct sshkey ***); | ||||
| +int	pkcs11_del_key(struct sshkey *);
 | ||||
|  int	pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***); | ||||
|  int	pkcs11_del_provider(char *); | ||||
|  int	pkcs11_uri_write(const struct sshkey *, FILE *); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| diff -up openssh-7.6p1/ssh-pkcs11.c.old openssh-7.6p1/ssh-pkcs11.c
 | ||||
| --- openssh-7.6p1/ssh-pkcs11.c.old	2018-02-16 16:43:08.861520255 +0100
 | ||||
| +++ openssh-7.6p1/ssh-pkcs11.c	2018-02-16 16:56:35.312601451 +0100
 | ||||
| @@ -917,13 +917,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
 | ||||
|  			} else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen) | ||||
|  			    == NULL) { | ||||
|  				error("d2i_X509 failed"); | ||||
| -			} else if ((evp = X509_get_pubkey(x509)) == NULL ||
 | ||||
| -			    evp->type != EVP_PKEY_RSA ||
 | ||||
| -			    evp->pkey.rsa == NULL) {
 | ||||
| -				debug("X509_get_pubkey failed or no rsa");
 | ||||
| -			} else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
 | ||||
| -			    == NULL) {
 | ||||
| -				error("RSAPublicKey_dup");
 | ||||
| +			} else if ((evp = X509_get_pubkey(x509)) == NULL) {
 | ||||
| +				debug("X509_get_pubkey failed");
 | ||||
| +			} else {
 | ||||
| +				switch (evp->type) {
 | ||||
| +				case EVP_PKEY_RSA:
 | ||||
| +					if (evp->pkey.rsa == NULL)
 | ||||
| +						debug("Missing RSA key");
 | ||||
| +					else if ((rsa = RSAPublicKey_dup(
 | ||||
| +					    evp->pkey.rsa)) == NULL)
 | ||||
| +						error("RSAPublicKey_dup failed");
 | ||||
| +					break;
 | ||||
| +				case EVP_PKEY_EC:
 | ||||
| +					if (evp->pkey.ecdsa == NULL)
 | ||||
| +						debug("Missing ECDSA key");
 | ||||
| +					else if ((ecdsa = EC_KEY_dup(
 | ||||
| +					    evp->pkey.ecdsa)) == NULL)
 | ||||
| +						error("EC_KEY_dup failed");
 | ||||
| +					break;
 | ||||
| +				default:
 | ||||
| +					debug("not a RSA or ECDSA key");
 | ||||
| +					break;
 | ||||
| +				}
 | ||||
|  			} | ||||
|  			X509_free(x509); | ||||
|  			EVP_PKEY_free(evp); | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,70 +1,6 @@ | ||||
| diff -up openssh-7.7p1/cipher.c.fips openssh-7.7p1/cipher.c
 | ||||
| --- openssh-7.7p1/cipher.c.fips	2018-08-08 10:08:40.814719906 +0200
 | ||||
| +++ openssh-7.7p1/cipher.c	2018-08-08 10:08:40.821719965 +0200
 | ||||
| @@ -39,6 +39,8 @@
 | ||||
|   | ||||
|  #include <sys/types.h> | ||||
|   | ||||
| +#include <openssl/fips.h>
 | ||||
| +
 | ||||
|  #include <string.h> | ||||
|  #include <stdarg.h> | ||||
|  #include <stdio.h> | ||||
| @@ -90,6 +92,33 @@ static const struct sshcipher ciphers[]
 | ||||
|  	{ NULL,			0, 0, 0, 0, 0, NULL } | ||||
|  }; | ||||
|   | ||||
| +static const struct sshcipher fips_ciphers[] = {
 | ||||
| +#ifdef WITH_OPENSSL
 | ||||
| +	{ "3des-cbc",		8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
 | ||||
| +	{ "aes128-cbc",		16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
 | ||||
| +	{ "aes192-cbc",		16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
 | ||||
| +	{ "aes256-cbc",		16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
 | ||||
| +	{ "rijndael-cbc@lysator.liu.se",
 | ||||
| +				16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
 | ||||
| +	{ "aes128-ctr",		16, 16, 0, 0, 0, EVP_aes_128_ctr },
 | ||||
| +	{ "aes192-ctr",		16, 24, 0, 0, 0, EVP_aes_192_ctr },
 | ||||
| +	{ "aes256-ctr",		16, 32, 0, 0, 0, EVP_aes_256_ctr },
 | ||||
| +# ifdef OPENSSL_HAVE_EVPGCM
 | ||||
| +	{ "aes128-gcm@openssh.com",
 | ||||
| +				16, 16, 12, 16, 0, EVP_aes_128_gcm },
 | ||||
| +	{ "aes256-gcm@openssh.com",
 | ||||
| +				16, 32, 12, 16, 0, EVP_aes_256_gcm },
 | ||||
| +# endif /* OPENSSL_HAVE_EVPGCM */
 | ||||
| +#else
 | ||||
| +	{ "aes128-ctr",		16, 16, 0, 0, CFLAG_AESCTR, NULL },
 | ||||
| +	{ "aes192-ctr",		16, 24, 0, 0, CFLAG_AESCTR, NULL },
 | ||||
| +	{ "aes256-ctr",		16, 32, 0, 0, CFLAG_AESCTR, NULL },
 | ||||
| +#endif
 | ||||
| +	{ "none",		8, 0, 0, 0, CFLAG_NONE, NULL },
 | ||||
| +
 | ||||
| +	{ NULL,			0, 0, 0, 0, 0, NULL }
 | ||||
| +};
 | ||||
| +
 | ||||
|  /*--*/ | ||||
|   | ||||
|  /* Returns a comma-separated list of supported ciphers. */ | ||||
| @@ -100,7 +129,7 @@ cipher_alg_list(char sep, int auth_only)
 | ||||
|  	size_t nlen, rlen = 0; | ||||
|  	const struct sshcipher *c; | ||||
|   | ||||
| -	for (c = ciphers; c->name != NULL; c++) {
 | ||||
| +	for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) {
 | ||||
|  		if ((c->flags & CFLAG_INTERNAL) != 0) | ||||
|  			continue; | ||||
|  		if (auth_only && c->auth_len == 0) | ||||
| @@ -172,7 +201,7 @@ const struct sshcipher *
 | ||||
|  cipher_by_name(const char *name) | ||||
|  { | ||||
|  	const struct sshcipher *c; | ||||
| -	for (c = ciphers; c->name != NULL; c++)
 | ||||
| +	for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++)
 | ||||
|  		if (strcmp(c->name, name) == 0) | ||||
|  			return c; | ||||
|  	return NULL; | ||||
| diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c
 | ||||
| --- openssh-7.7p1/cipher-ctr.c.fips	2018-08-08 10:08:40.709719021 +0200
 | ||||
| +++ openssh-7.7p1/cipher-ctr.c	2018-08-08 10:08:40.821719965 +0200
 | ||||
| diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c
 | ||||
| --- openssh-7.9p1/cipher-ctr.c.fips	2019-03-11 17:06:37.519877082 +0100
 | ||||
| +++ openssh-7.9p1/cipher-ctr.c	2019-03-11 17:06:37.620878031 +0100
 | ||||
| @@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
 | ||||
|  	aes_ctr.do_cipher = ssh_aes_ctr; | ||||
|  #ifndef SSH_OLD_EVP | ||||
| @ -75,10 +11,10 @@ diff -up openssh-7.7p1/cipher-ctr.c.fips openssh-7.7p1/cipher-ctr.c | ||||
|  #endif | ||||
|  	return (&aes_ctr); | ||||
|  } | ||||
| diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c
 | ||||
| --- openssh-7.7p1/clientloop.c.fips	2018-08-08 10:08:40.769719527 +0200
 | ||||
| +++ openssh-7.7p1/clientloop.c	2018-08-08 10:08:40.822719973 +0200
 | ||||
| @@ -1978,7 +1978,8 @@ key_accepted_by_hostkeyalgs(const struct
 | ||||
| diff -up openssh-7.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c
 | ||||
| --- openssh-7.9p1/clientloop.c.fips	2019-03-11 17:06:37.523877120 +0100
 | ||||
| +++ openssh-7.9p1/clientloop.c	2019-03-11 17:06:37.620878031 +0100
 | ||||
| @@ -2014,7 +2014,8 @@ key_accepted_by_hostkeyalgs(const struct
 | ||||
|  { | ||||
|  	const char *ktype = sshkey_ssh_name(key); | ||||
|  	const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? | ||||
| @ -88,86 +24,75 @@ diff -up openssh-7.7p1/clientloop.c.fips openssh-7.7p1/clientloop.c | ||||
|   | ||||
|  	if (key == NULL || key->type == KEY_UNSPEC) | ||||
|  		return 0; | ||||
| diff -up openssh-7.7p1/dh.h.fips openssh-7.7p1/dh.h
 | ||||
| --- openssh-7.7p1/dh.h.fips	2018-04-02 07:38:28.000000000 +0200
 | ||||
| +++ openssh-7.7p1/dh.h	2018-08-08 10:08:40.822719973 +0200
 | ||||
| @@ -51,6 +51,7 @@ u_int	 dh_estimate(int);
 | ||||
|   * Miniumum increased in light of DH precomputation attacks. | ||||
|   */ | ||||
|  #define DH_GRP_MIN	2048 | ||||
| +#define DH_GRP_MIN_FIPS	2048
 | ||||
|  #define DH_GRP_MAX	8192 | ||||
| diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c
 | ||||
| --- openssh-7.9p1/dh.c.fips	2018-10-17 02:01:20.000000000 +0200
 | ||||
| +++ openssh-7.9p1/dh.c	2019-03-11 17:08:11.769763057 +0100
 | ||||
| @@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max
 | ||||
|  	int best, bestcount, which, linenum; | ||||
|  	struct dhgroup dhg; | ||||
|   | ||||
|  /* | ||||
| diff -up openssh-7.7p1/entropy.c.fips openssh-7.7p1/entropy.c
 | ||||
| --- openssh-7.7p1/entropy.c.fips	2018-08-08 10:08:40.698718928 +0200
 | ||||
| +++ openssh-7.7p1/entropy.c	2018-08-08 10:08:40.822719973 +0200
 | ||||
| @@ -217,6 +217,9 @@ seed_rng(void)
 | ||||
|  		fatal("OpenSSL version mismatch. Built against %lx, you " | ||||
|  		    "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); | ||||
|   | ||||
| +	/* clean the PRNG status when exiting the program */
 | ||||
| +	atexit(RAND_cleanup);
 | ||||
| +	if (FIPS_mode()) {
 | ||||
| +		logit("Using arbitrary primes is not allowed in FIPS mode."
 | ||||
| +		    " Falling back to known groups.");
 | ||||
| +		return (dh_new_group_fallback(max));
 | ||||
| +	}
 | ||||
| +
 | ||||
|  #ifndef OPENSSL_PRNG_ONLY | ||||
|  	if (RAND_status() == 1) { | ||||
|  		debug3("RNG is ready, skipping seeding"); | ||||
| diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c
 | ||||
| --- openssh-7.7p1/kex.c.fips	2018-08-08 10:08:40.815719915 +0200
 | ||||
| +++ openssh-7.7p1/kex.c	2018-08-08 10:11:24.109081924 +0200
 | ||||
| @@ -35,6 +35,7 @@
 | ||||
|  #ifdef WITH_OPENSSL | ||||
|  #include <openssl/crypto.h> | ||||
|  #include <openssl/dh.h> | ||||
| +#include <openssl/fips.h>
 | ||||
|  #endif | ||||
|  	if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { | ||||
|  		logit("WARNING: could not open %s (%s), using fixed modulus", | ||||
|  		    _PATH_DH_MODULI, strerror(errno)); | ||||
| @@ -489,4 +495,38 @@ dh_estimate(int bits)
 | ||||
|  	return 8192; | ||||
|  } | ||||
|   | ||||
|  #include "ssh2.h" | ||||
| @@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = {
 | ||||
|  	{ NULL, -1, -1, -1}, | ||||
|  }; | ||||
|   | ||||
| +static const struct kexalg kexalgs_fips[] = {
 | ||||
| +	{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
 | ||||
| +	{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
 | ||||
| +	{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
 | ||||
| +#ifdef HAVE_EVP_SHA256
 | ||||
| +	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
 | ||||
| +#endif
 | ||||
| +#ifdef OPENSSL_HAS_ECC
 | ||||
| +	{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
 | ||||
| +	    NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
 | ||||
| +	{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
 | ||||
| +	    SSH_DIGEST_SHA384 },
 | ||||
| +# ifdef OPENSSL_HAS_NISTP521
 | ||||
| +	{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
 | ||||
| +	    SSH_DIGEST_SHA512 },
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| +	{ NULL, -1, -1, -1},
 | ||||
| +};
 | ||||
| +/*
 | ||||
| + * Compares the received DH parameters with known-good groups,
 | ||||
| + * which might be either from group14, group16 or group18.
 | ||||
| + */
 | ||||
| +int
 | ||||
| +dh_is_known_group(const DH *dh)
 | ||||
| +{
 | ||||
| +	const BIGNUM *p, *g;
 | ||||
| +	const BIGNUM *known_p, *known_g;
 | ||||
| +	DH *known = NULL;
 | ||||
| +	int bits = 0, rv = 0;
 | ||||
| +
 | ||||
|  char * | ||||
|  kex_alg_list(char sep) | ||||
|  { | ||||
| @@ -129,7 +150,7 @@ kex_alg_list(char sep)
 | ||||
|  	size_t nlen, rlen = 0; | ||||
|  	const struct kexalg *k; | ||||
| +	DH_get0_pqg(dh, &p, NULL, &g);
 | ||||
| +	bits = BN_num_bits(p);
 | ||||
| +
 | ||||
| +	if (bits <= 3072) {
 | ||||
| +		known = dh_new_group14();
 | ||||
| +	} else if (bits <= 6144) {
 | ||||
| +		known = dh_new_group16();
 | ||||
| +	} else {
 | ||||
| +		known = dh_new_group18();
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	DH_get0_pqg(known, &known_p, NULL, &known_g);
 | ||||
| +
 | ||||
| +	if (BN_cmp(g, known_g) == 0 &&
 | ||||
| +	    BN_cmp(p, known_p) == 0) {
 | ||||
| +		rv = 1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	DH_free(known);
 | ||||
| +	return rv;
 | ||||
| +}
 | ||||
| +
 | ||||
|  #endif /* WITH_OPENSSL */ | ||||
| diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h
 | ||||
| --- openssh-7.9p1/dh.h.fips	2018-10-17 02:01:20.000000000 +0200
 | ||||
| +++ openssh-7.9p1/dh.h	2019-03-11 17:08:18.718828381 +0100
 | ||||
| @@ -43,6 +43,7 @@ DH	*dh_new_group_fallback(int);
 | ||||
|   | ||||
| -	for (k = kexalgs; k->name != NULL; k++) {
 | ||||
| +	for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) {
 | ||||
|  		if (ret != NULL) | ||||
|  			ret[rlen++] = sep; | ||||
|  		nlen = strlen(k->name); | ||||
| @@ -149,7 +170,7 @@ kex_alg_by_name(const char *name)
 | ||||
|  { | ||||
|  	const struct kexalg *k; | ||||
|  int	 dh_gen_key(DH *, int); | ||||
|  int	 dh_pub_is_valid(const DH *, const BIGNUM *); | ||||
| +int	 dh_is_known_group(const DH *);
 | ||||
|   | ||||
| -	for (k = kexalgs; k->name != NULL; k++) {
 | ||||
| +	for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) {
 | ||||
|  		if (strcmp(k->name, name) == 0) | ||||
|  			return k; | ||||
|  #ifdef GSSAPI | ||||
|  u_int	 dh_estimate(int); | ||||
|   | ||||
| diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
 | ||||
| --- openssh-7.9p1/kex.c.fips	2019-03-11 17:06:37.614877975 +0100
 | ||||
| +++ openssh-7.9p1/kex.c	2019-03-11 17:06:37.621878041 +0100
 | ||||
| @@ -175,7 +196,10 @@ kex_names_valid(const char *names)
 | ||||
|  	for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||||
|  	    (p = strsep(&cp, ","))) { | ||||
| @ -180,108 +105,31 @@ diff -up openssh-7.7p1/kex.c.fips openssh-7.7p1/kex.c | ||||
|  			free(s); | ||||
|  			return 0; | ||||
|  		} | ||||
| diff -up openssh-7.7p1/kexgexc.c.fips openssh-7.7p1/kexgexc.c
 | ||||
| --- openssh-7.7p1/kexgexc.c.fips	2018-04-02 07:38:28.000000000 +0200
 | ||||
| +++ openssh-7.7p1/kexgexc.c	2018-08-08 10:08:40.822719973 +0200
 | ||||
| diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c
 | ||||
| --- openssh-7.9p1/kexgexc.c.fips	2018-10-17 02:01:20.000000000 +0200
 | ||||
| +++ openssh-7.9p1/kexgexc.c	2019-03-11 17:06:37.621878041 +0100
 | ||||
| @@ -28,6 +28,7 @@
 | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
|   | ||||
| +#include <openssl/fips.h>
 | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #include <sys/types.h> | ||||
|   | ||||
|  #include <openssl/dh.h> | ||||
| @@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh)
 | ||||
| @@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32
 | ||||
|  		r = SSH_ERR_ALLOC_FAIL; | ||||
|  		goto out; | ||||
|  	} | ||||
| +	if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
 | ||||
| +		r = SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
|  	p = g = NULL; /* belong to kex->dh now */ | ||||
|   | ||||
|  	nbits = dh_estimate(kex->dh_need * 8); | ||||
|   | ||||
| -	kex->min = DH_GRP_MIN;
 | ||||
| +	kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN;
 | ||||
|  	kex->max = DH_GRP_MAX; | ||||
|  	kex->nbits = nbits; | ||||
|  	if (datafellows & SSH_BUG_DHGEX_LARGE) | ||||
| diff -up openssh-7.7p1/kexgexs.c.fips openssh-7.7p1/kexgexs.c
 | ||||
| --- openssh-7.7p1/kexgexs.c.fips	2018-04-02 07:38:28.000000000 +0200
 | ||||
| +++ openssh-7.7p1/kexgexs.c	2018-08-08 10:08:40.823719982 +0200
 | ||||
| @@ -82,9 +82,9 @@ input_kex_dh_gex_request(int type, u_int
 | ||||
|  	kex->nbits = nbits; | ||||
|  	kex->min = min; | ||||
|  	kex->max = max; | ||||
| -	min = MAXIMUM(DH_GRP_MIN, min);
 | ||||
| +	min = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min);
 | ||||
|  	max = MINIMUM(DH_GRP_MAX, max); | ||||
| -	nbits = MAXIMUM(DH_GRP_MIN, nbits);
 | ||||
| +	nbits = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits);
 | ||||
|  	nbits = MINIMUM(DH_GRP_MAX, nbits); | ||||
|   | ||||
|  	if (kex->max < kex->min || kex->nbits < kex->min || | ||||
| diff -up openssh-7.7p1/mac.c.fips openssh-7.7p1/mac.c
 | ||||
| --- openssh-7.7p1/mac.c.fips	2018-08-08 10:08:40.815719915 +0200
 | ||||
| +++ openssh-7.7p1/mac.c	2018-08-08 10:11:56.915352642 +0200
 | ||||
| @@ -27,6 +27,8 @@
 | ||||
|   | ||||
|  #include <sys/types.h> | ||||
|   | ||||
| +#include <openssl/fips.h>
 | ||||
| +
 | ||||
|  #include <string.h> | ||||
|  #include <stdio.h> | ||||
|   | ||||
| @@ -54,7 +56,7 @@ struct macalg {
 | ||||
|  	int		etm;		/* Encrypt-then-MAC */ | ||||
|  }; | ||||
|   | ||||
| -static const struct macalg macs[] = {
 | ||||
| +static const struct macalg all_macs[] = {
 | ||||
|  	/* Encrypt-and-MAC (encrypt-and-authenticate) variants */ | ||||
|  	{ "hmac-sha1",				SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, | ||||
|  	{ "hmac-sha1-96",			SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, | ||||
| @@ -82,6 +84,24 @@ static const struct macalg macs[] = {
 | ||||
|  	{ NULL,					0, 0, 0, 0, 0, 0 } | ||||
|  }; | ||||
|   | ||||
| +static const struct macalg fips_macs[] = {
 | ||||
| +	/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
 | ||||
| +	{ "hmac-sha1",				SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
 | ||||
| +#ifdef HAVE_EVP_SHA256
 | ||||
| +	{ "hmac-sha2-256",			SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
 | ||||
| +	{ "hmac-sha2-512",			SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +	/* Encrypt-then-MAC variants */
 | ||||
| +	{ "hmac-sha1-etm@openssh.com",		SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
 | ||||
| +#ifdef HAVE_EVP_SHA256
 | ||||
| +	{ "hmac-sha2-256-etm@openssh.com",	SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
 | ||||
| +	{ "hmac-sha2-512-etm@openssh.com",	SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +	{ NULL,					0, 0, 0, 0, 0, 0 }
 | ||||
| +};
 | ||||
| +
 | ||||
|  /* Returns a list of supported MACs separated by the specified char. */ | ||||
|  char * | ||||
|  mac_alg_list(char sep) | ||||
| @@ -90,7 +110,7 @@ mac_alg_list(char sep)
 | ||||
|  	size_t nlen, rlen = 0; | ||||
|  	const struct macalg *m; | ||||
|   | ||||
| -	for (m = macs; m->name != NULL; m++) {
 | ||||
| +	for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
 | ||||
|  		if (ret != NULL) | ||||
|  			ret[rlen++] = sep; | ||||
|  		nlen = strlen(m->name); | ||||
| @@ -129,7 +149,7 @@ mac_setup(struct sshmac *mac, char *name
 | ||||
|  { | ||||
|  	const struct macalg *m; | ||||
|   | ||||
| -	for (m = macs; m->name != NULL; m++) {
 | ||||
| +	for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
 | ||||
|  		if (strcmp(name, m->name) != 0) | ||||
|  			continue; | ||||
|  		if (mac != NULL) | ||||
| diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in
 | ||||
| --- openssh-7.7p1/Makefile.in.fips	2018-08-08 10:08:40.815719915 +0200
 | ||||
| +++ openssh-7.7p1/Makefile.in	2018-08-08 10:08:40.823719982 +0200
 | ||||
|  	/* generate and send 'e', client DH public key */ | ||||
| diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in
 | ||||
| --- openssh-7.9p1/Makefile.in.fips	2019-03-11 17:06:37.615877984 +0100
 | ||||
| +++ openssh-7.9p1/Makefile.in	2019-03-11 17:06:37.621878041 +0100
 | ||||
| @@ -179,25 +179,25 @@ libssh.a: $(LIBSSH_OBJS)
 | ||||
|  	$(RANLIB) $@ | ||||
|   | ||||
| @ -308,7 +156,7 @@ diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in | ||||
| -	$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 | ||||
| +	$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
 | ||||
|   | ||||
|  ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o | ||||
|  ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o | ||||
| -	$(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 | ||||
| +	$(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
 | ||||
|   | ||||
| @ -323,15 +171,17 @@ diff -up openssh-7.7p1/Makefile.in.fips openssh-7.7p1/Makefile.in | ||||
|   | ||||
|  sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o | ||||
|  	$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) | ||||
| diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h
 | ||||
| --- openssh-7.7p1/myproposal.h.fips	2018-04-02 07:38:28.000000000 +0200
 | ||||
| +++ openssh-7.7p1/myproposal.h	2018-08-08 10:08:40.823719982 +0200
 | ||||
| @@ -114,6 +114,14 @@
 | ||||
| diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h
 | ||||
| --- openssh-7.9p1/myproposal.h.fips	2018-10-17 02:01:20.000000000 +0200
 | ||||
| +++ openssh-7.9p1/myproposal.h	2019-03-11 17:06:37.621878041 +0100
 | ||||
| @@ -116,6 +116,16 @@
 | ||||
|  	"rsa-sha2-256," \ | ||||
|  	"ssh-rsa" | ||||
|   | ||||
| +#define	KEX_FIPS_PK_ALG	\
 | ||||
| +	HOSTKEY_ECDSA_CERT_METHODS \
 | ||||
| +	"rsa-sha2-512-cert-v01@openssh.com," \
 | ||||
| +	"rsa-sha2-256-cert-v01@openssh.com," \
 | ||||
| +	"ssh-rsa-cert-v01@openssh.com," \
 | ||||
| +	HOSTKEY_ECDSA_METHODS \
 | ||||
| +	"rsa-sha2-512," \
 | ||||
| @ -341,7 +191,7 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h | ||||
|  /* the actual algorithms */ | ||||
|   | ||||
|  #define KEX_SERVER_ENCRYPT \ | ||||
| @@ -137,6 +145,38 @@
 | ||||
| @@ -139,6 +147,38 @@
 | ||||
|   | ||||
|  #define KEX_CLIENT_MAC KEX_SERVER_MAC | ||||
|   | ||||
| @ -377,16 +227,16 @@ diff -up openssh-7.7p1/myproposal.h.fips openssh-7.7p1/myproposal.h | ||||
| +       "hmac-sha1"
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #else /* WITH_OPENSSL */ | ||||
|   | ||||
|  #define KEX_SERVER_KEX		\ | ||||
| diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c
 | ||||
| --- openssh-7.7p1/readconf.c.fips	2018-08-08 10:08:40.769719527 +0200
 | ||||
| +++ openssh-7.7p1/readconf.c	2018-08-08 10:08:40.824719990 +0200
 | ||||
| @@ -2081,17 +2081,18 @@ fill_default_options(Options * options)
 | ||||
|  	all_mac = mac_alg_list(','); | ||||
|  /* Not a KEX value, but here so all the algorithm defaults are together */ | ||||
|  #define	SSH_ALLOWED_CA_SIGALGS	\ | ||||
|  	"ecdsa-sha2-nistp256," \ | ||||
| diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c
 | ||||
| --- openssh-7.9p1/readconf.c.fips	2019-03-11 17:06:37.601877853 +0100
 | ||||
| +++ openssh-7.9p1/readconf.c	2019-03-11 17:06:37.622878050 +0100
 | ||||
| @@ -2178,18 +2178,19 @@ fill_default_options(Options * options)
 | ||||
|  	all_kex = kex_alg_list(','); | ||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||
| -#define ASSEMBLE(what, defaults, all) \
 | ||||
| +#define ASSEMBLE(what, defaults, fips_defaults, all) \
 | ||||
|  	do { \ | ||||
| @ -396,22 +246,24 @@ diff -up openssh-7.7p1/readconf.c.fips openssh-7.7p1/readconf.c | ||||
| +		    all)) != 0) \
 | ||||
|  			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | ||||
|  	} while (0) | ||||
| -	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
 | ||||
| -	ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
 | ||||
| -	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
 | ||||
| -	ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher);
 | ||||
| -	ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
 | ||||
| -	ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
 | ||||
| -	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
 | ||||
| -	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
 | ||||
| +	ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
 | ||||
| +	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
 | ||||
| -	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
 | ||||
| +	ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
 | ||||
| +	ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac);
 | ||||
| +	ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
 | ||||
| +	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
 | ||||
|  #undef ASSEMBLE | ||||
|  	free(all_cipher); | ||||
|  	free(all_mac); | ||||
| diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-seccomp-filter.c
 | ||||
| --- openssh-7.7p1/sandbox-seccomp-filter.c.fips	2018-08-08 10:08:40.794719737 +0200
 | ||||
| +++ openssh-7.7p1/sandbox-seccomp-filter.c	2018-08-08 10:08:40.824719990 +0200
 | ||||
| diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-seccomp-filter.c
 | ||||
| --- openssh-7.9p1/sandbox-seccomp-filter.c.fips	2019-03-11 17:06:37.586877712 +0100
 | ||||
| +++ openssh-7.9p1/sandbox-seccomp-filter.c	2019-03-11 17:06:37.622878050 +0100
 | ||||
| @@ -137,6 +137,9 @@ static const struct sock_filter preauth_
 | ||||
|  #ifdef __NR_open | ||||
|  	SC_DENY(__NR_open, EACCES), | ||||
| @ -422,13 +274,13 @@ diff -up openssh-7.7p1/sandbox-seccomp-filter.c.fips openssh-7.7p1/sandbox-secco | ||||
|  #ifdef __NR_openat | ||||
|  	SC_DENY(__NR_openat, EACCES), | ||||
|  #endif | ||||
| diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c
 | ||||
| --- openssh-7.7p1/servconf.c.fips	2018-08-08 10:08:40.778719603 +0200
 | ||||
| +++ openssh-7.7p1/servconf.c	2018-08-08 10:08:40.824719990 +0200
 | ||||
| @@ -196,17 +196,18 @@ option_clear_or_none(const char *o)
 | ||||
|  	all_mac = mac_alg_list(','); | ||||
| diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c
 | ||||
| --- openssh-7.9p1/servconf.c.fips	2019-03-11 17:06:37.568877543 +0100
 | ||||
| +++ openssh-7.9p1/servconf.c	2019-03-11 17:06:37.622878050 +0100
 | ||||
| @@ -209,18 +209,19 @@ assemble_algorithms(ServerOptions *o)
 | ||||
|  	all_kex = kex_alg_list(','); | ||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||
| -#define ASSEMBLE(what, defaults, all) \
 | ||||
| +#define ASSEMBLE(what, defaults, fips_defaults, all) \
 | ||||
|  	do { \ | ||||
| @ -443,32 +295,36 @@ diff -up openssh-7.7p1/servconf.c.fips openssh-7.7p1/servconf.c | ||||
| -	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
 | ||||
| -	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
 | ||||
| -	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
 | ||||
| -	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
 | ||||
| +	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
 | ||||
| +	ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
 | ||||
| +	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
 | ||||
| +	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 | ||||
| +	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
 | ||||
|  #undef ASSEMBLE | ||||
|  	free(all_cipher); | ||||
|  	free(all_mac); | ||||
| diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c
 | ||||
| --- openssh-7.7p1/ssh.c.fips	2018-08-08 10:08:40.811719881 +0200
 | ||||
| +++ openssh-7.7p1/ssh.c	2018-08-08 10:08:40.825719999 +0200
 | ||||
| diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c
 | ||||
| --- openssh-7.9p1/ssh.c.fips	2019-03-11 17:06:37.602877862 +0100
 | ||||
| +++ openssh-7.9p1/ssh.c	2019-03-11 17:06:37.623878060 +0100
 | ||||
| @@ -76,6 +76,8 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
|  #endif | ||||
| +#include <openssl/fips.h>
 | ||||
| +#include <openssl/crypto.h>
 | ||||
| +#include <fipscheck.h>
 | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
| @@ -579,6 +581,14 @@ main(int ac, char **av)
 | ||||
| @@ -600,6 +602,16 @@ main(int ac, char **av)
 | ||||
|  	sanitise_stdfd(); | ||||
|   | ||||
|  	__progname = ssh_get_progname(av[0]); | ||||
| +        SSLeay_add_all_algorithms();
 | ||||
| +#if OPENSSL_VERSION_NUMBER < 0x10100000L
 | ||||
| +	SSLeay_add_all_algorithms();
 | ||||
| +#endif
 | ||||
| +	if (access("/etc/system-fips", F_OK) == 0)
 | ||||
| +		if (! FIPSCHECK_verify(NULL, NULL)){
 | ||||
| +			if (FIPS_mode())
 | ||||
| @ -479,15 +335,7 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c | ||||
|   | ||||
|  #ifndef HAVE_SETPROCTITLE | ||||
|  	/* Prepare for later setproctitle emulation */ | ||||
| @@ -1045,7 +1055,6 @@ main(int ac, char **av)
 | ||||
|  	host_arg = xstrdup(host); | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
| -	OpenSSL_add_all_algorithms();
 | ||||
|  	ERR_load_crypto_strings(); | ||||
|  #endif | ||||
|   | ||||
| @@ -1268,6 +1277,10 @@ main(int ac, char **av)
 | ||||
| @@ -1283,6 +1294,10 @@ main(int ac, char **av)
 | ||||
|   | ||||
|  	seed_rng(); | ||||
|   | ||||
| @ -495,22 +343,22 @@ diff -up openssh-7.7p1/ssh.c.fips openssh-7.7p1/ssh.c | ||||
| +		logit("FIPS mode initialized");
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	if (options.user == NULL) | ||||
|  		options.user = xstrdup(pw->pw_name); | ||||
|   | ||||
| diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c
 | ||||
| --- openssh-7.7p1/sshconnect2.c.fips	2018-08-08 10:08:40.786719670 +0200
 | ||||
| +++ openssh-7.7p1/sshconnect2.c	2018-08-08 10:08:40.825719999 +0200
 | ||||
|  	/* | ||||
|  	 * Discard other fds that are hanging around. These can cause problem | ||||
|  	 * with backgrounded ssh processes started by ControlPersist. | ||||
| diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
 | ||||
| --- openssh-7.9p1/sshconnect2.c.fips	2019-03-11 17:06:37.580877655 +0100
 | ||||
| +++ openssh-7.9p1/sshconnect2.c	2019-03-11 17:06:37.623878060 +0100
 | ||||
| @@ -44,6 +44,8 @@
 | ||||
|  #include <vis.h> | ||||
|  #endif | ||||
|   | ||||
| +#include <openssl/fips.h>
 | ||||
| +#include <openssl/crypto.h>
 | ||||
| +
 | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
|  #include "xmalloc.h" | ||||
| @@ -235,7 +237,8 @@ order_hostkeyalgs(char *host, struct soc
 | ||||
| @@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc
 | ||||
|  	for (i = 0; i < options.num_system_hostfiles; i++) | ||||
|  		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); | ||||
|   | ||||
| @ -520,56 +368,10 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c | ||||
|  	maxlen = strlen(avail) + 1; | ||||
|  	first = xmalloc(maxlen); | ||||
|  	last = xmalloc(maxlen); | ||||
| @@ -290,23 +293,28 @@ ssh_kex2(char *host, struct sockaddr *ho
 | ||||
|   | ||||
|  #ifdef GSSAPI | ||||
|  	if (options.gss_keyex) { | ||||
| -		/* Add the GSSAPI mechanisms currently supported on this 
 | ||||
| -		 * client to the key exchange algorithm proposal */
 | ||||
| -		orig = options.kex_algorithms;
 | ||||
| -
 | ||||
| -		if (options.gss_server_identity)
 | ||||
| -			gss_host = options.gss_server_identity;
 | ||||
| -		else if (options.gss_trust_dns)
 | ||||
| -			gss_host = (char *)get_canonical_hostname(active_state, 1);
 | ||||
| -		else
 | ||||
| -			gss_host = host;
 | ||||
| -
 | ||||
| -		gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||
| -		    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||
| -		if (gss) {
 | ||||
| -			debug("Offering GSSAPI proposal: %s", gss);
 | ||||
| -			xasprintf(&options.kex_algorithms,
 | ||||
| -			    "%s,%s", gss, orig);
 | ||||
| +		if (FIPS_mode()) {
 | ||||
| +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | ||||
| +			options.gss_keyex = 0;
 | ||||
| +		} else {
 | ||||
| +			/* Add the GSSAPI mechanisms currently supported on this
 | ||||
| +			 * client to the key exchange algorithm proposal */
 | ||||
| +			orig = options.kex_algorithms;
 | ||||
| +
 | ||||
| +			if (options.gss_server_identity)
 | ||||
| +				gss_host = options.gss_server_identity;
 | ||||
| +			else if (options.gss_trust_dns)
 | ||||
| +				gss_host = (char *)get_canonical_hostname(active_state, 1);
 | ||||
| +			else
 | ||||
| +				gss_host = host;
 | ||||
| +
 | ||||
| +			gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||
| +			    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||
| +			if (gss) {
 | ||||
| +				debug("Offering GSSAPI proposal: %s", gss);
 | ||||
| +				xasprintf(&options.kex_algorithms,
 | ||||
| +				    "%s,%s", gss, orig);
 | ||||
| +			}
 | ||||
|  		} | ||||
|  	} | ||||
|  #endif | ||||
| @@ -322,14 +330,16 @@ ssh_kex2(char *host, struct sockaddr *ho
 | ||||
| @@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho
 | ||||
|  	if (options.hostkeyalgorithms != NULL) { | ||||
|  		all_key = sshkey_alg_list(0, 0, 1, ','); | ||||
| 		if (kex_assemble_names(&options.hostkeyalgorithms, | ||||
|  		if (kex_assemble_names(&options.hostkeyalgorithms, | ||||
| -		    KEX_DEFAULT_PK_ALG, all_key) != 0)
 | ||||
| +		    (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG),
 | ||||
| +		    all_key) != 0)
 | ||||
| @ -585,9 +387,67 @@ diff -up openssh-7.7p1/sshconnect2.c.fips openssh-7.7p1/sshconnect2.c | ||||
|  		/* Prefer algorithms that we already have keys for */ | ||||
|  		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | ||||
|  		    compat_pkalg_proposal( | ||||
| diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c
 | ||||
| --- openssh-7.7p1/sshd.c.fips	2018-08-08 10:08:40.818719940 +0200
 | ||||
| +++ openssh-7.7p1/sshd.c	2018-08-08 10:08:40.826720007 +0200
 | ||||
| @@ -201,29 +201,34 @@ ssh_kex2(char *host, struct sockaddr *ho
 | ||||
|   | ||||
|  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||
|  	if (options.gss_keyex) { | ||||
| -		/* Add the GSSAPI mechanisms currently supported on this
 | ||||
| -		 * client to the key exchange algorithm proposal */
 | ||||
| -		orig = myproposal[PROPOSAL_KEX_ALGS];
 | ||||
| -
 | ||||
| -		if (options.gss_server_identity)
 | ||||
| -			gss_host = xstrdup(options.gss_server_identity);
 | ||||
| -		else if (options.gss_trust_dns)
 | ||||
| -			gss_host = remote_hostname(ssh);
 | ||||
| -		else
 | ||||
| -			gss_host = xstrdup(host);
 | ||||
| -
 | ||||
| -		gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||
| -		    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||
| -		if (gss) {
 | ||||
| -			debug("Offering GSSAPI proposal: %s", gss);
 | ||||
| -			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
 | ||||
| -			    "%s,%s", gss, orig);
 | ||||
| -
 | ||||
| -			/* If we've got GSSAPI algorithms, then we also support the
 | ||||
| -			 * 'null' hostkey, as a last resort */
 | ||||
| -			orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
 | ||||
| -			xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
 | ||||
| -			    "%s,null", orig);
 | ||||
| +		if (FIPS_mode()) {
 | ||||
| +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | ||||
| +			options.gss_keyex = 0;
 | ||||
| +		} else {
 | ||||
| +			/* Add the GSSAPI mechanisms currently supported on this
 | ||||
| +			 * client to the key exchange algorithm proposal */
 | ||||
| +			orig = myproposal[PROPOSAL_KEX_ALGS];
 | ||||
| +
 | ||||
| +			if (options.gss_server_identity)
 | ||||
| +				gss_host = xstrdup(options.gss_server_identity);
 | ||||
| +			else if (options.gss_trust_dns)
 | ||||
| +				gss_host = remote_hostname(ssh);
 | ||||
| +			else
 | ||||
| +				gss_host = xstrdup(host);
 | ||||
| +
 | ||||
| +			gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||
| +			    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||
| +			if (gss) {
 | ||||
| +				debug("Offering GSSAPI proposal: %s", gss);
 | ||||
| +				xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
 | ||||
| +				    "%s,%s", gss, orig);
 | ||||
| +
 | ||||
| +				/* If we've got GSSAPI algorithms, then we also support the
 | ||||
| +				 * 'null' hostkey, as a last resort */
 | ||||
| +				orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
 | ||||
| +				xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
 | ||||
| +				    "%s,null", orig);
 | ||||
| +			}
 | ||||
|  		} | ||||
|  	} | ||||
|  #endif | ||||
| diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c
 | ||||
| --- openssh-7.9p1/sshd.c.fips	2019-03-11 17:06:37.617878003 +0100
 | ||||
| +++ openssh-7.9p1/sshd.c	2019-03-11 17:06:37.624878069 +0100
 | ||||
| @@ -66,6 +66,7 @@
 | ||||
|  #include <grp.h> | ||||
|  #include <pwd.h> | ||||
| @ -600,16 +460,16 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c | ||||
|  #include <openssl/dh.h> | ||||
|  #include <openssl/bn.h> | ||||
|  #include <openssl/rand.h> | ||||
| +#include <openssl/fips.h>
 | ||||
| +#include <openssl/crypto.h>
 | ||||
| +#include <fipscheck.h>
 | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|  #endif | ||||
|   | ||||
| @@ -1534,6 +1537,18 @@ main(int ac, char **av)
 | ||||
| @@ -1581,6 +1584,18 @@ main(int ac, char **av)
 | ||||
|  #endif | ||||
|  	__progname = ssh_get_progname(av[0]); | ||||
|   | ||||
| +        SSLeay_add_all_algorithms();
 | ||||
| +	OpenSSL_add_all_algorithms();
 | ||||
| +	if (access("/etc/system-fips", F_OK) == 0)
 | ||||
| +		if (! FIPSCHECK_verify(NULL, NULL)) {
 | ||||
| +			openlog(__progname, LOG_PID, LOG_AUTHPRIV);
 | ||||
| @ -624,16 +484,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c | ||||
|  	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ | ||||
|  	saved_argc = ac; | ||||
|  	rexec_argc = ac; | ||||
| @@ -1675,7 +1690,7 @@ main(int ac, char **av)
 | ||||
|  	else | ||||
|  		closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); | ||||
|   | ||||
| -#ifdef WITH_OPENSSL
 | ||||
| +#if 0 /* FIPS */
 | ||||
|  	OpenSSL_add_all_algorithms(); | ||||
|  #endif | ||||
|   | ||||
| @@ -1979,6 +1994,10 @@ main(int ac, char **av)
 | ||||
| @@ -2036,6 +2051,10 @@ main(int ac, char **av)
 | ||||
|  	/* Reinitialize the log (because of the fork above). */ | ||||
|  	log_init(__progname, options.log_level, options.log_facility, log_stderr); | ||||
|   | ||||
| @ -644,7 +495,7 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c | ||||
|  	/* Chdir to the root directory so that the current disk can be | ||||
|  	   unmounted if desired. */ | ||||
|  	if (chdir("/") == -1) | ||||
| @@ -2359,10 +2378,14 @@ do_ssh2_kex(void)
 | ||||
| @@ -2412,10 +2431,14 @@ do_ssh2_kex(void)
 | ||||
|  	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||||
|  		orig = NULL; | ||||
|   | ||||
| @ -663,14 +514,14 @@ diff -up openssh-7.7p1/sshd.c.fips openssh-7.7p1/sshd.c | ||||
|   | ||||
|  	if (gss && orig) | ||||
|  		xasprintf(&newstr, "%s,%s", gss, orig); | ||||
| diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c
 | ||||
| --- openssh-7.7p1/sshkey.c.fips	2018-08-08 10:08:40.818719940 +0200
 | ||||
| +++ openssh-7.7p1/sshkey.c	2018-08-08 10:08:40.826720007 +0200
 | ||||
| diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c
 | ||||
| --- openssh-7.9p1/sshkey.c.fips	2019-03-11 17:06:37.617878003 +0100
 | ||||
| +++ openssh-7.9p1/sshkey.c	2019-03-11 17:06:37.624878069 +0100
 | ||||
| @@ -34,6 +34,7 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
|  #include <openssl/pem.h> | ||||
| +#include <openssl/fips.h>
 | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #endif | ||||
|   | ||||
|  #include "crypto_api.h" | ||||
| @ -682,7 +533,7 @@ diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c | ||||
|   | ||||
|  #include "xmss_fast.h" | ||||
|   | ||||
| @@ -1526,6 +1528,8 @@ rsa_generate_private_key(u_int bits, RSA
 | ||||
| @@ -1514,6 +1516,8 @@ rsa_generate_private_key(u_int bits, RSA
 | ||||
|  	} | ||||
|  	if (!BN_set_word(f4, RSA_F4) || | ||||
|  	    !RSA_generate_key_ex(private, bits, f4, NULL)) { | ||||
| @ -691,10 +542,10 @@ diff -up openssh-7.7p1/sshkey.c.fips openssh-7.7p1/sshkey.c | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c
 | ||||
| --- openssh-7.7p1/ssh-keygen.c.fips	2018-08-08 10:08:40.801719797 +0200
 | ||||
| +++ openssh-7.7p1/ssh-keygen.c	2018-08-08 10:08:40.827720016 +0200
 | ||||
| @@ -229,6 +229,12 @@ type_bits_valid(int type, const char *na
 | ||||
| diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c
 | ||||
| --- openssh-7.9p1/ssh-keygen.c.fips	2019-03-11 17:06:37.590877750 +0100
 | ||||
| +++ openssh-7.9p1/ssh-keygen.c	2019-03-11 17:06:37.625878079 +0100
 | ||||
| @@ -230,6 +230,12 @@ type_bits_valid(int type, const char *na
 | ||||
|  	    OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; | ||||
|  	if (*bitsp > maxbits) | ||||
|  		fatal("key bits exceeds maximum %d", maxbits); | ||||
| @ -707,3 +558,22 @@ diff -up openssh-7.7p1/ssh-keygen.c.fips openssh-7.7p1/ssh-keygen.c | ||||
|  	switch (type) { | ||||
|  	case KEY_DSA: | ||||
|  		if (*bitsp != 1024) | ||||
| @@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw)
 | ||||
|  			first = 1; | ||||
|  			printf("%s: generating new host keys: ", __progname); | ||||
|  		} | ||||
| +		type = sshkey_type_from_name(key_types[i].key_type);
 | ||||
| +
 | ||||
| +		/* Skip the keys that are not supported in FIPS mode */
 | ||||
| +		if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) {
 | ||||
| +			logit("Skipping %s key in FIPS mode",
 | ||||
| +			    key_types[i].key_type_display);
 | ||||
| +			goto next;
 | ||||
| +		}
 | ||||
| +
 | ||||
|  		printf("%s ", key_types[i].key_type_display); | ||||
|  		fflush(stdout); | ||||
| -		type = sshkey_type_from_name(key_types[i].key_type);
 | ||||
|  		if ((fd = mkstemp(prv_tmp)) == -1) { | ||||
|  			error("Could not save your public key in %s: %s", | ||||
|  			    prv_tmp, strerror(errno)); | ||||
|  | ||||
| @ -113,29 +113,12 @@ index a5a81ed2..63f877f2 100644 | ||||
|  	if (authctxt->krb5_user) { | ||||
|  		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); | ||||
|  		authctxt->krb5_user = NULL; | ||||
| @@ -237,36 +287,186 @@ krb5_cleanup_proc(Authctxt *authctxt)
 | ||||
| @@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
 | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| -#ifndef HEIMDAL
 | ||||
| -krb5_error_code
 | ||||
| -ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
 | ||||
| -	int tmpfd, ret, oerrno;
 | ||||
| -	char ccname[40];
 | ||||
| -	mode_t old_umask;
 | ||||
|   | ||||
| -	ret = snprintf(ccname, sizeof(ccname),
 | ||||
| -	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
 | ||||
| -	if (ret < 0 || (size_t)ret >= sizeof(ccname))
 | ||||
| -		return ENOMEM;
 | ||||
| -
 | ||||
| -	old_umask = umask(0177);
 | ||||
| -	tmpfd = mkstemp(ccname + strlen("FILE:"));
 | ||||
| -	oerrno = errno;
 | ||||
| -	umask(old_umask);
 | ||||
| -	if (tmpfd == -1) {
 | ||||
| -		logit("mkstemp(): %.100s", strerror(oerrno));
 | ||||
| -		return oerrno;
 | ||||
| +
 | ||||
| +#if !defined(HEIMDAL)
 | ||||
| +int
 | ||||
| +ssh_asprintf_append(char **dsc, const char *fmt, ...) {
 | ||||
| @ -195,14 +178,13 @@ index a5a81ed2..63f877f2 100644 | ||||
| +			continue;
 | ||||
| +		} else {
 | ||||
| +			p_o = strchr(p_n, '}') + 1;
 | ||||
| +			p_o = '\0';
 | ||||
| +			*p_o = '\0';
 | ||||
| +			debug("%s: unsupported token %s in %s", __func__, p_n, template);
 | ||||
| +			/* unknown token, fallback to the default */
 | ||||
| +			goto cleanup;
 | ||||
| +		}
 | ||||
|  	} | ||||
|   | ||||
| -	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (ssh_asprintf_append(&r, "%s", p_o) == -1)
 | ||||
| +		goto cleanup;
 | ||||
| +
 | ||||
| @ -216,7 +198,10 @@ index a5a81ed2..63f877f2 100644 | ||||
| +	return -1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +krb5_error_code
 | ||||
|  krb5_error_code | ||||
| -ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
 | ||||
| -	int tmpfd, ret, oerrno;
 | ||||
| -	char ccname[40];
 | ||||
| +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
 | ||||
| +	profile_t p;
 | ||||
| +	int ret = 0;
 | ||||
| @ -241,9 +226,22 @@ index a5a81ed2..63f877f2 100644 | ||||
| +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
 | ||||
| +	int tmpfd, ret, oerrno, type_len;
 | ||||
| +	char *ccname = NULL;
 | ||||
| +	mode_t old_umask;
 | ||||
|  	mode_t old_umask; | ||||
| +	char *type = NULL, *colon = NULL;
 | ||||
| +
 | ||||
|   | ||||
| -	ret = snprintf(ccname, sizeof(ccname),
 | ||||
| -	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
 | ||||
| -	if (ret < 0 || (size_t)ret >= sizeof(ccname))
 | ||||
| -		return ENOMEM;
 | ||||
| -
 | ||||
| -	old_umask = umask(0177);
 | ||||
| -	tmpfd = mkstemp(ccname + strlen("FILE:"));
 | ||||
| -	oerrno = errno;
 | ||||
| -	umask(old_umask);
 | ||||
| -	if (tmpfd == -1) {
 | ||||
| -		logit("mkstemp(): %.100s", strerror(oerrno));
 | ||||
| -		return oerrno;
 | ||||
| -	}
 | ||||
| +	debug3("%s: called", __func__);
 | ||||
| +	if (need_environment)
 | ||||
| +		*need_environment = 0;
 | ||||
| @ -258,7 +256,8 @@ index a5a81ed2..63f877f2 100644 | ||||
| +		    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
 | ||||
| +		if (ret < 0)
 | ||||
| +			return ENOMEM;
 | ||||
| +
 | ||||
|   | ||||
| -	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
 | ||||
| +		old_umask = umask(0177);
 | ||||
| +		tmpfd = mkstemp(ccname + strlen("FILE:"));
 | ||||
|  		oerrno = errno; | ||||
| @ -307,6 +306,7 @@ index a5a81ed2..63f877f2 100644 | ||||
| +	if (krb5_cc_support_switch(ctx, type)) {
 | ||||
| +		debug3("%s: calling cc_new_unique(%s)", __func__, ccname);
 | ||||
| +		ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
 | ||||
| +		free(type);
 | ||||
| +		if (ret)
 | ||||
| +			return ret;
 | ||||
| +
 | ||||
| @ -317,6 +317,7 @@ index a5a81ed2..63f877f2 100644 | ||||
| +		 * it is already unique from above or the type does not support
 | ||||
| +		 * collections
 | ||||
| +		 */
 | ||||
| +		free(type);
 | ||||
| +		debug3("%s: calling cc_resolve(%s)", __func__, ccname);
 | ||||
| +		return (krb5_cc_resolve(ctx, ccname, ccache));
 | ||||
| +	}
 | ||||
| @ -343,11 +344,10 @@ index 29491df9..fdab5040 100644 | ||||
| +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
 | ||||
|  #endif | ||||
|  #endif | ||||
| diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
 | ||||
| index 795992d9..0623a107 100644
 | ||||
| --- a/gss-serv-krb5.c
 | ||||
| +++ b/gss-serv-krb5.c
 | ||||
| @@ -114,7 +114,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
 | ||||
| diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
 | ||||
| --- openssh-7.9p1/gss-serv-krb5.c.ccache_name	2019-03-01 15:17:42.708611802 +0100
 | ||||
| +++ openssh-7.9p1/gss-serv-krb5.c	2019-03-01 15:17:42.713611844 +0100
 | ||||
| @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | ||||
|  /* This writes out any forwarded credentials from the structure populated | ||||
|   * during userauth. Called after we have setuid to the user */ | ||||
|   | ||||
| @ -356,12 +356,9 @@ index 795992d9..0623a107 100644 | ||||
|  ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) | ||||
|  { | ||||
|  	krb5_ccache ccache; | ||||
| @@ -121,16 +121,17 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 | ||||
|  	krb5_error_code problem; | ||||
|  	krb5_principal princ; | ||||
| @@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  	OM_uint32 maj_status, min_status; | ||||
| -	const char *new_ccname, *new_cctype;
 | ||||
| +	int len;
 | ||||
|  	const char *new_ccname, *new_cctype; | ||||
|  	const char *errmsg; | ||||
| +	int set_env = 0;
 | ||||
|   | ||||
| @ -377,7 +374,7 @@ index 795992d9..0623a107 100644 | ||||
|   | ||||
|  #ifdef HEIMDAL | ||||
|  # ifdef HAVE_KRB5_CC_NEW_UNIQUE | ||||
| @@ -144,14 +145,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 | ||||
| @@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		krb5_get_err_text(krb_context, problem)); | ||||
|  # endif | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
| @ -396,7 +393,7 @@ index 795992d9..0623a107 100644 | ||||
|  	} | ||||
|  #endif	/* #ifdef HEIMDAL */ | ||||
|   | ||||
| @@ -160,7 +161,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 | ||||
| @@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		errmsg = krb5_get_error_message(krb_context, problem); | ||||
|  		logit("krb5_parse_name(): %.100s", errmsg); | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
| @ -405,7 +402,7 @@ index 795992d9..0623a107 100644 | ||||
|  	} | ||||
|   | ||||
|  	if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { | ||||
| @@ -169,7 +170,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 | ||||
| @@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
|  		krb5_free_principal(krb_context, princ); | ||||
|  		krb5_cc_destroy(krb_context, ccache); | ||||
| @ -414,7 +411,7 @@ index 795992d9..0623a107 100644 | ||||
|  	} | ||||
|   | ||||
|  	krb5_free_principal(krb_context, princ); | ||||
| @@ -178,37 +179,27 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
 | ||||
| @@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  	    client->creds, ccache))) { | ||||
|  		logit("gss_krb5_copy_ccache() failed"); | ||||
|  		krb5_cc_destroy(krb_context, ccache); | ||||
| @ -422,30 +419,29 @@ index 795992d9..0623a107 100644 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|   | ||||
| -	new_cctype = krb5_cc_get_type(krb_context, ccache);
 | ||||
| -	new_ccname = krb5_cc_get_name(krb_context, ccache);
 | ||||
|  	new_cctype = krb5_cc_get_type(krb_context, ccache); | ||||
|  	new_ccname = krb5_cc_get_name(krb_context, ccache); | ||||
| -
 | ||||
| -	client->store.envvar = "KRB5CCNAME";
 | ||||
| -#ifdef USE_CCAPI
 | ||||
| -	xasprintf(&client->store.envval, "API:%s", new_ccname);
 | ||||
| -	client->store.filename = NULL;
 | ||||
| -#else
 | ||||
| -	if (new_ccname[0] == ':')
 | ||||
| -		new_ccname++;
 | ||||
| -	xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname);
 | ||||
|  	xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); | ||||
| -	if (strcmp(new_cctype, "DIR") == 0) {
 | ||||
| -		char *p;
 | ||||
| -		p = strrchr(client->store.envval, '/');
 | ||||
| -		if (p)
 | ||||
| -			*p = '\0';
 | ||||
| -	}
 | ||||
| -#endif
 | ||||
| +
 | ||||
| +	if (set_env) {
 | ||||
| +		const char *filename = krb5_cc_get_name(krb_context, ccache);
 | ||||
| +		client->store.envvar = "KRB5CCNAME";
 | ||||
| +		len = strlen(filename) + 6;
 | ||||
| +		client->store.envval = xmalloc(len);
 | ||||
| +		snprintf(client->store.envval, len, "FILE:%s", filename);
 | ||||
| +	}
 | ||||
|  	} | ||||
|  	if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) | ||||
|  		client->store.filename = xstrdup(new_ccname); | ||||
| -#endif
 | ||||
|   | ||||
|  #ifdef USE_PAM | ||||
| -	if (options.use_pam)
 | ||||
| @ -453,7 +449,7 @@ index 795992d9..0623a107 100644 | ||||
|  		do_pam_putenv(client->store.envvar, client->store.envval); | ||||
|  #endif | ||||
|   | ||||
|  	krb5_cc_close(krb_context, ccache); | ||||
| @@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|   | ||||
|  	client->store.data = krb_context; | ||||
|   | ||||
| @ -484,11 +480,21 @@ index 6cae720e..16e55cbc 100644 | ||||
|  } | ||||
|   | ||||
|  /* This allows GSSAPI methods to do things to the childs environment based | ||||
| diff --git a/servconf.c b/servconf.c
 | ||||
| index cb578658..a6e01df2 100644
 | ||||
| --- a/servconf.c
 | ||||
| +++ b/servconf.c
 | ||||
| @@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options)
 | ||||
| @@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() {
 | ||||
|  	char *envstr; | ||||
|  #endif | ||||
|   | ||||
| -	if (gssapi_client.store.filename == NULL &&
 | ||||
| -	    gssapi_client.store.envval == NULL &&
 | ||||
| -	    gssapi_client.store.envvar == NULL)
 | ||||
| +	if (gssapi_client.store.envval == NULL)
 | ||||
|  		return; | ||||
|   | ||||
|  	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); | ||||
| diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c
 | ||||
| --- openssh-7.9p1/servconf.c.ccache_name	2019-03-01 15:17:42.704611768 +0100
 | ||||
| +++ openssh-7.9p1/servconf.c	2019-03-01 15:17:42.713611844 +0100
 | ||||
| @@ -123,6 +123,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->kerberos_or_local_passwd = -1; | ||||
|  	options->kerberos_ticket_cleanup = -1; | ||||
|  	options->kerberos_get_afs_token = -1; | ||||
| @ -588,14 +594,6 @@ diff --git a/ssh-gss.h b/ssh-gss.h | ||||
| index 6593e422..245178af 100644
 | ||||
| --- a/ssh-gss.h
 | ||||
| +++ b/ssh-gss.h
 | ||||
| @@ -62,7 +62,6 @@
 | ||||
|  #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-" | ||||
|   | ||||
|  typedef struct { | ||||
| -	char *filename;
 | ||||
|  	char *envvar; | ||||
|  	char *envval; | ||||
|  	struct passwd *owner; | ||||
| @@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct {
 | ||||
|  	int (*dochild) (ssh_gssapi_client *); | ||||
|  	int (*userok) (ssh_gssapi_client *, char *); | ||||
|  | ||||
| @ -12,15 +12,13 @@ diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config | ||||
| diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat
 | ||||
| --- openssh-7.7p1/ssh_config_redhat.redhat	2018-07-03 10:44:06.522245125 +0200
 | ||||
| +++ openssh-7.7p1/ssh_config_redhat	2018-07-03 10:44:06.522245125 +0200
 | ||||
| @@ -0,0 +1,20 @@
 | ||||
| +# Follow system-wide Crypto Policy, if defined:
 | ||||
| +Include /etc/crypto-policies/back-ends/openssh.config
 | ||||
| @@ -0,0 +1,21 @@
 | ||||
| +# The options here are in the "Match final block" to be applied as the last
 | ||||
| +# options and could be potentially overwritten by the user configuration
 | ||||
| +Match final all
 | ||||
| +	# Follow system-wide Crypto Policy, if defined:
 | ||||
| +	Include /etc/crypto-policies/back-ends/openssh.config
 | ||||
| +
 | ||||
| +# Uncomment this if you want to use .local domain
 | ||||
| +# Host *.local
 | ||||
| +#   CheckHostIP no
 | ||||
| +
 | ||||
| +Host *
 | ||||
| +	GSSAPIAuthentication yes
 | ||||
| +
 | ||||
| +# If this option is set to yes then remote X11 clients will have full access
 | ||||
| @ -33,6 +31,10 @@ diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat | ||||
| +	SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
 | ||||
| +	SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
 | ||||
| +	SendEnv XMODIFIERS
 | ||||
| +
 | ||||
| +# Uncomment this if you want to use .local domain
 | ||||
| +# Host *.local
 | ||||
| +#   CheckHostIP no
 | ||||
| diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0
 | ||||
| --- openssh-7.7p1/sshd_config.0.redhat	2018-04-02 07:39:27.000000000 +0200
 | ||||
| +++ openssh-7.7p1/sshd_config.0	2018-07-03 10:44:06.523245133 +0200
 | ||||
|  | ||||
| @ -9,9 +9,9 @@ diff --git a/sshd.c b/sshd.c | ||||
| +	if (! options.use_pam)
 | ||||
| +		logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems.");
 | ||||
| +
 | ||||
|  	seed_rng(); | ||||
|   | ||||
|  	/* Fill in default values for those options not explicitly set. */ | ||||
|  	fill_default_server_options(&options); | ||||
|   | ||||
| diff --git a/sshd_config b/sshd_config
 | ||||
| --- a/sshd_config
 | ||||
| +++ b/sshd_config
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,72 +0,0 @@ | ||||
| diff -up openssh/misc.c.config openssh/misc.c
 | ||||
| --- openssh/misc.c.config	2018-08-22 13:58:54.922807799 +0200
 | ||||
| +++ openssh/misc.c	2018-08-22 13:58:55.000808428 +0200
 | ||||
| @@ -485,7 +485,7 @@ put_host_port(const char *host, u_short
 | ||||
|   * The delimiter char, if present, is stored in delim. | ||||
|   * If this is the last field, *cp is set to NULL. | ||||
|   */ | ||||
| -static char *
 | ||||
| +char *
 | ||||
|  hpdelim2(char **cp, char *delim) | ||||
|  { | ||||
|  	char *s, *old; | ||||
| diff -up openssh/misc.h.config openssh/misc.h
 | ||||
| --- openssh/misc.h.config	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/misc.h	2018-08-22 13:58:55.001808436 +0200
 | ||||
| @@ -54,6 +54,7 @@ int	 set_rdomain(int, const char *);
 | ||||
|  int	 a2port(const char *); | ||||
|  int	 a2tun(const char *, int *); | ||||
|  char	*put_host_port(const char *, u_short); | ||||
| +char	*hpdelim2(char **, char *);
 | ||||
|  char	*hpdelim(char **); | ||||
|  char	*cleanhostname(char *); | ||||
|  char	*colon(char *); | ||||
| diff -up openssh/servconf.c.config openssh/servconf.c
 | ||||
| --- openssh/servconf.c.config	2018-08-22 13:58:54.989808340 +0200
 | ||||
| +++ openssh/servconf.c	2018-08-22 14:18:49.235443937 +0200
 | ||||
| @@ -886,7 +886,7 @@ process_permitopen_list(struct ssh *ssh,
 | ||||
|  { | ||||
|  	u_int i; | ||||
|  	int port; | ||||
| -	char *host, *arg, *oarg;
 | ||||
| +	char *host, *arg, *oarg, ch;
 | ||||
|  	int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; | ||||
|  	const char *what = lookup_opcode_name(opcode); | ||||
|   | ||||
| @@ -904,8 +904,8 @@ process_permitopen_list(struct ssh *ssh,
 | ||||
|  	/* Otherwise treat it as a list of permitted host:port */ | ||||
|  	for (i = 0; i < num_opens; i++) { | ||||
|  		oarg = arg = xstrdup(opens[i]); | ||||
| -		host = hpdelim(&arg);
 | ||||
| -		if (host == NULL)
 | ||||
| +		host = hpdelim2(&arg, &ch);
 | ||||
| +		if (host == NULL || ch == '/')
 | ||||
|  			fatal("%s: missing host in %s", __func__, what); | ||||
|  		host = cleanhostname(host); | ||||
|  		if (arg == NULL || ((port = permitopen_port(arg)) < 0)) | ||||
| @@ -1323,8 +1323,10 @@ process_server_config_line(ServerOptions
 | ||||
|  			port = 0; | ||||
|  			p = arg; | ||||
|  		} else { | ||||
| -			p = hpdelim(&arg);
 | ||||
| -			if (p == NULL)
 | ||||
| +			char ch;
 | ||||
| +			arg2 = NULL;
 | ||||
| +			p = hpdelim2(&arg, &ch);
 | ||||
| +			if (p == NULL || ch == '/')
 | ||||
|  				fatal("%s line %d: bad address:port usage", | ||||
|  				    filename, linenum); | ||||
|  			p = cleanhostname(p); | ||||
| @@ -1965,9 +1967,10 @@ process_server_config_line(ServerOptions
 | ||||
|  				 */ | ||||
|  				xasprintf(&arg2, "*:%s", arg); | ||||
|  			} else { | ||||
| +				char ch;
 | ||||
|  				arg2 = xstrdup(arg); | ||||
| -				p = hpdelim(&arg);
 | ||||
| -				if (p == NULL) {
 | ||||
| +				p = hpdelim2(&arg, &ch);
 | ||||
| +				if (p == NULL || ch == '/') {
 | ||||
|  					fatal("%s line %d: missing host in %s", | ||||
|  					    filename, linenum, | ||||
|  					    lookup_opcode_name(opcode)); | ||||
| @ -4,11 +4,11 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c | ||||
| @@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32
 | ||||
|  	Authctxt *authctxt = ssh->authctxt; | ||||
|  	Authmethod *m = NULL; | ||||
|  	char *user, *service, *method, *style = NULL; | ||||
|  	char *user = NULL, *service = NULL, *method = NULL, *style = NULL; | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	char *role = NULL;
 | ||||
| +#endif
 | ||||
|  	int authenticated = 0; | ||||
|  	int r, authenticated = 0; | ||||
|  	double tstart = monotime_double(); | ||||
|   | ||||
| @@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32
 | ||||
| @ -37,9 +37,9 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c | ||||
| +			mm_inform_authrole(role);
 | ||||
| +#endif
 | ||||
| +		}
 | ||||
|  		userauth_banner(); | ||||
|  		userauth_banner(ssh); | ||||
|  		if (auth2_setup_methods_lists(authctxt) != 0) | ||||
|  			packet_disconnect("no authentication methods enabled"); | ||||
|  			ssh_packet_disconnect(ssh, | ||||
| diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
 | ||||
| --- openssh/auth2-gss.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth2-gss.c	2018-08-22 11:15:42.459799171 +0200
 | ||||
| @ -57,7 +57,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c | ||||
|  	mic.length = len; | ||||
| -	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	if (authctxt->role && (strlen(authctxt->role) > 0))
 | ||||
| +	if (authctxt->role && authctxt->role[0] != 0)
 | ||||
| +		xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
 | ||||
| +	else
 | ||||
| +#endif
 | ||||
| @ -197,15 +197,15 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | ||||
| --- openssh/monitor.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/monitor.c	2018-08-22 11:19:56.006844867 +0200
 | ||||
| @@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *)
 | ||||
|  int mm_answer_pwnamallow(int, struct sshbuf *); | ||||
|  int mm_answer_auth2_read_banner(int, struct sshbuf *); | ||||
|  int mm_answer_authserv(int, struct sshbuf *); | ||||
|  int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_authserv(struct ssh *, int, struct sshbuf *); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +int mm_answer_authrole(int, struct sshbuf *);
 | ||||
| +int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
 | ||||
| +#endif
 | ||||
|  int mm_answer_authpassword(int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthquery(int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthrespond(int, struct sshbuf *); | ||||
|  int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); | ||||
| @@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[]
 | ||||
|      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | ||||
|      {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | ||||
| @ -227,12 +227,12 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | ||||
|   | ||||
|  #ifdef USE_PAM | ||||
| @@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb
 | ||||
|  	return (0); | ||||
|  	return found; | ||||
|  } | ||||
|   | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +int
 | ||||
| +mm_answer_authrole(int sock, struct sshbuf *m)
 | ||||
| +mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
 | ||||
| +{
 | ||||
| +	int r;
 | ||||
| +	monitor_permit_authentications(1);
 | ||||
| @ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | ||||
| +#endif
 | ||||
| +
 | ||||
|  int | ||||
|  mm_answer_authpassword(int sock, struct sshbuf *m) | ||||
|  mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
|  { | ||||
| @@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i
 | ||||
|  { | ||||
| @ -338,13 +338,13 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h | ||||
| --- openssh/monitor_wrap.h.role-mls	2018-08-22 11:14:56.818430941 +0200
 | ||||
| +++ openssh/monitor_wrap.h	2018-08-22 11:22:10.439929513 +0200
 | ||||
| @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int);
 | ||||
|  int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, | ||||
|      const char *, u_int compat); | ||||
|  int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, | ||||
|      const u_char *, size_t, const char *, u_int compat); | ||||
|  void mm_inform_authserv(char *, char *); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +void mm_inform_authrole(char *);
 | ||||
| +#endif
 | ||||
|  struct passwd *mm_getpwnamallow(const char *); | ||||
|  struct passwd *mm_getpwnamallow(struct ssh *, const char *); | ||||
|  char *mm_auth2_read_banner(void); | ||||
|  int mm_auth_password(struct ssh *, char *); | ||||
| diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in
 | ||||
|  | ||||
| @ -1,14 +0,0 @@ | ||||
| -----BEGIN PGP SIGNATURE----- | ||||
| 
 | ||||
| iQHDBAABCgAdFiEEWcIRjtIG2SfmZ+vj0+X1a22SDTAFAlt+Xa8ACgkQ0+X1a22S | ||||
| DTAJPwx9HIW/obxNJYTU7M8trpalBekdl1SqUjxdDwInIsKTLSOpJCsnynBai/3c | ||||
| SuvZkBwcKwZZFe+xCvRQDHkf/YYLT+d7slUQolb0OJmzFKbvu6xwuv7q12ag9hQj | ||||
| /8BUfdYRKb63uemfKuVAHfcnUm9WlwSbif+Au/j1yg/MlETY47ezYA9/q75wignx | ||||
| 3g38JVHVgKDenDd8o9/hgjeQpEHKNdCQo71nN2h3MYRlh4xrR9ENZj7y8x65Kp1j | ||||
| WoZEhlvjYkka4deSGwj2MIAJnzsc39uppEoEjkB7F9SUo4O7CxbWFein70Ct7Xbs | ||||
| VDWXQibnJGHKatHIecaPLUYexGWO1XYNZErDhY7fPw0ChfMGbz3+0eDfDJqGY49r | ||||
| Lo6wzsrgv2kDJMqwciT/D/Zb3ocHnCrq1Isnz/Ug2lW58LMk7Y1HisPteZFQ/pkC | ||||
| xKeO+K1RkaRUSCrB5iToqF+7i8eRNVROYmkKLgKcMrC0WYEjnbEoFdr4bktAS9QM | ||||
| BS6aIsh2cyg2H0FjDKmYvcKOUf0IgA== | ||||
| =ZiYm | ||||
| -----END PGP SIGNATURE----- | ||||
| @ -1,62 +0,0 @@ | ||||
| diff --git a/monitor.c b/monitor.c
 | ||||
| index 12b33e7..a1c3c97 100644
 | ||||
| --- a/monitor.c
 | ||||
| +++ b/monitor.c
 | ||||
| @@ -875,6 +875,34 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m)
 | ||||
|  } | ||||
|  #endif | ||||
|   | ||||
| +/*
 | ||||
| + * Check that the key type appears in the supplied pattern list, ignoring
 | ||||
| + * mismastches in the signature algorithm. (Signature algorithm checks are
 | ||||
| + * performed in the unprivileged authentication code).
 | ||||
| + * Returns 1 on success, 0 otherwise.
 | ||||
| + */
 | ||||
| +static int
 | ||||
| +key_base_type_match(const struct sshkey *key, const char *list)
 | ||||
| +{
 | ||||
| +	char *s, *l, *ol = xstrdup(list);
 | ||||
| +	int found = 0;
 | ||||
| +
 | ||||
| +	l = ol;
 | ||||
| +	for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) {
 | ||||
| +		if (sshkey_type_from_name(s) == key->type) {
 | ||||
| +			found = 1;
 | ||||
| +			break;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	if (!found) {
 | ||||
| +		debug("key type %s does not appear in list %s",
 | ||||
| +		    sshkey_ssh_name(key), list);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	free(ol);
 | ||||
| +	return found;
 | ||||
| +}
 | ||||
| +
 | ||||
|  int | ||||
|  mm_answer_keyallowed(int sock, struct sshbuf *m) | ||||
|  { | ||||
| @@ -909,8 +937,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
 | ||||
|  				break; | ||||
|  			if (auth2_key_already_used(authctxt, key)) | ||||
|  				break; | ||||
| -			if (match_pattern_list(sshkey_ssh_name(key),
 | ||||
| -			    options.pubkey_key_types, 0) != 1)
 | ||||
| +			if (!key_base_type_match(key,
 | ||||
| +			    options.pubkey_key_types))
 | ||||
|  				break; | ||||
|  			allowed = user_key_allowed(ssh, authctxt->pw, key, | ||||
|  			    pubkey_auth_attempt, &opts); | ||||
| @@ -921,8 +949,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
 | ||||
|  				break; | ||||
|  			if (auth2_key_already_used(authctxt, key)) | ||||
|  				break; | ||||
| -			if (match_pattern_list(sshkey_ssh_name(key),
 | ||||
| -			    options.hostbased_key_types, 0) != 1)
 | ||||
| +			if (!key_base_type_match(key,
 | ||||
| +			    options.hostbased_key_types))
 | ||||
|  				break; | ||||
|  			allowed = hostbased_key_allowed(authctxt->pw, | ||||
|  			    cuser, chost, key); | ||||
| 
 | ||||
| @ -1,150 +0,0 @@ | ||||
| From bc74944ce7a2eabd228d47051f277ce108914c96 Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelen <jjelen@redhat.com> | ||||
| Date: Tue, 16 Oct 2018 16:44:40 +0200 | ||||
| Subject: [PATCH] Unbreak authentication using gssapi-keyex (#1625366) | ||||
| 
 | ||||
| ---
 | ||||
|  auth2-gss.c    |  6 +++--- | ||||
|  gss-serv.c     |  4 +++- | ||||
|  monitor.c      | 13 ++++++++++--- | ||||
|  monitor_wrap.c |  4 +++- | ||||
|  monitor_wrap.h |  2 +- | ||||
|  ssh-gss.h      |  2 +- | ||||
|  6 files changed, 21 insertions(+), 10 deletions(-) | ||||
| 
 | ||||
| diff --git a/auth2-gss.c b/auth2-gss.c
 | ||||
| index 3f2ad21d..a61ac089 100644
 | ||||
| --- a/auth2-gss.c
 | ||||
| +++ b/auth2-gss.c
 | ||||
| @@ -84,7 +84,7 @@ userauth_gsskeyex(Authctxt *authctxt)
 | ||||
|  	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,  | ||||
|  	    &gssbuf, &mic)))) | ||||
|  		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, | ||||
| -		    authctxt->pw));
 | ||||
| +		    authctxt->pw, 1));
 | ||||
|  	 | ||||
|  	sshbuf_free(b); | ||||
|  	free(mic.value); | ||||
| @@ -299,7 +299,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
 | ||||
|  		fatal("%s: %s", __func__, ssh_err(r)); | ||||
|   | ||||
|  	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, | ||||
| -	    authctxt->pw));
 | ||||
| +	    authctxt->pw, 1));
 | ||||
|   | ||||
|  	if ((!use_privsep || mm_is_monitor()) && | ||||
|  	    (displayname = ssh_gssapi_displayname()) != NULL) | ||||
| @@ -347,7 +347,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
 | ||||
|   | ||||
|  	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) | ||||
|  		authenticated =  | ||||
| -		    PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw));
 | ||||
| +		    PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0));
 | ||||
|  	else | ||||
|  		logit("GSSAPI MIC check failed"); | ||||
|   | ||||
| diff --git a/gss-serv.c b/gss-serv.c
 | ||||
| index 786ac95c..87de2baa 100644
 | ||||
| --- a/gss-serv.c
 | ||||
| +++ b/gss-serv.c
 | ||||
| @@ -493,10 +493,12 @@ verify_authentication_indicators(Gssctxt *gssctxt)
 | ||||
|   | ||||
|  /* Privileged */ | ||||
|  int | ||||
| -ssh_gssapi_userok(char *user, struct passwd *pw)
 | ||||
| +ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
 | ||||
|  { | ||||
|  	OM_uint32 lmin; | ||||
|   | ||||
| +	(void) kex; /* used in privilege separation */
 | ||||
| +
 | ||||
|  	if (gssapi_client.exportedname.length == 0 || | ||||
|  	    gssapi_client.exportedname.value == NULL) { | ||||
|  		debug("No suitable client data"); | ||||
| diff --git a/monitor.c b/monitor.c
 | ||||
| index 9bbe8cc4..7b1903af 100644
 | ||||
| --- a/monitor.c
 | ||||
| +++ b/monitor.c
 | ||||
| @@ -1877,14 +1877,17 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m)
 | ||||
|  int | ||||
|  mm_answer_gss_userok(int sock, struct sshbuf *m) | ||||
|  { | ||||
| -	int r, authenticated;
 | ||||
| +	int r, authenticated, kex;
 | ||||
|  	const char *displayname; | ||||
|   | ||||
|  	if (!options.gss_authentication && !options.gss_keyex) | ||||
|  		fatal("%s: GSSAPI authentication not enabled", __func__); | ||||
|   | ||||
| +	if ((r = sshbuf_get_u32(m, &kex)) != 0)
 | ||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
| +
 | ||||
|  	authenticated = authctxt->valid && | ||||
| -	    ssh_gssapi_userok(authctxt->user, authctxt->pw);
 | ||||
| +	    ssh_gssapi_userok(authctxt->user, authctxt->pw, kex);
 | ||||
|   | ||||
|  	sshbuf_reset(m); | ||||
|  	if ((r = sshbuf_put_u32(m, authenticated)) != 0) | ||||
| @@ -1893,7 +1896,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m)
 | ||||
|  	debug3("%s: sending result %d", __func__, authenticated); | ||||
|  	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); | ||||
|   | ||||
| -	auth_method = "gssapi-with-mic";
 | ||||
| +	if (kex) {
 | ||||
| +		auth_method = "gssapi-keyex";
 | ||||
| +	} else {
 | ||||
| +		auth_method = "gssapi-with-mic";
 | ||||
| +	}
 | ||||
|   | ||||
|  	if ((displayname = ssh_gssapi_displayname()) != NULL) | ||||
|  		auth2_record_info(authctxt, "%s", displayname); | ||||
| diff --git a/monitor_wrap.c b/monitor_wrap.c
 | ||||
| index fb52a530..508d926d 100644
 | ||||
| --- a/monitor_wrap.c
 | ||||
| +++ b/monitor_wrap.c
 | ||||
| @@ -984,13 +984,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| -mm_ssh_gssapi_userok(char *user, struct passwd *pw)
 | ||||
| +mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
 | ||||
|  { | ||||
|  	struct sshbuf *m; | ||||
|  	int r, authenticated = 0; | ||||
|   | ||||
|  	if ((m = sshbuf_new()) == NULL) | ||||
|  		fatal("%s: sshbuf_new failed", __func__); | ||||
| +	if ((r = sshbuf_put_u32(m, kex)) != 0)
 | ||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|   | ||||
|  	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); | ||||
|  	mm_request_receive_expect(pmonitor->m_recvfd, | ||||
| diff --git a/monitor_wrap.h b/monitor_wrap.h
 | ||||
| index 494760dd..5eba5ecc 100644
 | ||||
| --- a/monitor_wrap.h
 | ||||
| +++ b/monitor_wrap.h
 | ||||
| @@ -60,7 +60,7 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
 | ||||
|  OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | ||||
|  OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, | ||||
|     gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); | ||||
| -int mm_ssh_gssapi_userok(char *user, struct passwd *);
 | ||||
| +int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex);
 | ||||
|  OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); | ||||
|  OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); | ||||
|  int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); | ||||
| diff --git a/ssh-gss.h b/ssh-gss.h
 | ||||
| index 39b6ce69..98262837 100644
 | ||||
| --- a/ssh-gss.h
 | ||||
| +++ b/ssh-gss.h
 | ||||
| @@ -162,7 +162,7 @@ gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
 | ||||
|  int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,  | ||||
|      const char *); | ||||
|  OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | ||||
| -int ssh_gssapi_userok(char *name, struct passwd *);
 | ||||
| +int ssh_gssapi_userok(char *name, struct passwd *, int kex);
 | ||||
|  OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); | ||||
|  void ssh_gssapi_do_child(char ***, u_int *); | ||||
|  void ssh_gssapi_cleanup_creds(void); | ||||
| -- 
 | ||||
| 2.17.2 | ||||
| 
 | ||||
							
								
								
									
										31
									
								
								SOURCES/openssh-7.9p1-ssh-copy-id.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/openssh-7.9p1-ssh-copy-id.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id
 | ||||
| --- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id	2018-10-17 02:01:20.000000000 +0200
 | ||||
| +++ openssh-7.9p1/contrib/ssh-copy-id	2019-01-23 20:49:30.513393667 +0100
 | ||||
| @@ -112,7 +112,8 @@ do
 | ||||
|          usage | ||||
|    } | ||||
|   | ||||
| -  OPT= OPTARG=
 | ||||
| +  OPT=
 | ||||
| +  OPTARG=
 | ||||
|    # implement something like getopt to avoid Solaris pain | ||||
|    case "$1" in | ||||
|      -i?*|-o?*|-p?*) | ||||
| @@ -261,7 +262,7 @@ populate_new_ids() {
 | ||||
|    fi | ||||
|    if [ -z "$NEW_IDS" ] ; then | ||||
|      printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 | ||||
| -    printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2
 | ||||
| +    printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2
 | ||||
|      exit 0 | ||||
|    fi | ||||
|    printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 | ||||
| @@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in
 | ||||
|      # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; | ||||
|      #     'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. | ||||
|      [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ | ||||
| -      ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
 | ||||
| +      ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
 | ||||
|        || exit 1 | ||||
|      ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) | ||||
|      ;; | ||||
							
								
								
									
										210
									
								
								SOURCES/openssh-8.0p1-crypto-policies.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								SOURCES/openssh-8.0p1-crypto-policies.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,210 @@ | ||||
| diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5
 | ||||
| --- openssh-8.0p1/ssh_config.5.crypto-policies	2019-05-13 14:04:01.999099570 +0200
 | ||||
| +++ openssh-8.0p1/ssh_config.5	2019-05-13 14:12:36.343923071 +0200
 | ||||
| @@ -445,12 +445,10 @@ aes256-gcm@openssh.com
 | ||||
|  chacha20-poly1305@openssh.com | ||||
|  .Ed | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -chacha20-poly1305@openssh.com,
 | ||||
| -aes128-ctr,aes192-ctr,aes256-ctr,
 | ||||
| -aes128-gcm@openssh.com,aes256-gcm@openssh.com
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available ciphers may also be obtained using | ||||
|  .Qq ssh -Q cipher . | ||||
| @@ -812,8 +810,10 @@ gss-nistp256-sha256-,
 | ||||
|  gss-curve25519-sha256- | ||||
|  .Ed | ||||
|  .Pp | ||||
| -The default is
 | ||||
| -.Dq gss-gex-sha1-,gss-group14-sha1- .
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  This option only applies to protocol version 2 connections using GSSAPI. | ||||
|  .It Cm HashKnownHosts | ||||
|  Indicates that | ||||
| @@ -1123,16 +1123,10 @@ If the specified value begins with a
 | ||||
|  .Sq - | ||||
|  character, then the specified methods (including wildcards) will be removed | ||||
|  from the default set instead of replacing them. | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -curve25519-sha256,curve25519-sha256@libssh.org,
 | ||||
| -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | ||||
| -diffie-hellman-group-exchange-sha256,
 | ||||
| -diffie-hellman-group16-sha512,
 | ||||
| -diffie-hellman-group18-sha512,
 | ||||
| -diffie-hellman-group14-sha256,
 | ||||
| -diffie-hellman-group14-sha1
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available key exchange algorithms may also be obtained using | ||||
|  .Qq ssh -Q kex . | ||||
| @@ -1210,14 +1204,10 @@ The algorithms that contain
 | ||||
|  calculate the MAC after encryption (encrypt-then-mac). | ||||
|  These are considered safer and their use recommended. | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -umac-64-etm@openssh.com,umac-128-etm@openssh.com,
 | ||||
| -hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
 | ||||
| -hmac-sha1-etm@openssh.com,
 | ||||
| -umac-64@openssh.com,umac-128@openssh.com,
 | ||||
| -hmac-sha2-256,hmac-sha2-512,hmac-sha1
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available MAC algorithms may also be obtained using | ||||
|  .Qq ssh -Q mac . | ||||
| @@ -1361,17 +1351,10 @@ If the specified value begins with a
 | ||||
|  .Sq - | ||||
|  character, then the specified key types (including wildcards) will be removed | ||||
|  from the default set instead of replacing them. | ||||
| -The default for this option is:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | ||||
| -ssh-rsa-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available key types may also be obtained using | ||||
|  .Qq ssh -Q key . | ||||
| diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5
 | ||||
| --- openssh-8.0p1/sshd_config.5.crypto-policies	2019-05-13 14:12:41.226968863 +0200
 | ||||
| +++ openssh-8.0p1/sshd_config.5	2019-05-13 14:15:14.581406997 +0200
 | ||||
| @@ -490,12 +490,10 @@ aes256-gcm@openssh.com
 | ||||
|  chacha20-poly1305@openssh.com | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -chacha20-poly1305@openssh.com,
 | ||||
| -aes128-ctr,aes192-ctr,aes256-ctr,
 | ||||
| -aes128-gcm@openssh.com,aes256-gcm@openssh.com
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available ciphers may also be obtained using | ||||
|  .Qq ssh -Q cipher . | ||||
| @@ -700,8 +698,10 @@ gss-nistp256-sha256-,
 | ||||
|  gss-curve25519-sha256- | ||||
|  .Ed | ||||
|  .Pp | ||||
| -The default is
 | ||||
| -.Dq gss-gex-sha1-,gss-group14-sha1- .
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  This option only applies to protocol version 2 connections using GSSAPI. | ||||
|  .It Cm HostbasedAcceptedKeyTypes | ||||
|  Specifies the key types that will be accepted for hostbased authentication | ||||
| @@ -792,17 +792,10 @@ environment variable.
 | ||||
|  .It Cm HostKeyAlgorithms | ||||
|  Specifies the host key algorithms | ||||
|  that the server offers. | ||||
| -The default for this option is:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | ||||
| -ssh-rsa-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available key types may also be obtained using | ||||
|  .Qq ssh -Q key . | ||||
| @@ -960,14 +953,10 @@ ecdh-sha2-nistp384
 | ||||
|  ecdh-sha2-nistp521 | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -curve25519-sha256,curve25519-sha256@libssh.org,
 | ||||
| -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | ||||
| -diffie-hellman-group-exchange-sha256,
 | ||||
| -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
 | ||||
| -diffie-hellman-group14-sha256,diffie-hellman-group14-sha1
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available key exchange algorithms may also be obtained using | ||||
|  .Qq ssh -Q kex . | ||||
| @@ -1090,14 +1079,10 @@ umac-64-etm@openssh.com
 | ||||
|  umac-128-etm@openssh.com | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -umac-64-etm@openssh.com,umac-128-etm@openssh.com,
 | ||||
| -hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
 | ||||
| -hmac-sha1-etm@openssh.com,
 | ||||
| -umac-64@openssh.com,umac-128@openssh.com,
 | ||||
| -hmac-sha2-256,hmac-sha2-512,hmac-sha1
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available MAC algorithms may also be obtained using | ||||
|  .Qq ssh -Q mac . | ||||
| @@ -1455,17 +1440,10 @@ If the specified value begins with a
 | ||||
|  .Sq - | ||||
|  character, then the specified key types (including wildcards) will be removed | ||||
|  from the default set instead of replacing them. | ||||
| -The default for this option is:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | ||||
| -ssh-rsa-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
|  .Pp | ||||
|  The list of available key types may also be obtained using | ||||
|  .Qq ssh -Q key . | ||||
							
								
								
									
										3924
									
								
								SOURCES/openssh-8.0p1-gssapi-keyex.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3924
									
								
								SOURCES/openssh-8.0p1-gssapi-keyex.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										720
									
								
								SOURCES/openssh-8.0p1-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										720
									
								
								SOURCES/openssh-8.0p1-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,720 @@ | ||||
| From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelen <jjelen@redhat.com> | ||||
| Date: Tue, 14 May 2019 10:45:45 +0200 | ||||
| Subject: [PATCH] Use high-level OpenSSL API for signatures | ||||
| 
 | ||||
| ---
 | ||||
|  digest-openssl.c |  16 ++++ | ||||
|  digest.h         |   6 ++ | ||||
|  ssh-dss.c        |  65 ++++++++++------ | ||||
|  ssh-ecdsa.c      |  69 ++++++++++------- | ||||
|  ssh-rsa.c        | 193 +++++++++-------------------------------------- | ||||
|  sshkey.c         |  77 +++++++++++++++++++ | ||||
|  sshkey.h         |   4 + | ||||
|  7 files changed, 221 insertions(+), 209 deletions(-) | ||||
| 
 | ||||
| diff --git a/digest-openssl.c b/digest-openssl.c
 | ||||
| index da7ed72bc..6a21d8adb 100644
 | ||||
| --- a/digest-openssl.c
 | ||||
| +++ b/digest-openssl.c
 | ||||
| @@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
 | ||||
|  	{ -1,			NULL,		0,	NULL }, | ||||
|  }; | ||||
|   | ||||
| +const EVP_MD *
 | ||||
| +ssh_digest_to_md(int digest_type)
 | ||||
| +{
 | ||||
| +	switch (digest_type) {
 | ||||
| +	case SSH_DIGEST_SHA1:
 | ||||
| +		return EVP_sha1();
 | ||||
| +	case SSH_DIGEST_SHA256:
 | ||||
| +		return EVP_sha256();
 | ||||
| +	case SSH_DIGEST_SHA384:
 | ||||
| +		return EVP_sha384();
 | ||||
| +	case SSH_DIGEST_SHA512:
 | ||||
| +		return EVP_sha512();
 | ||||
| +	}
 | ||||
| +	return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static const struct ssh_digest * | ||||
|  ssh_digest_by_alg(int alg) | ||||
|  { | ||||
| diff --git a/digest.h b/digest.h
 | ||||
| index 274574d0e..c7ceeb36f 100644
 | ||||
| --- a/digest.h
 | ||||
| +++ b/digest.h
 | ||||
| @@ -32,6 +32,12 @@
 | ||||
|  struct sshbuf; | ||||
|  struct ssh_digest_ctx; | ||||
|   | ||||
| +#ifdef WITH_OPENSSL
 | ||||
| +#include <openssl/evp.h>
 | ||||
| +/* Converts internal digest representation to the OpenSSL one */
 | ||||
| +const EVP_MD *ssh_digest_to_md(int digest_type);
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  /* Looks up a digest algorithm by name */ | ||||
|  int ssh_digest_alg_by_name(const char *name); | ||||
|   | ||||
| diff --git a/ssh-dss.c b/ssh-dss.c
 | ||||
| index a23c383dc..ea45e7275 100644
 | ||||
| --- 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) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	DSA_SIG *sig = NULL; | ||||
|  	const BIGNUM *sig_r, *sig_s; | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
 | ||||
| -	size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 | ||||
| +	u_char sigblob[SIGBLOB_LEN];
 | ||||
| +	size_t rlen, slen;
 | ||||
| +	int len;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
| +	u_char *sigb = NULL;
 | ||||
| +	const u_char *psig = NULL;
 | ||||
|  	int ret = SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
|  	if (lenp != NULL) | ||||
| @@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	if (key == NULL || key->dsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_DSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	if (dlen == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
|   | ||||
| -	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
 | ||||
| +	    data, datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +	free(sigb);
 | ||||
| +	sigb = NULL;
 | ||||
|   | ||||
|  	DSA_SIG_get0(sig, &sig_r, &sig_s); | ||||
|  	rlen = BN_num_bytes(sig_r); | ||||
| @@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	DSA_SIG_free(sig); | ||||
|  	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) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	DSA_SIG *sig = 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);
 | ||||
| +	u_char *sigblob = NULL;
 | ||||
| +	size_t len, slen;
 | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  	struct sshbuf *b = NULL; | ||||
|  	char *ktype = NULL; | ||||
| +	u_char *sigb = NULL, *psig = NULL;
 | ||||
|   | ||||
|  	if (key == NULL || key->dsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_DSA || | ||||
|  	    signature == NULL || signaturelen == 0) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	if (dlen == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
|   | ||||
|  	/* fetch signature */ | ||||
|  	if ((b = sshbuf_from(signature, signaturelen)) == 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,
 | ||||
| -	    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)) {
 | ||||
| -	case 1:
 | ||||
| -		ret = 0;
 | ||||
| -		break;
 | ||||
| -	case 0:
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +	}
 | ||||
| +	if ((sigb = malloc(slen)) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
| -	default:
 | ||||
| +	}
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
 | ||||
| +	    sigb, slen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +
 | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	DSA_SIG_free(sig); | ||||
|  	BN_clear_free(sig_r); | ||||
|  	BN_clear_free(sig_s); | ||||
| diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
 | ||||
| index 599c7199d..b036796e8 100644
 | ||||
| --- 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) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	ECDSA_SIG *sig = 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;
 | ||||
| +	int len;
 | ||||
|  	struct sshbuf *b = NULL, *bb = NULL; | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
| @@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	    sshkey_type_plain(key->type) != KEY_ECDSA) | ||||
|  		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)
 | ||||
| +	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,
 | ||||
| -	    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);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| -
 | ||||
|  	if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
|  		goto out; | ||||
| @@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	sshbuf_free(b); | ||||
|  	sshbuf_free(bb); | ||||
|  	ECDSA_SIG_free(sig); | ||||
| @@ -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) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	ECDSA_SIG *sig = NULL; | ||||
|  	BIGNUM *sig_r = NULL, *sig_s = NULL; | ||||
| -	int hash_alg;
 | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH];
 | ||||
| -	size_t dlen;
 | ||||
| +	int hash_alg, len;
 | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  	struct sshbuf *b = NULL, *sigbuf = NULL; | ||||
|  	char *ktype = NULL; | ||||
| +	unsigned char *sigb = NULL, *psig = NULL;
 | ||||
|   | ||||
|  	if (key == NULL || key->ecdsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_ECDSA || | ||||
|  	    signature == NULL || signaturelen == 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)
 | ||||
| +	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
 | ||||
|  		return SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
|  	/* fetch signature */ | ||||
| @@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
 | ||||
|  	} | ||||
|  	sig_r = sig_s = NULL; /* transferred */ | ||||
|   | ||||
| -	if (sshbuf_len(sigbuf) != 0) {
 | ||||
| -		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 | ||||
| +	/* Figure out the length */
 | ||||
| +	if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	if ((sigb = malloc(len)) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
 | ||||
| -	case 1:
 | ||||
| -		ret = 0;
 | ||||
| -		break;
 | ||||
| -	case 0:
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +	if (sshbuf_len(sigbuf) != 0) {
 | ||||
| +		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 | ||||
|  		goto out; | ||||
| -	default:
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
 | ||||
| +		ret =  SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| +	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|   | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	sshbuf_free(sigbuf); | ||||
|  	sshbuf_free(b); | ||||
|  	ECDSA_SIG_free(sig); | ||||
| diff --git a/ssh-rsa.c b/ssh-rsa.c
 | ||||
| index 9b14f9a9a..8ef3a6aca 100644
 | ||||
| --- a/ssh-rsa.c
 | ||||
| +++ b/ssh-rsa.c
 | ||||
| @@ -37,7 +37,7 @@
 | ||||
|   | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|   | ||||
| -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) | ||||
| @@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
 | ||||
|  	return -1; | ||||
|  } | ||||
|   | ||||
| -static int
 | ||||
| -rsa_hash_alg_nid(int type)
 | ||||
| -{
 | ||||
| -	switch (type) {
 | ||||
| -	case SSH_DIGEST_SHA1:
 | ||||
| -		return NID_sha1;
 | ||||
| -	case SSH_DIGEST_SHA256:
 | ||||
| -		return NID_sha256;
 | ||||
| -	case SSH_DIGEST_SHA512:
 | ||||
| -		return NID_sha512;
 | ||||
| -	default:
 | ||||
| -		return -1;
 | ||||
| -	}
 | ||||
| -}
 | ||||
| -
 | ||||
|  int | ||||
|  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 BIGNUM *rsa_n;
 | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
 | ||||
| -	size_t slen = 0;
 | ||||
| -	u_int dlen, len;
 | ||||
| -	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
| +	u_char *sig = NULL;
 | ||||
| +	int len, slen = 0;
 | ||||
| +	int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
|   | ||||
|  	if (lenp != NULL) | ||||
| @@ -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); | ||||
| +
 | ||||
|  	if (key == NULL || key->rsa == NULL || hash_alg == -1 || | ||||
|  	    sshkey_type_plain(key->type) != KEY_RSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
 | ||||
| -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| -		return SSH_ERR_KEY_LENGTH;
 | ||||
|  	slen = RSA_size(key->rsa); | ||||
| -	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
 | ||||
| -		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -
 | ||||
| -	/* hash the data */
 | ||||
| -	nid = rsa_hash_alg_nid(hash_alg);
 | ||||
| -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| -		goto out;
 | ||||
| +	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| +		return SSH_ERR_KEY_LENGTH;
 | ||||
|   | ||||
| -	if ((sig = malloc(slen)) == NULL) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
 | ||||
| +	    datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -		goto out;
 | ||||
| -	}
 | ||||
|  	if (len < slen) { | ||||
|  		size_t diff = slen - len; | ||||
|  		memmove(sig + diff, sig, len); | ||||
| @@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +
 | ||||
|  	/* encode signature */ | ||||
|  	if ((b = sshbuf_new()) == NULL) { | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
| @@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
|  	freezero(sig, slen); | ||||
|  	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 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;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
|  	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; | ||||
|   | ||||
| @@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	    sshkey_type_plain(key->type) != KEY_RSA || | ||||
|  	    sig == NULL || siglen == 0) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
 | ||||
| -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| +	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
|  		return SSH_ERR_KEY_LENGTH; | ||||
|   | ||||
|  	if ((b = sshbuf_from(sig, siglen)) == NULL) | ||||
| @@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  		explicit_bzero(sigblob, diff); | ||||
|  		len = modlen; | ||||
|  	} | ||||
| -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
 | ||||
| -		ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| -		goto out;
 | ||||
| +	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|   | ||||
| -	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
 | ||||
| -	    key->rsa);
 | ||||
|   out: | ||||
|  	freezero(sigblob, len); | ||||
|  	free(sigtype); | ||||
| @@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| -/*
 | ||||
| - * See:
 | ||||
| - * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
 | ||||
| - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
 | ||||
| - */
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
 | ||||
| - *	oiw(14) secsig(3) algorithms(2) 26 }
 | ||||
| - */
 | ||||
| -static const u_char id_sha1[] = {
 | ||||
| -	0x30, 0x21, /* type Sequence, length 0x21 (33) */
 | ||||
| -	0x30, 0x09, /* type Sequence, length 0x09 */
 | ||||
| -	0x06, 0x05, /* type OID, length 0x05 */
 | ||||
| -	0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x14  /* Octet string, length 0x14 (20), followed by sha1 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
 | ||||
| - * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
 | ||||
| - *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
 | ||||
| - *      id-sha256(1) }
 | ||||
| - */
 | ||||
| -static const u_char id_sha256[] = {
 | ||||
| -	0x30, 0x31, /* type Sequence, length 0x31 (49) */
 | ||||
| -	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
 | ||||
| -	0x06, 0x09, /* type OID, length 0x09 */
 | ||||
| -	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x20  /* Octet string, length 0x20 (32), followed by sha256 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
 | ||||
| - * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
 | ||||
| - *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
 | ||||
| - *      id-sha256(3) }
 | ||||
| - */
 | ||||
| -static const u_char id_sha512[] = {
 | ||||
| -	0x30, 0x51, /* type Sequence, length 0x51 (81) */
 | ||||
| -	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
 | ||||
| -	0x06, 0x09, /* type OID, length 0x09 */
 | ||||
| -	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x40  /* Octet string, length 0x40 (64), followed by sha512 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
|  static int | ||||
| -rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
 | ||||
| +openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
 | ||||
| +    u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
 | ||||
|  { | ||||
| -	switch (hash_alg) {
 | ||||
| -	case SSH_DIGEST_SHA1:
 | ||||
| -		*oidp = id_sha1;
 | ||||
| -		*oidlenp = sizeof(id_sha1);
 | ||||
| -		break;
 | ||||
| -	case SSH_DIGEST_SHA256:
 | ||||
| -		*oidp = id_sha256;
 | ||||
| -		*oidlenp = sizeof(id_sha256);
 | ||||
| -		break;
 | ||||
| -	case SSH_DIGEST_SHA512:
 | ||||
| -		*oidp = id_sha512;
 | ||||
| -		*oidlenp = sizeof(id_sha512);
 | ||||
| -		break;
 | ||||
| -	default:
 | ||||
| -		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -	}
 | ||||
| -	return 0;
 | ||||
| -}
 | ||||
| +	size_t rsasize = 0;
 | ||||
| +	const RSA *rsa;
 | ||||
| +	int ret;
 | ||||
|   | ||||
| -static int
 | ||||
| -openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
 | ||||
| -    u_char *sigbuf, size_t siglen, RSA *rsa)
 | ||||
| -{
 | ||||
| -	size_t rsasize = 0, oidlen = 0, hlen = 0;
 | ||||
| -	int ret, len, oidmatch, hashmatch;
 | ||||
| -	const u_char *oid = NULL;
 | ||||
| -	u_char *decrypted = NULL;
 | ||||
| -
 | ||||
| -	if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
 | ||||
| -		return ret;
 | ||||
| -	ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| -	hlen = ssh_digest_bytes(hash_alg);
 | ||||
| -	if (hashlen != hlen) {
 | ||||
| -		ret = SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| +	rsa = EVP_PKEY_get0_RSA(pkey);
 | ||||
|  	rsasize = RSA_size(rsa); | ||||
|  	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || | ||||
|  	    siglen == 0 || siglen > rsasize) { | ||||
|  		ret = SSH_ERR_INVALID_ARGUMENT; | ||||
|  		goto done; | ||||
|  	} | ||||
| -	if ((decrypted = malloc(rsasize)) == NULL) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
 | ||||
| -	    RSA_PKCS1_PADDING)) < 0) {
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	if (len < 0 || (size_t)len != hlen + oidlen) {
 | ||||
| -		ret = SSH_ERR_INVALID_FORMAT;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
 | ||||
| -	hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
 | ||||
| -	if (!oidmatch || !hashmatch) {
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	ret = 0;
 | ||||
| +
 | ||||
| +	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
 | ||||
| +	    sigbuf, siglen);
 | ||||
| +
 | ||||
|  done: | ||||
| -	freezero(decrypted, rsasize);
 | ||||
|  	return ret; | ||||
|  } | ||||
|  #endif /* WITH_OPENSSL */ | ||||
| diff --git a/sshkey.c b/sshkey.c
 | ||||
| index ad1957762..b95ed0b10 100644
 | ||||
| --- a/sshkey.c
 | ||||
| +++ b/sshkey.c
 | ||||
| @@ -358,6 +358,83 @@ sshkey_type_plain(int type)
 | ||||
|  } | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
| +int
 | ||||
| +sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
 | ||||
| +    int *lenp, const u_char *data, size_t datalen)
 | ||||
| +{
 | ||||
| +	EVP_MD_CTX *ctx = NULL;
 | ||||
| +	u_char *sig = NULL;
 | ||||
| +	int ret, slen, len;
 | ||||
| +
 | ||||
| +	if (sigp == NULL || lenp == NULL) {
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	slen = EVP_PKEY_size(pkey);
 | ||||
| +	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +
 | ||||
| +	len = slen;
 | ||||
| +	if ((sig = malloc(slen)) == NULL) {
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((ctx = EVP_MD_CTX_new()) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto error;
 | ||||
| +	}
 | ||||
| +	if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| +	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
 | ||||
| +	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto error;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	*sigp = sig;
 | ||||
| +	*lenp = len;
 | ||||
| +	/* Now owned by the caller */
 | ||||
| +	sig = NULL;
 | ||||
| +	ret = 0;
 | ||||
| +
 | ||||
| +error:
 | ||||
| +	EVP_MD_CTX_free(ctx);
 | ||||
| +	free(sig);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
 | ||||
| +    size_t datalen, u_char *sigbuf, int siglen)
 | ||||
| +{
 | ||||
| +	EVP_MD_CTX *ctx = NULL;
 | ||||
| +	int ret;
 | ||||
| +
 | ||||
| +	if ((ctx = EVP_MD_CTX_new()) == NULL) {
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	}
 | ||||
| +	if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| +	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto done;
 | ||||
| +	}
 | ||||
| +	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
 | ||||
| +	switch (ret) {
 | ||||
| +	case 1:
 | ||||
| +		ret = 0;
 | ||||
| +		break;
 | ||||
| +	case 0:
 | ||||
| +		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +		break;
 | ||||
| +	default:
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		break;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +done:
 | ||||
| +	EVP_MD_CTX_free(ctx);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* XXX: these are really begging for a table-driven approach */ | ||||
|  int | ||||
|  sshkey_curve_name_to_nid(const char *name) | ||||
| diff --git a/sshkey.h b/sshkey.h
 | ||||
| index a91e60436..270901a87 100644
 | ||||
| --- a/sshkey.h
 | ||||
| +++ b/sshkey.h
 | ||||
| @@ -179,6 +179,10 @@ const char	*sshkey_ssh_name(const struct sshkey *);
 | ||||
|  const char	*sshkey_ssh_name_plain(const struct sshkey *); | ||||
|  int		 sshkey_names_valid2(const char *, int); | ||||
|  char		*sshkey_alg_list(int, int, int, char); | ||||
| +int		 sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
 | ||||
| +    int *, const u_char *, size_t);
 | ||||
| +int		 sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
 | ||||
| +    size_t, u_char *, int);
 | ||||
|   | ||||
|  int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **); | ||||
|  int	 sshkey_fromb(struct sshbuf *, struct sshkey **); | ||||
| 
 | ||||
							
								
								
									
										137
									
								
								SOURCES/openssh-8.0p1-openssl-kdf.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								SOURCES/openssh-8.0p1-openssl-kdf.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | ||||
| commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a | ||||
| Author: Jakub Jelen <jjelen@redhat.com> | ||||
| Date:   Tue Apr 16 15:35:18 2019 +0200 | ||||
| 
 | ||||
|     Use the new OpenSSL KDF | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 2a455e4e..e01c3d43 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then
 | ||||
|  		HMAC_CTX_init \ | ||||
|  		RSA_generate_key_ex \ | ||||
|  		RSA_get_default_method \ | ||||
| +		EVP_KDF_CTX_new_id \
 | ||||
|  	]) | ||||
|   | ||||
|  	# OpenSSL_add_all_algorithms may be a macro. | ||||
| diff --git a/kex.c b/kex.c
 | ||||
| index b6f041f4..1fbce2bb 100644
 | ||||
| --- a/kex.c
 | ||||
| +++ b/kex.c
 | ||||
| @@ -38,6 +38,9 @@
 | ||||
|  #ifdef WITH_OPENSSL | ||||
|  #include <openssl/crypto.h> | ||||
|  #include <openssl/dh.h> | ||||
| +# ifdef HAVE_EVP_KDF_CTX_NEW_ID
 | ||||
| +# include <openssl/kdf.h>
 | ||||
| +# endif
 | ||||
|  #endif | ||||
|   | ||||
|  #include "ssh.h" | ||||
| @@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
 | ||||
|  	return r; | ||||
|  } | ||||
|   | ||||
| +#ifdef HAVE_EVP_KDF_CTX_NEW_ID
 | ||||
| +static const EVP_MD *
 | ||||
| +digest_to_md(int digest_type)
 | ||||
| +{
 | ||||
| +	switch (digest_type) {
 | ||||
| +	case SSH_DIGEST_SHA1:
 | ||||
| +		return EVP_sha1();
 | ||||
| +	case SSH_DIGEST_SHA256:
 | ||||
| +		return EVP_sha256();
 | ||||
| +	case SSH_DIGEST_SHA384:
 | ||||
| +		return EVP_sha384();
 | ||||
| +	case SSH_DIGEST_SHA512:
 | ||||
| +		return EVP_sha512();
 | ||||
| +	}
 | ||||
| +	return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
 | ||||
| +    const struct sshbuf *shared_secret, u_char **keyp)
 | ||||
| +{
 | ||||
| +	struct kex *kex = ssh->kex;
 | ||||
| +	EVP_KDF_CTX *ctx = NULL;
 | ||||
| +	u_char *key = NULL;
 | ||||
| +	int r, key_len;
 | ||||
| +
 | ||||
| +	if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	key_len = ROUNDUP(need, key_len);
 | ||||
| +	if ((key = calloc(1, key_len)) == NULL) {
 | ||||
| +		r = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
 | ||||
| +	if (!ctx) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
 | ||||
| +	    sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
 | ||||
| +	    kex->session_id, kex->session_id_len);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_derive(ctx, key, key_len);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +#ifdef DEBUG_KEX
 | ||||
| +	fprintf(stderr, "key '%c'== ", id);
 | ||||
| +	dump_digest("key", key, key_len);
 | ||||
| +#endif
 | ||||
| +	*keyp = key;
 | ||||
| +	key = NULL;
 | ||||
| +	r = 0;
 | ||||
| +
 | ||||
| +out:
 | ||||
| +	free (key);
 | ||||
| +	EVP_KDF_CTX_free(ctx);
 | ||||
| +	if (r < 0) {
 | ||||
| +		return r;
 | ||||
| +	}
 | ||||
| +	return 0;
 | ||||
| +}
 | ||||
| +#else
 | ||||
|  static int | ||||
|  derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, | ||||
|      const struct sshbuf *shared_secret, u_char **keyp) | ||||
| @@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
 | ||||
|  	ssh_digest_free(hashctx); | ||||
|  	return r; | ||||
|  } | ||||
| +#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
 | ||||
|   | ||||
|  #define NKEYS	6 | ||||
|  int | ||||
| 
 | ||||
							
								
								
									
										324
									
								
								SOURCES/openssh-8.0p1-openssl-pem.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								SOURCES/openssh-8.0p1-openssl-pem.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,324 @@ | ||||
| From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001 | ||||
| From: "djm@openbsd.org" <djm@openbsd.org> | ||||
| Date: Mon, 15 Jul 2019 13:16:29 +0000 | ||||
| Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of | ||||
| 
 | ||||
| private keys, enabled via "ssh-keygen -m PKCS8" on operations that save | ||||
| private keys to disk. | ||||
| 
 | ||||
| The OpenSSH native key format remains the default, but PKCS8 is a | ||||
| superior format to PEM if interoperability with non-OpenSSH software | ||||
| is required, as it may use a less terrible KDF (IIRC PEM uses a single | ||||
| round of MD5 as a KDF). | ||||
| 
 | ||||
| adapted from patch by Jakub Jelen via bz3013; ok markus | ||||
| 
 | ||||
| OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1 | ||||
| ---
 | ||||
|  authfile.c   |  6 ++-- | ||||
|  ssh-keygen.1 |  9 +++--- | ||||
|  ssh-keygen.c | 25 +++++++++-------- | ||||
|  sshkey.c     | 78 +++++++++++++++++++++++++++++++++++++--------------- | ||||
|  sshkey.h     | 11 ++++++-- | ||||
|  5 files changed, 87 insertions(+), 42 deletions(-) | ||||
| 
 | ||||
| diff --git a/authfile.c b/authfile.c
 | ||||
| index 2166c1689..851c1a8a1 100644
 | ||||
| --- a/authfile.c
 | ||||
| +++ b/authfile.c
 | ||||
| @@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
 | ||||
|  int | ||||
|  sshkey_save_private(struct sshkey *key, const char *filename, | ||||
|      const char *passphrase, const char *comment, | ||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds)
 | ||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds)
 | ||||
|  { | ||||
|  	struct sshbuf *keyblob = NULL; | ||||
|  	int r; | ||||
| @@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
 | ||||
|  	if ((keyblob = sshbuf_new()) == NULL) | ||||
|  		return SSH_ERR_ALLOC_FAIL; | ||||
|  	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, | ||||
| -	    force_new_format, new_format_cipher, new_format_rounds)) != 0)
 | ||||
| +	    format, openssh_format_cipher, openssh_format_rounds)) != 0)
 | ||||
|  		goto out; | ||||
|  	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) | ||||
|  		goto out; | ||||
| diff --git a/ssh-keygen.1 b/ssh-keygen.1
 | ||||
| index f42127c60..8184a1797 100644
 | ||||
| --- a/ssh-keygen.1
 | ||||
| +++ b/ssh-keygen.1
 | ||||
| @@ -419,11 +419,12 @@ The supported key formats are:
 | ||||
|  .Dq RFC4716 | ||||
|  (RFC 4716/SSH2 public or private key), | ||||
|  .Dq PKCS8 | ||||
| -(PEM PKCS8 public key)
 | ||||
| +(PKCS8 public or private key)
 | ||||
|  or | ||||
|  .Dq PEM | ||||
|  (PEM public key). | ||||
| -The default conversion format is
 | ||||
| +By default OpenSSH will write newly-generated private keys in its own
 | ||||
| +format, but when converting public keys for export the default format is
 | ||||
|  .Dq RFC4716 . | ||||
|  Setting a format of | ||||
|  .Dq PEM | ||||
| diff --git a/ssh-keygen.c b/ssh-keygen.c
 | ||||
| index b019a02ff..5dcad1f61 100644
 | ||||
| --- a/ssh-keygen.c
 | ||||
| +++ b/ssh-keygen.c
 | ||||
| @@ -147,11 +147,11 @@ static char *key_type_name = NULL;
 | ||||
|  /* Load key from this PKCS#11 provider */ | ||||
|  static char *pkcs11provider = NULL; | ||||
|   | ||||
| -/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
 | ||||
| -static int use_new_format = 1;
 | ||||
| +/* Format for writing private keys */
 | ||||
| +static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
 | ||||
|   | ||||
|  /* Cipher for new-format private keys */ | ||||
| -static char *new_format_cipher = NULL;
 | ||||
| +static char *openssh_format_cipher = NULL;
 | ||||
|   | ||||
|  /* | ||||
|   * Number of KDF rounds to derive new format keys / | ||||
| @@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw)
 | ||||
|  		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, | ||||
|  		    hostname); | ||||
|  		if ((r = sshkey_save_private(private, prv_tmp, "", | ||||
| -		    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 | ||||
| +		    comment, private_key_format, openssh_format_cipher,
 | ||||
| +		    rounds)) != 0) {
 | ||||
|  			error("Saving key \"%s\" failed: %s", | ||||
|  			    prv_tmp, ssh_err(r)); | ||||
|  			goto failnext; | ||||
| @@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw)
 | ||||
|   | ||||
|  	/* Save the file using the new passphrase. */ | ||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase1, | ||||
| -	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 | ||||
| +	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
 | ||||
|  		error("Saving key \"%s\" failed: %s.", | ||||
|  		    identity_file, ssh_err(r)); | ||||
|  		explicit_bzero(passphrase1, strlen(passphrase1)); | ||||
| @@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
 | ||||
|  	} | ||||
|   | ||||
|  	if (private->type != KEY_ED25519 && private->type != KEY_XMSS && | ||||
| -	    !use_new_format) {
 | ||||
| +	    private_key_format != SSHKEY_PRIVATE_OPENSSH) {
 | ||||
|  		error("Comments are only supported for keys stored in " | ||||
|  		    "the new format (-o)."); | ||||
|  		explicit_bzero(passphrase, strlen(passphrase)); | ||||
| @@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
 | ||||
|   | ||||
|  	/* Save the file using the new passphrase. */ | ||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase, | ||||
| -	    new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
 | ||||
| +	    new_comment, private_key_format, openssh_format_cipher,
 | ||||
| +	    rounds)) != 0) {
 | ||||
|  		error("Saving key \"%s\" failed: %s", | ||||
|  		    identity_file, ssh_err(r)); | ||||
|  		explicit_bzero(passphrase, strlen(passphrase)); | ||||
| @@ -2525,11 +2527,12 @@ main(int argc, char **argv)
 | ||||
|  			} | ||||
|  			if (strcasecmp(optarg, "PKCS8") == 0) { | ||||
|  				convert_format = FMT_PKCS8; | ||||
| +				private_key_format = SSHKEY_PRIVATE_PKCS8;
 | ||||
|  				break; | ||||
|  			} | ||||
|  			if (strcasecmp(optarg, "PEM") == 0) { | ||||
|  				convert_format = FMT_PEM; | ||||
| -				use_new_format = 0;
 | ||||
| +				private_key_format = SSHKEY_PRIVATE_PEM;
 | ||||
|  				break; | ||||
|  			} | ||||
|  			fatal("Unsupported conversion format \"%s\"", optarg); | ||||
| @@ -2567,7 +2570,7 @@ main(int argc, char **argv)
 | ||||
|  			add_cert_option(optarg); | ||||
|  			break; | ||||
|  		case 'Z': | ||||
| -			new_format_cipher = optarg;
 | ||||
| +			openssh_format_cipher = optarg;
 | ||||
|  			break; | ||||
|  		case 'C': | ||||
|  			identity_comment = optarg; | ||||
| @@ -2912,7 +2915,7 @@ main(int argc, char **argv)
 | ||||
|   | ||||
|  	/* Save the key with the given passphrase and comment. */ | ||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase1, | ||||
| -	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 | ||||
| +	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
 | ||||
|  		error("Saving key \"%s\" failed: %s", | ||||
|  		    identity_file, ssh_err(r)); | ||||
|  		explicit_bzero(passphrase1, strlen(passphrase1)); | ||||
| diff --git a/sshkey.c b/sshkey.c
 | ||||
| index 6b5ff0485..a0cea9257 100644
 | ||||
| --- a/sshkey.c
 | ||||
| +++ b/sshkey.c
 | ||||
| @@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 | ||||
|   | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
| -/* convert SSH v2 key in OpenSSL PEM format */
 | ||||
| +/* convert SSH v2 key to PEM or PKCS#8 format */
 | ||||
|  static int | ||||
| -sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
 | ||||
| -    const char *_passphrase, const char *comment)
 | ||||
| +sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob,
 | ||||
| +    int format, const char *_passphrase, const char *comment)
 | ||||
|  { | ||||
|  	int success, r; | ||||
|  	int blen, len = strlen(_passphrase); | ||||
| @@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 | ||||
|  	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; | ||||
|  	char *bptr; | ||||
|  	BIO *bio = NULL; | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|   | ||||
|  	if (len > 0 && len <= 4) | ||||
|  		return SSH_ERR_PASSPHRASE_TOO_SHORT; | ||||
| -	if ((bio = BIO_new(BIO_s_mem())) == NULL)
 | ||||
| -		return SSH_ERR_ALLOC_FAIL;
 | ||||
| + 	if ((bio = BIO_new(BIO_s_mem())) == NULL) {
 | ||||
| +		r = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| + 	}
 | ||||
| +
 | ||||
| +	if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
 | ||||
| +		r = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| + 	}
 | ||||
|   | ||||
|  	switch (key->type) { | ||||
|  	case KEY_DSA: | ||||
| -		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
 | ||||
| -		    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 | ||||
| +			success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
 | ||||
| +			    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		} else {
 | ||||
| +			success = EVP_PKEY_set1_DSA(pkey, key->dsa);
 | ||||
| +		}
 | ||||
|  		break; | ||||
|  #ifdef OPENSSL_HAS_ECC | ||||
|  	case KEY_ECDSA: | ||||
| -		success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
 | ||||
| -		    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 | ||||
| +			success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
 | ||||
| +			    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		} else {
 | ||||
| +			success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
 | ||||
| +		}
 | ||||
|  		break; | ||||
|  #endif | ||||
|  	case KEY_RSA: | ||||
| -		success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
 | ||||
| -		    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 | ||||
| +			success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
 | ||||
| +			    cipher, passphrase, len, NULL, NULL);
 | ||||
| +		} else {
 | ||||
| +			success = EVP_PKEY_set1_RSA(pkey, key->rsa);
 | ||||
| +		}
 | ||||
|  		break; | ||||
|  	default: | ||||
|  		success = 0; | ||||
| @@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 | ||||
|  		r = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +	if (format == SSHKEY_PRIVATE_PKCS8) {
 | ||||
| +		if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
 | ||||
| +		    passphrase, len, NULL, NULL)) == 0) {
 | ||||
| +			r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
|  	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { | ||||
|  		r = SSH_ERR_INTERNAL_ERROR; | ||||
|  		goto out; | ||||
| @@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 | ||||
|  		goto out; | ||||
|  	r = 0; | ||||
|   out: | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|  	BIO_free(bio); | ||||
|  	return r; | ||||
|  } | ||||
| @@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 | ||||
|  int | ||||
|  sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, | ||||
|      const char *passphrase, const char *comment, | ||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds)
 | ||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds)
 | ||||
|  { | ||||
|  	switch (key->type) { | ||||
|  #ifdef WITH_OPENSSL | ||||
|  	case KEY_DSA: | ||||
|  	case KEY_ECDSA: | ||||
|  	case KEY_RSA: | ||||
| -		if (force_new_format) {
 | ||||
| -			return sshkey_private_to_blob2(key, blob, passphrase,
 | ||||
| -			    comment, new_format_cipher, new_format_rounds);
 | ||||
| -		}
 | ||||
| -		return sshkey_private_pem_to_blob(key, blob,
 | ||||
| -		    passphrase, comment);
 | ||||
| +		break; /* see below */
 | ||||
|  #endif /* WITH_OPENSSL */ | ||||
|  	case KEY_ED25519: | ||||
|  #ifdef WITH_XMSS | ||||
|  	case KEY_XMSS: | ||||
|  #endif /* WITH_XMSS */ | ||||
|  		return sshkey_private_to_blob2(key, blob, passphrase, | ||||
| -		    comment, new_format_cipher, new_format_rounds);
 | ||||
| +		    comment, openssh_format_cipher, openssh_format_rounds);
 | ||||
|  	default: | ||||
|  		return SSH_ERR_KEY_TYPE_UNKNOWN; | ||||
|  	} | ||||
| +
 | ||||
| +#ifdef WITH_OPENSSL
 | ||||
| +	switch (format) {
 | ||||
| +	case SSHKEY_PRIVATE_OPENSSH:
 | ||||
| +		return sshkey_private_to_blob2(key, blob, passphrase,
 | ||||
| +		    comment, openssh_format_cipher, openssh_format_rounds);
 | ||||
| +	case SSHKEY_PRIVATE_PEM:
 | ||||
| +	case SSHKEY_PRIVATE_PKCS8:
 | ||||
| +		return sshkey_private_to_blob_pem_pkcs8(key, blob,
 | ||||
| +		    format, passphrase, comment);
 | ||||
| +	default:
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	}
 | ||||
| +#endif /* WITH_OPENSSL */
 | ||||
|  } | ||||
|   | ||||
|   | ||||
| diff --git a/sshkey.h b/sshkey.h
 | ||||
| index 41d159a1b..d30a69cc9 100644
 | ||||
| --- a/sshkey.h
 | ||||
| +++ b/sshkey.h
 | ||||
| @@ -88,6 +88,13 @@ enum sshkey_serialize_rep {
 | ||||
|  	SSHKEY_SERIALIZE_INFO = 254, | ||||
|  }; | ||||
|   | ||||
| +/* Private key disk formats */
 | ||||
| +enum sshkey_private_format {
 | ||||
| +	SSHKEY_PRIVATE_OPENSSH = 0,
 | ||||
| +	SSHKEY_PRIVATE_PEM = 1,
 | ||||
| +	SSHKEY_PRIVATE_PKCS8 = 2,
 | ||||
| +};
 | ||||
| +
 | ||||
|  /* key is stored in external hardware */ | ||||
|  #define SSHKEY_FLAG_EXT		0x0001 | ||||
|   | ||||
| @@ -221,7 +228,7 @@ int	sshkey_private_deserialize(struct sshbuf *buf,  struct sshkey **keyp);
 | ||||
|  /* private key file format parsing and serialisation */ | ||||
|  int	sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, | ||||
|      const char *passphrase, const char *comment, | ||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds);
 | ||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds);
 | ||||
|  int	sshkey_parse_private_fileblob(struct sshbuf *buffer, | ||||
|      const char *passphrase, struct sshkey **keyp, char **commentp); | ||||
|  int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, | ||||
| 
 | ||||
							
								
								
									
										3135
									
								
								SOURCES/openssh-8.0p1-pkcs11-uri.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3135
									
								
								SOURCES/openssh-8.0p1-pkcs11-uri.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										61
									
								
								SOURCES/openssh-8.0p1-scp-tests.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								SOURCES/openssh-8.0p1-scp-tests.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh
 | ||||
| index 59f1ff63..dd48a482 100644
 | ||||
| --- a/regress/scp-ssh-wrapper.sh
 | ||||
| +++ b/regress/scp-ssh-wrapper.sh
 | ||||
| @@ -51,6 +51,18 @@ badserver_4)
 | ||||
|  	echo "C755 2 file" | ||||
|  	echo "X" | ||||
|  	;; | ||||
| +badserver_5)
 | ||||
| +	echo "D0555 0 "
 | ||||
| +	echo "X"
 | ||||
| +	;;
 | ||||
| +badserver_6)
 | ||||
| +	echo "D0555 0 ."
 | ||||
| +	echo "X"
 | ||||
| +	;;
 | ||||
| +badserver_7)
 | ||||
| +	echo "C0755 2 extrafile"
 | ||||
| +	echo "X"
 | ||||
| +	;;
 | ||||
|  *) | ||||
|  	set -- $arg | ||||
|  	shift | ||||
| diff --git a/regress/scp.sh b/regress/scp.sh
 | ||||
| index 57cc7706..104c89e1 100644
 | ||||
| --- a/regress/scp.sh
 | ||||
| +++ b/regress/scp.sh
 | ||||
| @@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp
 | ||||
|  scpclean() { | ||||
|  	rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} | ||||
|  	mkdir ${DIR} ${DIR2} | ||||
| +	chmod 755 ${DIR} ${DIR2}
 | ||||
|  } | ||||
|   | ||||
|  verbose "$tid: simple copy local file to local file" | ||||
| @@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then
 | ||||
|  	$SUDO rm ${DIR2}/copy | ||||
|  fi | ||||
|   | ||||
| -for i in 0 1 2 3 4; do
 | ||||
| +for i in 0 1 2 3 4 5 6 7; do
 | ||||
|  	verbose "$tid: disallow bad server #$i" | ||||
|  	SCPTESTMODE=badserver_$i | ||||
|  	export DIR SCPTESTMODE | ||||
| @@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do
 | ||||
|  	scpclean | ||||
|  	$SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null | ||||
|  	[ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" | ||||
| +
 | ||||
| +	scpclean
 | ||||
| +	$SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
 | ||||
| +	[ ! -w ${DIR2} ] && fail "allows target root attribute change"
 | ||||
| +
 | ||||
| +	scpclean
 | ||||
| +	$SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
 | ||||
| +	[ -e ${DIR2}/extrafile ] && fail "allows extranous object creation"
 | ||||
| +	rm -f ${DIR2}/extrafile
 | ||||
|  done | ||||
|   | ||||
|  verbose "$tid: detect non-directory target" | ||||
| 
 | ||||
							
								
								
									
										14
									
								
								SOURCES/openssh-8.0p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								SOURCES/openssh-8.0p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| -----BEGIN PGP SIGNATURE----- | ||||
| 
 | ||||
| iQHDBAABCgAdFiEEWcIRjtIG2SfmZ+vj0+X1a22SDTAFAly3ro8ACgkQ0+X1a22S | ||||
| DTCAiAx/W9XHoDs5NijyNIP43W2nFYuf6HG1duoLjdJ8rnsC3e90gx8h5RpUUh24 | ||||
| JDACoUFnbJsNgiQBaYpO7bOnf3Vw5Oui1gPeKnQ76KQsXDwD/N/0wLUf55+XdNJ6 | ||||
| tcgm6/x1W4b8bWje5bcS3qhxv6t/hSL/OxusA8zoNmnTD5XMg6QtJ0Rp9ZHPriCJ | ||||
| C4eCPdHfmyHCr1IATMX9+n5CO5JUPexaDjQug7k/Z1XA/UlwVfRRs1JMpviBodC+ | ||||
| ZUOuk9tH11RKSBcUeR3Ef4iaR3FchryyyBZUZdYBkmDrnHrYpUK5ifdHT+ZXdzPl | ||||
| laX03Kz094LqrP6L3lafk6b1PKOVjKwx1vM5fhnv+pfx4dmao9BwZMuIq6Fa5uMX | ||||
| w2oHGhlIDmeT66Yny5d0APn2wCewyYUGPanSZY/HolHAPs+doOBgI361kMAR9J3e | ||||
| Ii3VKhIdE8i4K3fC19uDkf7xL8UVvRVXjgM7i+GNndh1ou/vDYxmEAsW9IR/D3XC | ||||
| HM/jMdq+UewAiRG46aI5rsi/A8J8/A== | ||||
| =YtoH | ||||
| -----END PGP SIGNATURE----- | ||||
| @ -65,10 +65,10 @@ | ||||
| %endif | ||||
| 
 | ||||
| # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 | ||||
| %global openssh_ver 7.8p1 | ||||
| %global openssh_rel 4 | ||||
| %global openssh_ver 8.0p1 | ||||
| %global openssh_rel 3 | ||||
| %global pam_ssh_agent_ver 0.10.3 | ||||
| %global pam_ssh_agent_rel 5 | ||||
| %global pam_ssh_agent_rel 7 | ||||
| 
 | ||||
| Summary: An open source implementation of SSH protocol version 2 | ||||
| Name: openssh | ||||
| @ -92,16 +92,8 @@ Source13: sshd-keygen | ||||
| Source14: sshd.tmpfiles | ||||
| Source15: sshd-keygen.target | ||||
| 
 | ||||
| # Internal debug | ||||
| Patch0: openssh-5.9p1-wIm.patch | ||||
| 
 | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 | ||||
| Patch100: openssh-6.7p1-coverity.patch | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=1894 | ||||
| #https://bugzilla.redhat.com/show_bug.cgi?id=735889 | ||||
| #Patch102: openssh-5.8p1-getaddrinfo.patch | ||||
| # OpenSSL 1.1.0 compatibility | ||||
| Patch104: openssh-7.3p1-openssl-1.1.0.patch | ||||
| 
 | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 | ||||
| @ -155,8 +147,6 @@ Patch702: openssh-5.1p1-askpass-progress.patch | ||||
| Patch703: openssh-4.3p2-askpass-grab-info.patch | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) | ||||
| Patch707: openssh-7.7p1-redhat.patch | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX) | ||||
| Patch709: openssh-6.2p1-vendor.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 | ||||
| @ -166,29 +156,21 @@ Patch713: openssh-6.6p1-ctr-cavstest.patch | ||||
| # add SSH KDF CAVS test driver | ||||
| Patch714: openssh-6.7p1-kdf-cavs.patch | ||||
| 
 | ||||
| 
 | ||||
| #http://www.sxw.org.uk/computing/patches/openssh.html | ||||
| #changed cache storage type - #848228 | ||||
| Patch800: openssh-7.8p1-gsskex.patch | ||||
| # GSSAPI Key Exchange (RFC 4462 + draft-ietf-curdle-gss-keyex-sha2-08) | ||||
| # from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master | ||||
| Patch800: openssh-8.0p1-gssapi-keyex.patch | ||||
| #http://www.mail-archive.com/kerberos@mit.edu/msg17591.html | ||||
| Patch801: openssh-6.6p1-force_krb.patch | ||||
| # add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843) | ||||
| # CVE-2014-9278 | ||||
| Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch | ||||
| # Documentation about GSSAPI | ||||
| # from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655 | ||||
| Patch803: openssh-7.1p1-gssapi-documentation.patch | ||||
| # Improve ccache handling in openssh (#991186, #1199363, #1566494) | ||||
| # https://bugzilla.mindrot.org/show_bug.cgi?id=2775 | ||||
| Patch804: openssh-7.7p1-gssapi-new-unique.patch | ||||
| # Respect k5login_directory option in krk5.conf (#1328243) | ||||
| Patch805: openssh-7.2p2-k5login_directory.patch | ||||
| # Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02 | ||||
| Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch | ||||
| # Do not break when using AuthenticationMethods with gssapi-keyex auth method (#1625366) | ||||
| Patch808: openssh-7.9p1-gsskex-method.patch | ||||
| 
 | ||||
| Patch900: openssh-6.1p1-gssapi-canohost.patch | ||||
| 
 | ||||
| #https://bugzilla.mindrot.org/show_bug.cgi?id=1780 | ||||
| Patch901: openssh-6.6p1-kuserok.patch | ||||
| # Use tty allocation for a remote scp (#985650) | ||||
| @ -199,16 +181,12 @@ Patch916: openssh-6.6.1p1-selinux-contexts.patch | ||||
| Patch918: openssh-6.6.1p1-log-in-chroot.patch | ||||
| # scp file into non-existing directory (#1142223) | ||||
| Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch | ||||
| # Config parser shouldn't accept ip/port syntax (#1130733) | ||||
| Patch920: openssh-7.8p1-ip-port-config-parser.patch | ||||
| # apply upstream patch and make sshd -T more consistent (#1187521) | ||||
| Patch922: openssh-6.8p1-sshdT-output.patch | ||||
| # Add sftp option to force mode of created files (#1191055) | ||||
| Patch926: openssh-6.7p1-sftp-force-permission.patch | ||||
| # Restore compatible default (#89216) | ||||
| Patch929: openssh-6.9p1-permit-root-login.patch | ||||
| # Add GSSAPIKexAlgorithms option for server and client application | ||||
| Patch932: openssh-7.0p1-gssKexAlgorithms.patch | ||||
| # make s390 use /dev/ crypto devices -- ignore closefrom | ||||
| Patch939: openssh-7.2p2-s390-closefrom.patch | ||||
| # Move MAX_DISPLAYS to a configuration option (#1341302) | ||||
| @ -220,14 +198,24 @@ Patch949: openssh-7.6p1-cleanup-selinux.patch | ||||
| # Sandbox adjustments for s390 and audit | ||||
| Patch950: openssh-7.5p1-sandbox.patch | ||||
| # PKCS#11 URIs (upstream #2817, 2nd iteration) | ||||
| Patch951: openssh-7.6p1-pkcs11-uri.patch | ||||
| # PKCS#11 ECDSA keys (upstream #2474, 8th iteration) | ||||
| Patch952: openssh-7.6p1-pkcs11-ecdsa.patch | ||||
| Patch951: openssh-8.0p1-pkcs11-uri.patch | ||||
| # Unbreak scp between two IPv6 hosts (#1620333) | ||||
| Patch953: openssh-7.8p1-scp-ipv6.patch | ||||
| # Allow to disable RSA signatures with SHA-1 in server | ||||
| # https://bugzilla.mindrot.org/show_bug.cgi?id=2746 | ||||
| Patch954: openssh-7.9p1-disable-sha1.patch | ||||
| # ssh-copy-id is unmaintained: Aggreagete patches | ||||
| #  - do not return 0 if the write fails (full disk) | ||||
| #  - shellcheck reports (upstream #2902) | ||||
| Patch958: openssh-7.9p1-ssh-copy-id.patch | ||||
| # Verify the SCP vulnerabilities are fixed in the package testsuite | ||||
| # https://bugzilla.mindrot.org/show_bug.cgi?id=3007 | ||||
| Patch961: openssh-8.0p1-scp-tests.patch | ||||
| # Mention crypto-policies in manual pages (#1668325) | ||||
| Patch962: openssh-8.0p1-crypto-policies.patch | ||||
| # Use OpenSSL high-level API to produce and verify signatures (#1707485) | ||||
| Patch963: openssh-8.0p1-openssl-evp.patch | ||||
| # Use OpenSSL KDF (#1631761) | ||||
| Patch964: openssh-8.0p1-openssl-kdf.patch | ||||
| # Use new OpenSSL for PEM export to avoid MD5 dependency (#1712436) | ||||
| Patch965: openssh-8.0p1-openssl-pem.patch | ||||
| 
 | ||||
| License: BSD | ||||
| Group: Applications/Internet | ||||
| @ -381,12 +369,6 @@ The module is most useful for su and sudo service stacks. | ||||
| %prep | ||||
| gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} | ||||
| %setup -q -a 4 | ||||
| #Do not enable by default | ||||
| %if 0 | ||||
| %patch0 -p1 -b .wIm | ||||
| %endif | ||||
| 
 | ||||
| # investigate %%patch102 -p1 -b .getaddrinfo | ||||
| 
 | ||||
| %if %{pam_ssh_agent} | ||||
| pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} | ||||
| @ -417,7 +399,6 @@ popd | ||||
| %patch702 -p1 -b .progress | ||||
| %patch703 -p1 -b .grab-info | ||||
| %patch707 -p1 -b .redhat | ||||
| %patch709 -p1 -b .vendor | ||||
| %patch711 -p1 -b .log-usepam-no | ||||
| %patch712 -p1 -b .evp-ctr | ||||
| %patch713 -p1 -b .ctr-cavs | ||||
| @ -425,44 +406,37 @@ popd | ||||
| #  | ||||
| %patch800 -p1 -b .gsskex | ||||
| %patch801 -p1 -b .force_krb | ||||
| %patch803 -p1 -b .gss-docs | ||||
| %patch804 -p1 -b .ccache_name | ||||
| %patch805 -p1 -b .k5login | ||||
| #  | ||||
| %patch900 -p1 -b .canohost | ||||
| %patch901 -p1 -b .kuserok | ||||
| %patch906 -p1 -b .fromto-remote | ||||
| %patch916 -p1 -b .contexts | ||||
| %patch918 -p1 -b .log-in-chroot | ||||
| %patch919 -p1 -b .scp | ||||
| %patch920 -p1 -b .config | ||||
| %patch802 -p1 -b .GSSAPIEnablek5users | ||||
| %patch922 -p1 -b .sshdt | ||||
| %patch926 -p1 -b .sftp-force-mode | ||||
| %patch929 -p1 -b .root-login | ||||
| %patch932 -p1 -b .gsskexalg | ||||
| %patch939 -p1 -b .s390-dev | ||||
| %patch944 -p1 -b .x11max | ||||
| %patch948 -p1 -b .systemd | ||||
| %patch807 -p1 -b .gsskex-ec | ||||
| %patch949 -p1 -b .refactor | ||||
| %patch950 -p1 -b .sandbox | ||||
| %patch951 -p1 -b .pkcs11-uri | ||||
| %patch952 -p1 -b .pkcs11-ecdsa | ||||
| %patch953 -p1 -b .scp-ipv6 | ||||
| %patch808 -p1 -b .gsskex-method | ||||
| %patch954 -p1 -b .disable-sha1 | ||||
| %patch958 -p1 -b .ssh-copy-id | ||||
| %patch961 -p1 -b .scp-tests | ||||
| %patch962 -p1 -b .crypto-policies | ||||
| %patch963 -p1 -b .openssl-evp | ||||
| %patch964 -p1 -b .openssl-kdf | ||||
| %patch965 -p1 -b .openssl-pem | ||||
| 
 | ||||
| %patch200 -p1 -b .audit | ||||
| %patch201 -p1 -b .audit-race | ||||
| %patch700 -p1 -b .fips | ||||
| 
 | ||||
| %patch100 -p1 -b .coverity | ||||
| %patch104 -p1 -b .openssl | ||||
| 
 | ||||
| %if 0 | ||||
| # Nothing here yet | ||||
| %endif | ||||
| 
 | ||||
| autoreconf | ||||
| pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} | ||||
| @ -512,7 +486,6 @@ fi | ||||
| 	--with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \ | ||||
| 	--with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ | ||||
| 	--with-privsep-path=%{_var}/empty/sshd \ | ||||
| 	--enable-vendor-patchlevel="FC-%{openssh_ver}-%{openssh_rel}" \ | ||||
| 	--disable-strip \ | ||||
| 	--without-zlib-version-check \ | ||||
| 	--with-ssl-engine \ | ||||
| @ -575,7 +548,10 @@ popd | ||||
| %if %{pam_ssh_agent} | ||||
| pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} | ||||
| LDFLAGS="$SAVE_LDFLAGS" | ||||
| %configure --with-selinux --libexecdir=/%{_libdir}/security --with-mantype=man | ||||
| %configure --with-selinux \ | ||||
| 	--libexecdir=/%{_libdir}/security \ | ||||
| 	--with-mantype=man \ | ||||
| 	--without-openssl-header-check `# The check is broken` | ||||
| make | ||||
| popd | ||||
| %endif | ||||
| @ -757,6 +733,29 @@ getent passwd sshd >/dev/null || \ | ||||
| %endif | ||||
| 
 | ||||
| %changelog | ||||
| * Tue Jul 23 2019 Jakub Jelen <jjelen@redhat.com> - 8.0p1-3 + 0.10.3-7 | ||||
| - Fix typos in manual pages (#1668325) | ||||
| - Use the upstream support for PKCS#8 PEM files alongside with the legacy PEM files (#1712436) | ||||
| - Unbreak ssh-keygen -A in FIPS mode (#1732424) | ||||
| - Add missing RSA certificate types to offered hostkey types in FIPS mode (#1732449) | ||||
| 
 | ||||
| * Wed Jun 12 2019 Jakub Jelen <jjelen@redhat.com> - 8.0p1-2 + 0.10.3-7 | ||||
| - Allow specifying a pin-value in PKCS #11 URI in ssh-add (#1639698) | ||||
| - Whitelist another syscall variant for s390x cryptographic module (ibmca engine) (#1714915) | ||||
| 
 | ||||
| * Tue May 14 2019 Jakub Jelen <jjelen@redhat.com> - 8.0p1-1 + 0.10.3-7 | ||||
| - New upstream release (#1691045) | ||||
| - Remove support for unused VendorPatchLevel configuration option | ||||
| - Fix kerberos cleanup procedures (#1683295) | ||||
| - Do not negotiate arbitrary primes with DH GEX in FIPS (#1685096) | ||||
| - Several GSSAPI key exchange improvements and sync with Debian | ||||
| - Allow to use labels in PKCS#11 URIs even if they do not match on private key (#1671262) | ||||
| - Do not fall back to sshd_net_t SELinux context (#1678695) | ||||
| - Use FIPS compliant high-level signature OpenSSL API and KDF | ||||
| - Mention crypto-policies in manual pages | ||||
| - Do not fail if non-FIPS approved algorithm is enabled in FIPS | ||||
| - Generate the PEM files in new PKCS#8 format without the need of MD5 (#1712436) | ||||
| 
 | ||||
| * Mon Nov 26 2018 Jakub Jelen <jjelen@redhat.com> - 7.8p1-4 + 0.10.3-5 | ||||
| - Unbreak PKCS#11 URI tests (#1648262) | ||||
| - Allow to disable RSA signatures with SHA1 (#1648898) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user