import openssh-8.0p1-3.el8

This commit is contained in:
CentOS Sources 2019-11-05 15:55:14 -05:00 committed by Andrew Lukoshko
parent b830398e18
commit 0f83d08dcb
47 changed files with 9699 additions and 14632 deletions

2
.gitignore vendored
View File

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

View File

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

View File

@ -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());
+}
+
+

View File

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

View File

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

View File

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

View File

@ -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, ':')))

View File

@ -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 },

View File

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

View File

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

View File

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

View File

@ -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);
+ }
+}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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 .

File diff suppressed because it is too large Load Diff

View 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 **);

View 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

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

File diff suppressed because it is too large Load Diff

View 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"

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

View File

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