diff -ruN openssh-7.5p1/aclocal.m4 openssh-7.5p1+x509-10.2/aclocal.m4
--- openssh-7.5p1/aclocal.m4	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/aclocal.m4	2017-05-20 21:07:00.000000000 +0300
@@ -14,15 +14,16 @@
 	AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 	]])],
 		[
 if `grep -i "unrecognized option" conftest.err >/dev/null`
@@ -51,7 +52,8 @@
 	AC_LINK_IFELSE([AC_LANG_SOURCE([[
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -59,8 +61,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long int p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 	]])],
 		[
 if `grep -i "unrecognized option" conftest.err >/dev/null`
@@ -89,7 +91,8 @@
 	AC_LINK_IFELSE([AC_LANG_SOURCE([[
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -97,8 +100,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 		]])],
 		[ AC_MSG_RESULT([yes])
 		  LDFLAGS="$saved_LDFLAGS $_define_flag"],
diff -ruN openssh-7.5p1/a_utf8.c openssh-7.5p1+x509-10.2/a_utf8.c
--- openssh-7.5p1/a_utf8.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/a_utf8.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,197 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#if 0
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#endif
+#include "evp-compat.h"
+
+#ifdef HAVE_UTF8_GETC
+
+typedef int empty_translation_unit__a_utf8;
+
+#else
+/* UTF8 utilities */
+
+/*-
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+    const unsigned char *p;
+    unsigned long value;
+    int ret;
+    if (len <= 0)
+        return 0;
+    p = str;
+
+    /* Check syntax and work out the encoded value (if correct) */
+    if ((*p & 0x80) == 0) {
+        value = *p++ & 0x7f;
+        ret = 1;
+    } else if ((*p & 0xe0) == 0xc0) {
+        if (len < 2)
+            return -1;
+        if ((p[1] & 0xc0) != 0x80)
+            return -3;
+        value = (*p++ & 0x1f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x80)
+            return -4;
+        ret = 2;
+    } else if ((*p & 0xf0) == 0xe0) {
+        if (len < 3)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80))
+            return -3;
+        value = (*p++ & 0xf) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x800)
+            return -4;
+        ret = 3;
+    } else if ((*p & 0xf8) == 0xf0) {
+        if (len < 4)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x7)) << 18;
+        value |= (*p++ & 0x3f) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x10000)
+            return -4;
+        ret = 4;
+    } else if ((*p & 0xfc) == 0xf8) {
+        if (len < 5)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x3)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x200000)
+            return -4;
+        ret = 5;
+    } else if ((*p & 0xfe) == 0xfc) {
+        if (len < 6)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80)
+            || ((p[5] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x1)) << 30;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x4000000)
+            return -4;
+        ret = 6;
+    } else
+        return -2;
+    *val = value;
+    return ret;
+}
+
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
+ */
+
+int UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+    if (!str)
+        len = 6;                /* Maximum we will need */
+    else if (len <= 0)
+        return -1;
+    if (value < 0x80) {
+        if (str)
+            *str = (unsigned char)value;
+        return 1;
+    }
+    if (value < 0x800) {
+        if (len < 2)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 2;
+    }
+    if (value < 0x10000) {
+        if (len < 3)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 3;
+    }
+    if (value < 0x200000) {
+        if (len < 4)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 4;
+    }
+    if (value < 0x4000000) {
+        if (len < 5)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+            *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 5;
+    }
+    if (len < 6)
+        return -1;
+    if (str) {
+        *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+        *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+        *str = (unsigned char)((value & 0x3f) | 0x80);
+    }
+    return 6;
+}
+#endif /*ndef HAVE_UTF8_GETC*/
diff -ruN openssh-7.5p1/auth1.c openssh-7.5p1+x509-10.2/auth1.c
--- openssh-7.5p1/auth1.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth1.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,447 @@
+/* $OpenBSD: auth1.c,v 1.82 2014/07/15 15:54:14 millert Exp $ */
+/*
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SSH1
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "evp-compat.h"
+#include "openbsd-compat/sys-queue.h"
+#include "xmalloc.h"
+#include "rsa.h"
+#include "ssh1.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "misc.h"
+#include "servconf.h"
+#include "compat.h"
+#include "key.h"
+#include "hostfile.h"
+#include "auth.h"
+#include "channels.h"
+#include "session.h"
+#include "uidswap.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
+#include "buffer.h"
+
+/* import */
+extern ServerOptions options;
+extern Buffer loginmsg;
+
+static int auth1_process_password(Authctxt *);
+static int auth1_process_rsa(Authctxt *);
+static int auth1_process_rhosts_rsa(Authctxt *);
+static int auth1_process_tis_challenge(Authctxt *);
+static int auth1_process_tis_response(Authctxt *);
+
+static char *client_user = NULL;    /* Used to fill in remote user for PAM */
+
+struct AuthMethod1 {
+	int type;
+	char *name;
+	int *enabled;
+	int (*method)(Authctxt *);
+};
+
+const struct AuthMethod1 auth1_methods[] = {
+	{
+		SSH_CMSG_AUTH_PASSWORD, "password",
+		&options.password_authentication, auth1_process_password
+	},
+	{
+		SSH_CMSG_AUTH_RSA, "rsa",
+		&options.rsa_authentication, auth1_process_rsa
+	},
+	{
+		SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa",
+		&options.rhosts_rsa_authentication, auth1_process_rhosts_rsa
+	},
+	{
+		SSH_CMSG_AUTH_TIS, "challenge-response",
+		&options.challenge_response_authentication,
+		auth1_process_tis_challenge
+	},
+	{
+		SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response",
+		&options.challenge_response_authentication,
+		auth1_process_tis_response
+	},
+	{ -1, NULL, NULL, NULL}
+};
+
+static const struct AuthMethod1
+*lookup_authmethod1(int type)
+{
+	int i;
+
+	for (i = 0; auth1_methods[i].name != NULL; i++)
+		if (auth1_methods[i].type == type)
+			return (&(auth1_methods[i]));
+
+	return (NULL);
+}
+
+static char *
+get_authname(int type)
+{
+	const struct AuthMethod1 *a;
+	static char buf[64];
+
+	if ((a = lookup_authmethod1(type)) != NULL)
+		return (a->name);
+	snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type);
+	return (buf);
+}
+
+/*ARGSUSED*/
+static int
+auth1_process_password(Authctxt *authctxt)
+{
+	int authenticated = 0;
+	char *password;
+	u_int dlen;
+
+	/*
+	 * Read user password.  It is in plain text, but was
+	 * transmitted over the encrypted channel so it is
+	 * not visible to an outside observer.
+	 */
+	password = packet_get_string(&dlen);
+	packet_check_eom();
+
+	/* Try authentication with the password. */
+	authenticated = PRIVSEP(auth_password(authctxt, password));
+
+	explicit_bzero(password, dlen);
+	free(password);
+
+	return (authenticated);
+}
+
+/*ARGSUSED*/
+static int
+auth1_process_rsa(Authctxt *authctxt)
+{
+	int authenticated = 0;
+	BIGNUM *n;
+
+	/* RSA authentication requested. */
+	if ((n = BN_new()) == NULL)
+		fatal("do_authloop: BN_new failed");
+	packet_get_bignum(n);
+	packet_check_eom();
+	authenticated = auth_rsa(authctxt, n);
+	BN_clear_free(n);
+
+	return (authenticated);
+}
+
+/*ARGSUSED*/
+static int
+auth1_process_rhosts_rsa(Authctxt *authctxt)
+{
+	int keybits, authenticated = 0;
+	u_int bits;
+	Key *client_host_key;
+	u_int ulen;
+	BIGNUM *n = NULL, *e = NULL;
+
+	/*
+	 * Get client user name.  Note that we just have to
+	 * trust the client; root on the client machine can
+	 * claim to be any user.
+	 */
+	client_user = packet_get_cstring(&ulen);
+
+	/* Get the client host key. */
+	client_host_key = key_new(KEY_RSA1);
+	bits = packet_get_int();
+	RSA_get0_key(client_host_key->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
+	packet_get_bignum(e);
+	packet_get_bignum(n);
+
+	keybits = BN_num_bits(n);
+	if (keybits < 0 || bits != (u_int)keybits) {
+		verbose("Warning: keysize mismatch for client_host_key: "
+		    "actual %d, announced %d",
+		    BN_num_bits(n), bits);
+	}
+	packet_check_eom();
+
+	authenticated = auth_rhosts_rsa(authctxt, client_user,
+	    client_host_key);
+	key_free(client_host_key);
+
+	auth_info(authctxt, "ruser %.100s", client_user);
+
+	return (authenticated);
+}
+
+/*ARGSUSED*/
+static int
+auth1_process_tis_challenge(Authctxt *authctxt)
+{
+	char *challenge;
+
+	if ((challenge = get_challenge(authctxt)) == NULL)
+		return (0);
+
+	debug("sending challenge '%s'", challenge);
+	packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
+	packet_put_cstring(challenge);
+	free(challenge);
+	packet_send();
+	packet_write_wait();
+
+	return (-1);
+}
+
+/*ARGSUSED*/
+static int
+auth1_process_tis_response(Authctxt *authctxt)
+{
+	int authenticated = 0;
+	char *response;
+	u_int dlen;
+
+	response = packet_get_string(&dlen);
+	packet_check_eom();
+	authenticated = verify_response(authctxt, response);
+	explicit_bzero(response, dlen);
+	free(response);
+
+	return (authenticated);
+}
+
+/*
+ * read packets, try to authenticate the user and
+ * return only if authentication is successful
+ */
+static void
+do_authloop(Authctxt *authctxt)
+{
+	int authenticated = 0;
+	int prev = 0, type = 0;
+	const struct AuthMethod1 *meth;
+
+	debug("Attempting authentication for %s%.100s.",
+	    authctxt->valid ? "" : "invalid user ", authctxt->user);
+
+	/* If the user has no password, accept authentication immediately. */
+	if (options.permit_empty_passwd && options.password_authentication &&
+#ifdef KRB5
+	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
+#endif
+	    PRIVSEP(auth_password(authctxt, ""))) {
+#ifdef USE_PAM
+		if (options.use_pam && (PRIVSEP(do_pam_account())))
+#endif
+		{
+			auth_log(authctxt, 1, 0, "without authentication",
+			    NULL);
+			return;
+		}
+	}
+
+	/* Indicate that authentication is needed. */
+	packet_start(SSH_SMSG_FAILURE);
+	packet_send();
+	packet_write_wait();
+
+	for (;;) {
+		/* default to fail */
+		authenticated = 0;
+
+
+		/* Get a packet from the client. */
+		prev = type;
+		type = packet_read();
+
+		/*
+		 * If we started challenge-response authentication but the
+		 * next packet is not a response to our challenge, release
+		 * the resources allocated by get_challenge() (which would
+		 * normally have been released by verify_response() had we
+		 * received such a response)
+		 */
+		if (prev == SSH_CMSG_AUTH_TIS &&
+		    type != SSH_CMSG_AUTH_TIS_RESPONSE)
+			abandon_challenge_response(authctxt);
+
+		if (authctxt->failures >= options.max_authtries)
+			goto skip;
+		if ((meth = lookup_authmethod1(type)) == NULL) {
+			logit("Unknown message during authentication: "
+			    "type %d", type);
+			goto skip;
+		}
+
+		if (!*(meth->enabled)) {
+			verbose("%s authentication disabled.", meth->name);
+			goto skip;
+		}
+
+		authenticated = meth->method(authctxt);
+		if (authenticated == -1)
+			continue; /* "postponed" */
+
+#ifdef BSD_AUTH
+		if (authctxt->as) {
+			auth_close(authctxt->as);
+			authctxt->as = NULL;
+		}
+#endif
+		if (!authctxt->valid && authenticated)
+			fatal("INTERNAL ERROR: authenticated invalid user %s",
+			    authctxt->user);
+
+#ifdef _UNICOS
+		if (authenticated && cray_access_denied(authctxt->user)) {
+			authenticated = 0;
+			fatal("Access denied for user %s.",authctxt->user);
+		}
+#endif /* _UNICOS */
+
+#ifndef HAVE_CYGWIN
+		/* Special handling for root */
+		if (authenticated && authctxt->pw->pw_uid == 0 &&
+		    !auth_root_allowed(meth->name)) {
+ 			authenticated = 0;
+# ifdef SSH_AUDIT_EVENTS
+			PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+# endif
+		}
+#endif
+
+#ifdef USE_PAM
+		if (options.use_pam && authenticated &&
+		    !PRIVSEP(do_pam_account())) {
+			char *msg;
+			size_t len;
+
+			error("Access denied for user %s by PAM account "
+			    "configuration", authctxt->user);
+			len = buffer_len(&loginmsg);
+			buffer_append(&loginmsg, "\0", 1);
+			msg = buffer_ptr(&loginmsg);
+			/* strip trailing newlines */
+			if (len > 0)
+				while (len > 0 && msg[--len] == '\n')
+					msg[len] = '\0';
+			else
+				msg = "Access denied.";
+			packet_disconnect("%s", msg);
+		}
+#endif
+
+ skip:
+		/* Log before sending the reply */
+		auth_log(authctxt, authenticated, 0, get_authname(type), NULL);
+
+		free(client_user);
+		client_user = NULL;
+
+		if (authenticated)
+			return;
+
+		if (++authctxt->failures >= options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+			PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
+			auth_maxtries_exceeded(authctxt);
+		}
+
+		packet_start(SSH_SMSG_FAILURE);
+		packet_send();
+		packet_write_wait();
+	}
+}
+
+/*
+ * Performs authentication of an incoming connection.  Session key has already
+ * been exchanged and encryption is enabled.
+ */
+void
+do_authentication(Authctxt *authctxt)
+{
+	u_int ulen;
+	char *user, *style = NULL;
+
+	/* Get the name of the user that we wish to log in as. */
+	packet_read_expect(SSH_CMSG_USER);
+
+	/* Get the user name. */
+	user = packet_get_cstring(&ulen);
+	packet_check_eom();
+
+	if ((style = strchr(user, ':')) != NULL)
+		*style++ = '\0';
+
+	authctxt->user = user;
+	authctxt->style = style;
+
+	/* Verify that the user is a valid user. */
+	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
+		authctxt->valid = 1;
+	else {
+		debug("do_authentication: invalid user %s", user);
+		authctxt->pw = fakepw();
+	}
+
+	/* Configuration may have changed as a result of Match */
+	if (options.num_auth_methods != 0)
+		fatal("AuthenticationMethods is not supported with SSH "
+		    "protocol 1");
+
+	setproctitle("%s%s", authctxt->valid ? user : "unknown",
+	    use_privsep ? " [net]" : "");
+
+#ifdef USE_PAM
+	if (options.use_pam)
+		PRIVSEP(start_pam(authctxt));
+#endif
+
+	/*
+	 * If we are not running as root, the user must have the same uid as
+	 * the server.
+	 */
+#ifndef HAVE_CYGWIN
+	if (!use_privsep && getuid() != 0 && authctxt->pw &&
+	    authctxt->pw->pw_uid != getuid())
+		packet_disconnect("Cannot change user when server not running as root.");
+#endif
+
+	/*
+	 * Loop until the user has been authenticated or the connection is
+	 * closed, do_authloop() returns only if authentication is successful
+	 */
+	do_authloop(authctxt);
+
+	/* The user has been authenticated and accepted. */
+	packet_start(SSH_SMSG_SUCCESS);
+	packet_send();
+	packet_write_wait();
+}
+
+#endif /* WITH_SSH1 */
diff -ruN openssh-7.5p1/auth2-hostbased.c openssh-7.5p1+x509-10.2/auth2-hostbased.c
--- openssh-7.5p1/auth2-hostbased.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth2-hostbased.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2004-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -40,6 +43,7 @@
 #include "servconf.h"
 #include "compat.h"
 #include "key.h"
+#include "ssh-x509.h"
 #include "hostfile.h"
 #include "auth.h"
 #include "canohost.h"
@@ -55,6 +59,29 @@
 extern u_char *session_id2;
 extern u_int session_id2_len;
 
+/* return 1 if given hostbased algorithm is allowed */
+static int
+hostbased_algorithm_allowed(const char* pkalg)
+{
+	if (
+	    (options.hostbased_algorithms != NULL) &&
+	    (match_pattern_list(pkalg, options.hostbased_algorithms, 0) != 1)
+	) {
+		debug("disallowed hostbased algorithm: %s", pkalg);
+		return 0;
+	}
+
+	if (
+	    (options.accepted_algorithms != NULL) &&
+	    (match_pattern_list(pkalg, options.accepted_algorithms, 0) != 1)
+	) {
+		debug("non-accepted hostbased algorithm: %s", pkalg);
+		return 0;
+	}
+
+	return 1;
+}
+
 static int
 userauth_hostbased(Authctxt *authctxt)
 {
@@ -92,7 +119,10 @@
 		    "public key algorithm: %s", pkalg);
 		goto done;
 	}
-	key = key_from_blob(pkblob, blen);
+	if (!hostbased_algorithm_allowed(pkalg)) {
+		goto done;
+	}
+	key = xkey_from_blob(pkalg, pkblob, blen);
 	if (key == NULL) {
 		error("userauth_hostbased: cannot decode key: %s", pkalg);
 		goto done;
@@ -108,12 +138,6 @@
 		    "signature format");
 		goto done;
 	}
-	if (match_pattern_list(sshkey_ssh_name(key),
-	    options.hostbased_key_types, 0) != 1) {
-		logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
-		    __func__, sshkey_type(key));
-		goto done;
-	}
 
 	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
 	    authctxt->service;
@@ -137,10 +161,14 @@
 
 	/* test for allowed key and correct signature */
 	authenticated = 0;
-	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
-	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, key, &ctx_compat };
+
+	if (PRIVSEP(hostbased_xkey_allowed(authctxt->pw, &ctx, cuser, chost)) &&
+	    PRIVSEP(xkey_verify(&ctx, sig, slen, buffer_ptr(&b),
 			buffer_len(&b))) == 1)
 		authenticated = 1;
+}
 
 	buffer_free(&b);
 done:
@@ -157,9 +185,10 @@
 
 /* return 1 if given hostkey is allowed */
 int
-hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
-    Key *key)
+hostbased_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx,
+    const char *cuser, char *chost)
 {
+	Key *key = ctx->key;
 	struct ssh *ssh = active_state; /* XXX */
 	const char *resolvedname, *ipaddr, *lookup, *reason;
 	HostStatus host_status;
diff -ruN openssh-7.5p1/auth2-pubkey.c openssh-7.5p1+x509-10.2/auth2-pubkey.c
--- openssh-7.5p1/auth2-pubkey.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth2-pubkey.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2003-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -53,6 +56,7 @@
 #include "servconf.h"
 #include "compat.h"
 #include "key.h"
+#include "ssh-x509.h"
 #include "hostfile.h"
 #include "auth.h"
 #include "pathnames.h"
@@ -74,6 +78,29 @@
 extern u_char *session_id2;
 extern u_int session_id2_len;
 
+/* return 1 if given publickey algorithm is allowed */
+static int
+pubkey_algorithm_allowed(const char* pkalg)
+{
+	if (
+	    (options.pubkey_algorithms != NULL) &&
+	    (match_pattern_list(pkalg, options.pubkey_algorithms, 0) != 1)
+	) {
+		debug("disallowed publickey algorithm: %s", pkalg);
+		return 0;
+	}
+
+	if (
+	    (options.accepted_algorithms != NULL) &&
+	    (match_pattern_list(pkalg, options.accepted_algorithms, 0) != 1)
+	) {
+		debug("non-accepted publickey algorithm: %s", pkalg);
+		return 0;
+	}
+
+	return 1;
+}
+
 static int
 userauth_pubkey(Authctxt *authctxt)
 {
@@ -110,7 +137,12 @@
 		    __func__, pkalg);
 		goto done;
 	}
-	key = key_from_blob(pkblob, blen);
+	if (!pubkey_algorithm_allowed(pkalg)) {
+		debug("userauth_pubkey: disallowed public key algorithm: %s",
+		    pkalg);
+		goto done;
+	}
+	key = xkey_from_blob(pkalg, pkblob, blen);
 	if (key == NULL) {
 		error("%s: cannot decode key: %s", __func__, pkalg);
 		goto done;
@@ -131,12 +163,9 @@
 		logit("refusing previously-used %s key", key_type(key));
 		goto done;
 	}
-	if (match_pattern_list(sshkey_ssh_name(key),
-	    options.pubkey_key_types, 0) != 1) {
-		logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
-		    __func__, sshkey_ssh_name(key));
-		goto done;
-	}
+
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, key, &ctx_compat };
 
 	if (have_sig) {
 		debug3("%s: have signature for %s %s",
@@ -175,8 +204,9 @@
 
 		/* test for correct signature */
 		authenticated = 0;
-		if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
-		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+
+		if (PRIVSEP(user_xkey_allowed(authctxt->pw, &ctx, 1)) &&
+		    PRIVSEP(xkey_verify(&ctx, sig, slen, buffer_ptr(&b),
 		    buffer_len(&b))) == 1) {
 			authenticated = 1;
 			/* Record the successful key to prevent reuse */
@@ -198,7 +228,7 @@
 		 * if a user is not allowed to login. is this an
 		 * issue? -markus
 		 */
-		if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
+		if (PRIVSEP(user_xkey_allowed(authctxt->pw, &ctx, 0))) {
 			packet_start(SSH2_MSG_USERAUTH_PK_OK);
 			packet_put_string(pkalg, alen);
 			packet_put_string(pkblob, blen);
@@ -207,6 +237,7 @@
 			authctxt->postponed = 1;
 		}
 	}
+}
 	if (authenticated != 1)
 		auth_clear_options();
 done:
@@ -628,6 +659,95 @@
 	return success;
 }
 
+static int
+key_match(const Key *key, const Key *found) {
+	/* key always has X.509 identity - see user_key_allowed2 */
+	if (found == NULL)
+		return(0);
+
+	if (key->type == found->type) {
+		if (!key_equal(key, found))
+			return(0);
+
+		/*
+		 * Key are equal but in case of certificates
+		 * when x509store is enabled found key may
+		 * contain only distinguished name.
+		 */
+		if (!key_is_x509(found))
+			return(1);
+
+		debug3("key_match:found matching certificate");
+		if (!ssh_x509flags.key_allow_selfissued) {
+			/*
+			 * Only the verification process can
+			 * allow the received certificate.
+			 */
+			return(1);
+		}
+
+		/*
+		 * The public key or certificate found in
+		 * autorized keys file can allow self-issued.
+		 */
+		{
+			X509 *x = SSH_X509_get_cert(key->x509_data);
+			if (!ssh_X509_is_selfsigned(x))
+				return(1);
+		}
+
+		/* the certificate can be allowed by public key */
+	}
+
+	switch(X509KEY_BASETYPE(found)) {
+	case KEY_RSA: {
+		debug3("key_match:RSA");
+		return sshrsa_equal_public(key->rsa, found->rsa);
+		} break;
+	case KEY_DSA: {
+		debug3("key_match:DSA");
+		return sshdsa_equal_public(key->dsa, found->dsa);
+		} break;
+#ifdef OPENSSL_HAS_ECC
+	case KEY_ECDSA: {
+		BN_CTX *bnctx;
+
+		debug3("key_match:EC");
+		if (key->ecdsa == NULL ||
+		    found->ecdsa == NULL ||
+		    EC_KEY_get0_public_key(key->ecdsa) == NULL ||
+		    EC_KEY_get0_public_key(found->ecdsa) == NULL
+		)
+			return(0);
+
+		bnctx = BN_CTX_new();
+		if (bnctx == NULL)
+			fatal("key_match: BN_CTX_new failed");
+
+		if (EC_GROUP_cmp(
+			EC_KEY_get0_group(key->ecdsa),
+			EC_KEY_get0_group(found->ecdsa),
+			bnctx
+		    ) != 0 ||
+		    EC_POINT_cmp(
+			EC_KEY_get0_group(key->ecdsa),
+			EC_KEY_get0_public_key(key->ecdsa),
+			EC_KEY_get0_public_key(found->ecdsa),
+			bnctx
+		    ) != 0
+		) {
+			BN_CTX_free(bnctx);
+			return(0);
+		}
+
+		BN_CTX_free(bnctx);
+		return(1);
+		} break;
+#endif /* OPENSSL_HAS_ECC */
+	}
+	return(0);
+}
+
 /*
  * Checks whether principal is allowed in output of command.
  * returns 1 if the principal is allowed or 0 otherwise.
@@ -780,7 +900,7 @@
 			continue;
 		if (found != NULL)
 			key_free(found);
-		found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
+		found = key_new(key_is_cert(key) || key_is_x509(key) ? KEY_UNSPEC : key->type);
 		auth_clear_options();
 
 		/* Skip leading whitespace, empty and comment lines. */
@@ -850,7 +970,32 @@
 			    key_type(found), fp, file);
 			free(fp);
 			found_key = 1;
-			break;
+		} else if (key_is_x509(key)) {
+			/* Variable key always contain public key or
+			 * certificate. In case of X.509 certificate
+			 * x509 attribute of Key structure "found"
+			 * may contain only "Distinguished Name" !
+			 */
+			if (!key_match(key, found))
+				continue;
+			debug("matching key found: file %s, line %lu",
+			    file, linenum);
+			if (auth_parse_options(pw, key_options, file,
+			    linenum) != 1)
+				continue;
+			found_key = 1;
+			fp = key_is_x509(found)
+				? x509key_subject(found)
+				: sshkey_fingerprint(found, options.fingerprint_hash,
+				    SSH_FP_DEFAULT);
+			if (fp == NULL)
+				continue;
+			verbose("Authorized by %s : %s", key_type(found), fp);
+			if (ssh_x509key_verify_cert(key) != 1) {
+				found_key = 0;
+				verbose("X.509 certificate validation reject key");
+			}
+			free(fp);
 		} else if (key_equal(found, key)) {
 			if (auth_parse_options(pw, key_options, file,
 			    linenum) != 1)
@@ -864,7 +1009,6 @@
 			    file, linenum, key_type(found), fp);
 			free(fp);
 			found_key = 1;
-			continue;
 		}
 	}
 	if (found != NULL)
@@ -1088,8 +1232,9 @@
  * Check whether key authenticates and authorises the user.
  */
 int
-user_key_allowed(struct passwd *pw, Key *key, int auth_attempt)
+user_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx, int auth_attempt)
 {
+	Key *key = ctx->key;
 	u_int success, i;
 	char *file;
 
diff -ruN openssh-7.5p1/auth.c openssh-7.5p1+x509-10.2/auth.c
--- openssh-7.5p1/auth.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth.c	2017-05-20 21:07:01.000000000 +0300
@@ -77,6 +77,12 @@
 #include "ssherr.h"
 #include "compat.h"
 
+#ifdef __ANDROID__
+# define SECURE_MASK_DIR 002
+#else
+# define SECURE_MASK_DIR 022
+#endif
+
 /* import */
 extern ServerOptions options;
 extern int use_privsep;
@@ -309,7 +315,7 @@
 	else
 		authmsg = authenticated ? "Accepted" : "Failed";
 
-	authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
+	authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s",
 	    authmsg,
 	    method,
 	    submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
@@ -317,6 +323,7 @@
 	    authctxt->user,
 	    ssh_remote_ipaddr(ssh),
 	    ssh_remote_port(ssh),
+	    compat20 ? "ssh2" : "ssh1",
 	    authctxt->info != NULL ? ": " : "",
 	    authctxt->info != NULL ? authctxt->info : "");
 	free(authctxt->info);
@@ -349,11 +356,12 @@
 	struct ssh *ssh = active_state; /* XXX */
 
 	error("maximum authentication attempts exceeded for "
-	    "%s%.100s from %.200s port %d ssh2",
+	    "%s%.100s from %.200s port %d %s",
 	    authctxt->valid ? "" : "invalid user ",
 	    authctxt->user,
 	    ssh_remote_ipaddr(ssh),
-	    ssh_remote_port(ssh));
+	    ssh_remote_port(ssh),
+	    compat20 ? "ssh2" : "ssh1");
 	packet_disconnect("Too many authentication failures");
 	/* NOTREACHED */
 }
@@ -523,7 +531,7 @@
 
 		if (stat(buf, &st) < 0 ||
 		    (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
-		    (st.st_mode & 022) != 0) {
+		    (st.st_mode & SECURE_MASK_DIR) != 0) {
 			snprintf(err, errlen,
 			    "bad ownership or modes for directory %s", buf);
 			return -1;
diff -ruN openssh-7.5p1/auth-chall.c openssh-7.5p1+x509-10.2/auth-chall.c
--- openssh-7.5p1/auth-chall.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth-chall.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,125 @@
+/* $OpenBSD: auth-chall.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "auth.h"
+#include "log.h"
+#include "misc.h"
+#include "servconf.h"
+
+/* limited protocol v1 interface to kbd-interactive authentication */
+
+extern KbdintDevice *devices[];
+static KbdintDevice *device;
+extern ServerOptions options;
+
+char *
+get_challenge(Authctxt *authctxt)
+{
+	char *challenge, *name, *info, **prompts;
+	u_int i, numprompts;
+	u_int *echo_on;
+
+#ifdef USE_PAM
+	if (!options.use_pam)
+		remove_kbdint_device("pam");
+#endif
+
+	device = devices[0]; /* we always use the 1st device for protocol 1 */
+	if (device == NULL)
+		return NULL;
+	if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
+		return NULL;
+	if (device->query(authctxt->kbdintctxt, &name, &info,
+	    &numprompts, &prompts, &echo_on)) {
+		device->free_ctx(authctxt->kbdintctxt);
+		authctxt->kbdintctxt = NULL;
+		return NULL;
+	}
+	if (numprompts < 1)
+		fatal("get_challenge: numprompts < 1");
+	challenge = xstrdup(prompts[0]);
+	for (i = 0; i < numprompts; i++)
+		free(prompts[i]);
+	free(prompts);
+	free(name);
+	free(echo_on);
+	free(info);
+
+	return (challenge);
+}
+int
+verify_response(Authctxt *authctxt, const char *response)
+{
+	char *resp[1], *name, *info, **prompts;
+	u_int i, numprompts, *echo_on;
+	int authenticated = 0;
+
+	if (device == NULL)
+		return 0;
+	if (authctxt->kbdintctxt == NULL)
+		return 0;
+	resp[0] = (char *)response;
+	switch (device->respond(authctxt->kbdintctxt, 1, resp)) {
+	case 0: /* Success */
+		authenticated = 1;
+		break;
+	case 1: /* Postponed - retry with empty query for PAM */
+		if ((device->query(authctxt->kbdintctxt, &name, &info,
+		    &numprompts, &prompts, &echo_on)) != 0)
+			break;
+		if (numprompts == 0 &&
+		    device->respond(authctxt->kbdintctxt, 0, resp) == 0)
+			authenticated = 1;
+
+		for (i = 0; i < numprompts; i++)
+			free(prompts[i]);
+		free(prompts);
+		free(name);
+		free(echo_on);
+		free(info);
+		break;
+	}
+	device->free_ctx(authctxt->kbdintctxt);
+	authctxt->kbdintctxt = NULL;
+	return authenticated;
+}
+void
+abandon_challenge_response(Authctxt *authctxt)
+{
+	if (authctxt->kbdintctxt != NULL) {
+		device->free_ctx(authctxt->kbdintctxt);
+		authctxt->kbdintctxt = NULL;
+	}
+}
diff -ruN openssh-7.5p1/authfd.c openssh-7.5p1+x509-10.2/authfd.c
--- openssh-7.5p1/authfd.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/authfd.c	2017-05-20 21:07:01.000000000 +0300
@@ -14,6 +14,9 @@
  * SSH2 implementation,
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -49,11 +52,12 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include "evp-compat.h"
 #include "xmalloc.h"
 #include "ssh.h"
 #include "rsa.h"
 #include "sshbuf.h"
-#include "sshkey.h"
+#include "ssh-x509.h"
 #include "authfd.h"
 #include "cipher.h"
 #include "compat.h"
@@ -210,12 +214,16 @@
 
 	if ((key = sshkey_new(KEY_RSA1)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
+	{
+	BIGNUM *n = NULL, *e = NULL;
+	RSA_get0_key(key->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
 	if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
-	    (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
-	    (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
+	    (r = sshbuf_get_bignum1(ids, e)) != 0 ||
+	    (r = sshbuf_get_bignum1(ids, n)) != 0 ||
 	    (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
 		goto out;
-	keybits = BN_num_bits(key->rsa->n);
+	keybits = BN_num_bits(n);
+	}
 	/* XXX previously we just warned here. I think we should be strict */
 	if (keybits < 0 || bits != (u_int)keybits) {
 		r = SSH_ERR_KEY_BITS_MISMATCH;
@@ -398,14 +406,18 @@
 		return SSH_ERR_INVALID_ARGUMENT;
 	if ((msg = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
+	{
+	const BIGNUM *n = NULL, *e = NULL;
+	RSA_get0_key(key->rsa, &n, &e, NULL);
 	if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
-	    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
-	    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
-	    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
+	    (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 ||
+	    (r = sshbuf_put_bignum1(msg, e)) != 0 ||
+	    (r = sshbuf_put_bignum1(msg, n)) != 0 ||
 	    (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
 	    (r = sshbuf_put(msg, session_id, 16)) != 0 ||
 	    (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
 		goto out;
+	}
 	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
 		goto out;
 	if ((r = sshbuf_get_u8(msg, &type)) != 0)
@@ -430,20 +442,22 @@
 static u_int
 agent_encode_alg(struct sshkey *key, const char *alg)
 {
+#ifdef HAVE_EVP_SHA256
 	if (alg != NULL && key->type == KEY_RSA) {
 		if (strcmp(alg, "rsa-sha2-256") == 0)
 			return SSH_AGENT_RSA_SHA2_256;
 		else if (strcmp(alg, "rsa-sha2-512") == 0)
 			return SSH_AGENT_RSA_SHA2_512;
 	}
+#endif /*def HAVE_EVP_SHA256*/
 	return 0;
 }
 
 /* ask agent to sign data, returns err.h code on error, 0 on success */
 int
-ssh_agent_sign(int sock, struct sshkey *key,
+Xssh_agent_sign(int sock, ssh_sign_ctx *ctx,
     u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, const char *alg, u_int compat)
+    const u_char *data, size_t datalen)
 {
 	struct sshbuf *msg;
 	u_char *blob = NULL, type;
@@ -456,13 +470,15 @@
 
 	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
-	if (compat & SSH_BUG_SIGBLOB)
+	if (check_compat_datafellows(ctx->compat, SSH_BUG_SIGBLOB))
 		flags |= SSH_AGENT_OLD_SIGNATURE;
+	if (check_compat_x509(ctx->compat, SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE))
+		flags |= SSH_AGENT_RFC6187_OPAQUE_ECDSA_SIGNATURE;
 	if ((msg = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
-	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
+	if ((r = sshkey_to_blob(ctx->key, &blob, &blen)) != 0)
 		goto out;
-	flags |= agent_encode_alg(key, alg);
+	flags |= agent_encode_alg(ctx->key, ctx->alg);
 	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
 	    (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
 	    (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
@@ -499,15 +515,20 @@
 ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
 {
 	int r;
+	const BIGNUM *n = NULL, *e = NULL, *d = NULL;
+	const BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
 
+	RSA_get0_key(key, &n, &e, &d);
+	RSA_get0_crt_params(key, NULL, NULL, &iqmp);
+	RSA_get0_factors(key, &p, &q);
 	/* To keep within the protocol: p < q for ssh. in SSL p > q */
-	if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->n)) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->e)) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->d)) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->q)) != 0 ||
-	    (r = sshbuf_put_bignum1(b, key->p)) != 0 ||
+	if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 ||
+	    (r = sshbuf_put_bignum1(b, n)) != 0 ||
+	    (r = sshbuf_put_bignum1(b, e)) != 0 ||
+	    (r = sshbuf_put_bignum1(b, d)) != 0 ||
+	    (r = sshbuf_put_bignum1(b, iqmp)) != 0 ||
+	    (r = sshbuf_put_bignum1(b, q)) != 0 ||
+	    (r = sshbuf_put_bignum1(b, p)) != 0 ||
 	    (r = sshbuf_put_cstring(b, comment)) != 0)
 		return r;
 	return 0;
@@ -560,7 +581,7 @@
 	if ((msg = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 
-	switch (key->type) {
+	switch (X509KEY_BASETYPE(key)) {
 #ifdef WITH_SSH1
 	case KEY_RSA1:
 		type = constrained ?
@@ -622,11 +643,13 @@
 
 #ifdef WITH_SSH1
 	if (key->type == KEY_RSA1) {
+		const BIGNUM *n = NULL, *e = NULL;
+		RSA_get0_key(key->rsa, &n, &e, NULL);
 		if ((r = sshbuf_put_u8(msg,
 		    SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
-		    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
-		    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
-		    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
+		    (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 ||
+		    (r = sshbuf_put_bignum1(msg, e)) != 0 ||
+		    (r = sshbuf_put_bignum1(msg, n)) != 0)
 			goto out;
 	} else
 #endif
@@ -661,6 +684,7 @@
  */
 int
 ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
+    const char *xstore,
     u_int life, u_int confirm)
 {
 	struct sshbuf *msg;
@@ -678,7 +702,8 @@
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshbuf_put_u8(msg, type)) != 0 ||
 	    (r = sshbuf_put_cstring(msg, reader_id)) != 0 ||
-	    (r = sshbuf_put_cstring(msg, pin)) != 0)
+	    (r = sshbuf_put_cstring(msg, pin)) != 0 ||
+	    (r = sshbuf_put_cstring(msg, xstore)) != 0)
 		goto out;
 	if (constrained &&
 	    (r = encode_constraints(msg, life, confirm)) != 0)
diff -ruN openssh-7.5p1/authfd.h openssh-7.5p1+x509-10.2/authfd.h
--- openssh-7.5p1/authfd.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/authfd.h	2017-05-20 21:07:00.000000000 +0300
@@ -34,14 +34,15 @@
 	    const char *comment, u_int life, u_int confirm);
 int	ssh_remove_identity(int sock, struct sshkey *key);
 int	ssh_update_card(int sock, int add, const char *reader_id,
+	    const char *xstore,
 	    const char *pin, u_int life, u_int confirm);
 int	ssh_remove_all_identities(int sock, int version);
 
 int	ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
 	    u_char session_id[16], u_char response[16]);
-int	ssh_agent_sign(int sock, struct sshkey *key,
-	    u_char **sigp, size_t *lenp,
-	    const u_char *data, size_t datalen, const char *alg, u_int compat);
+
+int	Xssh_agent_sign(int sock, ssh_sign_ctx *ctx,
+	    u_char **sigp, size_t *lenp, const u_char *data, size_t datalen);
 
 /* Messages for the authentication agent connection. */
 #define SSH_AGENTC_REQUEST_RSA_IDENTITIES	1
@@ -89,4 +90,6 @@
 #define	SSH_AGENT_RSA_SHA2_256			0x02
 #define	SSH_AGENT_RSA_SHA2_512			0x04
 
+#define	SSH_AGENT_RFC6187_OPAQUE_ECDSA_SIGNATURE		0x00010000U
+
 #endif				/* AUTHFD_H */
diff -ruN openssh-7.5p1/authfile.c openssh-7.5p1+x509-10.2/authfile.c
--- openssh-7.5p1/authfile.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/authfile.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,8 @@
 /* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */
 /*
  * Copyright (c) 2000, 2013 Markus Friedl.  All rights reserved.
+ * X509 certificate support,
+ * Copyright (c) 2002-2006,2011,2012 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,6 +48,8 @@
 #include "misc.h"
 #include "atomicio.h"
 #include "sshkey.h"
+#include "ssh-x509.h"
+#include "key-eng.h"
 #include "sshbuf.h"
 #include "ssherr.h"
 #include "krl.h"
@@ -164,6 +168,10 @@
 	if (commentp != NULL)
 		*commentp = NULL;
 
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) return SSH_ERR_INVALID_FORMAT;
+#endif
+
 	if ((b = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshkey_load_file(fd, b)) != 0)
@@ -213,11 +221,22 @@
 {
 	int fd, r;
 
+	debug3("%s() type=%d, filename=%s", __func__, type, (filename ? filename : "?!?"));
 	if (keyp != NULL)
 		*keyp = NULL;
 	if (commentp != NULL)
 		*commentp = NULL;
 
+#ifdef USE_OPENSSL_ENGINE
+	if (strncmp(filename, "engine:", 7) == 0) {
+		r = eng_key_load_private_type(type, filename + 7,
+			passphrase, keyp, commentp);
+		if (perm_ok != NULL)
+			*perm_ok = (r == SSH_ERR_SUCCESS) ? 1 : 0;
+		return r;
+	}
+#endif
+
 	if ((fd = open(filename, O_RDONLY)) < 0) {
 		if (perm_ok != NULL)
 			*perm_ok = 0;
@@ -271,6 +290,8 @@
 	struct sshbuf *buffer = NULL;
 	int r, fd;
 
+	debug3("%s() filename=%s", __func__, (filename ? filename : "?!?"));
+
 	if (keyp != NULL)
 		*keyp = NULL;
 	if (commentp != NULL)
@@ -309,6 +330,13 @@
 
 	if (commentp != NULL)
 		*commentp = NULL;
+
+#ifdef USE_OPENSSL_ENGINE
+	if (strncmp(filename, "engine:", 7) == 0) {
+		return eng_key_try_load_public(k, filename + 7, commentp);
+	}
+#endif
+
 	if ((f = fopen(filename, "r")) == NULL)
 		return SSH_ERR_SYSTEM_ERROR;
 	while (read_keyfile_line(f, filename, line, sizeof(line),
@@ -328,7 +356,8 @@
 		for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
 			;
 		if (*cp) {
-			if ((r = sshkey_read(k, &cp)) == 0) {
+			char *pkalg = NULL;
+			if ((r = sshkey_read_pkalg(k, &cp, &pkalg)) == 0) {
 				cp[strcspn(cp, "\r\n")] = '\0';
 				if (commentp) {
 					*commentp = strdup(*cp ?
@@ -337,6 +366,11 @@
 						r = SSH_ERR_ALLOC_FAIL;
 				}
 				fclose(f);
+				if (pkalg) {
+					/* load extra certificates for RFC6187 keys */
+					x509key_load_certs(pkalg, k, filename);
+					free(pkalg);
+				}
 				return r;
 			}
 		}
@@ -353,6 +387,8 @@
 	char file[PATH_MAX];
 	int r, fd;
 
+	debug3("%s() filename=%s", __func__, (filename ? filename : "?!?"));
+
 	if (keyp != NULL)
 		*keyp = NULL;
 	if (commentp != NULL)
@@ -364,6 +400,11 @@
 		goto skip;
 #ifdef WITH_SSH1
 	/* try rsa1 private key */
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		debug3("FIPS mode - skip attempt to load protocol 1 identity");
+	} else {
+#endif
 	r = sshkey_load_public_rsa1(fd, keyp, commentp);
 	close(fd);
 	switch (r) {
@@ -374,6 +415,9 @@
 	case 0:
 		return r;
 	}
+#ifdef OPENSSL_FIPS
+	}
+#endif
 #else /* WITH_SSH1 */
 	close(fd);
 #endif /* WITH_SSH1 */
@@ -390,6 +434,9 @@
 
 #ifdef WITH_SSH1
 	/* try rsa1 public key */
+#ifdef OPENSSL_FIPS
+	if (!FIPS_mode()) {
+#endif
 	if ((pub = sshkey_new(KEY_RSA1)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
@@ -398,6 +445,9 @@
 		return 0;
 	}
 	sshkey_free(pub);
+#ifdef OPENSSL_FIPS
+	}
+#endif
 #endif /* WITH_SSH1 */
 
  skip:
@@ -425,6 +475,7 @@
 	char *file = NULL;
 	int r = SSH_ERR_INTERNAL_ERROR;
 
+	debug3("%s() filename=%s", __func__, (filename ? filename : "?!?"));
 	if (keyp != NULL)
 		*keyp = NULL;
 
@@ -456,6 +507,7 @@
 	struct sshkey *key = NULL, *cert = NULL;
 	int r;
 
+	debug3("%s() type=%d, filename=%s", __func__, type, (filename ? filename : "?!?"));
 	if (keyp != NULL)
 		*keyp = NULL;
 
diff -ruN openssh-7.5p1/auth.h openssh-7.5p1+x509-10.2/auth.h
--- openssh-7.5p1/auth.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth.h	2017-05-20 21:07:00.000000000 +0300
@@ -3,6 +3,9 @@
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -112,13 +115,26 @@
 	void	(*free_ctx)(void *ctx);
 };
 
+int      auth_rhosts(struct passwd *, const char *);
 int
 auth_rhosts2(struct passwd *, const char *, const char *, const char *);
 
+int	 auth_rhosts_rsa(Authctxt *, char *, Key *);
 int      auth_password(Authctxt *, const char *);
+int      auth_rsa(Authctxt *, BIGNUM *);
+int      auth_rsa_challenge_dialog(Key *);
+BIGNUM	*auth_rsa_generate_challenge(Key *);
+int	 auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
+int	 auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+
+#ifdef WITH_SSH1
+int	 auth_rhosts_rsa_xkey_allowed(struct passwd *, ssh_sign_ctx *,
+	    const char *, const char *);
+#endif
+int	 hostbased_xkey_allowed(struct passwd *, ssh_sign_ctx *,
+	     const char *, char *);
+int	 user_xkey_allowed(struct passwd *, ssh_sign_ctx *, int);
 
-int	 hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
-int	 user_key_allowed(struct passwd *, Key *, int);
 void	 pubkey_auth_info(Authctxt *, const Key *, const char *, ...)
 	    __attribute__((__format__ (printf, 3, 4)));
 void	 auth2_record_userkey(Authctxt *, struct sshkey *);
@@ -147,6 +163,7 @@
 
 void disable_forwarding(void);
 
+void	do_authentication(Authctxt *);
 void	do_authentication2(Authctxt *);
 
 void	auth_info(Authctxt *authctxt, const char *, ...)
@@ -177,6 +194,10 @@
 int	allowed_user(struct passwd *);
 struct passwd * getpwnamallow(const char *user);
 
+char	*get_challenge(Authctxt *);
+int	verify_response(Authctxt *, const char *);
+void	abandon_challenge_response(Authctxt *);
+
 char	*expand_authorized_keys(const char *, struct passwd *pw);
 char	*authorized_principals_file(struct passwd *);
 
@@ -193,11 +214,13 @@
 /* hostkey handling */
 Key	*get_hostkey_by_index(int);
 Key	*get_hostkey_public_by_index(int, struct ssh *);
-Key	*get_hostkey_public_by_type(int, int, struct ssh *);
-Key	*get_hostkey_private_by_type(int, int, struct ssh *);
+Key	*get_hostkey_public_by_alg(const char*, struct ssh *);
+Key	*get_hostkey_private_by_alg(const char*, struct ssh *);
 int	 get_hostkey_index(Key *, int, struct ssh *);
-int	 sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
-	     const u_char *, size_t, const char *, u_int);
+int	 ssh1_session_key(BIGNUM *);
+
+int	Xsshd_hostkey_sign(ssh_sign_ctx *ctx, struct sshkey *pubkey,
+	    u_char **signature, size_t *slen, const u_char *data, size_t dlen);
 
 /* debug messages during authentication */
 void	 auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
diff -ruN openssh-7.5p1/auth-rhosts.c openssh-7.5p1+x509-10.2/auth-rhosts.c
--- openssh-7.5p1/auth-rhosts.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth-rhosts.c	2017-05-20 21:07:01.000000000 +0300
@@ -186,8 +186,20 @@
  * true if authentication succeeds.  If ignore_rhosts is true, only
  * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored).
  */
+
 int
-auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
+auth_rhosts(struct passwd *pw, const char *client_user)
+{
+	struct ssh *ssh = active_state;	/* XXX */
+	const char *hostname, *ipaddr;
+
+	hostname = auth_get_canonical_hostname(ssh, options.use_dns);
+	ipaddr = ssh_remote_ipaddr(ssh);
+	return auth_rhosts2(pw, client_user, hostname, ipaddr);
+}
+
+static int
+auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname,
     const char *ipaddr)
 {
 	char buf[1024];
@@ -322,3 +334,10 @@
 	restore_uid();
 	return 0;
 }
+
+int
+auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
+    const char *ipaddr)
+{
+       return auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
+}
diff -ruN openssh-7.5p1/auth-rh-rsa.c openssh-7.5p1+x509-10.2/auth-rh-rsa.c
--- openssh-7.5p1/auth-rh-rsa.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth-rh-rsa.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,115 @@
+/* $OpenBSD: auth-rh-rsa.c,v 1.45 2016/03/07 19:02:43 djm Exp $ */
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Rhosts or /etc/hosts.equiv authentication combined with RSA host
+ * authentication.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SSH1
+
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <stdarg.h>
+
+#include "packet.h"
+#include "uidswap.h"
+#include "log.h"
+#include "buffer.h"
+#include "misc.h"
+#include "servconf.h"
+#include "ssh-x509.h"
+#include "compat.h"
+#include "hostfile.h"
+#include "pathnames.h"
+#include "auth.h"
+#include "canohost.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+
+int
+auth_rhosts_rsa_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx,
+    const char *cuser, const char *chost)
+{
+	Key *client_host_key = ctx->key;
+	HostStatus host_status;
+
+	if (auth_key_is_revoked(client_host_key))
+		return 0;
+
+	/* Check if we would accept it using rhosts authentication. */
+	if (!auth_rhosts(pw, cuser))
+		return 0;
+
+	host_status = check_key_in_hostfiles(pw, client_host_key,
+	    chost, _PATH_SSH_SYSTEM_HOSTFILE,
+	    options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+
+	return (host_status == HOST_OK);
+}
+
+/*
+ * Tries to authenticate the user using the .rhosts file and the host using
+ * its host key.  Returns true if authentication succeeds.
+ */
+int
+auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
+{
+	struct ssh *ssh = active_state; /* XXX */
+	const char *chost;
+	struct passwd *pw = authctxt->pw;
+
+	debug("Trying rhosts with RSA host authentication for client user %.100s",
+	    cuser);
+
+	if (!authctxt->valid || client_host_key == NULL ||
+	    client_host_key->rsa == NULL)
+		return 0;
+
+	chost = auth_get_canonical_hostname(ssh, options.use_dns);
+	debug("Rhosts RSA authentication: canonical host %.900s", chost);
+
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { NULL, client_host_key, &ctx_compat };
+
+	if (!PRIVSEP(auth_rhosts_rsa_xkey_allowed(pw, &ctx, cuser, chost))) {
+		debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
+		packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
+		return 0;
+	}
+}
+	/* A matching host key was found and is known. */
+
+	/* Perform the challenge-response dialog with the client for the host key. */
+	if (!auth_rsa_challenge_dialog(client_host_key)) {
+		logit("Client on %.800s failed to respond correctly to host authentication.",
+		    chost);
+		return 0;
+	}
+	/*
+	 * We have authenticated the user using .rhosts or /etc/hosts.equiv,
+	 * and the host using RSA. We accept the authentication.
+	 */
+
+	verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
+	    pw->pw_name, cuser, chost);
+	packet_send_debug("Rhosts with RSA host authentication accepted.");
+	return 1;
+}
+
+#endif /* WITH_SSH1 */
diff -ruN openssh-7.5p1/auth-rsa.c openssh-7.5p1+x509-10.2/auth-rsa.c
--- openssh-7.5p1/auth-rsa.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/auth-rsa.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,356 @@
+/* $OpenBSD: auth-rsa.c,v 1.90 2015/01/28 22:36:00 djm Exp $ */
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * RSA-based authentication.  This code determines whether to admit a login
+ * based on RSA authentication.  This file also contains functions to check
+ * validity of the host key.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SSH1
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <openssl/rsa.h>
+#include "evp-compat.h"
+
+#include <pwd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "xmalloc.h"
+#include "rsa.h"
+#include "packet.h"
+#include "ssh1.h"
+#include "uidswap.h"
+#include "match.h"
+#include "buffer.h"
+#include "pathnames.h"
+#include "log.h"
+#include "misc.h"
+#include "servconf.h"
+#include "key.h"
+#include "auth-options.h"
+#include "hostfile.h"
+#include "auth.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
+#include "ssh.h"
+
+#include "digest.h"
+
+/* import */
+extern ServerOptions options;
+
+/*
+ * Session identifier that is used to bind key exchange and authentication
+ * responses to a particular session.
+ */
+extern u_char session_id[16];
+
+/*
+ * The .ssh/authorized_keys file contains public keys, one per line, in the
+ * following format:
+ *   options bits e n comment
+ * where bits, e and n are decimal numbers,
+ * and comment is any string of characters up to newline.  The maximum
+ * length of a line is SSH_MAX_PUBKEY_BYTES characters.  See sshd(8) for a
+ * description of the options.
+ */
+
+BIGNUM *
+auth_rsa_generate_challenge(Key *key)
+{
+	BIGNUM *challenge;
+	BN_CTX *ctx;
+	const BIGNUM *n = NULL;
+
+	if ((challenge = BN_new()) == NULL)
+		fatal("auth_rsa_generate_challenge: BN_new() failed");
+	/* Generate a random challenge. */
+	if (BN_rand(challenge, 256, 0, 0) == 0)
+		fatal("auth_rsa_generate_challenge: BN_rand failed");
+	if ((ctx = BN_CTX_new()) == NULL)
+		fatal("auth_rsa_generate_challenge: BN_CTX_new failed");
+	RSA_get0_key(key->rsa, &n, NULL, NULL);
+	if (BN_mod(challenge, challenge, n, ctx) == 0)
+		fatal("auth_rsa_generate_challenge: BN_mod failed");
+	BN_CTX_free(ctx);
+
+	return challenge;
+}
+
+int
+auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+{
+	u_char buf[32], mdbuf[16];
+	struct ssh_digest_ctx *md;
+	int len;
+	const BIGNUM *n = NULL;
+
+	/* don't allow short keys */
+	RSA_get0_key(key->rsa, &n, NULL, NULL);
+	if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+		error("%s: RSA modulus too small: %d < minimum %d bits",
+		    __func__,
+		    BN_num_bits(n), SSH_RSA_MINIMUM_MODULUS_SIZE);
+		return (0);
+	}
+
+	/* The response is MD5 of decrypted challenge plus session id. */
+	len = BN_num_bytes(challenge);
+	if (len <= 0 || len > 32)
+		fatal("%s: bad challenge length %d", __func__, len);
+	memset(buf, 0, 32);
+	BN_bn2bin(challenge, buf + 32 - len);
+	if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
+	    ssh_digest_update(md, buf, 32) < 0 ||
+	    ssh_digest_update(md, session_id, 16) < 0 ||
+	    ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
+		fatal("%s: md5 failed", __func__);
+	ssh_digest_free(md);
+
+	/* Verify that the response is the original challenge. */
+	if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
+		/* Wrong answer. */
+		return (0);
+	}
+	/* Correct answer. */
+	return (1);
+}
+
+/*
+ * Performs the RSA authentication challenge-response dialog with the client,
+ * and returns true (non-zero) if the client gave the correct answer to
+ * our challenge; returns zero if the client gives a wrong answer.
+ */
+
+int
+auth_rsa_challenge_dialog(Key *key)
+{
+	BIGNUM *challenge, *encrypted_challenge;
+	u_char response[16];
+	int i, success;
+
+	if ((encrypted_challenge = BN_new()) == NULL)
+		fatal("auth_rsa_challenge_dialog: BN_new() failed");
+
+	challenge = PRIVSEP(auth_rsa_generate_challenge(key));
+
+	/* Encrypt the challenge with the public key. */
+	if (rsa_public_encrypt(encrypted_challenge, challenge, key->rsa) != 0)
+		fatal("%s: rsa_public_encrypt failed", __func__);
+
+	/* Send the encrypted challenge to the client. */
+	packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
+	packet_put_bignum(encrypted_challenge);
+	packet_send();
+	BN_clear_free(encrypted_challenge);
+	packet_write_wait();
+
+	/* Wait for a response. */
+	packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE);
+	for (i = 0; i < 16; i++)
+		response[i] = (u_char)packet_get_char();
+	packet_check_eom();
+
+	success = PRIVSEP(auth_rsa_verify_response(key, challenge, response));
+	BN_clear_free(challenge);
+	return (success);
+}
+
+static int
+rsa_key_allowed_in_file(struct passwd *pw, char *file,
+    const BIGNUM *client_n, Key **rkey)
+{
+	char *fp, line[SSH_MAX_PUBKEY_BYTES];
+	int allowed = 0, bits;
+	FILE *f;
+	u_long linenum = 0;
+	Key *key;
+
+	debug("trying public RSA key file %s", file);
+	if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL)
+		return 0;
+
+	/*
+	 * Go though the accepted keys, looking for the current key.  If
+	 * found, perform a challenge-response dialog to verify that the
+	 * user really has the corresponding private key.
+	 */
+	key = key_new(KEY_RSA1);
+	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
+		char *cp;
+		char *key_options;
+		int keybits;
+		const BIGNUM *n = NULL;
+
+		/* Skip leading whitespace, empty and comment lines. */
+		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+			;
+		if (!*cp || *cp == '\n' || *cp == '#')
+			continue;
+
+		/*
+		 * Check if there are options for this key, and if so,
+		 * save their starting address and skip the option part
+		 * for now.  If there are no options, set the starting
+		 * address to NULL.
+		 */
+		if (*cp < '0' || *cp > '9') {
+			int quoted = 0;
+			key_options = cp;
+			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+				if (*cp == '\\' && cp[1] == '"')
+					cp++;	/* Skip both */
+				else if (*cp == '"')
+					quoted = !quoted;
+			}
+		} else
+			key_options = NULL;
+
+		/* Parse the key from the line. */
+		if (hostfile_read_key(&cp, &bits, key) == 0) {
+			debug("%.100s, line %lu: non ssh1 key syntax",
+			    file, linenum);
+			continue;
+		}
+		/* cp now points to the comment part. */
+
+		/*
+		 * Check if the we have found the desired key (identified
+		 * by its modulus).
+		 */
+		RSA_get0_key(key->rsa, &n, NULL, NULL);
+		if (BN_cmp(n, client_n) != 0)
+			continue;
+
+		/* check the real bits  */
+		keybits = BN_num_bits(n);
+		if (keybits < 0 || bits != keybits)
+			logit("Warning: %s, line %lu: keysize mismatch: "
+			    "actual %d vs. announced %d.",
+			    file, linenum, BN_num_bits(n), bits);
+
+		if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
+		    SSH_FP_DEFAULT)) == NULL)
+			continue;
+		debug("matching key found: file %s, line %lu %s %s",
+		    file, linenum, key_type(key), fp);
+		free(fp);
+
+		/* Never accept a revoked key */
+		if (auth_key_is_revoked(key))
+			break;
+
+		/* We have found the desired key. */
+		/*
+		 * If our options do not allow this key to be used,
+		 * do not send challenge.
+		 */
+		if (!auth_parse_options(pw, key_options, file, linenum))
+			continue;
+		if (key_is_cert_authority)
+			continue;
+		/* break out, this key is allowed */
+		allowed = 1;
+		break;
+	}
+
+	/* Close the file. */
+	fclose(f);
+
+	/* return key if allowed */
+	if (allowed && rkey != NULL)
+		*rkey = key;
+	else
+		key_free(key);
+
+	return allowed;
+}
+
+/*
+ * check if there's user key matching client_n,
+ * return key if login is allowed, NULL otherwise
+ */
+
+int
+auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+	char *file;
+	u_int i, allowed = 0;
+
+	temporarily_use_uid(pw);
+
+	for (i = 0; !allowed && i < options.num_authkeys_files; i++) {
+		if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
+			continue;
+		file = expand_authorized_keys(
+		    options.authorized_keys_files[i], pw);
+		allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey);
+		free(file);
+	}
+
+	restore_uid();
+
+	return allowed;
+}
+
+/*
+ * Performs the RSA authentication dialog with the client.  This returns
+ * 0 if the client could not be authenticated, and 1 if authentication was
+ * successful.  This may exit if there is a serious protocol violation.
+ */
+int
+auth_rsa(Authctxt *authctxt, BIGNUM *client_n)
+{
+	Key *key;
+	struct passwd *pw = authctxt->pw;
+
+	/* no user given */
+	if (!authctxt->valid)
+		return 0;
+
+	if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) {
+		auth_clear_options();
+		return (0);
+	}
+
+	/* Perform the challenge-response dialog for this key. */
+	if (!auth_rsa_challenge_dialog(key)) {
+		/* Wrong response. */
+		verbose("Wrong response to RSA authentication challenge.");
+		packet_send_debug("Wrong response to RSA authentication challenge.");
+		/*
+		 * Break out of the loop. Otherwise we might send
+		 * another challenge and break the protocol.
+		 */
+		key_free(key);
+		return (0);
+	}
+	/*
+	 * Correct response.  The client has been successfully
+	 * authenticated. Note that we have not yet processed the
+	 * options; this will be reset if the options cause the
+	 * authentication to be rejected.
+	 */
+	pubkey_auth_info(authctxt, key, NULL);
+
+	packet_send_debug("RSA authentication accepted.");
+	return (1);
+}
+
+#endif /* WITH_SSH1 */
diff -ruN openssh-7.5p1/ChangeLog openssh-7.5p1+x509-10.2/ChangeLog
--- openssh-7.5p1/ChangeLog	2017-03-20 11:52:54.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ChangeLog	1970-01-01 02:00:00.000000000 +0200
@@ -1,9394 +0,0 @@
-commit d38f05dbdd291212bc95ea80648b72b7177e9f4e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Mar 20 13:38:27 2017 +1100
-
-    Add llabs() implementation.
-
-commit 72536316a219b7394996a74691a5d4ec197480f7
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Mar 20 12:23:04 2017 +1100
-
-    crank version numbers
-
-commit 3be52bc36bdfd24ded7e0f46999e7db520fb4e3f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 20 01:18:59 2017 +0000
-
-    upstream commit
-    
-    openssh-7.5
-    
-    Upstream-ID: b8b9a4a949427c393cd868215e1724ceb3467ee5
-
-commit db84e52fe9cfad57f22e7e23c5fbf00092385129
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Mar 20 12:07:20 2017 +1100
-
-    I'm a doofus.
-    
-    Unbreak obvious syntax error.
-
-commit 89f04852db27643717c9c3a2b0dde97ae50099ee
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Mar 20 11:53:34 2017 +1100
-
-    on Cygwin, check paths from server for backslashes
-    
-    Pointed out by Jann Horn of Google Project Zero
-
-commit 7ef1f9bafc2cc8d97ff2fbd4f280002b6e8ea5d9
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Mar 20 11:48:34 2017 +1100
-
-    Yet another synonym for ASCII: "646"
-    
-    Used by NetBSD; this unbreaks mprintf() and friends there for the C
-    locale (caught by dtucker@ and his menagerie of test systems).
-
-commit 9165abfea3f68a0c684a6ed2e575e59bc31a3a6b
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Mar 20 09:58:34 2017 +1100
-
-    create test mux socket in /tmp
-    
-    Creating the socket in $OBJ could blow past the (quite limited)
-    path limit for Unix domain sockets. As a bandaid for bz#2660,
-    reported by Colin Watson; ok dtucker@
-
-commit 2adbe1e63bc313d03e8e84e652cc623af8ebb163
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Mar 15 07:07:39 2017 +0000
-
-    upstream commit
-    
-    disallow KEXINIT before NEWKEYS; ok djm; report by
-    vegard.nossum at oracle.com
-    
-    Upstream-ID: 3668852d1f145050e62f1da08917de34cb0c5234
-
-commit 2fbf91684d76d38b9cf06550b69c9e41bca5a71c
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Mar 16 14:05:46 2017 +1100
-
-    Include includes.h for compat bits.
-
-commit b55f634e96b9c5b0cd991e23a9ca181bec4bdbad
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Mar 16 13:45:17 2017 +1100
-
-    Wrap stdint.h in #ifdef HAVE_STDINT_H
-
-commit 55a1117d7342a0bf8b793250cf314bab6b482b99
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Mar 16 11:22:42 2017 +1100
-
-    Adapt Cygwin config script to privsep knob removal
-    
-    Patch from Corinna Vinschen.
-
-commit 1a321bfdb91defe3c4d9cca5651724ae167e5436
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Wed Mar 15 03:52:30 2017 +0000
-
-    upstream commit
-    
-    accidents happen to the best of us; ok djm
-    
-    Upstream-ID: b7a9dbd71011ffde95e06f6945fe7197dedd1604
-
-commit 25f837646be8c2017c914d34be71ca435dfc0e07
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Mar 15 02:25:09 2017 +0000
-
-    upstream commit
-    
-    fix regression in 7.4: deletion of PKCS#11-hosted keys
-    would fail unless they were specified by full physical pathname. Report and
-    fix from Jakub Jelen via bz#2682; ok dtucker@
-    
-    Upstream-ID: 5b5bc20ca11cacb5d5eb29c3f93fd18425552268
-
-commit a8c5eeacf032a7d3408957e45dd7603cc1baf55f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Mar 15 02:19:09 2017 +0000
-
-    upstream commit
-    
-    Fix segfault when sshd attempts to load RSA1 keys (can
-    only happen when protocol v.1 support is enabled for the client). Reported by
-    Jakub Jelen in bz#2686; ok dtucker
-    
-    Upstream-ID: 8fdaec2ba4b5f65db1d094f6714ce64b25d871d7
-
-commit 66705948c0639a7061a0d0753266da7685badfec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 14 07:19:07 2017 +0000
-
-    upstream commit
-    
-    Mark the sshd_config UsePrivilegeSeparation option as
-    deprecated, effectively making privsep mandatory in sandboxing mode. ok
-    markus@ deraadt@
-    
-    (note: this doesn't remove the !privsep code paths, though that will
-    happen eventually).
-    
-    Upstream-ID: b4c52666256c4dd865f8ce9431af5d6ce2d74a0a
-
-commit f86586b03fe6cd8f595289bde200a94bc2c191af
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 14 18:26:29 2017 +1100
-
-    Make seccomp-bpf sandbox work on Linux/X32
-    
-    Allow clock_gettime syscall with X32 bit masked off. Apparently
-    this is required for at least some kernel versions. bz#2142
-    Patch mostly by Colin Watson. ok dtucker@
-
-commit 2429cf78dd2a9741ce27ba25ac41c535274a0af6
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 14 18:01:52 2017 +1100
-
-    require OpenSSL >=1.0.1
-
-commit e3ea335abeab731c68f2b2141bee85a4b0bf680f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 14 17:48:43 2017 +1100
-
-    Remove macro trickery; no binary change
-    
-    This stops the SC_ALLOW(), SC_ALLOW_ARG() and SC_DENY() macros
-    prepending __NR_ to the syscall number parameter and just makes
-    them explicit in the macro invocations.
-    
-    No binary change in stripped object file before/after.
-
-commit 5f1596e11d55539678c41f68aed358628d33d86f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 14 13:15:18 2017 +1100
-
-    support ioctls for ICA crypto card on Linux/s390
-    
-    Based on patch from Eduardo Barretto; ok dtucker@
-
-commit b1b22dd0df2668b322dda174e501dccba2cf5c44
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Mar 14 14:19:36 2017 +1100
-
-    Plumb conversion test into makefile.
-
-commit f57783f1ddfb4cdfbd612c6beb5ec01cb5b9a6b9
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Mar 14 01:20:29 2017 +0000
-
-    upstream commit
-    
-    Add unit test for convtime().
-    
-    Upstream-Regress-ID: 8717bc0ca4c21120f6dd3a1d3b7a363f707c31e1
-
-commit 8884b7247d094cd11ff9e39c325ba928c5bdbc6c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Mar 14 01:10:07 2017 +0000
-
-    upstream commit
-    
-    Add ASSERT_LONG_* helpers.
-    
-    Upstream-Regress-ID: fe15beaea8f5063c7f21b0660c722648e3d76431
-
-commit c6774d21185220c0ba11e8fd204bf0ad1a432071
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Mar 14 00:55:37 2017 +0000
-
-    upstream commit
-    
-    Fix convtime() overflow test on boundary condition,
-    spotted by & ok djm.
-    
-    Upstream-ID: 51f14c507ea87a3022e63f574100613ab2ba5708
-
-commit f5746b40cfe6d767c8e128fe50c43274b31cd594
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Mar 14 00:25:03 2017 +0000
-
-    upstream commit
-    
-    Check for integer overflow when parsing times in
-    convtime().  Reported by nicolas.iooss at m4x.org, ok djm@
-    
-    Upstream-ID: 35e6a4e98f6fa24df50bfb8ba1307cf70e966f13
-
-commit f5907982f42a8d88a430b8a46752cbb7859ba979
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Mar 14 13:38:15 2017 +1100
-
-    Add a "unit" target to run only unit tests.
-
-commit 9e96b41682aed793fadbea5ccd472f862179fb02
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 14 12:24:47 2017 +1100
-
-    Fix weakness in seccomp-bpf sandbox arg inspection
-    
-    Syscall arguments are passed via an array of 64-bit values in struct
-    seccomp_data, but we were only inspecting the bottom 32 bits and not
-    even those correctly for BE systems.
-    
-    Fortunately, the only case argument inspection was used was in the
-    socketcall filtering so using this for sandbox escape seems
-    impossible.
-    
-    ok dtucker
-
-commit 8ff3fc3f2f7c13e8968717bc2b895ee32c441275
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Mar 11 23:44:16 2017 +0000
-
-    upstream commit
-    
-    regress tests for loading certificates without public keys;
-    bz#2617 based on patch from Adam Eijdenberg; ok markus@ dtucker@
-    
-    Upstream-Regress-ID: 0145d19328ed995b73fe2d9da33596b17429d0d0
-
-commit 1e24552716194db8f2f620587b876158a9ef56ad
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Mar 11 23:40:26 2017 +0000
-
-    upstream commit
-    
-    allow ssh to use certificates accompanied by a private
-    key file but no corresponding plain *.pub public key. bz#2617 based on patch
-    from Adam Eijdenberg; ok dtucker@ markus@
-    
-    Upstream-ID: 295668dca2c39505281577217583ddd2bd4b00b9
-
-commit 0fb1a617a07b8df5de188dd5a0c8bf293d4bfc0e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Sat Mar 11 13:07:35 2017 +0000
-
-    upstream commit
-    
-    Don't count the initial block twice when computing how
-    many bytes to discard for the work around for the attacks against CBC-mode.
-    ok djm@; report from Jean Paul, Kenny, Martin and Torben @ RHUL
-    
-    Upstream-ID: f445f509a4e0a7ba3b9c0dae7311cb42458dc1e2
-
-commit ef653dd5bd5777132d9f9ee356225f9ee3379504
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 07:18:32 2017 +0000
-
-    upstream commit
-    
-    krl.c
-    
-    Upstream-ID: fc5e695d5d107d730182e2da7b23f00b489e0ee1
-
-commit d94c1dfef2ea30ca67b1204ada7c3b537c54f4d0
-Author: Damien Miller <djm@mindrot.org>
-Date:   Sun Mar 12 10:48:14 2017 +1100
-
-    sync fmt_scaled.c with OpenBSD
-    
-    revision 1.13
-    date: 2017/03/11 23:37:23;  author: djm;  state: Exp;  lines: +14 -1;  commitid: jnFKyHkB3CEiEZ2R;
-    fix signed integer overflow in scan_scaled. Found by Nicolas Iooss
-    using AFL against ssh_config. ok deraadt@ millert@
-    ----------------------------
-    revision 1.12
-    date: 2013/11/29 19:00:51;  author: deraadt;  state: Exp;  lines: +6 -5;
-    fairly simple unsigned char casts for ctype
-    ok krw
-    ----------------------------
-    revision 1.11
-    date: 2012/11/12 14:07:20;  author: halex;  state: Exp;  lines: +4 -2;
-    make scan_scaled set errno to EINVAL rather than ERANGE if it encounters
-    an invalid multiplier, like the man page says it should
-    
-    "looks sensible" deraadt@, ok ian@
-    ----------------------------
-    revision 1.10
-    date: 2009/06/20 15:00:04;  author: martynas;  state: Exp;  lines: +4 -4;
-    use llabs instead of the home-grown version;  and some comment changes
-    ok ian@, millert@
-    ----------------------------
-
-commit 894221a63fa061e52e414ca58d47edc5fe645968
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 05:01:13 2017 +0000
-
-    upstream commit
-    
-    When updating hostkeys, accept RSA keys if
-    HostkeyAlgorithms contains any RSA keytype. Previously, ssh could ignore RSA
-    keys when any of the ssh-rsa-sha2-* methods was enabled in HostkeyAlgorithms
-    nit ssh-rsa (SHA1 signatures) was not. bz#2650 reported by Luis Ressel; ok
-    dtucker@
-    
-    Upstream-ID: c5e8cfee15c42f4a05d126158a0766ea06da79d2
-
-commit dd3e2298663f4cc1a06bc69582d00dcfee27d73c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 04:24:55 2017 +0000
-
-    upstream commit
-    
-    make hostname matching really insensitive to case;
-    bz#2685, reported by Petr Cerny; ok dtucker@
-    
-    Upstream-ID: e467622ff154269e36ba8b6c9e3d105e1c4a9253
-
-commit 77a9be9446697fe8b5499fe651f4a82a71a4b51f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 03:52:48 2017 +0000
-
-    upstream commit
-    
-    reword a comment to make it fit 80 columns
-    
-    Upstream-ID: 4ef509a66b96c7314bbcc87027c2af71fa9d0ba4
-
-commit 61b8ef6a66efaec07e023342cb94a10bdc2254dc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 04:27:32 2017 +0000
-
-    upstream commit
-    
-    better match sshd config parser behaviour: fatal() if
-    line is overlong, increase line buffer to match sshd's; bz#2651 reported by
-    Don Fong; ok dtucker@
-    
-    Upstream-ID: b175ae7e0ba403833f1ee566edf10f67443ccd18
-
-commit db2597207e69912f2592cd86a1de8e948a9d7ffb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 04:26:06 2017 +0000
-
-    upstream commit
-    
-    ensure hostname is lower-case before hashing it;
-    bz#2591 reported by Griff Miller II; ok dtucker@
-    
-    Upstream-ID: c3b8b93804f376bd00d859b8bcd9fc0d86b4db17
-
-commit df9936936c695f85c1038bd706d62edf752aca4b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 04:24:55 2017 +0000
-
-    upstream commit
-    
-    make hostname matching really insensitive to case;
-    bz#2685, reported by Petr Cerny; ok dtucker@
-    
-    Upstream-ID: e632b7a9bf0d0558d5ff56dab98b7cca6c3db549
-
-commit 67eed24bfa7645d88fa0b883745fccb22a0e527e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 04:11:00 2017 +0000
-
-    upstream commit
-    
-    Remove old null check from config dumper.  Patch from
-    jjelen at redhat.com vi bz#2687, ok djm@
-    
-    Upstream-ID: 824ab71467b78c4bab0dd1b3a38e8bc5f63dd528
-
-commit 183ba55aaaecca0206184b854ad6155df237adbe
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 04:07:20 2017 +0000
-
-    upstream commit
-    
-    fix regression in 7.4 server-sig-algs, where we were
-    accidentally excluding SHA2 RSA signature methods. bz#2680, patch from Nuno
-    Goncalves; ok dtucker@
-    
-    Upstream-ID: 81ac8bfb30960447740b9b8f6a214dcf322f12e8
-
-commit 66be4fe8c4435af5bbc82998501a142a831f1181
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 03:53:11 2017 +0000
-
-    upstream commit
-    
-    Check for NULL return value from key_new.  Patch from
-    jjelen at redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: 059e33cd43cba88dc8caf0b1936fd4dd88fd5b8e
-
-commit ec2892b5c7fea199914cb3a6afb3af38f84990bf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 03:52:48 2017 +0000
-
-    upstream commit
-    
-    reword a comment to make it fit 80 columns
-    
-    Upstream-ID: b4b48b4487c0821d16e812c40c9b09f03b28e349
-
-commit 7fadbb6da3f4122de689165651eb39985e1cba85
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 03:48:57 2017 +0000
-
-    upstream commit
-    
-    Check for NULL argument to sshkey_read.  Patch from
-    jjelen at redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: c2d00c2ea50c4861d271d0a586f925cc64a87e0e
-
-commit 5a06b9e019e2b0b0f65a223422935b66f3749de3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 03:45:40 2017 +0000
-
-    upstream commit
-    
-    Plug some mem leaks mostly on error paths.  From jjelen
-    at redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: 3fb030149598957a51b7c8beb32bf92cf30c96f2
-
-commit f6edbe9febff8121f26835996b1229b5064d31b7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 03:24:48 2017 +0000
-
-    upstream commit
-    
-    Plug mem leak on GLOB_NOMATCH case.  From jjelen at
-    redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: 8016a7ae97719d3aa55fb723fc2ad3200058340d
-
-commit 566b3a46e89a2fda2db46f04f2639e92da64a120
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 03:22:40 2017 +0000
-
-    upstream commit
-    
-    Plug descriptor leaks of auth_sock.  From jjelen at
-    redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: 248acb99a5ed2fdca37d1aa33c0fcee7be286d88
-
-commit 8a2834454c73dfc1eb96453c0e97690595f3f4c2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 03:18:24 2017 +0000
-
-    upstream commit
-    
-    correctly hash hosts with a port number. Reported by Josh
-    Powers in bz#2692; ok dtucker@
-    
-    Upstream-ID: 468e357ff143e00acc05bdd2803a696b3d4b6442
-
-commit 9747b9c742de409633d4753bf1a752cbd211e2d3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 10 03:15:58 2017 +0000
-
-    upstream commit
-    
-    don't truncate off \r\n from long stderr lines; bz#2688,
-    reported by Brian Dyson; ok dtucker@
-    
-    Upstream-ID: cdfdc4ba90639af807397ce996153c88af046ca4
-
-commit 4a4b75adac862029a1064577eb5af299b1580cdd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 10 02:59:51 2017 +0000
-
-    upstream commit
-    
-    Validate digest arg in ssh_digest_final; from jjelen at
-    redhat.com via bz#2687, ok djm@
-    
-    Upstream-ID: dbe5494dfddfe523fab341a3dab5a79e7338f878
-
-commit bee0167be2340d8de4bdc1ab1064ec957c85a447
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Mar 10 13:40:18 2017 +1100
-
-    Check for NULL from malloc.
-    
-    Part of bz#2687, from jjelen at redhat.com.
-
-commit da39b09d43b137a5a3d071b51589e3efb3701238
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Mar 10 13:22:32 2017 +1100
-
-    If OSX is using launchd, remove screen no.
-    
-    Check for socket with and without screen number.  From Apple and Jakob
-    Schlyter via bz#2341, with contributions from Ron Frederick, ok djm@
-
-commit 8fb15311a011517eb2394bb95a467c209b8b336c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Mar 8 12:07:47 2017 +0000
-
-    upstream commit
-    
-    quote [host]:port in generated ProxyJump commandline; the
-    [ / ] characters can confuse some shells (e.g. zsh). Reported by Lauri
-    Tirkkonen via bugs@
-    
-    Upstream-ID: 65cdd161460e1351c3d778e974c1c2a4fa4bc182
-
-commit 18501151cf272a15b5f2c5e777f2e0933633c513
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Mar 6 02:03:20 2017 +0000
-
-    upstream commit
-    
-    Check l->hosts before dereferencing; fixes potential null
-    pointer deref. ok djm@
-    
-    Upstream-ID: 81c0327c6ec361da794b5c680601195cc23d1301
-
-commit d072370793f1a20f01ad827ba8fcd3b8f2c46165
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Mar 6 00:44:51 2017 +0000
-
-    upstream commit
-    
-    linenum is unsigned long so use %lu in log formats.  ok
-    deraadt@
-    
-    Upstream-ID: 9dc582d9bb887ebe0164e030d619fc20b1a4ea08
-
-commit 12d3767ba4c84c32150cbe6ff6494498780f12c9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 3 06:13:11 2017 +0000
-
-    upstream commit
-    
-    fix ssh-keygen -H accidentally corrupting known_hosts that
-    contained already-hashed entries. HKF_MATCH_HOST_HASHED is only set by
-    hostkeys_foreach() when hostname matching is in use, so we need to look for
-    the hash marker explicitly.
-    
-    Upstream-ID: da82ad653b93e8a753580d3cf5cd448bc2520528
-
-commit d7abb771bd5a941b26144ba400a34563a1afa589
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 28 06:10:08 2017 +0000
-
-    upstream commit
-    
-    small memleak: free fd_set on connection timeout (though
-    we are heading to exit anyway). From Tom Rix in bz#2683
-    
-    Upstream-ID: 10e3dadbb8199845b66581473711642d9e6741c4
-
-commit 78142e3ab3887e53a968d6e199bcb18daaf2436e
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Mon Feb 27 14:30:33 2017 +0000
-
-    upstream commit
-    
-    errant dot; from klemens nanni
-    
-    Upstream-ID: 83d93366a5acf47047298c5d3ebc5e7426f37921
-
-commit 8071a6924c12bb51406a9a64a4b2892675112c87
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 24 03:16:34 2017 +0000
-
-    upstream commit
-    
-    might as well set the listener socket CLOEXEC
-    
-    Upstream-ID: 9c538433d6a0ca79f5f21decc5620e46fb68ab57
-
-commit d5499190559ebe374bcdfa8805408646ceffad64
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Feb 19 00:11:29 2017 +0000
-
-    upstream commit
-    
-    add test cases for C locale; ok schwarze@
-    
-    Upstream-Regress-ID: 783d75de35fbc923d46e2a5e6cee30f8f381ba87
-
-commit 011c8ffbb0275281a0cf330054cf21be10c43e37
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Feb 19 00:10:57 2017 +0000
-
-    upstream commit
-    
-    Add a common nl_langinfo(CODESET) alias for US-ASCII
-    "ANSI_X3.4-1968" that is used by Linux. Fixes mprintf output truncation for
-    non-UTF-8 locales on Linux spotted by dtucker@; ok deraadt@ schwarze@
-    
-    Upstream-ID: c6808956ebffd64066f9075d839f74ff0dd60719
-
-commit 0c4430a19b73058a569573492f55e4c9eeaae67b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Feb 7 23:03:11 2017 +0000
-
-    upstream commit
-    
-    Remove deprecated SSH1 options RSAAuthentication and
-    RhostsRSAAuthentication from regression test sshd_config.
-    
-    Upstream-Regress-ID: 8066b753d9dce7cf02ff87af5c727ff680d99491
-
-commit 3baa4cdd197c95d972ec3d07f1c0d08f2d7d9199
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Feb 17 02:32:05 2017 +0000
-
-    upstream commit
-    
-    Do not show rsa1 key type in usage when compiled without
-    SSH1 support.
-    
-    Upstream-ID: 068b5c41357a02f319957746fa4e84ea73960f57
-
-commit ecc35893715f969e98fee118481f404772de4132
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Feb 17 02:31:14 2017 +0000
-
-    upstream commit
-    
-    ifdef out "rsa1" from the list of supported keytypes when
-    compiled without SSH1 support.  Found by kdunlop at guralp.com, ok djm@
-    
-    Upstream-ID: cea93a26433d235bb1d64b1d990f19a9c160a70f
-
-commit 10577c6d96a55b877a960b2d0b75edef1b9945af
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 17 02:04:15 2017 +0000
-
-    upstream commit
-    
-    For ProxyJump/-J, surround host name with brackets to
-    allow literal IPv6 addresses. From Dick Visser; ok dtucker@
-    
-    Upstream-ID: 3a5d3b0171250daf6a5235e91bce09c1d5746bf1
-
-commit b2afdaf1b52231aa23d2153f4a8c5a60a694dda4
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Wed Feb 15 23:38:31 2017 +0000
-
-    upstream commit
-    
-    Fix memory leaks in match_filter_list() error paths.
-    
-    ok dtucker@ markus@
-    
-    Upstream-ID: c7f96ac0877f6dc9188bbc908100a8d246cc7f0e
-
-commit 6d5a41b38b55258213ecfaae9df7a758caa752a1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Feb 15 01:46:47 2017 +0000
-
-    upstream commit
-    
-    fix division by zero crash in "df" output when server
-    returns zero total filesystem blocks/inodes. Spotted by Guido Vranken; ok
-    dtucker@
-    
-    Upstream-ID: 6fb6c2ae6b289aa07b6232dbc0be54682ef5419f
-
-commit bd5d7d239525d595ecea92765334af33a45d9d63
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Sun Feb 12 15:45:15 2017 +1100
-
-    ifdef out EVP_R_PRIVATE_KEY_DECODE_ERROR
-    
-    EVP_R_PRIVATE_KEY_DECODE_ERROR was added in OpenSSL 1.0.0 so ifdef out
-    for the benefit of OpenSSL versions prior to that.
-
-commit 155d540d00ff55f063421ec182ec8ff2b7ab6cbe
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 10 04:34:50 2017 +0000
-
-    upstream commit
-    
-    bring back r1.34 that was backed out for problems loading
-    public keys:
-    
-    translate OpenSSL error codes to something more
-    meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@
-    
-    with additional fix from Jakub Jelen to solve the backout.
-    bz#2525 bz#2523 re-ok dtucker@
-    
-    Upstream-ID: a9d5bc0306f4473d9b4f4484f880e95f3c1cc031
-
-commit a287c5ad1e0bf9811c7b9221979b969255076019
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 10 03:36:40 2017 +0000
-
-    upstream commit
-    
-    Sanitise escape sequences in key comments sent to printf
-    but preserve valid UTF-8 when the locale supports it; bz#2520 ok dtucker@
-    
-    Upstream-ID: e8eed28712ba7b22d49be534237eed019875bd1e
-
-commit e40269be388972848aafcca7060111c70aab5b87
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Wed Feb 8 20:32:43 2017 +0000
-
-    upstream commit
-    
-    Avoid printf %s NULL.  From semarie@, OK djm@
-    
-    Upstream-ID: 06beef7344da0208efa9275d504d60d2a5b9266c
-
-commit 5b90709ab8704dafdb31e5651073b259d98352bc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Feb 6 09:22:51 2017 +0000
-
-    upstream commit
-    
-    Restore \r\n newline sequence for server ident string. The CR
-    got lost in the flensing of SSHv1. Pointed out by Stef Bon
-    
-    Upstream-ID: 5333fd43ce5396bf5999496096fac5536e678fac
-
-commit 97c31c46ee2e6b46dfffdfc4f90bbbf188064cbc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 3 23:01:42 2017 +0000
-
-    upstream commit
-    
-    unit test for match_filter_list() function; still want a
-    better name for this...
-    
-    Upstream-Regress-ID: 840ad6118552c35111f0a897af9c8d93ab8de92a
-
-commit f1a193464a7b77646f0d0cedc929068e4a413ab4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 3 23:05:57 2017 +0000
-
-    upstream commit
-    
-    use ssh_packet_set_log_preamble() to include connection
-    username in packet log messages, e.g.
-    
-    Connection closed by invalid user foo 10.1.1.1 port 44056 [preauth]
-    
-    ok markus@ bz#113
-    
-    Upstream-ID: 3591b88bdb5416d6066fb3d49d8fff2375bf1a15
-
-commit 07edd7e9537ab32aa52abb5fb2a915c350fcf441
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 3 23:03:33 2017 +0000
-
-    upstream commit
-    
-    add ssh_packet_set_log_preamble() to allow inclusion of a
-    preamble string in disconnect messages; ok markus@
-    
-    Upstream-ID: 34cb41182cd76d414c214ccb01c01707849afead
-
-commit 68bc8cfa7642d3ccbf2cd64281c16b8b9205be59
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 3 23:01:19 2017 +0000
-
-    upstream commit
-    
-    support =- for removing methods from algorithms lists,
-    e.g. Ciphers=-*cbc; suggested by Cristian Ionescu-Idbohrn in bz#2671 "I like
-    it" markus@
-    
-    Upstream-ID: c78c38f9f81a963b33d0eade559f6048add24a6d
-
-commit c924b2ef941028a1f31e6e94f54dfeeeef462a4e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 3 05:05:56 2017 +0000
-
-    upstream commit
-    
-    allow form-feed characters at EOL; bz#2431 ok dtucker@
-    
-    Upstream-ID: 1f453afaba6da2ae69d6afdf1ae79a917552f1a2
-
-commit 523db8540b720c4d21ab0ff6f928476c70c38aab
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Feb 3 16:01:22 2017 +1100
-
-    prefer to use ldns-config to find libldns
-    
-    Should fix bz#2603 - "Build with ldns and without kerberos support
-    fails if ldns compiled with kerberos support" by including correct
-    cflags/libs
-    
-    ok dtucker@
-
-commit c998bf0afa1a01257a53793eba57941182e9e0b7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Feb 3 02:56:00 2017 +0000
-
-    upstream commit
-    
-    Make ssh_packet_set_rekey_limits take u32 for the number of
-    seconds until rekeying (negative values are rejected at config parse time).
-    This allows the removal of some casts and a signed vs unsigned comparison
-    warning.
-    
-    rekey_time is cast to int64 for the comparison which is a no-op
-    on OpenBSD, but should also do the right thing in -portable on
-    anything still using 32bit time_t (until the system time actually
-    wraps, anyway).
-    
-    some early guidance deraadt@, ok djm@
-    
-    Upstream-ID: c9f18613afb994a07e7622eb326f49de3d123b6c
-
-commit 3ec5fa4ba97d4c4853620daea26a33b9f1fe3422
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Thu Feb 2 10:54:25 2017 +0000
-
-    upstream commit
-    
-    In vasnmprintf() return an error if malloc fails and
-    don't set a function argument to the address of free'd memory.
-    
-    ok djm@
-    
-    Upstream-ID: 1efffffff2f51d53c9141f245b90ac23d33b9779
-
-commit 858252fb1d451ebb0969cf9749116c8f0ee42753
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Feb 1 02:59:09 2017 +0000
-
-    upstream commit
-    
-    Return true reason for port forwarding failures where
-    feasible rather than always "administratively prohibited".  bz#2674, ok djm@
-    
-    Upstream-ID: d901d9887951774e604ca970e1827afaaef9e419
-
-commit 6ba9f893838489add6ec4213c7a997b425e4a9e0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Jan 30 23:27:39 2017 +0000
-
-    upstream commit
-    
-    Small correction to the known_hosts section on when it is
-    updated. Patch from lkppo at free.fr some time ago, pointed out by smallm at
-    sdf.org
-    
-    Upstream-ID: 1834d7af179dea1a12ad2137f84566664af225d5
-
-commit c61d5ec3c11e7ff9779b6127421d9f166cf10915
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Feb 3 14:10:34 2017 +1100
-
-    Remove _XOPEN_SOURCE from wide char detection.
-    
-    Having _XOPEN_SOURCE unconditionally causes problems on some platforms
-    and configurations, notably Solaris 64-bit binaries.  It was there for
-    the benefit of Linux put the required bits in the *-*linux* section.
-    
-    Patch from yvoinov at gmail.com.
-
-commit f25ee13b3e81fd80efeb871dc150fe49d7fc8afd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 05:22:14 2017 +0000
-
-    upstream commit
-    
-    fully unbreak: some $SSH invocations did not have -F
-    specified and could pick up the ~/.ssh/config of the user running the tests
-    
-    Upstream-Regress-ID: f362d1892c0d3e66212d5d3fc02d915c58ef6b89
-
-commit 6956e21fb26652887475fe77ea40d2efcf25908b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 04:54:07 2017 +0000
-
-    upstream commit
-    
-    partially unbreak: was not specifying hostname on some
-    $SSH invocations
-    
-    Upstream-Regress-ID: bc8a5e98e57bad0a92ef4f34ed91c1d18294e2cc
-
-commit 52763dd3fe0a4678dafdf7aeb32286e514130afc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 01:03:00 2017 +0000
-
-    upstream commit
-    
-    revise keys/principals command hang fix (bz#2655) to
-    consume entire output, avoiding sending SIGPIPE to subprocesses early; ok
-    dtucker@
-    
-    Upstream-ID: 7cb04b31a61f8c78c4e48ceededcd2fd5c4ee1bc
-
-commit 381a2615a154a82c4c53b787f4a564ef894fe9ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 00:38:50 2017 +0000
-
-    upstream commit
-    
-    small cleanup post SSHv1 removal:
-    
-    remove SSHv1-isms in commented examples
-    
-    reorder token table to group deprecated and compile-time conditional tokens
-    better
-    
-    fix config dumping code for some compile-time conditional options that
-    weren't being correctly skipped (SSHv1 and PKCS#11)
-    
-    Upstream-ID: f2e96b3cb3158d857c5a91ad2e15925df3060105
-
-commit 4833d01591b7eb049489d9558b65f5553387ed43
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 00:34:01 2017 +0000
-
-    upstream commit
-    
-    some explicit NULL tests when dumping configured
-    forwardings; from Karsten Weiss
-    
-    Upstream-ID: 40957b8dea69672b0e50df6b4a91a94e3e37f72d
-
-commit 326e2fae9f2e3e067b5651365eba86b35ee5a6b2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 00:32:28 2017 +0000
-
-    upstream commit
-    
-    misplaced braces in test; from Karsten Weiss
-    
-    Upstream-ID: f7b794074d3aae8e35b69a91d211c599c94afaae
-
-commit 3e032a95e46bfaea9f9e857678ac8fa5f63997fb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jan 30 00:32:03 2017 +0000
-
-    upstream commit
-    
-    don't dereference authctxt before testing != NULL, it
-    causes compilers to make assumptions; from Karsten Weiss
-    
-    Upstream-ID: 794243aad1e976ebc717885b7a97a25e00c031b2
-
-commit 01cfaa2b1cfb84f3cdd32d1bf82b120a8d30e057
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 6 02:51:16 2017 +0000
-
-    upstream commit
-    
-    use correct ssh-add program; bz#2654, from Colin Watson
-    
-    Upstream-Regress-ID: 7042a36e1bdaec6562f6e57e9d047efe9c7a6030
-
-commit e5c7ec67cdc42ae2584085e0fc5cc5ee91133cf5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 6 02:26:10 2017 +0000
-
-    upstream commit
-    
-    Account for timeouts in the integrity tests as failures.
-    
-    If the first test in a series for a given MAC happens to modify the low
-    bytes of a packet length, then ssh will time out and this will be
-    interpreted as a test failure.  Patch from cjwatson at debian.org via
-    bz#2658.
-    
-    Upstream-Regress-ID: e7467613b0badedaa300bc6fc7495ec2f44e2fb9
-
-commit dbaf599b61bd6e0f8469363a8c8e7f633b334018
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 6 02:09:25 2017 +0000
-
-    upstream commit
-    
-    Make forwarding test less racy by using unix domain
-    sockets instead of TCP ports where possible.  Patch from cjwatson at
-    debian.org via bz#2659.
-    
-    Upstream-Regress-ID: 4756375aac5916ef9d25452a1c1d5fa9e90299a9
-
-commit 9390b0031ebd6eb5488d3bc4d4333c528dffc0a6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Sun Jan 29 21:35:23 2017 +0000
-
-    upstream commit
-    
-    Fix typo in ~C error message for bad port forward
-    cancellation. bz#2672, from Brad Marshall via Colin Watson and Ubuntu's
-    bugtracker.
-    
-    Upstream-ID: 0d4a7e5ead6cc59c9a44b4c1e5435ab3aada09af
-
-commit 4ba15462ca38883b8a61a1eccc093c79462d5414
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Sat Jan 21 11:32:04 2017 +0000
-
-    upstream commit
-    
-    The POSIX APIs that that sockaddrs all ignore the s*_len
-    field in the incoming socket, so userspace doesn't need to set it unless it
-    has its own reasons for tracking the size along with the sockaddr.
-    
-    ok phessler@ deraadt@ florian@
-    
-    Upstream-ID: ca6e49e2f22f2b9e81d6d924b90ecd7e422e7437
-
-commit a1187bd3ef3e4940af849ca953a1b849dae78445
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Jan 6 16:28:12 2017 +0000
-
-    upstream commit
-    
-    keep the tokens list sorted;
-    
-    Upstream-ID: b96239dae4fb3aa94146bb381afabcc7740a1638
-
-commit b64077f9767634715402014f509e58decf1e140d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 6 09:27:52 2017 +0000
-
-    upstream commit
-    
-    fix previous
-    
-    Upstream-ID: c107d6a69bc22325d79fbf78a2a62e04bcac6895
-
-commit 5e820e9ea2e949aeb93071fe31c80b0c42f2b2de
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 6 03:53:58 2017 +0000
-
-    upstream commit
-    
-    show a useful error message when included config files
-    can't be opened; bz#2653, ok dtucker@
-    
-    Upstream-ID: f598b73b5dfe497344cec9efc9386b4e5a3cb95b
-
-commit 13bd2e2d622d01dc85d22b94520a5b243d006049
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 6 03:45:41 2017 +0000
-
-    upstream commit
-    
-    sshd_config is documented to set
-    GSSAPIStrictAcceptorCheck=yes by default, so actually make it do this.
-    bz#2637 ok dtucker
-    
-    Upstream-ID: 99ef8ac51f17f0f7aec166cb2e34228d4d72a665
-
-commit f89b928534c9e77f608806a217d39a2960cc7fd0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 6 03:41:58 2017 +0000
-
-    upstream commit
-    
-    Avoid confusing error message when attempting to use
-    ssh-keyscan built without SSH protocol v.1 to scan for v.1 keys; bz#2583
-    
-    Upstream-ID: 5d214abd3a21337d67c6dcc5aa6f313298d0d165
-
-commit 0999533014784579aa6f01c2d3a06e3e8804b680
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 6 02:34:54 2017 +0000
-
-    upstream commit
-    
-    Re-add '%k' token for AuthorizedKeysCommand which was
-    lost during the re-org in rev 1.235.  bz#2656, from jboning at gmail.com.
-    
-    Upstream-ID: 2884e203c02764d7b3fe7472710d9c24bdc73e38
-
-commit 51045869fa084cdd016fdd721ea760417c0a3bf3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jan 4 05:37:40 2017 +0000
-
-    upstream commit
-    
-    unbreak Unix domain socket forwarding for root; ok
-    markus@
-    
-    Upstream-ID: 6649c76eb7a3fa15409373295ca71badf56920a2
-
-commit 58fca12ba967ea5c768653535604e1522d177e44
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jan 16 09:08:32 2017 +1100
-
-    Remove LOGIN_PROGRAM.
-    
-    UseLogin is gone, remove leftover.  bz#2665, from cjwatson at debian.org
-
-commit b108ce92aae0ca0376dce9513d953be60e449ae1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jan 4 02:21:43 2017 +0000
-
-    upstream commit
-    
-    relax PKCS#11 whitelist a bit to allow libexec as well as
-    lib directories.
-    
-    Upstream-ID: cf5617958e2e2d39f8285fd3bc63b557da484702
-
-commit c7995f296b9222df2846f56ecf61e5ae13d7a53d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jan 3 05:46:51 2017 +0000
-
-    upstream commit
-    
-    check number of entries in SSH2_FXP_NAME response; avoids
-    unreachable overflow later. Reported by Jann Horn
-    
-    Upstream-ID: b6b2b434a6d6035b1644ca44f24cd8104057420f
-
-commit ddd3d34e5c7979ca6f4a3a98a7d219a4ed3d98c2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 30 22:08:02 2016 +0000
-
-    upstream commit
-    
-    fix deadlock when keys/principals command produces a lot of
-    output and a key is matched early; bz#2655, patch from jboning AT gmail.com
-    
-    Upstream-ID: e19456429bf99087ea994432c16d00a642060afe
-
-commit 30eee7d1b2fec33c14870cc11910610be5d2aa6f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 20 12:16:11 2016 +1100
-
-    Re-add missing "Prerequisites" header and fix typo
-    
-    Patch from HARUYAMA Seigo <haruyama at unixuser org>.
-
-commit c8c60f3663165edd6a52632c6ddbfabfce1ca865
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Dec 19 22:35:23 2016 +0000
-
-    upstream commit
-    
-    use standard /bin/sh equality test; from Mike Frysinger
-    
-    Upstream-Regress-ID: 7b6f0b63525f399844c8ac211003acb8e4b0bec2
-
-commit 4a354fc231174901f2629437c2a6e924a2dd6772
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Dec 19 15:59:26 2016 +1100
-
-    crank version numbers for release
-
-commit 5f8d0bb8413d4d909cc7aa3c616fb0538224c3c9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Dec 19 04:55:51 2016 +0000
-
-    upstream commit
-    
-    openssh-7.4
-    
-    Upstream-ID: 1ee404adba6bbe10ae9277cbae3a94abe2867b79
-
-commit 3a8213ea0ed843523e34e55ab9c852332bab4c7b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Dec 19 04:55:18 2016 +0000
-
-    upstream commit
-    
-    remove testcase that depends on exact output and
-    behaviour of snprintf(..., "%s", NULL)
-    
-    Upstream-Regress-ID: cab4288531766bd9593cb556613b91a2eeefb56f
-
-commit eae735a82d759054f6ec7b4e887fb7a5692c66d7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Dec 19 03:32:57 2016 +0000
-
-    upstream commit
-    
-    Use LOGNAME to get current user and fall back to whoami if
-    not set. Mainly to benefit -portable since some platforms don't have whoami.
-    
-    Upstream-Regress-ID: e3a16b7836a3ae24dc8f8a4e43fdf8127a60bdfa
-
-commit 0d2f88428487518eea60602bd593989013831dcf
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Dec 16 03:51:19 2016 +0000
-
-    upstream commit
-    
-    Add regression test for AllowUsers and DenyUsers.  Patch from
-    Zev Weiss <zev at bewilderbeest.net>
-    
-    Upstream-Regress-ID: 8f1aac24d52728398871dac14ad26ea38b533fb9
-
-commit 3bc8180a008929f6fe98af4a56fb37d04444b417
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Dec 16 15:02:24 2016 +1100
-
-    Add missing monitor.h include.
-    
-    Fixes warning pointed out by Zev Weiss <zev at bewilderbeest.net>
-
-commit 410681f9015d76cc7b137dd90dac897f673244a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 16 02:48:55 2016 +0000
-
-    upstream commit
-    
-    revert to rev1.2; the new bits in this test depend on changes
-    to ssh that aren't yet committed
-    
-    Upstream-Regress-ID: 828ffc2c7afcf65d50ff2cf3dfc47a073ad39123
-
-commit 2f2ffa4fbe4b671bbffa0611f15ba44cff64d58e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Dec 16 01:06:27 2016 +0000
-
-    upstream commit
-    
-    Move the "stop sshd" code into its own helper function.
-    Patch from Zev Weiss <zev at bewilderbeest.net>, ok djm@
-    
-    Upstream-Regress-ID: a113dea77df5bd97fb4633ea31f3d72dbe356329
-
-commit e15e7152331e3976b35475fd4e9c72897ad0f074
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 16 01:01:07 2016 +0000
-
-    upstream commit
-    
-    regression test for certificates along with private key
-    with no public half. bz#2617, mostly from Adam Eijdenberg
-    
-    Upstream-Regress-ID: 2e74dc2c726f4dc839609b3ce045466b69f01115
-
-commit 9a70ec085faf6e55db311cd1a329f1a35ad2a500
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Dec 15 23:50:37 2016 +0000
-
-    upstream commit
-    
-    Use $SUDO to read pidfile in case root's umask is
-    restricted.  From portable.
-    
-    Upstream-Regress-ID: f6b1c7ffbc5a0dfb7d430adb2883344899174a98
-
-commit fe06b68f824f8f55670442fb31f2c03526dd326c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Dec 15 21:29:05 2016 +0000
-
-    upstream commit
-    
-    Add missing braces in DenyUsers code.  Patch from zev at
-    bewilderbeest.net, ok deraadt@
-    
-    Upstream-ID: d747ace338dcf943b077925f90f85f789714b54e
-
-commit dcc7d74242a574fd5c4afbb4224795b1644321e7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Dec 15 21:20:41 2016 +0000
-
-    upstream commit
-    
-    Fix text in error message.  Patch from zev at
-    bewilderbeest.net.
-    
-    Upstream-ID: deb0486e175e7282f98f9a15035d76c55c84f7f6
-
-commit b737e4d7433577403a31cff6614f6a1b0b5e22f4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Dec 14 00:36:34 2016 +0000
-
-    upstream commit
-    
-    disable Unix-domain socket forwarding when privsep is
-    disabled
-    
-    Upstream-ID: ab61516ae0faadad407857808517efa900a0d6d0
-
-commit 08a1e7014d65c5b59416a0e138c1f73f417496eb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 9 03:04:29 2016 +0000
-
-    upstream commit
-    
-    log connections dropped in excess of MaxStartups at
-    verbose LogLevel; bz#2613 based on diff from Tomas Kuthan; ok dtucker@
-    
-    Upstream-ID: 703ae690dbf9b56620a6018f8a3b2389ce76d92b
-
-commit 10e290ec00964b2bf70faab15a10a5574bb80527
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 13 13:51:32 2016 +1100
-
-    Get default of TEST_SSH_UTF8 from environment.
-
-commit b9b8ba3f9ed92c6220b58d70d1e6d8aa3eea1104
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 13 12:56:40 2016 +1100
-
-    Remove commented-out includes.
-    
-    These commented-out includes have "Still needed?" comments.  Since
-    they've been commented out for ~13 years I assert that they're not.
-
-commit 25275f1c9d5f01a0877d39444e8f90521a598ea0
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 13 12:54:23 2016 +1100
-
-    Add prototype for strcasestr in compat library.
-
-commit afec07732aa2985142f3e0b9a01eb6391f523dec
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 13 10:23:03 2016 +1100
-
-    Add strcasestr to compat library.
-    
-    Fixes build on (at least) Solaris 10.
-
-commit dda78a03af32e7994f132d923c2046e98b7c56c8
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Dec 12 13:57:10 2016 +1100
-
-    Force Turkish locales back to C/POSIX; bz#2643
-    
-    Turkish locales are unique in their handling of the letters 'i' and
-    'I' (yes, they are different letters) and OpenSSH isn't remotely
-    prepared to deal with that. For now, the best we can do is to force
-    OpenSSH to use the C/POSIX locale and try to preserve the UTF-8
-    encoding if possible.
-    
-    ok dtucker@
-
-commit c35995048f41239fc8895aadc3374c5f75180554
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Dec 9 12:52:02 2016 +1100
-
-    exit is in stdlib.h not unistd.h (that's _exit).
-
-commit d399a8b914aace62418c0cfa20341aa37a192f98
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Dec 9 12:33:25 2016 +1100
-
-    Include <unistd.h> for exit in utf8 locale test.
-
-commit 47b8c99ab3221188ad3926108dd9d36da3b528ec
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Dec 8 15:48:34 2016 +1100
-
-    Check for utf8 local support before testing it.
-    
-    Check for utf8 local support and if not found, do not attempt to run the
-    utf8 tests.  Suggested by djm@
-
-commit 4089fc1885b3a2822204effbb02b74e3da58240d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Dec 8 12:57:24 2016 +1100
-
-    Use AC_PATH_TOOL for krb5-config.
-    
-    This will use the host-prefixed version when cross compiling; patch from
-    david.michael at coreos.com.
-
-commit b4867e0712c89b93be905220c82f0a15e6865d1e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Dec 6 07:48:01 2016 +0000
-
-    upstream commit
-    
-    make IdentityFile successfully load and use certificates that
-    have no corresponding bare public key. E.g. just a private id_rsa and
-    certificate id_rsa-cert.pub (and no id_rsa.pub).
-    
-    bz#2617 ok dtucker@
-    
-    Upstream-ID: c1e9699b8c0e3b63cc4189e6972e3522b6292604
-
-commit c9792783a98881eb7ed295680013ca97a958f8ac
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Nov 25 14:04:21 2016 +1100
-
-    Add a gnome-ssh-askpass3 target for GTK+3 version
-    
-    Based on patch from Colin Watson via bz#2640
-
-commit 7be85ae02b9de0993ce0a1d1e978e11329f6e763
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Nov 25 14:03:53 2016 +1100
-
-    Make gnome-ssh-askpass2.c GTK+3-friendly
-    
-    Patch from Colin Watson via bz#2640
-
-commit b9844a45c7f0162fd1b5465683879793d4cc4aaa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Dec 4 23:54:02 2016 +0000
-
-    upstream commit
-    
-    Fix public key authentication when multiple
-    authentication is in use. Instead of deleting and re-preparing the entire
-    keys list, just reset the 'used' flags; the keys list is already in a good
-    order (with already- tried keys at the back)
-    
-    Analysis and patch from Vincent Brillault on bz#2642; ok dtucker@
-    
-    Upstream-ID: 7123f12dc2f3bcaae715853035a97923d7300176
-
-commit f2398eb774075c687b13af5bc22009eb08889abe
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Sun Dec 4 22:27:25 2016 +0000
-
-    upstream commit
-    
-    Unlink PidFile on SIGHUP and always recreate it when the
-    new sshd starts. Regression tests (and possibly other things) depend on the
-    pidfile being recreated after SIGHUP, and unlinking it means it won't contain
-    a stale pid if sshd fails to restart.  ok djm@ markus@
-    
-    Upstream-ID: 132dd6dda0c77dd49d2f15b2573b5794f6160870
-
-commit 85aa2efeba51a96bf6834f9accf2935d96150296
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 30 03:01:33 2016 +0000
-
-    upstream commit
-    
-    test new behaviour of cert force-command restriction vs.
-    authorized_key/ principals
-    
-    Upstream-Regress-ID: 399efa7469d40c404c0b0a295064ce75d495387c
-
-commit 5d333131cd8519d022389cfd3236280818dae1bc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Nov 30 06:54:26 2016 +0000
-
-    upstream commit
-    
-    tweak previous; while here fix up FILES and AUTHORS;
-    
-    Upstream-ID: 93f6e54086145a75df8d8ec7d8689bdadbbac8fa
-
-commit 786d5994da79151180cb14a6cf157ebbba61c0cc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 30 03:07:37 2016 +0000
-
-    upstream commit
-    
-    add a whitelist of paths from which ssh-agent will load
-    (via ssh-pkcs11-helper) a PKCS#11 module; ok markus@
-    
-    Upstream-ID: fe79769469d9cd6d26fe0dc15751b83ef2a06e8f
-
-commit 7844f357cdd90530eec81340847783f1f1da010b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 30 03:00:05 2016 +0000
-
-    upstream commit
-    
-    Add a sshd_config DisableForwaring option that disables
-    X11, agent, TCP, tunnel and Unix domain socket forwarding, as well as
-    anything else we might implement in the future.
-    
-    This, like the 'restrict' authorized_keys flag, is intended to be a
-    simple and future-proof way of restricting an account. Suggested as
-    a complement to 'restrict' by Jann Horn; ok markus@
-    
-    Upstream-ID: 203803f66e533a474086b38a59ceb4cf2410fcf7
-
-commit fd6dcef2030d23c43f986d26979f84619c10589d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 30 02:57:40 2016 +0000
-
-    upstream commit
-    
-    When a forced-command appears in both a certificate and
-    an authorized keys/principals command= restriction, refuse to accept the
-    certificate unless they are identical.
-    
-    The previous (documented) behaviour of having the certificate forced-
-    command override the other could be a bit confused and more error-prone.
-    
-    Pointed out by Jann Horn of Project Zero; ok dtucker@
-    
-    Upstream-ID: 79d811b6eb6bbe1221bf146dde6928f92d2cd05f
-
-commit 7fc4766ac78abae81ee75b22b7550720bfa28a33
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Nov 30 00:28:31 2016 +0000
-
-    upstream commit
-    
-    On startup, check to see if sshd is already daemonized
-    and if so, skip the call to daemon() and do not rewrite the PidFile.  This
-    means that when sshd re-execs itself on SIGHUP the process ID will no longer
-    change.  Should address bz#2641.  ok djm@ markus@.
-    
-    Upstream-ID: 5ea0355580056fb3b25c1fd6364307d9638a37b9
-
-commit c9f880c195c65f1dddcbc4ce9d6bfea7747debcc
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Nov 30 13:51:49 2016 +1100
-
-    factor out common PRNG reseed before privdrop
-    
-    Add a call to RAND_poll() to ensure than more than pid+time gets
-    stirred into child processes states. Prompted by analysis from Jann
-    Horn at Project Zero. ok dtucker@
-
-commit 79e4829ec81dead1b30999e1626eca589319a47f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Nov 25 03:02:01 2016 +0000
-
-    upstream commit
-    
-    Allow PuTTY interop tests to run unattended.  bz#2639,
-    patch from cjwatson at debian.org.
-    
-    Upstream-Regress-ID: 4345253558ac23b2082aebabccd48377433b6fe0
-
-commit 504c3a9a1bf090f6b27260fc3e8ea7d984d163dc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Nov 25 02:56:49 2016 +0000
-
-    upstream commit
-    
-    Reverse args to sshd-log-wrapper.  Matches change in
-    portable, where it allows sshd do be optionally run under Valgrind.
-    
-    Upstream-Regress-ID: b438d1c6726dc5caa2a45153e6103a0393faa906
-
-commit bd13017736ec2f8f9ca498fe109fb0035f322733
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Nov 25 02:49:18 2016 +0000
-
-    upstream commit
-    
-    Fix typo in trace message; from portable.
-    
-    Upstream-Regress-ID: 4c4a2ba0d37faf5fd230a91b4c7edb5699fbd73a
-
-commit 7da751d8b007c7f3e814fd5737c2351440d78b4c
-Author: tb@openbsd.org <tb@openbsd.org>
-Date:   Tue Nov 1 13:43:27 2016 +0000
-
-    upstream commit
-    
-    Clean up MALLOC_OPTIONS.  For the unittests, move
-    MALLOC_OPTIONS and TEST_ENV to unittets/Makefile.inc.
-    
-    ok otto
-    
-    Upstream-Regress-ID: 890d497e0a38eeddfebb11cc429098d76cf29f12
-
-commit 36f58e68221bced35e06d1cca8d97c48807a8b71
-Author: tb@openbsd.org <tb@openbsd.org>
-Date:   Mon Oct 31 23:45:08 2016 +0000
-
-    upstream commit
-    
-    Remove the obsolete A and P flags from MALLOC_OPTIONS.
-    
-    ok dtucker
-    
-    Upstream-Regress-ID: 6cc25024c8174a87e5734a0dc830194be216dd59
-
-commit b0899ee26a6630883c0f2350098b6a35e647f512
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Nov 29 03:54:50 2016 +0000
-
-    upstream commit
-    
-    Factor out code to disconnect from controlling terminal
-    into its own function.  ok djm@
-    
-    Upstream-ID: 39fd9e8ebd7222615a837312face5cc7ae962885
-
-commit 54d022026aae4f53fa74cc636e4a032d9689b64d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 25 23:24:45 2016 +0000
-
-    upstream commit
-    
-    use sshbuf_allocate() to pre-allocate the buffer used for
-    loading keys. This avoids implicit realloc inside the buffer code, which
-    might theoretically leave fragments of the key on the heap. This doesn't
-    appear to happen in practice for normal sized keys, but was observed for
-    novelty oversize ones.
-    
-    Pointed out by Jann Horn of Project Zero; ok markus@
-    
-    Upstream-ID: d620e1d46a29fdea56aeadeda120879eddc60ab1
-
-commit a9c746088787549bb5b1ae3add7d06a1b6d93d5e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 25 23:22:04 2016 +0000
-
-    upstream commit
-    
-    split allocation out of sshbuf_reserve() into a separate
-    sshbuf_allocate() function; ok markus@
-    
-    Upstream-ID: 11b8a2795afeeb1418d508a2c8095b3355577ec2
-
-commit f0ddedee460486fa0e32fefb2950548009e5026e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Nov 23 23:14:15 2016 +0000
-
-    upstream commit
-    
-    allow ClientAlive{Interval,CountMax} in Match; ok dtucker,
-    djm
-    
-    Upstream-ID: 8beb4c1eadd588f1080b58932281983864979f55
-
-commit 1a6f9d2e2493d445cd9ee496e6e3c2a2f283f66a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Nov 8 22:04:34 2016 +0000
-
-    upstream commit
-    
-    unbreak DenyUsers; reported by henning@
-    
-    Upstream-ID: 1c67d4148f5e953c35acdb62e7c08ae8e33f7cb2
-
-commit 010359b32659f455fddd2bd85fd7cc4d7a3b994a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Nov 6 05:46:37 2016 +0000
-
-    upstream commit
-    
-    Validate address ranges for AllowUser/DenyUsers at
-    configuration load time and refuse to accept bad ones. It was previously
-    possible to specify invalid CIDR address ranges (e.g. djm@127.1.2.3/55) and
-    these would always match.
-    
-    Thanks to Laurence Parry for a detailed bug report. ok markus (for
-    a previous diff version)
-    
-    Upstream-ID: 9dfcdd9672b06e65233ea4434c38226680d40bfb
-
-commit efb494e81d1317209256b38b49f4280897c61e69
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Oct 28 03:33:52 2016 +0000
-
-    upstream commit
-    
-    Improve pkcs11_add_provider() logging: demote some
-    excessively verbose error()s to debug()s, include PKCS#11 provider name and
-    slot in log messages where possible. bz#2610, based on patch from Jakub Jelen
-    
-    Upstream-ID: 3223ef693cfcbff9079edfc7e89f55bf63e1973d
-
-commit 5ee3fb5affd7646f141749483205ade5fc54adaf
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Nov 1 08:12:33 2016 +1100
-
-    Use ptrace(PT_DENY_ATTACH, ..) on OS X.
-
-commit 315d2a4e674d0b7115574645cb51f968420ebb34
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Oct 28 14:34:07 2016 +1100
-
-    Unbreak AES-CTR ciphers on old (~0.9.8) OpenSSL
-    
-    ok dtucker@
-
-commit a9ff3950b8e80ff971b4d44bbce96df27aed28af
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 28 14:26:58 2016 +1100
-
-    Move OPENSSL_NO_RIPEMD160 to compat.
-    
-    Move OPENSSL_NO_RIPEMD160 to compat and add ifdefs to mac.c around the
-    ripemd160 MACs.
-
-commit bce58885160e5db2adda3054c3b81fe770f7285a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 28 13:52:31 2016 +1100
-
-    Check if RIPEMD160 is disabled in OpenSSL.
-
-commit d924640d4c355d1b5eca1f4cc60146a9975dbbff
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 28 13:38:19 2016 +1100
-
-    Skip ssh1 specfic ciphers.
-    
-    cipher-3des1.c and cipher-bf1.c are specific to sshv1 so don't even try
-    to compile them when Protocol 1 is not enabled.
-
-commit 79d078e7a49caef746516d9710ec369ba45feab6
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Tue Oct 25 04:08:13 2016 +0000
-
-    upstream commit
-    
-    Fix logic in add_local_forward() that inverted a test
-    when code was refactored out into bind_permitted().  This broke ssh port
-    forwarding for non-priv ports as a non root user.
-    
-    ok dtucker@ 'looks good' deraadt@
-    
-    Upstream-ID: ddb8156ca03cc99997de284ce7777536ff9570c9
-
-commit a903e315dee483e555c8a3a02c2946937f9b4e5d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Oct 24 01:09:17 2016 +0000
-
-    upstream commit
-    
-    Remove dead breaks, found via opencoverage.net.  ok
-    deraadt@
-    
-    Upstream-ID: ad9cc655829d67fad219762810770787ba913069
-
-commit b4e96b4c9bea4182846e4942ba2048e6d708ee54
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Oct 26 08:43:25 2016 +1100
-
-    Use !=NULL instead of >0 for getdefaultproj.
-    
-    getdefaultproj() returns a pointer so test it for NULL inequality
-    instead of >0.  Fixes compiler warning and is more correct.  Patch from
-    David Binderman.
-
-commit 1c4ef0b808d3d38232aeeb1cebb7e9a43def42c5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Sun Oct 23 22:04:05 2016 +0000
-
-    upstream commit
-    
-    Factor out "can bind to low ports" check into its own function.  This will
-    make it easier for Portable to support platforms with permissions models
-    other than uid==0 (eg bz#2625).  ok djm@, "doesn't offend me too much"
-    deraadt@.
-    
-    Upstream-ID: 86213df4183e92b8f189a6d2dac858c994bfface
-
-commit 0b9ee623d57e5de7e83e66fd61a7ba9a5be98894
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Oct 19 23:21:56 2016 +0000
-
-    upstream commit
-    
-    When tearing down ControlMaster connecctions, don't
-    pollute stderr when LogLevel=quiet.  Patch from Tim Kuijsten via tech@.
-    
-    Upstream-ID: d9b3a68b2a7c2f2fc7f74678e29a4618d55ceced
-
-commit 09e6a7d8354224933febc08ddcbc2010f542284e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Oct 24 09:06:18 2016 +1100
-
-    Wrap stdint.h include in ifdef.
-
-commit 08d9e9516e587b25127545c029e5464b2e7f2919
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 21 09:46:46 2016 +1100
-
-    Fix formatting.
-
-commit 461f50e7ab8751d3a55e9158c44c13031db7ba1d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 21 06:55:58 2016 +1100
-
-    Update links to https.
-    
-    www.openssh.com now supports https and ftp.openbsd.org no longer
-    supports ftp.  Make all links to these https.
-
-commit dd4e7212a6141f37742de97795e79db51e4427ad
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 21 06:48:46 2016 +1100
-
-    Update host key generation examples.
-    
-    Remove ssh1 host key generation, add ssh-keygen -A
-
-commit 6d49ae82634c67e9a4d4af882bee20b40bb8c639
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Oct 21 05:22:55 2016 +1100
-
-    Update links.
-    
-    Make links to openssh.com HTTPS now that it's supported, point release
-    notes link to the HTML release notes page, and update a couple of other
-    links and bits of text.
-
-commit fe0d1ca6ace06376625084b004ee533f2c2ea9d6
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 20 03:42:09 2016 +1100
-
-    Remote channels .orig and .rej files.
-    
-    These files were incorrectly added during an OpenBSD sync.
-
-commit 246aa842a4ad368d8ce030495e657ef3a0e1f95c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Oct 18 17:32:54 2016 +0000
-
-    upstream commit
-    
-    Remove channel_input_port_forward_request(); the only caller
-    was the recently-removed SSH1 server code so it's now dead code.  ok markus@
-    
-    Upstream-ID: 05453983230a1f439562535fec2818f63f297af9
-
-commit 2c6697c443d2c9c908260eed73eb9143223e3ec9
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Tue Oct 18 12:41:22 2016 +0000
-
-    upstream commit
-    
-    Install a signal handler for tty-generated signals and
-    wait for the ssh child to suspend before suspending sftp.  This lets ssh
-    restore the terminal mode as needed when it is suspended at the password
-    prompt.  OK dtucker@
-    
-    Upstream-ID: a31c1f42aa3e2985dcc91e46e6a17bd22e372d69
-
-commit fd2a8f1033fa2316fff719fd5176968277560158
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sat Oct 15 19:56:25 2016 +0000
-
-    upstream commit
-    
-    various formatting fixes, specifically removing Dq;
-    
-    Upstream-ID: 81e85df2b8e474f5f93d66e61d9a4419ce87347c
-
-commit 8f866d8a57b9a2dc5dd04504e27f593b551618e3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Oct 19 03:26:09 2016 +1100
-
-    Import readpassphrase.c rev 1.26.
-    
-    Author: miller@openbsd.org:
-    Avoid generate SIGTTOU when restoring the terminal mode.  If we get
-    SIGTTOU it means the process is not in the foreground process group
-    which, in most cases, means that the shell has taken control of the tty.
-    Requiring the user the fg the process in this case doesn't make sense
-    and can result in both SIGTSTP and SIGTTOU being sent which can lead to
-    the process being suspended again immediately after being brought into
-    the foreground.
-
-commit f901440cc844062c9bab0183d133f7ccc58ac3a5
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Oct 19 03:23:16 2016 +1100
-
-    Import readpassphrase.c rev 1.25.
-    
-    Wrap <readpassphrase.h> so internal calls go direct and
-    readpassphrase is weak.
-    
-    (DEF_WEAK is a no-op in portable.)
-
-commit 032147b69527e5448a511049b2d43dbcae582624
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Sat Oct 15 05:51:12 2016 +1100
-
-    Move DEF_WEAK into defines.h.
-    
-    As well pull in more recent changes from OpenBSD these will start to
-    arrive so put it where the definition is shared.
-
-commit e0259a82ddd950cfb109ddee86fcebbc09c6bd04
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Sat Oct 15 04:34:46 2016 +1100
-
-    Remove do_pam_set_tty which is dead code.
-    
-    The callers of do_pam_set_tty were removed in 2008, so this is now dead
-    code.  bz#2604, pointed out by jjelen at redhat.com.
-
-commit ca04de83f210959ad2ed870a30ba1732c3ae00e3
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Oct 13 18:53:43 2016 +1100
-
-    unbreak principals-command test
-    
-    Undo inconsistetly updated variable name.
-
-commit 1723ec92eb485ce06b4cbf49712d21975d873909
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 11 21:49:54 2016 +0000
-
-    upstream commit
-    
-    fix the KEX fuzzer - the previous method of obtaining the
-    packet contents was broken. This now uses the new per-packet input hook, so
-    it sees exact post-decrypt packets and doesn't have to pass packet integrity
-    checks. ok markus@
-    
-    Upstream-Regress-ID: 402fb6ffabd97de590e8e57b25788949dce8d2fd
-
-commit 09f997893f109799cddbfce6d7e67f787045cbb2
-Author: natano@openbsd.org <natano@openbsd.org>
-Date:   Thu Oct 6 09:31:38 2016 +0000
-
-    upstream commit
-    
-    Move USER out of the way to unbreak the BUILDUSER
-    mechanism. ok tb
-    
-    Upstream-Regress-ID: 74ab9687417dd071d62316eaadd20ddad1d5af3c
-
-commit 3049a012c482a7016f674db168f23fd524edce27
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date:   Fri Sep 30 11:55:20 2016 +0000
-
-    upstream commit
-    
-    In ssh tests set REGRESS_FAIL_EARLY with ?= so that the
-    environment can change it. OK djm@
-    
-    Upstream-Regress-ID: 77bcb50e47b68c7209c7f0a5a020d73761e5143b
-
-commit 39af7b444db28c1cb01b7ea468a4f574a44f375b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 11 21:47:45 2016 +0000
-
-    upstream commit
-    
-    Add a per-packet input hook that is called with the
-    decrypted packet contents. This will be used for fuzzing; ok markus@
-    
-    Upstream-ID: a3221cee6b1725dd4ae1dd2c13841b4784cb75dc
-
-commit ec165c392ca54317dbe3064a8c200de6531e89ad
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Mon Oct 10 19:28:48 2016 +0000
-
-    upstream commit
-    
-    Unregister the KEXINIT handler after message has been
-    received. Otherwise an unauthenticated peer can repeat the KEXINIT and cause
-    allocation of up to 128MB -- until the connection is closed. Reported by
-    shilei-c at 360.cn
-    
-    Upstream-ID: 43649ae12a27ef94290db16d1a98294588b75c05
-
-commit 29d40319392e6e19deeca9d45468aa1119846e50
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 13 04:07:20 2016 +1100
-
-    Import rev 1.24 from OpenBSD.
-    
-    revision 1.24
-    date: 2013/11/24 23:51:29;  author: deraadt;  state: Exp;  lines: +4 -4;
-    most obvious unsigned char casts for ctype
-    ok jca krw ingo
-
-commit 12069e56221de207ed666c2449dedb431a2a7ca2
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 13 04:04:44 2016 +1100
-
-    Import rev 1.23 from OpenBSD.  Fixes bz#2619.
-    
-    revision 1.23
-    date: 2010/05/14 13:30:34;  author: millert;  state: Exp;  lines: +41 -39;
-    Defer installing signal handlers until echo is disabled so that we
-    get suspended normally when not the foreground process.  Fix potential
-    infinite loop when restoring terminal settings if process is in the
-    background when restore occurs.  OK miod@
-
-commit 7508d83eff89af069760b4cc587305588a64e415
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 13 03:53:51 2016 +1100
-
-    If we don't have TCSASOFT, define it to zero.
-    
-    This makes it a no-op when we use it below, which allows us to re-sync
-    those lines with the upstream and make future updates easier.
-
-commit aae4dbd4c058d3b1fe1eb5c4e6ddf35827271377
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Oct 7 14:41:52 2016 +0000
-
-    upstream commit
-    
-    tidy up the formatting in this file. more specifically,
-    replace .Dq, which looks appalling, with .Cm, where appropriate;
-    
-    Upstream-ID: ff8e90aa0343d9bb56f40a535e148607973cc738
-
-commit a571dbcc7b7b25371174569b13df5159bc4c6c7a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 4 21:34:40 2016 +0000
-
-    upstream commit
-    
-    add a comment about implicitly-expected checks to
-    sshkey_ec_validate_public()
-    
-    Upstream-ID: 74a7f71c28f7c13a50f89fc78e7863b9cd61713f
-
-commit 2f78a2a698f4222f8e05cad57ac6e0c3d1faff00
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 30 20:24:46 2016 +0000
-
-    upstream commit
-    
-    fix some -Wpointer-sign warnings in the new mux proxy; ok
-    markus@
-    
-    Upstream-ID: b1ba7b3769fbc6b7f526792a215b0197f5e55dfd
-
-commit ca71c36645fc26fcd739a8cfdc702cec85607761
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date:   Wed Sep 28 20:09:52 2016 +0000
-
-    upstream commit
-    
-    Add a makefile rule to create the ssh library when
-    regress needs it.  This allows to run the ssh regression tests without doing
-    a "make build" before. Discussed with dtucker@ and djm@; OK djm@
-    
-    Upstream-Regress-ID: ce489bd53afcd471225a125b4b94565d4717c025
-
-commit ce44c970f913d2a047903dba8670554ac42fc479
-Author: bluhm@openbsd.org <bluhm@openbsd.org>
-Date:   Mon Sep 26 21:34:38 2016 +0000
-
-    upstream commit
-    
-    Allow to run ssh regression tests as root.  If the user
-    is already root, the test should not expect that SUDO is set.  If ssh needs
-    another user, use sudo or doas to switch from root if necessary. OK dtucker@
-    
-    Upstream-Regress-ID: b464e55185ac4303529e3e6927db41683aaeace2
-
-commit 8d0578478586e283e751ca51e7b0690631da139a
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Fri Sep 30 09:19:13 2016 +0000
-
-    upstream commit
-    
-    ssh proxy mux mode (-O proxy; idea from Simon Tatham): - mux
-    client speaks the ssh-packet protocol directly over unix-domain socket. - mux
-    server acts as a proxy, translates channel IDs and relays to the server. - no
-    filedescriptor passing necessary. - combined with unix-domain forwarding it's
-    even possible to run mux client   and server on different machines. feedback
-    & ok djm@
-    
-    Upstream-ID: 666a2fb79f58e5c50e246265fb2b9251e505c25b
-
-commit b7689155f3f5c4999846c07a852b1c7a43b09cec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 28 21:44:52 2016 +0000
-
-    upstream commit
-    
-    put back some pre-auth zlib bits that I shouldn't have
-    removed - they are still used by the client. Spotted by naddy@
-    
-    Upstream-ID: 80919468056031037d56a1f5b261c164a6f90dc2
-
-commit 4577adead6a7d600c8e764619d99477a08192c8f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 28 20:32:42 2016 +0000
-
-    upstream commit
-    
-    restore pre-auth compression support in the client -- the
-    previous commit was intended to remove it from the server only.
-    
-    remove a few server-side pre-auth compression bits that escaped
-    
-    adjust wording of Compression directive in sshd_config(5)
-    
-    pointed out by naddy@ ok markus@
-    
-    Upstream-ID: d23696ed72a228dacd4839dd9f2dec424ba2016b
-
-commit 80d1c963b4dc84ffd11d09617b39c4bffda08956
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Sep 28 17:59:22 2016 +0000
-
-    upstream commit
-    
-    use a separate TOKENS section, as we've done for
-    sshd_config(5); help/ok djm
-    
-    Upstream-ID: 640e32b5e4838e4363738cdec955084b3579481d
-
-commit 1cfd5c06efb121e58e8b6671548fda77ef4b4455
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Sep 29 03:19:23 2016 +1000
-
-    Remove portability support for mmap
-    
-    We no longer need to wrap/replace mmap for portability now that
-    pre-auth compression has been removed from OpenSSH.
-
-commit 0082fba4efdd492f765ed4c53f0d0fbd3bdbdf7f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 28 16:33:06 2016 +0000
-
-    upstream commit
-    
-    Remove support for pre-authentication compression. Doing
-    compression early in the protocol probably seemed reasonable in the 1990s,
-    but today it's clearly a bad idea in terms of both cryptography (cf. multiple
-    compression oracle attacks in TLS) and attack surface.
-    
-    Moreover, to support it across privilege-separation zlib needed
-    the assistance of a complex shared-memory manager that made the
-    required attack surface considerably larger.
-    
-    Prompted by Guido Vranken pointing out a compiler-elided security
-    check in the shared memory manager found by Stack
-    (http://css.csail.mit.edu/stack/); ok deraadt@ markus@
-    
-    NB. pre-auth authentication has been disabled by default in sshd
-    for >10 years.
-    
-    Upstream-ID: 32af9771788d45a0779693b41d06ec199d849caf
-
-commit 27c3a9c2aede2184856b5de1e6eca414bb751c38
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 26 21:16:11 2016 +0000
-
-    upstream commit
-    
-    Avoid a theoretical signed integer overflow should
-    BN_num_bytes() ever violate its manpage and return a negative value. Improve
-    order of tests to avoid confusing increasingly pedantic compilers.
-    
-    Reported by Guido Vranken from stack (css.csail.mit.edu/stack)
-    unstable optimisation analyser output.  ok deraadt@
-    
-    Upstream-ID: f8508c830c86d8f36c113985e52bf8eedae23505
-
-commit 8663e51c80c6aa3d750c6d3bcff6ee05091922be
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Sep 28 07:40:33 2016 +1000
-
-    fix mdoc2man.awk formatting for top-level lists
-    
-    Reported by Glenn Golden
-    Diagnosis and fix from Ingo Schwarze
-
-commit b97739dc21570209ed9d4e7beee0c669ed23b097
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 22 21:15:41 2016 +0000
-
-    upstream commit
-    
-    missing bit from previous commit
-    
-    Upstream-ID: 438d5ed6338b28b46e822eb13eee448aca31df37
-
-commit de6a175a99d22444e10d19ad3fffef39bc3ee3bb
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Thu Sep 22 19:19:01 2016 +0000
-
-    upstream commit
-    
-    organise the token stuff into a separate section; ok
-    markus for an earlier version of the diff ok/tweaks djm
-    
-    Upstream-ID: 81a6daa506a4a5af985fce7cf9e59699156527c8
-
-commit 16277fc45ffc95e4ffc3d45971ff8320b974de2b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 22 17:55:13 2016 +0000
-
-    upstream commit
-    
-    mention curve25519-sha256 KEX
-    
-    Upstream-ID: 33ae1f433ce4795ffa6203761fbdf86e0d7ffbaf
-
-commit 0493766d5676c7ca358824ea8d3c90f6047953df
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 22 17:52:53 2016 +0000
-
-    upstream commit
-    
-    support plain curve25519-sha256 KEX algorithm now that it
-    is approaching standardisation (same algorithm is currently supported as
-    curve25519-sha256@libssh.org)
-    
-    Upstream-ID: 5e2b6db2e72667048cf426da43c0ee3fc777baa2
-
-commit f31c654b30a6f02ce0b8ea8ab81791b675489628
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Sep 22 02:29:57 2016 +0000
-
-    upstream commit
-    
-    If ssh receives a PACKET_DISCONNECT during userauth it
-    will cause ssh_dispatch_run(DISPATCH_BLOCK, ...) to return without the
-    session being authenticated.  Check for this and exit if necessary.  ok djm@
-    
-    Upstream-ID: b3afe126c0839d2eae6cddd41ff2ba317eda0903
-
-commit 1622649b7a829fc8dc313042a43a974f0f3e8a99
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 19:53:12 2016 +0000
-
-    upstream commit
-    
-    correctly return errors from kex_send_ext_info(). Fix from
-    Sami Farin via https://github.com/openssh/openssh-portable/pull/50
-    
-    Upstream-ID: c85999af28aaecbf92cfa2283381df81e839b42c
-
-commit f83a0cfe16c7a73627b46a9a94e40087d60f32fb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 17:44:20 2016 +0000
-
-    upstream commit
-    
-    cast uint64_t for printf
-    
-    Upstream-ID: 76d23e89419ccbd2320f92792a6d878211666ac1
-
-commit 5f63ab474f58834feca4f35c498be03b7dd38a16
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 17:03:54 2016 +0000
-
-    upstream commit
-    
-    disable tests for affirmative negated match after backout of
-    match change
-    
-    Upstream-Regress-ID: acebb8e5042f03d66d86a50405c46c4de0badcfd
-
-commit a5ad3a9db5a48f350f257a67b62fafd719ecb7e0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 16:55:42 2016 +0000
-
-    upstream commit
-    
-    Revert two recent changes to negated address matching. The
-    new behaviour offers unintuitive surprises. We'll find a better way to deal
-    with single negated matches.
-    
-    match.c 1.31:
-    > fix matching for pattern lists that contain a single negated match,
-    > e.g. "Host !example"
-    >
-    > report and patch from Robin Becker. bz#1918 ok dtucker@
-    
-    addrmatch.c 1.11:
-    > fix negated address matching where the address list consists of a
-    > single negated match, e.g. "Match addr !192.20.0.1"
-    >
-    > Report and patch from Jakub Jelen. bz#2397 ok dtucker@
-    
-    Upstream-ID: ec96c770f0f5b9a54e5e72fda25387545e9c80c6
-
-commit 119b7a2ca0ef2bf3f81897ae10301b8ca8cba844
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 01:35:12 2016 +0000
-
-    upstream commit
-    
-    test all the AuthorizedPrincipalsCommand % expansions
-    
-    Upstream-Regress-ID: 0a79a84dfaa59f958e46b474c3db780b454d30e3
-
-commit bfa9d969ab6235d4938ce069d4db7e5825c56a19
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 21 01:34:45 2016 +0000
-
-    upstream commit
-    
-    add a way for principals command to get see key ID and serial
-    too
-    
-    Upstream-ID: 0d30978bdcf7e8eaeee4eea1b030eb2eb1823fcb
-
-commit 920585b826af1c639e4ed78b2eba01fd2337b127
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 16 06:09:31 2016 +0000
-
-    upstream commit
-    
-    add a note on kexfuzz' limitations
-    
-    Upstream-Regress-ID: 03804d4a0dbc5163e1a285a4c8cc0a76a4e864ec
-
-commit 0445ff184080b196e12321998b4ce80b0f33f8d1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 16 01:01:41 2016 +0000
-
-    upstream commit
-    
-    fix for newer modp DH groups
-    (diffie-hellman-group14-sha256 etc)
-    
-    Upstream-Regress-ID: fe942c669959462b507516ae1634fde0725f1c68
-
-commit 28652bca29046f62c7045e933e6b931de1d16737
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Mon Sep 19 19:02:19 2016 +0000
-
-    upstream commit
-    
-    move inbound NEWKEYS handling to kex layer; otherwise
-    early NEWKEYS causes NULL deref; found by Robert Swiecki/honggfuzz; fixed
-    with & ok djm@
-    
-    Upstream-ID: 9a68b882892e9f51dc7bfa9f5a423858af358b2f
-
-commit 492710894acfcc2f173d14d1d45bd2e688df605d
-Author: natano@openbsd.org <natano@openbsd.org>
-Date:   Mon Sep 19 07:52:42 2016 +0000
-
-    upstream commit
-    
-    Replace two more arc4random() loops with
-    arc4random_buf().
-    
-    tweaks and ok dtucker
-    ok deraadt
-    
-    Upstream-ID: 738d3229130ccc7eac975c190276ca6fcf0208e4
-
-commit 1036356324fecc13099ac6e986b549f6219327d7
-Author: tedu@openbsd.org <tedu@openbsd.org>
-Date:   Sat Sep 17 18:00:27 2016 +0000
-
-    upstream commit
-    
-    replace two arc4random loops with arc4random_buf ok
-    deraadt natano
-    
-    Upstream-ID: e18ede972d1737df54b49f011fa4f3917a403f48
-
-commit 00df97ff68a49a756d4b977cd02283690f5dfa34
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 14 20:11:26 2016 +0000
-
-    upstream commit
-    
-    take fingerprint of correct key for
-    AuthorizedPrincipalsCommand
-    
-    Upstream-ID: 553581a549cd6a3e73ce9f57559a325cc2cb1f38
-
-commit e7907c1cb938b96dd33d27c2fea72c4e08c6b2f6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 14 05:42:25 2016 +0000
-
-    upstream commit
-    
-    add %-escapes to AuthorizedPrincipalsCommand to match those
-    supported for AuthorizedKeysCommand (key, key type, fingerprint, etc) and a
-    few more to provide access to the certificate's CA key; 'looks ok' dtucker@
-    
-    Upstream-ID: 6b00fd446dbebe67f4e4e146d2e492d650ae04eb
-
-commit 2b939c272a81c4d0c47badeedbcb2ba7c128ccda
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Sep 14 00:45:31 2016 +0000
-
-    upstream commit
-    
-    Improve test coverage of ssh-keygen -T a bit.
-    
-    Upstream-Regress-ID: 8851668c721bcc2b400600cfc5a87644cc024e72
-
-commit 44d82fc83be6c5ccd70881c2dac1a73e5050398b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Sep 12 02:25:46 2016 +0000
-
-    upstream commit
-    
-    Add testcase for ssh-keygen -j, -J and -K options for
-    moduli screening. Does not currently test generation as that is extremely
-    slow.
-    
-    Upstream-Regress-ID: 9de6ce801377ed3ce0a63a1413f1cd5fd3c2d062
-
-commit 44e5f756d286bc3a1a5272ea484ee276ba3ac5c2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 23 08:17:04 2016 +0000
-
-    upstream commit
-    
-    add tests for addr_match_list()
-    
-    Upstream-Regress-ID: fae2d1fef84687ece584738a924c7bf969616c8e
-
-commit 445e218878035b59c704c18406e8aeaff4c8aa25
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 12 23:39:34 2016 +0000
-
-    upstream commit
-    
-    handle certs in rsa_hash_alg_from_ident(), saving an
-    unnecessary special case elsewhere.
-    
-    Upstream-ID: 901cb081c59d6d2698b57901c427f3f6dc7397d4
-
-commit 130f5df4fa37cace8c079dccb690e5cafbf00751
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 12 23:31:27 2016 +0000
-
-    upstream commit
-    
-    list all supported signature algorithms in the
-    server-sig-algs Reported by mb AT smartftp.com in bz#2547 and (independantly)
-    Ron Frederick; ok markus@
-    
-    Upstream-ID: ddf702d721f54646b11ef2cee6d916666cb685cd
-
-commit 8f750ccfc07acb8aa98be5a5dd935033a6468cfd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 14:43:58 2016 +1000
-
-    Remove no-op brackets to resync with upstream.
-
-commit 7050896e7395866278c19c2ff080c26152619d1d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 13:57:28 2016 +1000
-
-    Resync ssh-keygen -W error message with upstream.
-
-commit 43cceff82cc20413cce58ba3375e19684e62cec4
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 13:55:37 2016 +1000
-
-    Move ssh-keygen -W handling code to match upstream
-
-commit af48d541360b1d7737b35740a4b1ca34e1652cd9
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 13:52:17 2016 +1000
-
-    Move ssh-keygen -T handling code to match upstream.
-
-commit d8c3cfbb018825c6c86547165ddaf11924901c49
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 13:30:50 2016 +1000
-
-    Move -M handling code to match upstream.
-
-commit 7b63cf6dbbfa841c003de57d1061acbf2ff22364
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Sep 12 03:29:16 2016 +0000
-
-    upstream commit
-    
-    Spaces->tabs.
-    
-    Upstream-ID: f4829dfc3f36318273f6082b379ac562eead70b7
-
-commit 11e5e644536821ceb3bb4dd8487fbf0588522887
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Sep 12 03:25:20 2016 +0000
-
-    upstream commit
-    
-    Style whitespace fix.  Also happens to remove a no-op
-    diff with portable.
-    
-    Upstream-ID: 45d90f9a62ad56340913a433a9453eb30ceb8bf3
-
-commit 9136ec134c97a8aff2917760c03134f52945ff3c
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Mon Sep 12 01:22:38 2016 +0000
-
-    upstream commit
-    
-    Add MAXIMUM(), MINIMUM(), and ROUNDUP() to misc.h, then
-    use those definitions rather than pulling <sys/param.h> and unknown namespace
-    pollution. ok djm markus dtucker
-    
-    Upstream-ID: 712cafa816c9f012a61628b66b9fbd5687223fb8
-
-commit f219fc8f03caca7ac82a38ed74bbd6432a1195e7
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Sep 7 18:39:24 2016 +0000
-
-    upstream commit
-    
-    sort; from matthew martin
-    
-    Upstream-ID: 73cec7f7ecc82d37a4adffad7745e4684de67ce7
-
-commit 06ce56b05def9460aecc7cdb40e861a346214793
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Sep 6 09:22:56 2016 +0000
-
-    upstream commit
-    
-    ssh_set_newkeys: print correct block counters on
-    rekeying; ok djm@
-    
-    Upstream-ID: 32bb7a9cb9919ff5bab28d50ecef3a2b2045dd1e
-
-commit e5e8d9114ac6837a038f4952994ca95a97fafe8d
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Sep 6 09:14:05 2016 +0000
-
-    upstream commit
-    
-    update ext_info_c every time we receive a kexinit msg;
-    fixes sending of ext_info if privsep is disabled; report Aris Adamantiadis &
-    Mancha; ok djm@
-    
-    Upstream-ID: 2ceaa1076e19dbd3542254b4fb8e42d608f28856
-
-commit da95318dbedbaa1335323dba370975c2f251afd8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 5 14:02:42 2016 +0000
-
-    upstream commit
-    
-    remove 3des-cbc from the client's default proposal;
-    64-bit block ciphers are not safe in 2016 and we don't want to wait until
-    attacks like sweet32 are extended to SSH.
-    
-    As 3des-cbc was the only mandatory cipher in the SSH RFCs, this may
-    cause problems connecting to older devices using the defaults, but
-    it's highly likely that such devices already need explicit
-    configuration for KEX and hostkeys anyway.
-    
-    ok deraadt, markus, dtucker
-    
-    Upstream-ID: a505dfe65c6733af0f751b64cbc4bb7e0761bc2f
-
-commit b33ad6d997d36edfea65e243cd12ccd01f413549
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 5 13:57:31 2016 +0000
-
-    upstream commit
-    
-    enforce expected request flow for GSSAPI calls; thanks to
-    Jakub Jelen for testing; ok markus@
-    
-    Upstream-ID: d4bc0e70e1be403735d3d9d7e176309b1fd626b9
-
-commit 0bb2980260fb24e5e0b51adac471395781b66261
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 12 11:07:00 2016 +1000
-
-    Restore ssh-keygen's -J and -j option handling.
-    
-    These were incorrectly removed in the 1d9a2e28 sync commit.
-
-commit 775f8a23f2353f5869003c57a213d14b28e0736e
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Aug 31 10:48:07 2016 +1000
-
-    tighten PAM monitor calls
-    
-    only allow kbd-interactive ones when that authentication method is
-    enabled. Prompted by Solar Designer
-
-commit 7fd0ea8a1db4bcfb3d8cd9df149e5d571ebea1f4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 30 07:50:21 2016 +0000
-
-    upstream commit
-    
-    restrict monitor auth calls to be allowed only when their
-    respective authentication methods are enabled in the configuration.
-    
-    prompted by Solar Designer; ok markus dtucker
-    
-    Upstream-ID: 6eb3f89332b3546d41d6dbf5a8e6ff920142b553
-
-commit b38b95f5bcc52278feb839afda2987933f68ff96
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Aug 29 11:47:07 2016 +1000
-
-    Tighten monitor state-machine flow for PAM calls
-    
-    (attack surface reduction)
-
-commit dc664d1bd0fc91b24406a3e9575b81c285b8342b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Aug 28 22:28:12 2016 +0000
-
-    upstream commit
-    
-    fix uninitialised optlen in getsockopt() call; harmless
-    on Unix/BSD but potentially crashy on Cygwin. Reported by James Slepicka ok
-    deraadt@
-    
-    Upstream-ID: 1987ccee508ba5b18f016c85100d7ac3f70ff965
-
-commit 5bcc1e2769f7d6927d41daf0719a9446ceab8dd7
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Sat Aug 27 04:05:12 2016 +0000
-
-    upstream commit
-    
-    Pull in <sys/time.h> for struct timeval
-    
-    ok deraadt@
-    
-    Upstream-ID: ae34525485a173bccd61ac8eefeb91c57e3b7df6
-
-commit fa4a4c96b19127dc2fd4e92f20d99c0c7f34b538
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Sat Aug 27 04:04:56 2016 +0000
-
-    upstream commit
-    
-    Pull in <stdlib.h> for NULL
-    
-    ok deraadt@
-    
-    Upstream-ID: 7baa6a0f1e049bb3682522b4b95a26c866bfc043
-
-commit ae363d74ccc1451185c0c8bd4631e28c67c7fd36
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Aug 25 23:57:54 2016 +0000
-
-    upstream commit
-    
-    add a sIgnore opcode that silently ignores options and
-    use it to suppress noisy deprecation warnings for the Protocol directive.
-    
-    req henning, ok markus
-    
-    Upstream-ID: 9fe040aca3d6ff393f6f7e60045cdd821dc4cbe0
-
-commit a94c60306643ae904add6e8ed219e4be3494255c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Aug 25 23:56:51 2016 +0000
-
-    upstream commit
-    
-    remove superfluous NOTREACHED comment
-    
-    Upstream-ID: a7485c1f1be618e8c9e38fd9be46c13b2d03b90c
-
-commit fc041c47144ce28cf71353124a8a5d183cd6a251
-Author: otto@openbsd.org <otto@openbsd.org>
-Date:   Tue Aug 23 16:21:45 2016 +0000
-
-    upstream commit
-    
-    fix previous, a condition was modified incorrectly; ok
-    markus@ deraadt@
-    
-    Upstream-ID: c443e339768e7ed396dff3bb55f693e7d3641453
-
-commit 23555eb13a9b0550371a16dcf8beaab7a5806a64
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 23 08:17:42 2016 +0000
-
-    upstream commit
-    
-    downgrade an error() to a debug2() to match similar cases
-    in addr_match_list()
-    
-    Upstream-ID: 07c3d53e357214153d9d08f234411e0d1a3d6f5c
-
-commit a39627134f6d90e7009eeb14e9582ecbc7a99192
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 23 06:36:23 2016 +0000
-
-    upstream commit
-    
-    remove Protocol directive from client/server configs that
-    causes spammy deprecation warnings
-    
-    hardcode SSH_PROTOCOLS=2, since that's all we support on the server
-    now (the client still may support both, so it could get confused)
-    
-    Upstream-Regress-ID: c16662c631af51633f9fd06aca552a70535de181
-
-commit 6ee4f1c01ee31e65245881d49d4bccf014956066
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 23 16:33:48 2016 +1000
-
-    hook match and utf8 unittests up to Makefile
-
-commit 114efe2bc0dd2842d997940a833f115e6fc04854
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 19 06:44:13 2016 +0000
-
-    upstream commit
-    
-    add tests for matching functions
-    
-    Upstream-Regress-ID: 0869d4f5c5d627c583c6a929d69c17d5dd65882c
-
-commit 857568d2ac81c14bcfd625b27536c1e28c992b3c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 23 14:32:37 2016 +1000
-
-    removing UseLogin bits from configure.ac
-
-commit cc182d01cef8ca35a1d25ea9bf4e2ff72e588208
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 23 03:24:10 2016 +0000
-
-    upstream commit
-    
-    fix negated address matching where the address list
-    consists of a single negated match, e.g. "Match addr !192.20.0.1"
-    
-    Report and patch from Jakub Jelen. bz#2397 ok dtucker@
-    
-    Upstream-ID: 01dcac3f3e6ca47518cf293e31c73597a4bb40d8
-
-commit 4067ec8a4c64ccf16250c35ff577b4422767da64
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 23 03:22:49 2016 +0000
-
-    upstream commit
-    
-    fix matching for pattern lists that contain a single
-    negated match, e.g. "Host !example"
-    
-    report and patch from Robin Becker. bz#1918 ok dtucker@
-    
-    Upstream-ID: 05a0cb323ea4bc20e98db099b42c067bfb9ea1ea
-
-commit 83b581862a1dbb06fc859959f829dde2654aef3c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 19 03:18:06 2016 +0000
-
-    upstream commit
-    
-    remove UseLogin option and support for having /bin/login
-    manage login sessions; ok deraadt markus dtucker
-    
-    Upstream-ID: bea7213fbf158efab7e602d9d844fba4837d2712
-
-commit ffe6549c2f7a999cc5264b873a60322e91862581
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Mon Aug 15 12:32:04 2016 +0000
-
-    upstream commit
-    
-    Catch up with the SSH1 code removal and delete all
-    mention of protocol 1 particularities, key files and formats, command line
-    options, and configuration keywords from the server documentation and
-    examples.  ok jmc@
-    
-    Upstream-ID: 850328854675b4b6a0d4a90f0b4a9dd9ca4e905f
-
-commit c38ea634893a1975dbbec798fb968c9488013f4a
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Mon Aug 15 12:27:56 2016 +0000
-
-    upstream commit
-    
-    Remove more SSH1 server code: * Drop sshd's -k option. *
-    Retire configuration keywords that only apply to protocol 1, as well as   the
-    "protocol" keyword. * Remove some related vestiges of protocol 1 support.
-    
-    ok markus@
-    
-    Upstream-ID: 9402f82886de917779db12f8ee3f03d4decc244d
-
-commit 33ba55d9e358c07f069e579bfab80eccaaad52cb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 16:26:04 2016 +1000
-
-    Only check for prctl once.
-
-commit 976ba8a8fd66a969bf658280c1e5adf694cc2fc6
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 15:33:10 2016 +1000
-
-    Fix typo.
-
-commit 9abf84c25ff4448891edcde60533a6e7b2870de1
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 14:25:43 2016 +1000
-
-    Correct LDFLAGS for clang example.
-    
-    --with-ldflags isn't used until after the -ftrapv test, so mention
-    LDFLAGS instead for now.
-
-commit 1e8013a17ff11e3c6bd0012fb1fc8d5f1330eb21
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 14:08:42 2016 +1000
-
-    Remove obsolete CVS $Id from source files.
-    
-    Since -portable switched to git the CVS $Id tags are no longer being
-    updated and are becoming increasingly misleading.  Remove them.
-
-commit adab758242121181700e48b4f6c60d6b660411fe
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 13:40:58 2016 +1000
-
-    Remove now-obsolete CVS $Id tags from text files.
-    
-    Since -portable switched to git, the CVS $Id tags are no longer being
-    updated and are becoming increasingly misleading.  Remove them.
-
-commit 560c0068541315002ec4c1c00a560bbd30f2d671
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 13:38:30 2016 +1000
-
-    Add a section for compiler specifics.
-    
-    Add a section for compiler specifics and document the runtime requirements
-    for clang's integer sanitization.
-
-commit a8fc0f42e1eda2fa3393d1ea5e61322d5e07a9cd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Aug 17 13:35:43 2016 +1000
-
-    Test multiplying two long long ints.
-    
-    When using clang with -ftrapv or -sanitize=integer the tests would pass
-    but linking would fail with "undefined reference to __mulodi4".
-    Explicitly test for this before enabling -trapv.
-
-commit a1cc637e7e11778eb727559634a6ef1c19c619f6
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 16 14:47:34 2016 +1000
-
-    add a --with-login-program configure argument
-    
-    Saves messing around with LOGIN_PROGRAM env var, which come
-    packaging environments make hard to do during configure phase.
-
-commit 8bd81e1596ab1bab355146cb65e82fb96ade3b23
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 16 13:30:56 2016 +1000
-
-    add --with-pam-service to specify PAM service name
-    
-    Saves messing around with CFLAGS to do it.
-
-commit 74433a19bb6f4cef607680fa4d1d7d81ca3826aa
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 16 13:28:23 2016 +1000
-
-    fix false positives when compiled with msan
-    
-    Our explicit_bzero successfully confused clang -fsanitize-memory
-    in to thinking that memset is never called to initialise memory.
-    Ensure that it is called in a way that the compiler recognises.
-
-commit 6cb6dcffe1a2204ba9006de20f73255c268fcb6b
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Sat Aug 13 17:47:40 2016 +0000
-
-    upstream commit
-    
-    remove ssh1 server code; ok djm@
-    
-    Upstream-ID: c24c0c32c49b91740d5a94ae914fb1898ea5f534
-
-commit 42d47adc5ad1187f22c726cbc52e71d6b1767ca2
-Author: jca@openbsd.org <jca@openbsd.org>
-Date:   Fri Aug 12 19:19:04 2016 +0000
-
-    upstream commit
-    
-    Use 2001:db8::/32, the official IPv6 subnet for
-    configuration examples.
-    
-    This makes the IPv6 example consistent with IPv4, and removes a dubious
-    mention of a 6bone subnet.
-    
-    ok sthen@ millert@
-    
-    Upstream-ID: b027f3d0e0073419a132fd1bf002e8089b233634
-
-commit b61f53c0c3b43c28e013d3b3696d64d1c0204821
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Aug 11 01:42:11 2016 +0000
-
-    upstream commit
-    
-    Update moduli file.
-    
-    Upstream-ID: 6da9a37f74aef9f9cc639004345ad893cad582d8
-
-commit f217d9bd42d306f69f56335231036b44502d8191
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Aug 11 11:42:48 2016 +1000
-
-    Import updated moduli.
-
-commit 67dca60fbb4923b7a11c1645b90a5ca57c03d8be
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Aug 8 22:40:57 2016 +0000
-
-    upstream commit
-    
-    Improve error message for overlong ControlPath.  ok markus@
-    djm@
-    
-    Upstream-ID: aed374e2e88dd3eb41390003e5303d0089861eb5
-
-commit 4706c1d8c15cd5565b59512853c2da9bd4ca26c9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 3 05:41:57 2016 +0000
-
-    upstream commit
-    
-    small refactor of cipher.c: make ciphercontext opaque to
-    callers feedback and ok markus@
-    
-    Upstream-ID: 094849f8be68c3bdad2c0f3dee551ecf7be87f6f
-
-commit e600348a7afd6325cc5cd783cb424065cbc20434
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Aug 3 04:23:55 2016 +0000
-
-    upstream commit
-    
-    Fix bug introduced in rev 1.467 which causes
-    "buffer_get_bignum_ret: incomplete message" errors when built with WITH_SSH1
-    and run such that no Protocol 1 ephemeral host key is generated (eg "Protocol
-    2", no SSH1 host key supplied).  Reported by rainer.laatsch at t-online.de,
-    ok deraadt@
-    
-    Upstream-ID: aa6b132da5c325523aed7989cc5a320497c919dc
-
-commit d7e7348e72f9b203189e3fffb75605afecba4fda
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 27 23:18:12 2016 +0000
-
-    upstream commit
-    
-    better bounds check on iovcnt (we only ever use fixed,
-    positive values)
-    
-    Upstream-ID: 9baa6eb5cd6e30c9dc7398e5fe853721a3a5bdee
-
-commit 5faa52d295f764562ed6dd75c4a4ce9134ae71e3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 15:22:40 2016 +1000
-
-    Use tabs consistently inside "case $host".
-
-commit 20e5e8ba9c5d868d897896190542213a60fffbd2
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 12:16:34 2016 +1000
-
-    Explicitly test for broken strnvis.
-    
-    NetBSD added an strnvis and unfortunately made it incompatible with the
-    existing one in OpenBSD and Linux's libbsd (the former having existed
-    for over ten years). Despite this incompatibility being reported during
-    development (see http://gnats.netbsd.org/44977) they still shipped it.
-    Even more unfortunately FreeBSD and later MacOS picked up this incompatible
-    implementation.  Try to detect this mess, and assume the only safe option
-    if we're cross compiling.
-    
-    OpenBSD 2.9 (2001): strnvis(char *dst, const char *src, size_t dlen, int flag);
-    NetBSD 6.0 (2012):  strnvis(char *dst, size_t dlen, const char *src, int flag);
-    
-    ok djm@
-
-commit b0b48beab1b74100b61ecbadb9140c9ab4c2ea8c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 2 11:06:23 2016 +1000
-
-    update recommended autoconf version
-
-commit 23902e31dfd18c6d7bb41ccd73de3b5358a377da
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 2 10:48:04 2016 +1000
-
-    update config.guess and config.sub to current
-    
-    upstream commit 562f3512b3911ba0c77a7f68214881d1f241f46e
-
-commit dd1031b78b83083615b68d7163c44f4408635be2
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 10:01:52 2016 +1000
-
-    Replace spaces with tabs.
-    
-    Mechanically replace spaces with tabs in compat files not synced with
-    OpenBSD.
-
-commit c20dccb5614c5714f4155dda01bcdebf97cfae7e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 09:44:25 2016 +1000
-
-    Strip trailing whitespace.
-    
-    Mechanically strip trailing whitespace on files not synced with OpenBSD
-    (or in the case of bsd-snprint.c, rsync).
-
-commit 30f9bd1c0963c23bfba8468dfd26aa17609ba42f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 09:06:27 2016 +1000
-
-    Repair $OpenBSD markers.
-
-commit 9715d4ad4b53877ec23dc8681dd7a405de9419a6
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Aug 2 09:02:42 2016 +1000
-
-    Repair $OpenBSD marker.
-
-commit cf3e0be7f5828a5e5f6c296a607d20be2f07d60c
-Author: Tim Rice <tim@multitalents.net>
-Date:   Mon Aug 1 14:31:52 2016 -0700
-
-    modified:   configure.ac opensshd.init.in
-    Skip generating missing RSA1 key on startup unless ssh1 support is enabled.
-    Spotted by Jean-Pierre Radley
-
-commit 99522ba7ec6963a05c04a156bf20e3ba3605987c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jul 28 08:54:27 2016 +1000
-
-    define _OPENBSD_SOURCE for reallocarray on NetBSD
-    
-    Report by and debugged with Hisashi T Fujinaka, dtucker nailed
-    the problem (lack of prototype causing return type confusion).
-
-commit 3e1e076550c27c6bbdddf36d8f42bd79fbaaa187
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jul 27 08:25:42 2016 +1000
-
-    KNF
-
-commit d99ee9c4e5e217e7d05eeec84e9ce641f4675331
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jul 27 08:25:23 2016 +1000
-
-    Linux auditing also needs packet.h
-
-commit 393bd381a45884b589baa9aed4394f1d250255ca
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jul 27 08:18:05 2016 +1000
-
-    fix auditing on Linux
-    
-    get_remote_ipaddr() was replaced with ssh_remote_ipaddr()
-
-commit 80e766fb089de4f3c92b1600eb99e9495e37c992
-Author: Damien Miller <djm@mindrot.org>
-Date:   Sun Jul 24 21:50:13 2016 +1000
-
-    crank version numbers
-
-commit b1a478792d458f2e938a302e64bab2b520edc1b3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Jul 24 11:45:36 2016 +0000
-
-    upstream commit
-    
-    openssh-7.3
-    
-    Upstream-ID: af106a7eb665f642648cf1993e162c899f358718
-
-commit 353766e0881f069aeca30275ab706cd60a1a8fdd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Sat Jul 23 16:14:42 2016 +1000
-
-    Move Cygwin IPPORT_RESERVED overrride to defines.h
-    
-    Patch from vinschen at redhat.com.
-
-commit 368dd977ae07afb93f4ecea23615128c95ab2b32
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Jul 23 02:54:08 2016 +0000
-
-    upstream commit
-    
-    fix pledge violation with ssh -f; reported by Valentin
-    Kozamernik ok dtucker@
-    
-    Upstream-ID: a61db7988db88d9dac3c4dd70e18876a8edf84aa
-
-commit f00211e3c6d24d6ea2b64b4b1209f671f6c1d42e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 22 07:00:46 2016 +0000
-
-    upstream commit
-    
-    improve wording; suggested by jmc@
-    
-    Upstream-ID: 55cb0a24c8e0618b3ceec80998dc82c85db2d2f8
-
-commit 83cbca693c3b0719270e6a0f2efe3f9ee93a65b8
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jul 22 05:46:11 2016 +0000
-
-    upstream commit
-    
-    Lower loglevel for "Authenticated with partial success"
-    message similar to other similar level.  bz#2599, patch from cgallek at
-    gmail.com, ok markus@
-    
-    Upstream-ID: 3faab814e947dc7b2e292edede23e94c608cb4dd
-
-commit 10358abd087ab228b7ce2048efc4f3854a9ab9a6
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 22 14:06:36 2016 +1000
-
-    retry waitpid on EINTR failure
-    
-    patch from Jakub Jelen on bz#2581; ok dtucker@
-
-commit da88a70a89c800e74ea8e5661ffa127a3cc79a92
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 22 03:47:36 2016 +0000
-
-    upstream commit
-    
-    constify a few functions' arguments; patch from Jakub
-    Jelen bz#2581
-    
-    Upstream-ID: f2043f51454ea37830ff6ad60c8b32b4220f448d
-
-commit c36d91bd4ebf767f310f7cea88d61d1c15f53ddf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 22 03:39:13 2016 +0000
-
-    upstream commit
-    
-    move debug("%p", key) to before key is free'd; probable
-    undefined behaviour on strict compilers; reported by Jakub Jelen bz#2581
-    
-    Upstream-ID: 767f323e1f5819508a0e35e388ec241bac2f953a
-
-commit 286f5a77c3bfec1e8892ca268087ac885ac871bf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 22 03:35:11 2016 +0000
-
-    upstream commit
-    
-    reverse the order in which -J/JumpHost proxies are visited to
-    be more intuitive and document
-    
-    reported by and manpage bits naddy@
-    
-    Upstream-ID: 3a68fd6a841fd6cf8cedf6552a9607ba99df179a
-
-commit fcd135c9df440bcd2d5870405ad3311743d78d97
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Jul 21 01:39:35 2016 +0000
-
-    upstream commit
-    
-    Skip passwords longer than 1k in length so clients can't
-    easily DoS sshd by sending very long passwords, causing it to spend CPU
-    hashing them. feedback djm@, ok markus@.
-    
-    Brought to our attention by tomas.kuthan at oracle.com, shilei-c at
-    360.cn and coredump at autistici.org
-    
-    Upstream-ID: d0af7d4a2190b63ba1d38eec502bc4be0be9e333
-
-commit 324583e8fb3935690be58790425793df619c6d4d
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Wed Jul 20 10:45:27 2016 +0000
-
-    upstream commit
-    
-    Do not clobber the global jump_host variables when
-    parsing an inactive configuration.  ok djm@
-    
-    Upstream-ID: 5362210944d91417d5976346d41ac0b244350d31
-
-commit 32d921c323b989d28405e78d0a8923d12913d737
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Tue Jul 19 12:59:16 2016 +0000
-
-    upstream commit
-    
-    tweak previous;
-    
-    Upstream-ID: f3c1a5b3f05dff366f60c028728a2b43f15ff534
-
-commit d7eabc86fa049a12ba2c3fb198bd1d51b37f7025
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Jul 19 11:38:53 2016 +0000
-
-    upstream commit
-    
-    Allow wildcard for PermitOpen hosts as well as ports.
-    bz#2582, patch from openssh at mzpqnxow.com and jjelen at redhat.com.  ok
-    markus@
-    
-    Upstream-ID: af0294e9b9394c4e16e991424ca0a47a7cc605f2
-
-commit b98a2a8348e907b3d71caafd80f0be8fdd075943
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Mon Jul 18 11:35:33 2016 +0000
-
-    upstream commit
-    
-    Reduce timing attack against obsolete CBC modes by always
-    computing the MAC over a fixed size of data. Reported by Jean Paul
-    Degabriele, Kenny Paterson, Torben Hansen and Martin Albrecht. ok djm@
-    
-    Upstream-ID: f20a13279b00ba0afbacbcc1f04e62e9d41c2912
-
-commit dbf788b4d9d9490a5fff08a7b09888272bb10fcc
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jul 21 14:17:31 2016 +1000
-
-    Search users for one with a valid salt.
-    
-    If the root account is locked (eg password "!!" or "*LK*") keep looking
-    until we find a user with a valid salt to use for crypting passwords of
-    invalid users.  ok djm@
-
-commit e8b58f48fbb1b524fb4f0d4865fa0005d6a4b782
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 17:22:49 2016 +1000
-
-    Explicitly specify source files for regress tools.
-    
-    Since adding $(REGRESSLIBS), $? is wrong because it includes only the
-    changed source files.  $< seems like it'd be right however it doesn't
-    seem to work on some non-GNU makes, so do what works everywhere.
-
-commit eac1bbd06872c273f16ac0f9976b0aef026b701b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 17:12:22 2016 +1000
-
-    Conditionally include err.h.
-
-commit 0a454147568746c503f669e1ba861f76a2e7a585
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 16:26:26 2016 +1000
-
-    Remove local implementation of err, errx.
-    
-    We now have a shared implementation in libopenbsd-compat.
-
-commit eb999a4590846ba4d56ddc90bd07c23abfbab7b1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jul 18 06:08:01 2016 +0000
-
-    upstream commit
-    
-    Add some unsigned overflow checks for extra_pad. None of
-    these are reachable with the amount of padding that we use internally.
-    bz#2566, pointed out by Torben Hansen. ok markus@
-    
-    Upstream-ID: 4d4be8450ab2fc1b852d5884339f8e8c31c3fd76
-
-commit c71ba790c304545464bb494de974cdf0f4b5cf1e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 15:43:25 2016 +1000
-
-    Add dependency on libs for unit tests.
-    
-    Makes "./configure && make tests" work again.  ok djm@
-
-commit 8199d0311aea3e6fd0284c9025e7a83f4ece79e8
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 13:47:39 2016 +1000
-
-    Correct location for kexfuzz in clean target.
-
-commit 01558b7b07af43da774d3a11a5c51fa9c310849d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 18 09:33:25 2016 +1000
-
-    Handle PAM_MAXTRIES from modules.
-    
-    bz#2249: handle the case where PAM returns PAM_MAXTRIES by ceasing to offer
-    password and keyboard-interative authentication methods.  Should prevent
-    "sshd ignoring max retries" warnings in the log.  ok djm@
-    
-    It probably won't trigger with keyboard-interactive in the default
-    configuration because the retry counter is stored in module-private
-    storage which goes away with the sshd PAM process (see bz#688).  On the
-    other hand, those cases probably won't log a warning either.
-
-commit 65c6c6b567ab5ab12945a5ad8e0ab3a8c26119cc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Jul 17 04:20:16 2016 +0000
-
-    upstream commit
-    
-    support UTF-8 characters in ssh(1) banners using
-    schwarze@'s safe fmprintf printer; bz#2058
-    
-    feedback schwarze@ ok dtucker@
-    
-    Upstream-ID: a72ce4e3644c957643c9524eea2959e41b91eea7
-
-commit e4eb7d910976fbfc7ce3e90c95c11b07b483d0d7
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sat Jul 16 06:57:55 2016 +0000
-
-    upstream commit
-    
-    - add proxyjump to the options list - formatting fixes -
-    update usage()
-    
-    ok djm
-    
-    Upstream-ID: 43d318e14ce677a2eec8f21ef5ba2f9f68a59457
-
-commit af1f084857621f14bd9391aba8033d35886c2455
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jul 15 05:01:58 2016 +0000
-
-    upstream commit
-    
-    Reduce the syslog level of some relatively common protocol
-    events from LOG_CRIT by replacing fatal() calls with logdie().  Part of
-    bz#2585, ok djm@
-    
-    Upstream-ID: 9005805227c94edf6ac02a160f0e199638d288e5
-
-commit bd5f2b78b69cf38d6049a0de445a79c8595e4a1f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 15 19:14:48 2016 +1000
-
-    missing openssl/dh.h
-
-commit 4a984fd342effe5f0aad874a0d538c4322d973c0
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 15 18:47:07 2016 +1000
-
-    cast to avoid type warning in error message
-
-commit 5abfb15ced985c340359ae7fb65a625ed3692b3e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jul 15 14:48:30 2016 +1000
-
-    Move VA_COPY macro into compat header.
-    
-    Some AIX compilers unconditionally undefine va_copy but don't set it back
-    to an internal function, causing link errors.  In some compat code we
-    already use VA_COPY instead so move the two existing instances into the
-    shared header and use for sshbuf-getput-basic.c too.  Should fix building
-    with at lease some versions of AIX's compiler.  bz#2589, ok djm@
-
-commit 832b7443b7a8e181c95898bc5d73497b7190decd
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 15 14:45:34 2016 +1000
-
-    disable ciphers not supported by OpenSSL
-    
-    bz#2466 ok dtucker@
-
-commit 5fbe93fc6fbb2fe211e035703dec759d095e3dd8
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 15 13:54:31 2016 +1000
-
-    add a --disable-pkcs11 knob
-
-commit 679ce88ec2a8e2fe6515261c489e8c1449bb9da9
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 15 13:44:38 2016 +1000
-
-    fix newline escaping for unsupported_algorithms
-    
-    The hmac-ripemd160 was incorrect and could lead to broken
-    Makefiles on systems that lacked support for it, but I made
-    all the others consistent too.
-
-commit ed877ef653847d056bb433975d731b7a1132a979
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 15 00:24:30 2016 +0000
-
-    upstream commit
-    
-    Add a ProxyJump ssh_config(5) option and corresponding -J
-    ssh(1) command-line flag to allow simplified indirection through a SSH
-    bastion or "jump host".
-    
-    These options construct a proxy command that connects to the
-    specified jump host(s) (more than one may be specified) and uses
-    port-forwarding to establish a connection to the next destination.
-    
-    This codifies the safest way of indirecting connections through SSH
-    servers and makes it easy to use.
-    
-    ok markus@
-    
-    Upstream-ID: fa899cb8b26d889da8f142eb9774c1ea36b04397
-
-commit 5c02dd126206a26785379e80f2d3848e4470b711
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jul 15 12:56:39 2016 +1000
-
-    Map umac_ctx struct name too.
-    
-    Prevents size mismatch linker warnings on Solaris 11.
-
-commit 283b97ff33ea2c641161950849931bd578de6946
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jul 15 13:49:44 2016 +1000
-
-    Mitigate timing of disallowed users PAM logins.
-    
-    When sshd decides to not allow a login (eg PermitRootLogin=no) and
-    it's using PAM, it sends a fake password to PAM so that the timing for
-    the failure is not noticeably different whether or not the password
-    is correct.  This behaviour can be detected by sending a very long
-    password string which is slower to hash than the fake password.
-    
-    Mitigate by constructing an invalid password that is the same length
-    as the one from the client and thus takes the same time to hash.
-    Diff from djm@
-
-commit 9286875a73b2de7736b5e50692739d314cd8d9dc
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jul 15 13:32:45 2016 +1000
-
-    Determine appropriate salt for invalid users.
-    
-    When sshd is processing a non-PAM login for a non-existent user it uses
-    the string from the fakepw structure as the salt for crypt(3)ing the
-    password supplied by the client.  That string has a Blowfish prefix, so on
-    systems that don't understand that crypt will fail fast due to an invalid
-    salt, and even on those that do it may have significantly different timing
-    from the hash methods used for real accounts (eg sha512).  This allows
-    user enumeration by, eg, sending large password strings.  This was noted
-    by EddieEzra.Harari at verint.com (CVE-2016-6210).
-    
-    To mitigate, use the same hash algorithm that root uses for hashing
-    passwords for users that do not exist on the system.  ok djm@
-
-commit a162dd5e58ca5b224d7500abe35e1ef32b5de071
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jul 14 21:19:59 2016 +1000
-
-    OpenSSL 1.1.x not currently supported.
-
-commit 7df91b01fc558a33941c5c5f31abbcdc53a729fb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jul 14 12:25:24 2016 +1000
-
-    Check for VIS_ALL.
-    
-    If we don't have it, set BROKEN_STRNVIS to activate the compat replacement.
-
-commit ee67716f61f1042d5e67f91c23707cca5dcdd7d0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Jul 14 01:24:21 2016 +0000
-
-    upstream commit
-    
-    Correct equal in test.
-    
-    Upstream-Regress-ID: 4e32f7a5c57a619c4e8766cb193be2a1327ec37a
-
-commit 372807c2065c8572fdc6478b25cc5ac363743073
-Author: tb@openbsd.org <tb@openbsd.org>
-Date:   Mon Jul 11 21:38:13 2016 +0000
-
-    upstream commit
-    
-    Add missing "recvfd" pledge promise: Raf Czlonka reported
-    ssh coredumps when Control* keywords were set in ssh_config. This patch also
-    fixes similar problems with scp and sftp.
-    
-    ok deraadt, looks good to millert
-    
-    Upstream-ID: ca2099eade1ef3e87a79614fefa26a0297ad8a3b
-
-commit e0453f3df64bf485c61c7eb6bd12893eee9fe2cd
-Author: tedu@openbsd.org <tedu@openbsd.org>
-Date:   Mon Jul 11 03:19:44 2016 +0000
-
-    upstream commit
-    
-    obsolete note about fascistloggin is obsolete. ok djm
-    dtucker
-    
-    Upstream-ID: dae60df23b2bb0e89f42661ddd96a7b0d1b7215a
-
-commit a2333584170a565adf4f209586772ef8053b10b8
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jul 14 10:59:09 2016 +1000
-
-    Add compat code for missing wcwidth.
-    
-    If we don't have wcwidth force fallback implementations of nl_langinfo
-    and mbtowc.  Based on advice from Ingo Schwarze.
-
-commit 8aaec7050614494014c47510b7e94daf6e644c62
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jul 14 09:48:48 2016 +1000
-
-    fix missing include for systems with err.h
-
-commit 6310ef27a2567cda66d6cf0c1ad290ee1167f243
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Jul 13 14:42:35 2016 +1000
-
-    Move err.h replacements into compat lib.
-    
-    Move implementations of err.h replacement functions into their own file
-    in the libopenbsd-compat so we can use them in kexfuzz.c too.  ok djm@
-
-commit f3f2cc8386868f51440c45210098f65f9787449a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 11 17:23:38 2016 +1000
-
-    Check for wchar.h and langinfo.h
-    
-    Wrap includes in the appropriate #ifdefs.
-
-commit b9c50614eba9d90939b2b119b6e1b7e03b462278
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jul 8 13:59:13 2016 +1000
-
-    whitelist more architectures for seccomp-bpf
-    
-    bz#2590 - testing and patch from Jakub Jelen
-
-commit 18813a32b6fd964037e0f5e1893cb4468ac6a758
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Mon Jul 4 18:01:44 2016 +0000
-
-    upstream commit
-    
-    DEBUGLIBS has been broken since the gcc4 switch, so delete
-    it.  CFLAGS contains -g by default anyway
-    
-    problem noted by Edgar Pettijohn (edgar (at) pettijohn-web.com)
-    ok millert@ kettenis@ deraadt@
-    
-    Upstream-Regress-ID: 4a0bb72f95c63f2ae9daa8a040ac23914bddb542
-
-commit 6d31193d0baa3da339c196ac49625b7ba1c2ecc7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 8 03:44:42 2016 +0000
-
-    upstream commit
-    
-    Improve crypto ordering for Encrypt-then-MAC (EtM) mode
-    MAC algorithms.
-    
-    Previously we were computing the MAC, decrypting the packet and then
-    checking the MAC. This gave rise to the possibility of creating a
-    side-channel oracle in the decryption step, though no such oracle has
-    been identified.
-    
-    This adds a mac_check() function that computes and checks the MAC in
-    one pass, and uses it to advance MAC checking for EtM algorithms to
-    before payload decryption.
-    
-    Reported by Jean Paul Degabriele, Kenny Paterson, Torben Hansen and
-    Martin Albrecht. feedback and ok markus@
-    
-    Upstream-ID: 1999bb67cab47dda5b10b80d8155fe83d4a1867b
-
-commit 71f5598f06941f645a451948c4a5125c83828e1c
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Mon Jul 4 18:01:44 2016 +0000
-
-    upstream commit
-    
-    DEBUGLIBS has been broken since the gcc4 switch, so
-    delete it.  CFLAGS contains -g by default anyway
-    
-    problem noted by Edgar Pettijohn (edgar (at) pettijohn-web.com)
-    ok millert@ kettenis@ deraadt@
-    
-    Upstream-ID: 96c5054e3e1f170c6276902d5bc65bb3b87a2603
-
-commit e683fc6f1c8c7295648dbda679df8307786ec1ce
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Jun 30 05:17:05 2016 +0000
-
-    upstream commit
-    
-    Explicitly check for 100% completion to avoid potential
-    floating point rounding error, which could cause progressmeter to report 99%
-    on completion. While there invert the test so the 100% case is clearer.  with
-    & ok djm@
-    
-    Upstream-ID: a166870c5878e422f3c71ff802e2ccd7032f715d
-
-commit 772e6cec0ed740fc7db618dc30b4134f5a358b43
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Jun 29 17:14:28 2016 +0000
-
-    upstream commit
-    
-    sort the -o list;
-    
-    Upstream-ID: 1a97465ede8790b4d47cb618269978e07f41f8ac
-
-commit 46ecd19e554ccca15a7309cd1b6b44bc8e6b84af
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Jun 23 05:17:51 2016 +0000
-
-    upstream commit
-    
-    fix AuthenticationMethods during configuration re-parse;
-    reported by Juan Francisco Cantero Hurtado
-    
-    Upstream-ID: 8ffa1dac25c7577eca8238e825317ab20848f9b4
-
-commit 3147e7595d0f2f842a666c844ac53e6c7a253d7e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Jun 19 07:48:02 2016 +0000
-
-    upstream commit
-    
-    revert 1.34; causes problems loading public keys
-    
-    reported by semarie@
-    
-    Upstream-ID: b393794f8935c8b15d98a407fe7721c62d2ed179
-
-commit ad23a75509f4320d43f628c50f0817e3ad12bfa7
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Jun 17 06:33:30 2016 +0000
-
-    upstream commit
-    
-    grammar fix;
-    
-    Upstream-ID: 5d5b21c80f1e81db367333ce0bb3e5874fb3e463
-
-commit 5e28b1a2a3757548b40018cc2493540a17c82e27
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jun 17 05:06:23 2016 +0000
-
-    upstream commit
-    
-    translate OpenSSL error codes to something more
-    meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@
-    
-    Upstream-ID: 4cb0795a366381724314e6515d57790c5930ffe5
-
-commit b64faeb5eda7eff8210c754d00464f9fe9d23de5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jun 17 05:03:40 2016 +0000
-
-    upstream commit
-    
-    ban AuthenticationMethods="" and accept
-    AuthenticationMethods=any for the default behaviour of not requiring multiple
-    authentication
-    
-    bz#2398 from Jakub Jelen; ok dtucker@
-    
-    Upstream-ID: fabd7f44d59e4518d241d0d01e226435cc23cf27
-
-commit 9816fc5daee5ca924dd5c4781825afbaab728877
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Jun 16 11:00:17 2016 +0000
-
-    upstream commit
-    
-    Include stdarg.h for va_copy as per man page.
-    
-    Upstream-ID: 105d6b2f1af2fbd9d91c893c436ab121434470bd
-
-commit b6cf84b51bc0f5889db48bf29a0c771954ade283
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Thu Jun 16 06:10:45 2016 +0000
-
-    upstream commit
-    
-    keys stored in openssh format can have comments too; diff
-    from yonas yanfa, tweaked a bit;
-    
-    ok djm
-    
-    Upstream-ID: 03d48536da6e51510d73ade6fcd44ace731ceb27
-
-commit aa37768f17d01974b6bfa481e5e83841b6c76f86
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jun 20 15:55:34 2016 +1000
-
-    get_remote_name_or_ip inside LOGIN_NEEDS_UTMPX
-    
-    Apply the same get_remote_name_or_ip -> session_get_remote_name_or_ip
-    change as commit 95767262 to the code inside #ifdef LOGIN_NEEDS_UTMPX.
-    Fixes build on AIX.
-
-commit 009891afc8df37bc2101e15d1e0b6433cfb90549
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jun 17 14:34:09 2016 +1000
-
-    Remove duplicate code from PAM.  ok djm@
-
-commit e690fe85750e93fca1fb7c7c8587d4130a4f7aba
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jun 15 00:40:40 2016 +0000
-
-    upstream commit
-    
-    Remove "POSSIBLE BREAK-IN ATTEMPT!" from log message
-    about forward and reverse DNS not matching.  We haven't supported IP-based
-    auth methods for a very long time so it's now misleading.  part of bz#2585,
-    ok markus@
-    
-    Upstream-ID: 5565ef0ee0599b27f0bd1d3bb1f8a323d8274e29
-
-commit 57b4ee04cad0d3e0fec1194753b0c4d31e39a1cd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Jun 15 11:22:38 2016 +1000
-
-    Move platform_disable_tracing into its own file.
-    
-    Prevents link errors resolving the extern "options" when platform.o
-    gets linked into ssh-agent when building --with-pam.
-
-commit 78dc8e3724e30ee3e1983ce013e80277dc6ca070
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Jun 14 13:55:12 2016 +1000
-
-    Track skipped upstream commit IDs.
-    
-    There are a small number of "upstream" commits that do not correspond to
-    a file in -portable.  This file tracks those so that we can reconcile
-    OpenBSD and Portable to ensure that no commits are accidentally missed.
-    
-    If you add something to .skipped-commit-ids please also add an upstream
-    ID line in the following format when you commit it.
-    
-        Upstream-ID: 321065a95a7ccebdd5fd08482a1e19afbf524e35
-        Upstream-ID: d4f699a421504df35254cf1c6f1a7c304fb907ca
-        Upstream-ID: aafe246655b53b52bc32c8a24002bc262f4230f7
-        Upstream-ID: 8fa9cd1dee3c3339ae329cf20fb591db6d605120
-        Upstream-ID: f31327a48dd4103333cc53315ec53fe65ed8a17a
-        Upstream-ID: edbfde98c40007b7752a4ac106095e060c25c1ef
-        Upstream-ID: 052fd565e3ff2d8cec3bc957d1788f50c827f8e2
-        Upstream-ID: 7cf73737f357492776223da1c09179fa6ba74660
-        Upstream-ID: 180d84674be1344e45a63990d60349988187c1ae
-        Upstream-ID: f6ae971186ba68d066cd102e57d5b0b2c211a5ee
-
-commit 9f919d1a3219d476d6a662d18df058e1c4f36a6f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Jun 14 13:51:01 2016 +1000
-
-    Remove now-defunct .cvsignore files. ok djm
-
-commit 68777faf271efb2713960605c748f6c8a4b26d55
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jun 8 02:13:01 2016 +0000
-
-    upstream commit
-    
-    Back out rev 1.28 "Check min and max sizes sent by the
-    client" change. It caused "key_verify failed for server_host_key" in clients
-    that send a DH-GEX min value less that DH_GRP_MIN, eg old OpenSSH and PuTTY.
-    ok djm@
-    
-    Upstream-ID: 452979d3ca5c1e9dff063287ea0a5314dd091f65
-
-commit a86ec4d0737ac5879223e7cd9d68c448df46e169
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Jun 14 10:48:27 2016 +1000
-
-    Use Solaris setpflags(__PROC_PROTECT, ...).
-    
-    Where possible, use Solaris setpflags to disable process tracing on
-    ssh-agent and sftp-server.  bz#2584, based on a patch from huieying.lee
-    at oracle.com, ok djm.
-
-commit 0f916d39b039fdc0b5baf9b5ab0754c0f11ec573
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Jun 14 10:43:53 2016 +1000
-
-    Shorten prctl code a tiny bit.
-
-commit 0fb7f5985351fbbcd2613d8485482c538e5123be
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jun 9 16:23:07 2016 +1000
-
-    Move prctl PR_SET_DUMPABLE into platform.c.
-    
-    This should make it easier to add additional platform support such as
-    Solaris (bz#2584).
-
-commit e6508898c3cd838324ecfe1abd0eb8cf802e7106
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jun 3 04:10:41 2016 +0000
-
-    upstream commit
-    
-    Add a test for ssh(1)'s config file parsing.
-    
-    Upstream-Regress-ID: 558b7f4dc45cc3761cc3d3e889b9f3c5bc91e601
-
-commit ab0a536066dfa32def0bd7272c096ebb5eb25b11
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jun 3 03:47:59 2016 +0000
-
-    upstream commit
-    
-    Add 'sshd' to the test ID as I'm about to add a similar
-     set for ssh.
-    
-    Upstream-Regress-ID: aea7a9c3bac638530165c801ce836875b228ae7a
-
-commit a5577c1ed3ecdfe4b7b1107c526cae886fc91afb
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Mon May 30 12:14:08 2016 +0000
-
-    upstream commit
-    
-    stricter malloc.conf(5) options for utf8 tests
-    
-    Upstream-Regress-ID: 111efe20a0fb692fa1a987f6e823310f9b25abf6
-
-commit 75f0844b4f29d62ec3a5e166d2ee94b02df819fc
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Mon May 30 12:05:56 2016 +0000
-
-    upstream commit
-    
-    Fix two rare edge cases: 1. If vasprintf() returns < 0,
-     do not access a NULL pointer in snmprintf(), and do not free() the pointer
-     returned from vasprintf() because on some systems other than OpenBSD, it
-     might be a bogus pointer. 2. If vasprintf() returns == 0, return 0 and ""
-     rather than -1 and NULL.
-    
-    Besides, free(dst) is pointless after failure (not a bug).
-    
-    One half OK martijn@, the other half OK deraadt@;
-    committing quickly before people get hurt.
-    
-    Upstream-Regress-ID: b164f20923812c9bac69856dbc1385eb1522cba4
-
-commit 016881eb33a7948028848c90f4c7ac42e3af0e87
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Thu May 26 19:14:25 2016 +0000
-
-    upstream commit
-    
-    test the new utf8 module
-    
-    Upstream-Regress-ID: c923d05a20e84e4ef152cbec947fdc4ce6eabbe3
-
-commit d4219028bdef448e089376f3afe81ef6079da264
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 3 15:30:46 2016 +0000
-
-    upstream commit
-    
-    Set umask to prevent "Bad owner or permissions" errors.
-    
-    Upstream-Regress-ID: 8fdf2fc4eb595ccd80c443f474d639f851145417
-
-commit 07d5608bb237e9b3fe86a2aeaa429392230faebf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 14:41:04 2016 +0000
-
-    upstream commit
-    
-    support doas
-    
-    Upstream-Regress-ID: 8d5572b27ea810394eeda432d8b4e9e1064a7c38
-
-commit 01cabf10adc7676cba5f40536a34d3b246edb73f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 13:48:33 2016 +0000
-
-    upstream commit
-    
-    unit tests for sshbuf_dup_string()
-    
-    Upstream-Regress-ID: 7521ff150dc7f20511d1c2c48fd3318e5850a96d
-
-commit 6915f1698e3d1dd4e22eac20f435e1dfc1d46372
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Jun 3 06:44:12 2016 +0000
-
-    upstream commit
-    
-    tweak previous;
-    
-    Upstream-ID: 92979f1a0b63e041a0e5b08c9ed0ba9b683a3698
-
-commit 0cb2f4c2494b115d0f346ed2d8b603ab3ba643f4
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jun 3 04:09:38 2016 +0000
-
-    upstream commit
-    
-    Allow ExitOnForwardFailure and ClearAllForwardings to be
-     overridden when using ssh -W (but still default to yes in that case).
-     bz#2577, ok djm@.
-    
-    Upstream-ID: 4b20c419e93ca11a861c81c284090cfabc8c54d4
-
-commit 8543ff3f5020fe659839b15f05b8c522bde6cee5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jun 3 03:14:41 2016 +0000
-
-    upstream commit
-    
-    Move the host and port used by ssh -W into the Options
-     struct. This will make future changes a bit easier.  ok djm@
-    
-    Upstream-ID: 151bce5ecab2fbedf0d836250a27968d30389382
-
-commit 6b87311d3acdc460f926b2c40f4c4f3fd345f368
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jun 1 04:19:49 2016 +0000
-
-    upstream commit
-    
-    Check min and max sizes sent by the client against what
-     we support before passing them to the monitor.  ok djm@
-    
-    Upstream-ID: 750627e8117084215412bff00a25b1586ab17ece
-
-commit 564cd2a8926ccb1dca43a535073540935b5e0373
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 31 23:46:14 2016 +0000
-
-    upstream commit
-    
-    Ensure that the client's proposed DH-GEX max value is at
-     least as big as the minimum the server will accept.  ok djm@
-    
-    Upstream-ID: b4b84fa04aab2de7e79a6fee4a6e1c189c0fe775
-
-commit df820722e40309c9b3f360ea4ed47a584ed74333
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jun 6 11:36:13 2016 +1000
-
-    Add compat bits to utf8.c.
-
-commit 05c6574652571becfe9d924226c967a3f4b3f879
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jun 6 11:33:43 2016 +1000
-
-    Fix utf->utf8 typo.
-
-commit 6c1717190b4d5ddd729cd9e24e8ed71ed4f087ce
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Mon May 30 18:34:41 2016 +0000
-
-    upstream commit
-    
-    Backout rev. 1.43 for now.
-    
-    The function update_progress_meter() calls refresh_progress_meter()
-    which calls snmprintf() which calls malloc(); but update_progress_meter()
-    acts as the SIGALRM signal handler.
-    
-    "malloc(): error: recursive call" reported by sobrado@.
-    
-    Upstream-ID: aaae57989431e5239c101f8310f74ccc83aeb93e
-
-commit cd9e1eabeb4137182200035ab6fa4522f8d24044
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Mon May 30 12:57:21 2016 +0000
-
-    upstream commit
-    
-    Even when only writing an unescaped character, the dst
-     buffer may need to grow, or it would be overrun; issue found by tb@ with
-     malloc.conf(5) 'C'.
-    
-    While here, reserve an additional byte for the terminating NUL
-    up front such that we don't have to realloc() later just for that.
-    
-    OK tb@
-    
-    Upstream-ID: 30ebcc0c097c4571b16f0a78b44969f170db0cff
-
-commit ac284a355f8065eaef2a16f446f3c44cdd17371d
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Mon May 30 12:05:56 2016 +0000
-
-    upstream commit
-    
-    Fix two rare edge cases: 1. If vasprintf() returns < 0,
-     do not access a NULL pointer in snmprintf(), and do not free() the pointer
-     returned from vasprintf() because on some systems other than OpenBSD, it
-     might be a bogus pointer. 2. If vasprintf() returns == 0, return 0 and ""
-     rather than -1 and NULL.
-    
-    Besides, free(dst) is pointless after failure (not a bug).
-    
-    One half OK martijn@, the other half OK deraadt@;
-    committing quickly before people get hurt.
-    
-    Upstream-ID: b7bcd2e82fc168a8eff94e41f5db336ed986fed0
-
-commit 0e059cdf5fd86297546c63fa8607c24059118832
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date:   Wed May 25 23:48:45 2016 +0000
-
-    upstream commit
-    
-    To prevent screwing up terminal settings when printing to
-     the terminal, for ASCII and UTF-8, escape bytes not forming characters and
-     bytes forming non-printable characters with vis(3) VIS_OCTAL. For other
-     character sets, abort printing of the current string in these cases.  In
-     particular, * let scp(1) respect the local user's LC_CTYPE locale(1); *
-     sanitize data received from the remote host; * sanitize filenames, usernames,
-     and similar data even locally; * take character display widths into account
-     for the progressmeter.
-    
-    This is believed to be sufficient to keep the local terminal safe
-    on OpenBSD, but bad things can still happen on other systems with
-    state-dependent locales because many places in the code print
-    unencoded ASCII characters into the output stream.
-    
-    Using feedback from djm@ and martijn@,
-    various aspects discussed with many others.
-    
-    deraadt@ says it should go in now, i probably already hesitated too long
-    
-    Upstream-ID: e66afbc94ee396ddcaffd433b9a3b80f387647e0
-
-commit 8c02e3639acefe1e447e293dbe23a0917abd3734
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 24 04:43:45 2016 +0000
-
-    upstream commit
-    
-    KNF compression proposal and simplify the client side a
-     little.  ok djm@
-    
-    Upstream-ID: aa814b694efe9e5af8a26e4c80a05526ae6d6605
-
-commit 7ec4946fb686813eb5f8c57397e465f5485159f4
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 24 02:31:57 2016 +0000
-
-    upstream commit
-    
-    Back out 'plug memleak'.
-    
-    Upstream-ID: 4faacdde136c24a961e24538de373660f869dbc0
-
-commit 82f24c3ddc52053aeb7beb3332fa94c92014b0c5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 23 23:30:50 2016 +0000
-
-    upstream commit
-    
-    prefer agent-hosted keys to keys from PKCS#11; ok markus
-    
-    Upstream-ID: 7417f7653d58d6306d9f8c08d0263d050e2fd8f4
-
-commit a0cb7778fbc9b43458f7072eb68dd858766384d1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon May 23 00:17:27 2016 +0000
-
-    upstream commit
-    
-    Plug mem leak in filter_proposal.  ok djm@
-    
-    Upstream-ID: bf968da7cfcea2a41902832e7d548356a4e2af34
-
-commit ae9c0d4d5c581b3040d1f16b5c5f4b1cd1616743
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jun 3 16:03:44 2016 +1000
-
-    Update vis.h and vis.c from OpenBSD.
-    
-    This will be needed for the upcoming utf8 changes.
-
-commit e1d93705f8f48f519433d6ca9fc3d0abe92a1b77
-Author: Tim Rice <tim@multitalents.net>
-Date:   Tue May 31 11:13:22 2016 -0700
-
-    modified:   configure.ac
-    whitspace clean up. No code changes.
-
-commit 604a037d84e41e31f0aec9075df0b8740c130200
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue May 31 16:45:28 2016 +1000
-
-    whitespace at EOL
-
-commit 18424200160ff5c923113e0a37ebe21ab7bcd17c
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon May 30 19:35:28 2016 +1000
-
-    Add missing ssh-host-config --name option
-    
-    Patch from vinschen@redhat.com.
-
-commit 39c0cecaa188a37a2e134795caa68e03f3ced592
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri May 20 10:01:58 2016 +1000
-
-    Fix comment about sshpam_const and AIX.
-    
-    From mschwager via github.
-
-commit f64062b1f74ad5ee20a8a49aab2732efd0f7ce30
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri May 20 09:56:53 2016 +1000
-
-    Deny lstat syscalls in seccomp sandbox
-    
-    Avoids sandbox violations for some krb/gssapi libraries.
-
-commit 531c135409b8d8810795b1f3692a4ebfd5c9cae0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 19 07:45:32 2016 +0000
-
-    upstream commit
-    
-    fix type of ed25519 values
-    
-    Upstream-ID: b32d0cb372bbe918ca2de56906901eae225a59b0
-
-commit 75e21688f523799c9e0cc6601d76a9c5ca79f787
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed May 4 14:32:26 2016 +0000
-
-    upstream commit
-    
-    add IdentityAgent; noticed & ok jmc@
-    
-    Upstream-ID: 4ba9034b00a4cf1beae627f0728da897802df88a
-
-commit 1a75d14daf4b60db903e6103cf50e74e0cd0a76b
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed May 4 14:29:58 2016 +0000
-
-    upstream commit
-    
-    allow setting IdentityAgent to SSH_AUTH_SOCK; ok djm@
-    
-    Upstream-ID: 20c508480d8db3eef18942c0fc39b1fcf25652ac
-
-commit 0516454151ae722fc8256c3c56115c6baf24c5b0
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed May 4 14:22:33 2016 +0000
-
-    upstream commit
-    
-    move SSH_MSG_NONE, so we don't have to include ssh1.h;
-     ok deraadt@
-    
-    Upstream-ID: c2f97502efc761a41b18c17ddf460e138ca7994e
-
-commit 332ff3d770631e7513fea38cf0d3689f673f0e3f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue May 10 09:51:06 2016 +1000
-
-    initialise salen in binresvport_sa
-    
-    avoids failures with UsePrivilegedPort=yes
-    
-    patch from Juan Gallego
-
-commit c5c1d5d2f04ce00d2ddd6647e61b32f28be39804
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed May 4 14:04:40 2016 +0000
-
-    upstream commit
-    
-    missing const in prototypes (ssh1)
-    
-    Upstream-ID: 789c6ad4928b5fa557369b88c3a6a34926082c05
-
-commit 9faae50e2e82ba42eb0cb2726bf6830fe7948f28
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed May 4 14:00:09 2016 +0000
-
-    upstream commit
-    
-    Fix inverted logic for updating StreamLocalBindMask which
-     would cause the server to set an invalid mask. ok djm@
-    
-    Upstream-ID: 8a4404c8307a5ef9e07ee2169fc6d8106b527587
-
-commit b02ad1ce9105bfa7394ac7590c0729dd52e26a81
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed May 4 12:21:53 2016 +0000
-
-    upstream commit
-    
-    IdentityAgent for specifying specific agent sockets; ok
-     djm@
-    
-    Upstream-ID: 3e6a15eb89ea0fd406f108826b7dc7dec4fbfac1
-
-commit 910e59bba09ac309d78ce61e356da35292212935
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed May 4 12:16:39 2016 +0000
-
-    upstream commit
-    
-    fix junk characters after quotes
-    
-    Upstream-ID: cc4d0cd32cb6b55a2ef98975d2f7ae857d0dc578
-
-commit 9283884e647b8be50ccd2997537af0065672107d
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Tue May 3 18:38:12 2016 +0000
-
-    upstream commit
-    
-    correct article;
-    
-    Upstream-ID: 1fbd5b7ab16d2d9834ec79c3cedd4738fa42a168
-
-commit cfefbcea1057c2623e76c579174a4107a0b6e6cd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 15:57:39 2016 +0000
-
-    upstream commit
-    
-    fix overriding of StreamLocalBindMask and
-     StreamLocalBindUnlink in Match blocks; found the hard way Rogan Dawes
-    
-    Upstream-ID: 940bc69ec0249ab428d24ccd0722ce35cb932ee2
-
-commit 771c2f51ffc0c9a2877b7892fada0c77bd1f6549
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 15:25:06 2016 +0000
-
-    upstream commit
-    
-    don't forget to include StreamLocalBindUnlink in the
-     config dump output
-    
-    Upstream-ID: 14a6d970b3b45c8e94272e3c661e9a0b2a0ee7cb
-
-commit cdcd941994dc430f50d0a4e6a712d32b66e6199e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 14:54:08 2016 +0000
-
-    upstream commit
-    
-    make nethack^wrandomart fingerprint flag more readily
-     searchable pointed out by Matt Johnston
-    
-    Upstream-ID: cb40d0235dc153c478c1aad3bc60b195422a54fb
-
-commit 05855bf2ce7d5cd0a6db18bc0b4214ed5ef7516d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 13:10:24 2016 +0000
-
-    upstream commit
-    
-    clarify ordering of subkeys; pointed out by ietf-ssh AT
-     stbuehler.de
-    
-    Upstream-ID: 05ebe9f949449a555ebce8e0aad7c8c9acaf8463
-
-commit cca3b4395807bfb7aaeb83d2838f5c062ce30566
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 3 12:15:49 2016 +0000
-
-    upstream commit
-    
-    Use a subshell for constructing key types to work around
-     different sed behaviours for -portable.
-    
-    Upstream-Regress-ID: 0f6eb673162df229eda9a134a0f10da16151552d
-
-commit fa58208c6502dcce3e0daac0ca991ee657daf1f5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 10:27:59 2016 +0000
-
-    upstream commit
-    
-    correct some typos and remove a long-stale XXX note.
-    
-    add specification for ed25519 certificates
-    
-    mention no host certificate options/extensions are currently defined
-    
-    pointed out by Simon Tatham
-    
-    Upstream-ID: 7b535ab7dba3340b7d8210ede6791fdaefdf839a
-
-commit b466f956c32cbaff4200bfcd5db6739fe4bc7d04
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue May 3 10:24:27 2016 +0000
-
-    upstream commit
-    
-    add ed25519 keys that are supported but missing from this
-     documents; from Peter Moody
-    
-    Upstream-ID: 8caac2d8e8cfd2fca6dc304877346e0a064b014b
-
-commit 7f3d76319a69dab2efe3a520a8fef5b97e923636
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 3 09:03:49 2016 +0000
-
-    upstream commit
-    
-    Implement IUTF8 as per draft-sgtatham-secsh-iutf8-00.  Patch
-     from Simon Tatham, ok markus@
-    
-    Upstream-ID: 58268ebdf37d9d467f78216c681705a5e10c58e8
-
-commit 31bc01c05d9f51bee3ebe33dc57c4fafb059fb62
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 2 14:10:58 2016 +0000
-
-    upstream commit
-    
-    unbreak config parsing on reexec from previous commit
-    
-    Upstream-ID: bc69932638a291770955bd05ca55a32660a613ab
-
-commit 67f1459efd2e85bf03d032539283fa8107218936
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 2 09:52:00 2016 +0000
-
-    upstream commit
-    
-    unit and regress tests for SHA256/512; ok markus
-    
-    Upstream-Regress-ID: a0cd1a92dc824067076a5fcef83c18df9b0bf2c6
-
-commit 0e8eeec8e75f6d0eaf33317376f773160018a9c7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 2 10:26:04 2016 +0000
-
-    upstream commit
-    
-    add support for additional fixed DH groups from
-     draft-ietf-curdle-ssh-kex-sha2-03
-    
-    diffie-hellman-group14-sha256 (2K group)
-    diffie-hellman-group16-sha512 (4K group)
-    diffie-hellman-group18-sha512 (8K group)
-    
-    based on patch from Mark D. Baushke and Darren Tucker
-    ok markus@
-    
-    Upstream-ID: ac00406ada4f0dfec41585ca0839f039545bc46f
-
-commit 57464e3934ba53ad8590ee3ccd840f693407fc1e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 2 09:36:42 2016 +0000
-
-    upstream commit
-    
-    support SHA256 and SHA512 RSA signatures in certificates;
-     ok markus@
-    
-    Upstream-ID: b45be2f2ce8cacd794dc5730edaabc90e5eb434a
-
-commit 1a31d02b2411c4718de58ce796dbb7b5e14db93e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 2 08:49:03 2016 +0000
-
-    upstream commit
-    
-    fix signed/unsigned errors reported by clang-3.7; add
-     sshbuf_dup_string() to replace a common idiom of strdup(sshbuf_ptr()) with
-     better safety checking; feedback and ok markus@
-    
-    Upstream-ID: 71f926d9bb3f1efed51319a6daf37e93d57c8820
-
-commit d2d6bf864e52af8491a60dd507f85b74361f5da3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 29 08:07:53 2016 +0000
-
-    upstream commit
-    
-    close ControlPersist background process stderr when not
-     in debug mode or when logging to a file or syslog. bz#1988 ok dtucker
-    
-    Upstream-ID: 4fb726f0fdcb155ad419913cea10dc4afd409d24
-
-commit 9ee692fa1146e887e008a2b9a3d3ea81770c9fc8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Apr 28 14:30:21 2016 +0000
-
-    upstream commit
-    
-    fix comment
-    
-    Upstream-ID: 313a385bd7b69a82f8e28ecbaf5789c774457b15
-
-commit ee1e0a16ff2ba41a4d203c7670b54644b6c57fa6
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Apr 27 13:53:48 2016 +0000
-
-    upstream commit
-    
-    cidr permitted for {allow,deny}users; from lars nooden ok djm
-    
-    Upstream-ID: 13e7327fe85f6c63f3f7f069e0fdc8c351515d11
-
-commit b6e0140a5aa883c27b98415bd8aa9f65fc04ee22
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Apr 21 06:08:02 2016 +0000
-
-    upstream commit
-    
-    make argument == NULL tests more consistent
-    
-    Upstream-ID: dc4816678704aa5cbda3a702e0fa2033ff04581d
-
-commit 6aaabc2b610e44bae473457ad9556ffb43d90ee3
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sun Apr 17 14:34:46 2016 +0000
-
-    upstream commit
-    
-    tweak previous;
-    
-    Upstream-ID: 46c1bab91c164078edbccd5f7d06b9058edd814f
-
-commit 0f839e5969efa3bda615991be8a9d9311554c573
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 15 02:57:10 2016 +0000
-
-    upstream commit
-    
-    missing bit of Include regress
-    
-    Upstream-Regress-ID: 1063595f7f40f8489a1b7a27230b9e8acccea34f
-
-commit 12e4ac46aed681da55c2bba3cd11dfcab23591be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 15 02:55:53 2016 +0000
-
-    upstream commit
-    
-    remove redundant CLEANFILES section
-    
-    Upstream-Regress-ID: 29ef1b267fa56daa60a1463396635e7d53afb587
-
-commit b1d05aa653ae560c44baf8e8a9756e33f98ea75c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 15 00:48:01 2016 +0000
-
-    upstream commit
-    
-    sync CLEANFILES with portable, sort
-    
-    Upstream-Regress-ID: cb782f4f1ab3e079efbc335c6b64942f790766ed
-
-commit 35f22dad263cce5c61d933ae439998cb965b8748
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 15 00:31:10 2016 +0000
-
-    upstream commit
-    
-    regression test for ssh_config Include directive
-    
-    Upstream-Regress-ID: 46a38c8101f635461c506d1aac2d96af80f97f1e
-
-commit 6b8a1a87005818d4700ce8b42faef746e82c1f51
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Apr 14 23:57:17 2016 +0000
-
-    upstream commit
-    
-    unbreak test for recent ssh de-duplicated forwarding
-     change
-    
-    Upstream-Regress-ID: 6b2b115d99acd7cff13986e6739ea214cf2a3da3
-
-commit 076787702418985a2cc6808212dc28ce7afc01f0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Apr 14 23:21:42 2016 +0000
-
-    upstream commit
-    
-    add test knob and warning for StrictModes
-    
-    Upstream-Regress-ID: 8cd10952ce7898655ee58945904f2a0a3bdf7682
-
-commit dc7990be865450574c7940c9880567f5d2555b37
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 15 00:30:19 2016 +0000
-
-    upstream commit
-    
-    Include directive for ssh_config(5); feedback & ok markus@
-    
-    Upstream-ID: ae3b76e2e343322b9f74acde6f1e1c5f027d5fff
-
-commit 85bdcd7c92fe7ff133bbc4e10a65c91810f88755
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Apr 13 10:39:57 2016 +1000
-
-    ignore PAM environment vars when UseLogin=yes
-    
-    If PAM is configured to read user-specified environment variables
-    and UseLogin=yes in sshd_config, then a hostile local user may
-    attack /bin/login via LD_PRELOAD or similar environment variables
-    set via PAM.
-    
-    CVE-2015-8325, found by Shayan Sadigh, via Colin Watson
-
-commit dce19bf6e4a2a3d0b13a81224de63fc316461ab9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Apr 9 12:39:30 2016 +0000
-
-    upstream commit
-    
-    make private key loading functions consistently handle NULL
-     key pointer arguments; ok markus@
-    
-    Upstream-ID: 92038726ef4a338169c35dacc9c5a07fcc7fa761
-
-commit 5f41f030e2feb5295657285aa8c6602c7810bc4b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Apr 8 21:14:13 2016 +1000
-
-    Remove NO_IPPORT_RESERVED_CONCEPT
-    
-    Replace by defining IPPORT_RESERVED to zero on Cygwin, which should have
-    the same effect without causing problems syncing patches with OpenBSD.
-    Resync the two affected functions with OpenBSD.  ok djm, sanity checked
-    by Corinna.
-
-commit 34a01b2cf737d946ddb140618e28c3048ab7a229
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 8 08:19:17 2016 +0000
-
-    upstream commit
-    
-    whitespace at EOL
-    
-    Upstream-ID: 5beffd4e001515da12851b974e2323ae4aa313b6
-
-commit 90ee563fa6b54c59896c6c332c5188f866c5e75f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 8 06:35:54 2016 +0000
-
-    upstream commit
-    
-    We accidentally send an empty string and a zero uint32 with
-     every direct-streamlocal@openssh.com channel open, in contravention of our
-     own spec.
-    
-    Fixing this is too hard wrt existing versions that expect these
-    fields to be present and fatal() if they aren't, so document them
-    as "reserved" fields in the PROTOCOL spec as though we always
-    intended this and let us never speak of it again.
-    
-    bz#2529, reported by Ron Frederick
-    
-    Upstream-ID: 34cd326a4d236ca6e39084c4ff796bd97ab833e7
-
-commit 0ccbd5eca0f0dd78e71a4b69c66f03a66908d558
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Apr 6 06:42:17 2016 +0000
-
-    upstream commit
-    
-    don't record duplicate LocalForward and RemoteForward
-     entries; fixes failure with ExitOnForwardFailure+hostname canonicalisation
-     where the same forwards are added on the second pass through the
-     configuration file. bz#2562; ok dtucker@
-    
-    Upstream-ID: 40a51d68b6300f1cc61deecdb7d4847b8b7b0de1
-
-commit 574def0eb493cd6efeffd4ff2e9257abcffee0c8
-Author: krw@openbsd.org <krw@openbsd.org>
-Date:   Sat Apr 2 14:37:42 2016 +0000
-
-    upstream commit
-    
-    Another use for fcntl() and thus of the superfluous 3rd
-     parameter is when sanitising standard fd's before calling daemon().
-    
-    Use a tweaked version of the ssh(1) function in all three places
-    found using fcntl() this way.
-    
-    ok jca@ beck@
-    
-    Upstream-ID: f16811ffa19a1c5f4ef383c5f0fecb843c84e218
-
-commit b3413534aa9d71a941005df2760d1eec2c2b0854
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Apr 4 11:09:21 2016 +1000
-
-    Tidy up openssl header test.
-
-commit 815bcac0b94bb448de5acdd6ba925b8725240b4f
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Apr 4 11:07:59 2016 +1000
-
-    Fix configure-time warnings for openssl test.
-
-commit 95687f5831ae680f7959446d8ae4b52452ee05dd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 1 02:34:10 2016 +0000
-
-    upstream commit
-    
-    whitespace at EOL
-    
-    Upstream-ID: 40ae2203d07cb14e0a89e1a0d4c6120ee8fd8c3a
-
-commit fdfbf4580de09d84a974211715e14f88a5704b8e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Mar 31 05:24:06 2016 +0000
-
-    upstream commit
-    
-    Remove fallback from moduli to "primes" file that was
-     deprecated in 2001 and fix log messages referring to primes file.  Based on
-     patch from xnox at ubuntu.com via bz#2559.  "kill it" deraadt@
-    
-    Upstream-ID: 0d4f8c70e2fa7431a83b95f8ca81033147ba8713
-
-commit 0235a5fa67fcac51adb564cba69011a535f86f6b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Mar 17 17:19:43 2016 +0000
-
-    upstream commit
-    
-    UseDNS affects ssh hostname processing in authorized_keys,
-     not known_hosts; bz#2554 reported by jjelen AT redhat.com
-    
-    Upstream-ID: c1c1bb895dde46095fc6d81d8653703928437591
-
-commit 8c4739338f5e379d05b19d6e544540114965f07e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Mar 15 09:24:43 2016 +1100
-
-    Don't call Solaris setproject() with UsePAM=yes.
-    
-    When Solaris Projects are enabled along with PAM setting the project
-    is PAM's responsiblity.  bz#2425, based on patch from
-    brent.paulson at gmail.com.
-
-commit cff26f373c58457a32cb263e212cfff53fca987b
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 15 04:30:21 2016 +1100
-
-    remove slogin from *.spec
-
-commit c38905ba391434834da86abfc988a2b8b9b62477
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 14 16:20:54 2016 +0000
-
-    upstream commit
-    
-    unbreak authentication using lone certificate keys in
-     ssh-agent: when attempting pubkey auth with a certificate, if no separate
-     private key is found among the keys then try with the certificate key itself.
-    
-    bz#2550 reported by Peter Moody
-    
-    Upstream-ID: f939cd76d68e6a9a3d1711b5a943d6ed1e623966
-
-commit 4b4bfb01cd40b9ddb948e6026ddd287cc303d871
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Mar 10 11:47:57 2016 +0000
-
-    upstream commit
-    
-    sanitise characters destined for xauth reported by
-     github.com/tintinweb feedback and ok deraadt and markus
-    
-    Upstream-ID: 18ad8d0d74cbd2ea3306a16595a306ee356aa261
-
-commit 732b463d37221722b1206f43aa59563766a6a968
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Mar 14 16:04:23 2016 +1100
-
-    Pass supported malloc options to connect-privsep.
-    
-    This allows us to activate only the supported options during the malloc
-    option portion of the connect-privsep test.
-
-commit d29c5b9b3e9f27394ca97a364ed4bb4a55a59744
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Mar 14 09:30:58 2016 +1100
-
-    Remove leftover roaming.h file.
-    
-    Pointed out by des at des.no.
-
-commit 8ff20ec95f4377021ed5e9b2331320f5c5a34cea
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Mar 14 09:24:03 2016 +1100
-
-    Quote variables that may contain whitespace.
-    
-    The variable $L_TMP_ID_FILE needs to be surrounded by quotes in order to
-    survive paths containing whitespace.  bz#2551, from Corinna Vinschen via
-    Philip Hands.
-
-commit 627824480c01f0b24541842c7206ab9009644d02
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Mar 11 14:47:41 2016 +1100
-
-    Include priv.h for priv_set_t.
-    
-    From alex at cooperi.net.
-
-commit e960051f9a264f682c4d2fefbeecffcfc66b0ddf
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Mar 9 13:14:18 2016 +1100
-
-    Wrap stdint.h inside #ifdef HAVE_STDINT_H.
-
-commit 2c48bd344d2c4b5e08dae9aea5ff44fc19a5e363
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Mar 9 12:46:50 2016 +1100
-
-    Add compat to monotime_double().
-    
-    Apply all of the portability changes in monotime() to monotime() double.
-    Fixes build on at least older FreeBSD systems.
-
-commit 7b40ef6c2eef40c339f6ea8920cb8a44838e10c9
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 8 14:12:58 2016 -0800
-
-    make a regress-binaries target
-    
-    Easier to build all the regression/unit test binaries in one pass
-    than going through all of ${REGRESS_BINARIES}
-
-commit c425494d6b6181beb54a1b3763ef9e944fd3c214
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 8 14:03:54 2016 -0800
-
-    unbreak kexfuzz for -Werror without __bounded__
-
-commit 3ed9218c336607846563daea5d5ab4f701f4e042
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Mar 8 14:01:29 2016 -0800
-
-    unbreak PAM after canohost refactor
-
-commit 885fb2a44ff694f01e4f6470f803629e11f62961
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Mar 8 11:58:43 2016 +1100
-
-    auth_get_canonical_hostname in portable code.
-    
-    "refactor canohost.c" replaced get_canonical_hostname, this makes the
-    same change to some portable-specific code.
-
-commit 95767262caa6692eff1e1565be1f5cb297949a89
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 7 19:02:43 2016 +0000
-
-    upstream commit
-    
-    refactor canohost.c: move functions that cache results closer
-     to the places that use them (authn and session code). After this, no state is
-     cached in canohost.c
-    
-    feedback and ok markus@
-    
-    Upstream-ID: 5f2e4df88d4803fc8ec59ec53629105e23ce625e
-
-commit af0bb38ffd1f2c4f9f43b0029be2efe922815255
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Mar 4 15:11:55 2016 +1100
-
-    hook unittests/misc/kexfuzz into build
-
-commit 331b8e07ee5bcbdca12c11cc8f51a7e8de09b248
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Mar 4 02:48:06 2016 +0000
-
-    upstream commit
-    
-    Filter debug messages out of log before picking the last
-     two lines. Should prevent problems if any more debug output is added late in
-     the connection.
-    
-    Upstream-Regress-ID: 345d0a9589c381e7d640a4ead06cfaadf4db1363
-
-commit 0892edaa3ce623381d3a7635544cbc69b31cf9cb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 4 02:30:36 2016 +0000
-
-    upstream commit
-    
-    add KEX fuzzer harness; ok deraadt@
-    
-    Upstream-Regress-ID: 3df5242d30551b12b828aa9ba4a4cec0846be8d1
-
-commit ae2562c47d41b68dbb00240fd6dd60bed205367a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Mar 3 00:46:53 2016 +0000
-
-    upstream commit
-    
-    Look back 3 lines for possible error messages.  Changes
-     to the code mean that "Bad packet length" errors are 3 lines back instead of
-     the previous two, which meant we didn't skip some offsets that we intended
-     to.
-    
-    Upstream-Regress-ID: 24f36912740a634d509a3144ebc8eb7c09b9c684
-
-commit 988e429d903acfb298bfddfd75e7994327adfed0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Mar 4 03:35:44 2016 +0000
-
-    upstream commit
-    
-    fix ClientAliveInterval when a time-based RekeyLimit is
-     set; previously keepalive packets were not being sent. bz#2252 report and
-     analysis by Christian Wittenhorst and Garrett Lee feedback and ok dtucker@
-    
-    Upstream-ID: d48f9deadd35fdacdd5106b41bb07630ddd4aa81
-
-commit 8ef04d7a94bcdb8b0085fdd2a79a844b7d40792d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Mar 2 22:43:52 2016 +0000
-
-    upstream commit
-    
-    Improve accuracy of reported transfer speeds by waiting
-     for the ack from the other end.  Pointed out by mmcc@, ok deraadt@ markus@
-    
-    Upstream-ID: 99f1cf15c9a8f161086b814d414d862795ae153d
-
-commit b8d4eafe29684fe4f5bb587f7eab948e6ed62723
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Mar 2 22:42:40 2016 +0000
-
-    upstream commit
-    
-    Improve precision of progressmeter for sftp and scp by
-     storing sub-second timestamps.  Pointed out by mmcc@, ok deraadt@ markus@
-    
-    Upstream-ID: 38fd83a3d83dbf81c8ff7b5d1302382fe54970ab
-
-commit 18f64b969c70ed00e74b9d8e50359dbe698ce4c0
-Author: jca@openbsd.org <jca@openbsd.org>
-Date:   Mon Feb 29 20:22:36 2016 +0000
-
-    upstream commit
-    
-    Print ssize_t with %zd; ok deraadt@ mmcc@
-    
-    Upstream-ID: 0590313bbb013ff6692298c98f7e0be349d124bd
-
-commit 6e7f68ce38130c794ec1fb8d2a6091fbe982628d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Feb 28 22:27:00 2016 +0000
-
-    upstream commit
-    
-    rearrange DH public value tests to be a little more clear
-    
-    rearrange DH private value generation to explain rationale more
-    clearly and include an extra sanity check.
-    
-    ok deraadt
-    
-    Upstream-ID: 9ad8a07e1a12684e1b329f9bd88941b249d4b2ad
-
-commit 2ed17aa34008bdfc8db674315adc425a0712be11
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Mar 1 15:24:20 2016 +1100
-
-    Import updated moduli file from OpenBSD.
-    
-    Note that 1.5k bit groups have been removed.
-
-commit 72b061d4ba0f909501c595d709ea76e06b01e5c9
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Feb 26 14:40:04 2016 +1100
-
-    Add a note about using xlc on AIX.
-
-commit fd4e4f2416baa2e6565ea49d52aade296bad3e28
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Feb 24 10:44:25 2016 +1100
-
-    Skip PrintLastLog in config dump mode.
-    
-    When DISABLE_LASTLOG is set, do not try to include PrintLastLog in the
-    config dump since it'll be reported as UNKNOWN.
-
-commit 99135c764fa250801da5ec3b8d06cbd0111caae8
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 23 20:17:23 2016 +1100
-
-    update spec/README versions ahead of release
-
-commit b86a334aaaa4d1e643eb1fd71f718573d6d948b5
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 23 20:16:53 2016 +1100
-
-    put back portable patchlevel to p1
-
-commit 555dd35ff176847e3c6bd068ba2e8db4022eb24f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 23 09:14:34 2016 +0000
-
-    upstream commit
-    
-    openssh-7.2
-    
-    Upstream-ID: 9db776b26014147fc907ece8460ef2bcb0f11e78
-
-commit 1acc058d0a7913838c830ed998a1a1fb5b7864bf
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 23 16:12:13 2016 +1100
-
-    Disable tests where fs perms are incorrect
-    
-    Some tests have strict requirements on the filesystem permissions
-    for certain files and directories. This adds a regress/check-perm
-    tool that copies the relevant logic from sshd to exactly test
-    the paths in question. This lets us skip tests when the local
-    filesystem doesn't conform to our expectations rather than
-    continuing and failing the test run.
-    
-    ok dtucker@
-
-commit 39f303b1f36d934d8410b05625f25c7bcb75db4d
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 23 12:56:59 2016 +1100
-
-    fix sandbox on OSX Lion
-    
-    sshd was failing with:
-    
-    ssh_sandbox_child: sandbox_init: dlopen(/usr/lib/libsandbox.1.dylib, 261):cw
-      image not found [preauth]
-    
-    caused by chroot before sandboxing. Avoid by explicitly linking libsandbox
-    to sshd. Spotted by Darren.
-
-commit 0d1451a32c7436e6d3d482351e776bc5e7824ce4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 23 01:34:14 2016 +0000
-
-    upstream commit
-    
-    fix spurious error message when incorrect passphrase
-     entered for keys; reported by espie@ ok deraadt@
-    
-    Upstream-ID: 58b2e46e63ed6912ed1ee780bd3bd8560f9a5899
-
-commit 09d87d79741beb85768b5e788d7dfdf4bc3543dc
-Author: sobrado@openbsd.org <sobrado@openbsd.org>
-Date:   Sat Feb 20 23:06:23 2016 +0000
-
-    upstream commit
-    
-    set ssh(1) protocol version to 2 only.
-    
-    ok djm@
-    
-    Upstream-ID: e168daf9d27d7e392e3c9923826bd8e87b2b3a10
-
-commit 9262e07826ba5eebf8423f7ac9e47ec488c47869
-Author: sobrado@openbsd.org <sobrado@openbsd.org>
-Date:   Sat Feb 20 23:02:39 2016 +0000
-
-    upstream commit
-    
-    add missing ~/.ssh/id_ecdsa and ~/.ssh/id_ed25519 to
-     IdentityFile.
-    
-    ok djm@
-    
-    Upstream-ID: 6ce99466312e4ae7708017c3665e3edb976f70cf
-
-commit c12f0fdce8f985fca8d71829fd64c5b89dc777f5
-Author: sobrado@openbsd.org <sobrado@openbsd.org>
-Date:   Sat Feb 20 23:01:46 2016 +0000
-
-    upstream commit
-    
-    AddressFamily defaults to any.
-    
-    ok djm@
-    
-    Upstream-ID: 0d94aa06a4b889bf57a7f631c45ba36d24c13e0c
-
-commit 907091acb188b1057d50c2158f74c3ecf1c2302b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Feb 19 09:05:39 2016 +1100
-
-    Make Solaris privs code build on older systems.
-    
-    Not all systems with Solaris privs have priv_basicset so factor that
-    out and provide backward compatibility code.  Similarly, not all have
-    PRIV_NET_ACCESS so wrap that in #ifdef.  Based on code from
-    alex at cooperi.net and djm@ with help from carson at taltos.org and
-    wieland at purdue.edu.
-
-commit 292a8dee14e5e67dcd1b49ba5c7b9023e8420d59
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Feb 17 22:20:14 2016 +0000
-
-    upstream commit
-    
-    rekey refactor broke SSH1; spotted by Tom G. Christensen
-    
-    Upstream-ID: 43f0d57928cc077c949af0bfa71ef574dcb58243
-
-commit 3a13cb543df9919aec2fc6b75f3dd3802facaeca
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Feb 17 08:57:34 2016 +0000
-
-    upstream commit
-    
-    rsa-sha2-512,rsa-sha2-256 cannot be selected explicitly
-     in *KeyTypes options yet. Remove them from the lists of algorithms for now.
-     committing on behalf of markus@ ok djm@
-    
-    Upstream-ID: c6e8820eb8e610ac21551832c0c89684a9a51bb7
-
-commit a685ae8d1c24fb7c712c55a4f3280ee76f5f1e4b
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Wed Feb 17 07:38:19 2016 +0000
-
-    upstream commit
-    
-    since these pages now clearly tell folks to avoid v1,
-     normalise the docs from a v2 perspective (i.e. stop pointing out which bits
-     are v2 only);
-    
-    ok/tweaks djm ok markus
-    
-    Upstream-ID: eb474f8c36fb6a532dc05c282f7965e38dcfa129
-
-commit c5c3f3279a0e4044b8de71b70d3570d692d0f29d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Feb 17 05:29:04 2016 +0000
-
-    upstream commit
-    
-    make sandboxed privilege separation the default, not just
-     for new installs; "absolutely" deraadt@
-    
-    Upstream-ID: 5221ef3b927d2df044e9aa3f5db74ae91743f69b
-
-commit eb3f7337a651aa01d5dec019025e6cdc124ed081
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Tue Feb 16 07:47:54 2016 +0000
-
-    upstream commit
-    
-    no need to state that protocol 2 is the default twice;
-    
-    Upstream-ID: b1e4c36b0c2e12e338e5b66e2978f2ac953b95eb
-
-commit e7901efa9b24e5b0c7e74f2c5520d47eead4d005
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 16 05:11:04 2016 +0000
-
-    upstream commit
-    
-    Replace list of ciphers and MACs adjacent to -1/-2 flag
-     descriptions in ssh(1) with a strong recommendation not to use protocol 1.
-     Add a similar warning to the Protocol option descriptions in ssh_config(5)
-     and sshd_config(5);
-    
-    prompted by and ok mmcc@
-    
-    Upstream-ID: 961f99e5437d50e636feca023978950a232ead5e
-
-commit 5a0fcb77287342e2fc2ba1cee79b6af108973dc2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 16 03:37:48 2016 +0000
-
-    upstream commit
-    
-    add a "Close session" log entry (at loglevel=verbose) to
-     correspond to the existing "Starting session" one. Also include the session
-     id number to make multiplexed sessions more apparent.
-    
-    feedback and ok dtucker@
-    
-    Upstream-ID: e72d2ac080e02774376325136e532cb24c2e617c
-
-commit 624fd395b559820705171f460dd33d67743d13d6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Feb 17 02:24:17 2016 +0000
-
-    upstream commit
-    
-    include bad $SSH_CONNECTION in failure output
-    
-    Upstream-Regress-ID: b22d72edfde78c403aaec2b9c9753ef633cc0529
-
-commit 60d860e54b4f199e5e89963b1c086981309753cb
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Feb 17 13:37:09 2016 +1100
-
-    Rollback addition of va_start.
-    
-    va_start was added in 0f754e29dd3760fc0b172c1220f18b753fb0957e, however
-    it has the wrong number of args and it's not usable in non-variadic
-    functions anyway so it breaks things (for example Solaris 2.6 as
-    reported by Tom G. Christensen).i  ok djm@
-
-commit 2fee909c3cee2472a98b26eb82696297b81e0d38
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Feb 17 09:48:15 2016 +1100
-
-    Look for gethostbyname in libresolv and libnsl.
-    
-    Should fix build problem on Solaris 2.6 reported by Tom G. Christensen.
-
-commit 5ac712d81a84396aab441a272ec429af5b738302
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 16 10:45:02 2016 +1100
-
-    make existing ssh_malloc_init only for __OpenBSD__
-
-commit 24c9bded569d9f2449ded73f92fb6d12db7a9eec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Feb 15 23:32:37 2016 +0000
-
-    upstream commit
-    
-    memleak of algorithm name in mm_answer_sign; reported by
-     Jakub Jelen
-    
-    Upstream-ID: ccd742cd25952240ebd23d7d4d6b605862584d08
-
-commit ffb1e7e896139a42ceb78676f637658f44612411
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Feb 15 09:47:49 2016 +0000
-
-    upstream commit
-    
-    Add a function to enable security-related malloc_options.
-      With and ok deraadt@, something similar has been in the snaps for a while.
-    
-    Upstream-ID: 43a95523b832b7f3b943d2908662191110c380ed
-
-commit ef39e8c0497ff0564990a4f9e8b7338b3ba3507c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Feb 16 10:34:39 2016 +1100
-
-    sync ssh-copy-id with upstream 783ef08b0a75
-
-commit d2d772f55b19bb0e8d03c2fe1b9bb176d9779efd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 12 00:20:30 2016 +0000
-
-    upstream commit
-    
-    avoid fatal() for PKCS11 tokens that present empty key IDs
-     bz#1773, ok markus@
-    
-    Upstream-ID: 044a764fee526f2c4a9d530bd10695422d01fc54
-
-commit e4c918a6c721410792b287c9fd21356a1bed5805
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Feb 11 02:56:32 2016 +0000
-
-    upstream commit
-    
-    sync crypto algorithm lists in ssh_config(5) and
-     sshd_config(5) with current reality. bz#2527
-    
-    Upstream-ID: d7fd1b6c1ed848d866236bcb1d7049d2bb9b2ff6
-
-commit e30cabfa4ab456a30b3224f7f545f1bdfc4a2517
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Feb 11 02:21:34 2016 +0000
-
-    upstream commit
-    
-    fix regression in openssh-6.8 sftp client: existing
-     destination directories would incorrectly terminate recursive uploads;
-     bz#2528
-    
-    Upstream-ID: 3306be469f41f26758e3d447987ac6d662623e18
-
-commit 714e367226ded4dc3897078be48b961637350b05
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Feb 9 05:30:04 2016 +0000
-
-    upstream commit
-    
-    turn off more old crypto in the client: hmac-md5, ripemd,
-     truncated HMACs, RC4, blowfish. ok markus@ dtucker@
-    
-    Upstream-ID: 96aa11c2c082be45267a690c12f1d2aae6acd46e
-
-commit 5a622844ff7f78dcb75e223399f9ef0977e8d0a3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Feb 8 23:40:12 2016 +0000
-
-    upstream commit
-    
-    don't attempt to percent_expand() already-canonicalised
-     addresses, avoiding unnecessary failures when attempting to connect to scoped
-     IPv6 addresses (that naturally contain '%' characters)
-    
-    Upstream-ID: f24569cffa1a7cbde5f08dc739a72f4d78aa5c6a
-
-commit 19bcf2ea2d17413f2d9730dd2a19575ff86b9b6a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Feb 8 10:57:07 2016 +0000
-
-    upstream commit
-    
-    refactor activation of rekeying
-    
-    This makes automatic rekeying internal to the packet code (previously
-    the server and client loops needed to assist). In doing to it makes
-    application of rekey limits more accurate by accounting for packets
-    about to be sent as well as packets queued during rekeying events
-    themselves.
-    
-    Based on a patch from dtucker@ which was in turn based on a patch
-    Aleksander Adamowski in bz#2521; ok markus@
-    
-    Upstream-ID: a441227fd64f9739850ca97b4cf794202860fcd8
-
-commit 603ba41179e4b53951c7b90ee95b6ef3faa3f15d
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Fri Feb 5 13:28:19 2016 +0000
-
-    upstream commit
-    
-    Only check errno if read() has returned an error.  EOF is
-     not an error. This fixes a problem where the mux master would sporadically
-     fail to notice that the client had exited. ok mikeb@ djm@
-    
-    Upstream-ID: 3c2dadc21fac6ef64665688aac8a75fffd57ae53
-
-commit 56d7dac790693ce420d225119283bc355cff9185
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Fri Feb 5 04:31:21 2016 +0000
-
-    upstream commit
-    
-    avoid an uninitialised value when NumberOfPasswordPrompts
-     is 0 ok markus@ djm@
-    
-    Upstream-ID: 11b068d83c2865343aeb46acf1e9eec00f829b6b
-
-commit deae7d52d59c5019c528f977360d87fdda15d20b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 5 03:07:06 2016 +0000
-
-    upstream commit
-    
-    mention internal DH-GEX fallback groups; bz#2302
-    
-    Upstream-ID: e7b395fcca3122cd825515f45a2e41c9a157e09e
-
-commit cac3b6665f884d46192c0dc98a64112e8b11a766
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Feb 5 02:37:56 2016 +0000
-
-    upstream commit
-    
-    better description for MaxSessions; bz#2531
-    
-    Upstream-ID: e2c0d74ee185cd1a3e9d4ca1f1b939b745b354da
-
-commit 5ef4b0fdcc7a239577a754829b50022b91ab4712
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jan 27 17:45:56 2016 +1100
-
-    avoid FreeBSD RCS Id in comment
-    
-    Change old $FreeBSD version string in comment so it doesn't
-    become an RCS ident downstream; requested by des AT des.no
-
-commit 696d12683c90d20a0a9c5f4275fc916b7011fb04
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Feb 4 23:43:48 2016 +0000
-
-    upstream commit
-    
-    printf argument casts to avoid warnings on strict
-     compilers
-    
-    Upstream-ID: 7b9f6712cef01865ad29070262d366cf13587c9c
-
-commit 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Mon Feb 1 21:18:17 2016 +0000
-
-    upstream commit
-    
-    Avoid ugly "DISPLAY "(null)" invalid; disabling X11
-     forwarding" message when DISPLAY is not set.  This could also result in a
-     crash on systems with a printf that doesn't handle NULL.  OK djm@
-    
-    Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412
-
-commit 537f88ec7bcf40bd444ac5584c707c5588c55c43
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 29 05:18:15 2016 +0000
-
-    upstream commit
-    
-    Add regression test for RekeyLimit parsing of >32bit values
-     (4G and 8G).
-    
-    Upstream-Regress-ID: 548390350c62747b6234f522a99c319eee401328
-
-commit 4c6cb8330460f94e6c7ae28a364236d4188156a3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 29 23:04:46 2016 +0000
-
-    upstream commit
-    
-    Remove leftover roaming dead code.  ok djm markus.
-    
-    Upstream-ID: 13d1f9c8b65a5109756bcfd3b74df949d53615be
-
-commit 28136471809806d6246ef41e4341467a39fe2f91
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jan 29 05:46:01 2016 +0000
-
-    upstream commit
-    
-    include packet type of non-data packets in debug3 output;
-     ok markus dtucker
-    
-    Upstream-ID: 034eaf639acc96459b9c5ce782db9fcd8bd02d41
-
-commit 6fd6e28daccafaa35f02741036abe64534c361a1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 29 03:31:03 2016 +0000
-
-    upstream commit
-    
-    Revert "account for packets buffered but not yet
-     processed" change as it breaks for very small RekeyLimit values due to
-     continuous rekeying.  ok djm@
-    
-    Upstream-ID: 7e03f636cb45ab60db18850236ccf19079182a19
-
-commit 921ff00b0ac429666fb361d2d6cb1c8fff0006cb
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 29 02:54:45 2016 +0000
-
-    upstream commit
-    
-    Allow RekeyLimits in excess of 4G up to 2**63 bits
-     (limited by the return type of scan_scaled).  Part of bz#2521, ok djm.
-    
-    Upstream-ID: 13bea82be566b9704821b1ea05bf7804335c7979
-
-commit c0060a65296f01d4634f274eee184c0e93ba0f23
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Jan 29 02:42:46 2016 +0000
-
-    upstream commit
-    
-    Account for packets buffered but not yet processed when
-     computing whether or not it is time to perform rekeying.  bz#2521, based
-     loosely on a patch from olo at fb.com, ok djm@
-    
-    Upstream-ID: 67e268b547f990ed220f3cb70a5624d9bda12b8c
-
-commit 44cf930e670488c85c9efeb373fa5f4b455692ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jan 27 06:44:58 2016 +0000
-
-    upstream commit
-    
-    change old $FreeBSD version string in comment so it doesn't
-     become an RCS ident downstream; requested by des AT des.no
-    
-    Upstream-ID: 8ca558c01f184e596b45e4fc8885534b2c864722
-
-commit ebacd377769ac07d1bf3c75169644336056b7060
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jan 27 00:53:12 2016 +0000
-
-    upstream commit
-    
-    make the debug messages a bit more useful here
-    
-    Upstream-ID: 478ccd4e897e0af8486b294aa63aa3f90ab78d64
-
-commit 458abc2934e82034c5c281336d8dc0f910aecad3
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Sat Jan 23 05:31:35 2016 +0000
-
-    upstream commit
-    
-    Zero a stack buffer with explicit_bzero() instead of
-     memset() when returning from client_loop() for consistency with
-     buffer_free()/sshbuf_free().
-    
-    ok dtucker@ deraadt@ djm@
-    
-    Upstream-ID: bc9975b2095339811c3b954694d7d15ea5c58f66
-
-commit 65a3c0dacbc7dbb75ddb6a70ebe22d8de084d0b0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jan 20 09:22:39 2016 +0000
-
-    upstream commit
-    
-    Include sys/time.h for gettimeofday.  From sortie at
-     maxsi.org.
-    
-    Upstream-ID: 6ed0c33b836d9de0a664cd091e86523ecaa2fb3b
-
-commit fc77ccdc2ce6d5d06628b8da5048a6a5f6ffca5a
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Thu Jan 14 22:56:56 2016 +0000
-
-    upstream commit
-    
-    fd leaks; report Qualys Security Advisory team; ok
-     deraadt@
-    
-    Upstream-ID: 4ec0f12b9d8fa202293c9effa115464185aa071d
-
-commit a306863831c57ec5fad918687cc5d289ee8e2635
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Thu Jan 14 16:17:39 2016 +0000
-
-    upstream commit
-    
-    remove roaming support; ok djm@
-    
-    Upstream-ID: 2cab8f4b197bc95776fb1c8dc2859dad0c64dc56
-
-commit 6ef49e83e30688504552ac10875feabd5521565f
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Thu Jan 14 14:34:34 2016 +0000
-
-    upstream commit
-    
-    Disable experimental client-side roaming support.  Server
-     side was disabled/gutted for years already, but this aspect was surprisingly
-     forgotten. Thanks for report from Qualys
-    
-    Upstream-ID: 2328004b58f431a554d4c1bf67f5407eae3389df
-
-commit 8d7b523b96d3be180572d9d338cedaafc0570f60
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jan 14 11:08:19 2016 +1100
-
-    bump version numbers
-
-commit 8c3d512a1fac8b9c83b4d0c9c3f2376290bd84ca
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jan 14 11:04:04 2016 +1100
-
-    openssh-7.1p2
-
-commit e6c85f8889c5c9eb04796fdb76d2807636b9eef5
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jan 15 01:30:36 2016 +1100
-
-    forcibly disable roaming support in the client
-
-commit ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jan 13 23:04:47 2016 +0000
-
-    upstream commit
-    
-    eliminate fallback from untrusted X11 forwarding to trusted
-     forwarding when the X server disables the SECURITY extension; Reported by
-     Thomas Hoger; ok deraadt@
-    
-    Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938
-
-commit 9a728cc918fad67c8a9a71201088b1e150340ba4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jan 12 23:42:54 2016 +0000
-
-    upstream commit
-    
-    use explicit_bzero() more liberally in the buffer code; ok
-     deraadt
-    
-    Upstream-ID: 0ece37069fd66bc6e4f55eb1321f93df372b65bf
-
-commit 4626cbaf78767fc8e9c86dd04785386c59ae0839
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Jan 8 14:24:56 2016 +1100
-
-    Support Illumos/Solaris fine-grained privileges
-    
-    Includes a pre-auth privsep sandbox and several pledge()
-    emulations. bz#2511, patch by Alex Wilson.
-    
-    ok dtucker@
-
-commit 422d1b3ee977ff4c724b597fb2e437d38fc8de9d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Dec 31 00:33:52 2015 +0000
-
-    upstream commit
-    
-    fix three bugs in KRL code related to (unused) signature
-     support: verification length was being incorrectly calculated, multiple
-     signatures were being incorrectly processed and a NULL dereference that
-     occurred when signatures were verified. Reported by Carl Jackson
-    
-    Upstream-ID: e705e97ad3ccce84291eaa651708dd1b9692576b
-
-commit 6074c84bf95d00f29cc7d5d3cd3798737851aa1a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Dec 30 23:46:14 2015 +0000
-
-    upstream commit
-    
-    unused prototype
-    
-    Upstream-ID: f3eef4389d53ed6c0d5c77dcdcca3060c745da97
-
-commit 6213f0e180e54122bb1ba928e11c784e2b4e5380
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Sat Dec 26 20:51:35 2015 +0000
-
-    upstream commit
-    
-    Use pread/pwrite instead separate lseek+read/write for
-     lastlog. Cast to off_t before multiplication to avoid truncation on ILP32
-    
-    ok kettenis@ mmcc@
-    
-    Upstream-ID: fc40092568cd195719ddf1a00aa0742340d616cf
-
-commit d7d2bc95045a43dd56ea696cc1d030ac9d77e81f
-Author: semarie@openbsd.org <semarie@openbsd.org>
-Date:   Sat Dec 26 07:46:03 2015 +0000
-
-    upstream commit
-    
-    adjust pledge promises for ControlMaster: when using
-     "ask" or "autoask", the process will use ssh-askpass for asking confirmation.
-    
-    problem found by halex@
-    
-    ok halex@
-    
-    Upstream-ID: 38a58b30ae3eef85051c74d3c247216ec0735f80
-
-commit 271df8185d9689b3fb0523f58514481b858f6843
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Dec 13 22:42:23 2015 +0000
-
-    upstream commit
-    
-    unbreak connections with peers that set
-     first_kex_follows; fix from Matt Johnston va bz#2515
-    
-    Upstream-ID: decc88ec4fc7515594fdb42b04aa03189a44184b
-
-commit 43849a47c5f8687699eafbcb5604f6b9c395179f
-Author: doug@openbsd.org <doug@openbsd.org>
-Date:   Fri Dec 11 17:41:37 2015 +0000
-
-    upstream commit
-    
-    Add "id" to ssh-agent pledge for subprocess support.
-    
-    Found the hard way by Jan Johansson when using ssh-agent with X.  Also,
-    rearranged proc/exec and retval to match other pledge calls in the tree.
-    
-    ok djm@
-    
-    Upstream-ID: 914255f6850e5e7fa830a2de6c38605333b584db
-
-commit 52d7078421844b2f88329f5be3de370b0a938636
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Fri Dec 11 04:21:11 2015 +0000
-
-    upstream commit
-    
-    Remove NULL-checks before sshbuf_free().
-    
-    ok djm@
-    
-    Upstream-ID: 5ebed00ed5f9f03b119a345085e8774565466917
-
-commit a4b9e0f4e4a6980a0eb8072f76ea611cab5b77e7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 11 03:24:25 2015 +0000
-
-    upstream commit
-    
-    include remote port number in a few more messages; makes
-     tying log messages together into a session a bit easier; bz#2503 ok dtucker@
-    
-    Upstream-ID: 9300dc354015f7a7368d94a8ff4a4266a69d237e
-
-commit 6091c362e89079397e68744ae30df121b0a72c07
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 11 03:20:09 2015 +0000
-
-    upstream commit
-    
-    don't try to load SSHv1 private key when compiled without
-     SSHv1 support. From Iain Morgan bz#2505
-    
-    Upstream-ID: 8b8e7b02a448cf5e5635979df2d83028f58868a7
-
-commit cce6a36bb95e81fa8bfb46daf22eabcf13afc352
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 11 03:19:09 2015 +0000
-
-    upstream commit
-    
-    use SSH_MAX_PUBKEY_BYTES consistently as buffer size when
-     reading key files. Increase it to match the size of the buffers already being
-     used.
-    
-    Upstream-ID: 1b60586b484b55a947d99a0b32bd25e0ced56fae
-
-commit 89540b6de025b80404a0cb8418c06377f3f98848
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Fri Dec 11 02:31:47 2015 +0000
-
-    upstream commit
-    
-    Remove NULL-checks before sshkey_free().
-    
-    ok djm@
-    
-    Upstream-ID: 3e35afe8a25e021216696b5d6cde7f5d2e5e3f52
-
-commit 79394ed6d74572c2d2643d73937dad33727fc240
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Dec 11 02:29:03 2015 +0000
-
-    upstream commit
-    
-    fflush stdout so that output is seen even when running in
-     debug mode when output may otherwise not be flushed.  Patch from dustin at
-     null-ptr.net.
-    
-    Upstream-ID: b0c6b4cd2cdb01d7e9eefbffdc522e35b5bc4acc
-
-commit ee607cccb6636eb543282ba90e0677b0604d8b7a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 15 15:23:49 2015 +1100
-
-    Increase robustness of redhat/openssh.spec
-    
-     - remove configure --with-rsh, because this option isn't supported anymore
-     - replace last occurrence of BuildPreReq by BuildRequires
-     - update grep statement to query the krb5 include directory
-    
-    Patch from CarstenGrohmann via github, ok djm.
-
-commit b5fa0cd73555b991a543145603658d7088ec6b60
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 15 15:10:32 2015 +1100
-
-    Allow --without-ssl-engine with --without-openssl
-    
-    Patch from Mike Frysinger via github.
-
-commit c1d7e546f6029024f3257cc25c92f2bddf163125
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 15 14:27:09 2015 +1100
-
-    Include openssl crypto.h for SSLeay.
-    
-    Patch from doughdemon via github.
-
-commit c6f5f01651526e88c00d988ce59d71f481ebac62
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Dec 15 13:59:12 2015 +1100
-
-    Add sys/time.h for gettimeofday.
-    
-    Should allow it it compile with MUSL libc.  Based on patch from
-    doughdemon via github.
-
-commit 39736be06c7498ef57d6970f2d85cf066ae57c82
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 11 02:20:28 2015 +0000
-
-    upstream commit
-    
-    correct error messages; from Tomas Kuthan bz#2507
-    
-    Upstream-ID: 7454a0affeab772398052954c79300aa82077093
-
-commit 94141b7ade24afceeb6762a3f99e09e47a6c42b6
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Fri Dec 11 00:20:04 2015 +0000
-
-    upstream commit
-    
-    Pass (char *)NULL rather than (char *)0 to execl and
-     execlp.
-    
-    ok dtucker@
-    
-    Upstream-ID: 56c955106cbddba86c3dd9bbf786ac0d1b361492
-
-commit d59ce08811bf94111c2f442184cf7d1257ffae24
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Thu Dec 10 17:08:40 2015 +0000
-
-    upstream commit
-    
-    Remove NULL-checks before free().
-    
-    ok dtucker@
-    
-    Upstream-ID: e3d3cb1ce900179906af36517b5eea0fb15e6ef8
-
-commit 8e56dd46cb37879c73bce2d6032cf5e7f82d5a71
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Thu Dec 10 07:01:35 2015 +0000
-
-    upstream commit
-    
-    Fix a couple "the the" typos. ok dtucker@
-    
-    Upstream-ID: ec364c5af32031f013001fd28d1bd3dfacfe9a72
-
-commit 6262a0522ddc2c0f2e9358dcb68d59b46e9c533e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Mon Dec 7 20:04:09 2015 +0000
-
-    upstream commit
-    
-    stricter encoding type checks for ssh-rsa; ok djm@
-    
-    Upstream-ID: 8cca7c787599a5e8391e184d0b4f36fdc3665650
-
-commit d86a3ba7af160c13496102aed861ae48a4297072
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Dec 9 09:18:45 2015 +1100
-
-    Don't set IPV6_V6ONLY on OpenBSD
-    
-    It isn't necessary and runs afoul of pledge(2) restrictions.
-
-commit da98c11d03d819a15429d8fff9688acd7505439f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Dec 7 02:20:46 2015 +0000
-
-    upstream commit
-    
-    basic unit tests for rsa-sha2-* signature types
-    
-    Upstream-Regress-ID: 7dc4b9db809d578ff104d591b4d86560c3598d3c
-
-commit 3da893fdec9936dd2c23739cdb3c0c9d4c59fca0
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Sat Dec 5 20:53:21 2015 +0000
-
-    upstream commit
-    
-    prefer rsa-sha2-512 over -256 for hostkeys, too; noticed
-     by naddy@
-    
-    Upstream-ID: 685f55f7ec566a8caca587750672723a0faf3ffe
-
-commit 8b56e59714d87181505e4678f0d6d39955caf10e
-Author: tobias@openbsd.org <tobias@openbsd.org>
-Date:   Fri Dec 4 21:51:06 2015 +0000
-
-    upstream commit
-    
-    Properly handle invalid %-format by calling fatal.
-    
-    ok deraadt, djm
-    
-    Upstream-ID: 5692bce7d9f6eaa9c488cb93d3b55e758bef1eac
-
-commit 76c9fbbe35aabc1db977fb78e827644345e9442e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Fri Dec 4 16:41:28 2015 +0000
-
-    upstream commit
-    
-    implement SHA2-{256,512} for RSASSA-PKCS1-v1_5 signatures
-     (user and host auth) based on draft-rsa-dsa-sha2-256-03.txt and
-     draft-ssh-ext-info-04.txt; with & ok djm@
-    
-    Upstream-ID: cf82ce532b2733e5c4b34bb7b7c94835632db309
-
-commit 6064a8b8295cb5a17b5ebcfade53053377714f40
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Dec 4 00:24:55 2015 +0000
-
-    upstream commit
-    
-    clean up agent_fd handling; properly initialise it to -1
-     and make tests consistent
-    
-    ok markus@
-    
-    Upstream-ID: ac9554323d5065745caf17b5e37cb0f0d4825707
-
-commit b91926a97620f3e51761c271ba57aa5db790f48d
-Author: semarie@openbsd.org <semarie@openbsd.org>
-Date:   Thu Dec 3 17:00:18 2015 +0000
-
-    upstream commit
-    
-    pledges ssh client:   - mux client: which is used when
-     ControlMaster is in use.     will end with "stdio proc tty" (proc is to
-     permit sending SIGWINCH to mux master on window resize)
-    
-      - client loop: several levels of pledging depending of your used options
-    
-    ok deraadt@
-    
-    Upstream-ID: 21676155a700e51f2ce911e33538e92a2cd1d94b
-
-commit bcce47466bbc974636f588b5e4a9a18ae386f64a
-Author: doug@openbsd.org <doug@openbsd.org>
-Date:   Wed Dec 2 08:30:50 2015 +0000
-
-    upstream commit
-    
-    Add "cpath" to the ssh-agent pledge so the cleanup
-     handler can unlink().
-    
-    ok djm@
-    
-    Upstream-ID: 9e632991d48241d56db645602d381253a3d8c29d
-
-commit a90d001543f46716b6590c6dcc681d5f5322f8cf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Dec 2 08:00:58 2015 +0000
-
-    upstream commit
-    
-    ssh-agent pledge needs proc for askpass; spotted by todd@
-    
-    Upstream-ID: 349aa261b29cc0e7de47ef56167769c432630b2a
-
-commit d952162b3c158a8f23220587bb6c8fcda75da551
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Dec 1 23:29:24 2015 +0000
-
-    upstream commit
-    
-    basic pledge() for ssh-agent, more refinement needed
-    
-    Upstream-ID: 5b5b03c88162fce549e45e1b6dd833f20bbb5e13
-
-commit f0191d7c8e76e30551084b79341886d9bb38e453
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Nov 30 10:53:25 2015 +1100
-
-    Revert "stub for pledge(2) for systems that lack it"
-    
-    This reverts commit 14c887c8393adde2d9fd437d498be30f8c98535c.
-    
-    dtucker beat me to it :/
-
-commit 6283cc72eb0e49a3470d30e07ca99a1ba9e89676
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Nov 30 10:37:03 2015 +1100
-
-    revert 7d4c7513: bring back S/Key prototypes
-    
-    (but leave RCSID changes)
-
-commit 14c887c8393adde2d9fd437d498be30f8c98535c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Nov 30 09:45:29 2015 +1100
-
-    stub for pledge(2) for systems that lack it
-
-commit 452c0b6af5d14c37553e30059bf74456012493f3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Nov 29 22:18:37 2015 +0000
-
-    upstream commit
-    
-    pledge, better fatal() messages; feedback deraadt@
-    
-    Upstream-ID: 3e00f6ccfe2b9a7a2d1dbba5409586180801488f
-
-commit 6da413c085dba37127687b2617a415602505729b
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Sat Nov 28 06:50:52 2015 +0000
-
-    upstream commit
-    
-    do not leak temp file if there is no known_hosts file
-     from craig leres, ok djm
-    
-    Upstream-ID: c820497fd5574844c782e79405c55860f170e426
-
-commit 3ddd15e1b63a4d4f06c8ab16fbdd8a5a61764f16
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Nov 30 07:23:53 2015 +1100
-
-    Add a null implementation of pledge.
-    
-    Fixes builds on almost everything.
-
-commit b1d6b3971ef256a08692efc409fc9ada719111cc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Nov 28 06:41:03 2015 +0000
-
-    upstream commit
-    
-    don't include port number in tcpip-forward replies for
-     requests that don't allocate a port; bz#2509 diagnosed by Ron Frederick ok
-     markus
-    
-    Upstream-ID: 77efad818addb61ec638b5a2362f1554e21a970a
-
-commit 9080bd0b9cf10d0f13b1f642f20cb84285cb8d65
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Nov 27 00:49:31 2015 +0000
-
-    upstream commit
-    
-    pledge "stdio rpath wpath cpath fattr tty proc exec"
-     except for the -p option (which sadly has insane semantics...) ok semarie
-     dtucker
-    
-    Upstream-ID: 8854bbd58279abe00f6c33f8094bdc02c8c65059
-
-commit 4d90625b229cf6b3551d81550a9861897509a65f
-Author: halex@openbsd.org <halex@openbsd.org>
-Date:   Fri Nov 20 23:04:01 2015 +0000
-
-    upstream commit
-    
-    allow comment change for all supported formats
-    
-    ok djm@
-    
-    Upstream-ID: 5fc477cf2f119b2d44aa9c683af16cb00bb3744b
-
-commit 8ca915fc761519dd1f7766a550ec597a81db5646
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 20 01:45:29 2015 +0000
-
-    upstream commit
-    
-    add cast to make -Werror clean
-    
-    Upstream-ID: 288db4f8f810bd475be01320c198250a04ff064d
-
-commit ac9473580dcd401f8281305af98635cdaae9bf96
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Nov 20 12:35:41 2015 +1100
-
-    fix multiple authentication using S/Key w/ privsep
-    
-    bz#2502, patch from Kevin Korb and feandil_
-
-commit 88b6fcdeb87a2fb76767854d9eb15006662dca57
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Nov 19 08:23:27 2015 +0000
-
-    upstream commit
-    
-    ban ConnectionAttempts=0, it makes no sense and would cause
-     ssh_connect_direct() to print an uninitialised stack variable; bz#2500
-     reported by dvw AT phas.ubc.ca
-    
-    Upstream-ID: 32b5134c608270583a90b93a07b3feb3cbd5f7d5
-
-commit 964ab3ee7a8f96bdbc963d5b5a91933d6045ebe7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Nov 19 01:12:32 2015 +0000
-
-    upstream commit
-    
-    trailing whitespace
-    
-    Upstream-ID: 31fe0ad7c4d08e87f1d69c79372f5e3c5cd79051
-
-commit f96516d052dbe38561f6b92b0e4365d8e24bb686
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Nov 19 01:09:38 2015 +0000
-
-    upstream commit
-    
-    print host certificate contents at debug level
-    
-    Upstream-ID: 39354cdd8a2b32b308fd03f98645f877f540f00d
-
-commit 499cf36fecd6040e30e2912dd25655bc574739a7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Nov 19 01:08:55 2015 +0000
-
-    upstream commit
-    
-    move the certificate validity formatting code to
-     sshkey.[ch]
-    
-    Upstream-ID: f05f7c78fab20d02ff1d5ceeda533ef52e8fe523
-
-commit bcb7bc77bbb1535d1008c7714085556f3065d99d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 18 08:37:28 2015 +0000
-
-    upstream commit
-    
-    fix "ssh-keygen -l" of private key, broken in support for
-     multiple plain keys on stdin
-    
-    Upstream-ID: 6b3132d2c62d03d0bad6f2bcd7e2d8b7dab5cd9d
-
-commit 259adb6179e23195c8f6913635ea71040d1ccd63
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Mon Nov 16 23:47:52 2015 +0000
-
-    upstream commit
-    
-    Replace remaining calls to index(3) with strchr(3).  OK
-     jca@ krw@
-    
-    Upstream-ID: 33837d767a0cf1db1489b96055f9e330bc0bab6d
-
-commit c56a255162c2166884539c0a1f7511575325b477
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Nov 16 22:53:07 2015 +0000
-
-    upstream commit
-    
-    Allow fingerprinting from standard input "ssh-keygen -lf
-     -"
-    
-    Support fingerprinting multiple plain keys in a file and authorized_keys
-    files too (bz#1319)
-    
-    ok markus@
-    
-    Upstream-ID: 903f8b4502929d6ccf53509e4e07eae084574b77
-
-commit 5b4010d9b923cf1b46c9c7b1887c013c2967e204
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Nov 16 22:51:05 2015 +0000
-
-    upstream commit
-    
-    always call privsep_preauth_child() regardless of whether
-     sshd was started by root; it does important priming before sandboxing and
-     failing to call it could result in sandbox violations later; ok markus@
-    
-    Upstream-ID: c8a6d0d56c42f3faab38460dc917ca0d1705d383
-
-commit 3a9f84b58b0534bbb485f1eeab75665e2d03371f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Nov 16 22:50:01 2015 +0000
-
-    upstream commit
-    
-    improve sshkey_read() semantics; only update *cpp when a
-     key is successfully read; ok markus@
-    
-    Upstream-ID: f371e78e8f4fab366cf69a42bdecedaed5d1b089
-
-commit db6f8dc5dd5655b59368efd074994d4568bc3556
-Author: logan@openbsd.org <logan@openbsd.org>
-Date:   Mon Nov 16 06:13:04 2015 +0000
-
-    upstream commit
-    
-    1) Use xcalloc() instead of xmalloc() to check for
-     potential overflow.    (Feedback from both mmcc@ and djm@) 2) move set_size
-     just before the for loop. (suggested by djm@)
-    
-    OK djm@
-    
-    Upstream-ID: 013534c308187284756c3141f11d2c0f33c47213
-
-commit 383f10fb84a0fee3c01f9d97594f3e22aa3cd5e0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Nov 16 00:30:02 2015 +0000
-
-    upstream commit
-    
-    Add a new authorized_keys option "restrict" that
-     includes all current and future key restrictions (no-*-forwarding, etc). Also
-     add permissive versions of the existing restrictions, e.g. "no-pty" -> "pty".
-     This simplifies the task of setting up restricted keys and ensures they are
-     maximally-restricted, regardless of any permissions we might implement in the
-     future.
-    
-    Example:
-    
-    restrict,pty,command="nethack" ssh-ed25519 AAAAC3NzaC1lZDI1...
-    
-    Idea from Jann Horn; ok markus@
-    
-    Upstream-ID: 04ceb9d448e46e67e13887a7ae5ea45b4f1719d0
-
-commit e41a071f7bda6af1fb3f081bed0151235fa61f15
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sun Nov 15 23:58:04 2015 +0000
-
-    upstream commit
-    
-    correct section number for ssh-agent;
-    
-    Upstream-ID: 44be72fd8bcc167635c49b357b1beea8d5674bd6
-
-commit 1a11670286acddcc19f5eff0966c380831fc4638
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sun Nov 15 23:54:15 2015 +0000
-
-    upstream commit
-    
-    do not confuse mandoc by presenting "Dd";
-    
-    Upstream-ID: 1470fce171c47b60bbc7ecd0fc717a442c2cfe65
-
-commit f361df474c49a097bfcf16d1b7b5c36fcd844b4b
-Author: jcs@openbsd.org <jcs@openbsd.org>
-Date:   Sun Nov 15 22:26:49 2015 +0000
-
-    upstream commit
-    
-    Add an AddKeysToAgent client option which can be set to
-     'yes', 'no', 'ask', or 'confirm', and defaults to 'no'.  When enabled, a
-     private key that is used during authentication will be added to ssh-agent if
-     it is running (with confirmation enabled if set to 'confirm').
-    
-    Initial version from Joachim Schipper many years ago.
-    
-    ok markus@
-    
-    Upstream-ID: a680db2248e8064ec55f8be72d539458c987d5f4
-
-commit d87063d9baf5479b6e813d47dfb694a97df6f6f5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 13 04:39:35 2015 +0000
-
-    upstream commit
-    
-    send SSH2_MSG_UNIMPLEMENTED replies to unexpected
-     messages during KEX; bz#2949, ok dtucker@
-    
-    Upstream-ID: 2b3abdff344d53c8d505f45c83a7b12e84935786
-
-commit 9fd04681a1e9b0af21e08ff82eb674cf0a499bfc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 13 04:38:06 2015 +0000
-
-    upstream commit
-    
-    Support "none" as an argument for sshd_config
-     ForceCommand and ChrootDirectory. Useful inside Match blocks to override a
-     global default. bz#2486 ok dtucker@
-    
-    Upstream-ID: 7ef478d6592bc7db5c7376fc33b4443e63dccfa5
-
-commit 94bc0b72c29e511cbbc5772190d43282e5acfdfe
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 13 04:34:15 2015 +0000
-
-    upstream commit
-    
-    support multiple certificates (one per line) and
-     reading from standard input (using "-f -") for "ssh-keygen -L"; ok dtucker@
-    
-    Upstream-ID: ecbadeeef3926e5be6281689b7250a32a80e88db
-
-commit b6b9108f5b561c83612cb97ece4134eb59fde071
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Nov 13 02:57:46 2015 +0000
-
-    upstream commit
-    
-    list a couple more options usable in Match blocks;
-     bz#2489
-    
-    Upstream-ID: e4d03f39d254db4c0cc54101921bb89fbda19879
-
-commit a7994b3f5a5a5a33b52b0a6065d08e888f0a99fb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 11 04:56:39 2015 +0000
-
-    upstream commit
-    
-    improve PEEK/POKE macros: better casts, don't multiply
-     evaluate arguments; ok deraadt@
-    
-    Upstream-ID: 9a1889e19647615ededbbabab89064843ba92d3e
-
-commit 7d4c7513a7f209cb303a608ac6e46b3f1dfc11ec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Nov 11 01:48:01 2015 +0000
-
-    upstream commit
-    
-    remove prototypes for long-gone s/key support; ok
-     dtucker@
-    
-    Upstream-ID: db5bed3c57118af986490ab23d399df807359a79
-
-commit 07889c75926c040b8e095949c724e66af26441cb
-Author: Damien Miller <djm@mindrot.org>
-Date:   Sat Nov 14 18:44:49 2015 +1100
-
-    read back from libcrypto RAND when privdropping
-    
-    makes certain libcrypto implementations cache a /dev/urandom fd
-    in preparation of sandboxing. Based on patch by Greg Hartman.
-
-commit 1560596f44c01bb0cef977816410950ed17b8ecd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Nov 10 11:14:47 2015 +1100
-
-    Fix compiler warnings in the openssl header check.
-    
-    Noted by Austin English.
-
-commit e72a8575ffe1d8adff42c9abe9ca36938acc036b
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sun Nov 8 23:24:03 2015 +0000
-
-    upstream commit
-    
-    -c before -H, in SYNOPSIS and usage();
-    
-    Upstream-ID: 25e8c58a69e1f37fcd54ac2cd1699370acb5e404
-
-commit 3a424cdd21db08c7b0ded902f97b8f02af5aa485
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Nov 8 22:30:20 2015 +0000
-
-    upstream commit
-    
-    Add "ssh-keyscan -c ..." flag to allow fetching
-     certificates instead of plain keys; ok markus@
-    
-    Upstream-ID: 0947e2177dba92339eced9e49d3c5bf7dda69f82
-
-commit 69fead5d7cdaa73bdece9fcba80f8e8e70b90346
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Sun Nov 8 22:08:38 2015 +0000
-
-    upstream commit
-    
-    remove slogin links; ok deraadt markus djm
-    
-    Upstream-ID: 39ba08548acde4c54f2d4520c202c2a863a3c730
-
-commit 2fecfd486bdba9f51b3a789277bb0733ca36e1c0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Nov 8 21:59:11 2015 +0000
-
-    upstream commit
-    
-    fix OOB read in packet code caused by missing return
-     statement found by Ben Hawkes; ok markus@ deraadt@
-    
-    Upstream-ID: a3e3a85434ebfa0690d4879091959591f30efc62
-
-commit 5e288923a303ca672b686908320bc5368ebec6e6
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Fri Nov 6 00:31:41 2015 +0000
-
-    upstream commit
-    
-    1. rlogin and rsh are long gone 2. protocol version isn't
-     of core relevance here, and v1 is going away
-    
-    ok markus@, deraadt@
-    
-    Upstream-ID: 8b46bc94cf1ca7c8c1a75b1c958b2bb38d7579c8
-
-commit 8b29008bbe97f33381d9b4b93fcfa304168d0286
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Thu Nov 5 09:48:05 2015 +0000
-
-    upstream commit
-    
-    "commandline" -> "command line", since there are so few
-     examples of the former in the pages, so many of the latter, and in some of
-     these pages we had multiple spellings;
-    
-    prompted by tj
-    
-    Upstream-ID: 78459d59bff74223f8139d9001ccd56fc4310659
-
-commit 996b24cebf20077fbe5db07b3a2c20c2d9db736e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 29 20:57:34 2015 +1100
-
-    (re)wrap SYS_sendsyslog in ifdef.
-    
-    Replace ifdef that went missing in commit
-    c61b42f2678f21f05653ac2d3d241b48ab5d59ac.  Fixes build on older
-    OpenBSDs.
-
-commit b67e2e76fcf1ae7c802eb27ca927e16c91a513ff
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Oct 29 08:05:17 2015 +0000
-
-    upstream commit
-    
-    regress test for "PubkeyAcceptedKeyTypes +..." inside a
-     Match block
-    
-    Upstream-Regress-ID: 246c37ed64a2e5704d4c158ccdca1ff700e10647
-
-commit abd9dbc3c0d8c8c7561347cfa22166156e78c077
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Oct 26 02:50:58 2015 +0000
-
-    upstream commit
-    
-    Fix typo certopt->certopts in shell variable.  This would
-     cause the test to hang at a host key prompt if you have an A or CNAME for
-     "proxy" in your local domain.
-    
-    Upstream-Regress-ID: 6ea03bcd39443a83c89e2c5606392ceb9585836a
-
-commit ed08510d38aef930a061ae30d10f2a9cf233bafa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Oct 29 08:05:01 2015 +0000
-
-    upstream commit
-    
-    Fix "PubkeyAcceptedKeyTypes +..." inside a Match block;
-     ok dtucker@
-    
-    Upstream-ID: 853662c4036730b966aab77684390c47b9738c69
-
-commit a4aef3ed29071719b2af82fdf1ac3c2514f82bc5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 27 08:54:52 2015 +0000
-
-    upstream commit
-    
-    fix execv arguments in a way less likely to cause grief
-     for -portable; ok dtucker@
-    
-    Upstream-ID: 5902bf0ea0371f39f1300698dc3b8e4105fc0fc5
-
-commit 63d188175accea83305e89fafa011136ff3d96ad
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 27 01:44:45 2015 +0000
-
-    upstream commit
-    
-    log certificate serial in verbose() messages to match the
-     main auth success/fail message; ok dtucker@
-    
-    Upstream-ID: dfc48b417c320b97c36ff351d303c142f2186288
-
-commit 2aaba0cfd560ecfe92aa50c00750e6143842cf1f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 27 00:49:53 2015 +0000
-
-    upstream commit
-    
-    avoid de-const warning & shrink; ok dtucker@
-    
-    Upstream-ID: 69a85ef94832378952a22c172009cbf52aaa11db
-
-commit 03239c18312b9bab7d1c3b03062c61e8bbc1ca6e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Sun Oct 25 23:42:00 2015 +0000
-
-    upstream commit
-    
-    Expand tildes in filenames passed to -i before checking
-     whether or not the identity file exists.  This means that if the shell
-     doesn't do the expansion (eg because the option and filename were given as a
-     single argument) then we'll still add the key.  bz#2481, ok markus@
-    
-    Upstream-ID: db1757178a14ac519e9a3e1a2dbd21113cb3bfc6
-
-commit 97e184e508dd33c37860c732c0eca3fc57698b40
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Sun Oct 25 23:14:03 2015 +0000
-
-    upstream commit
-    
-    Do not prepend "exec" to the shell command run by "Match
-     exec" in a config file.  It's an unnecessary optimization from repurposed
-     ProxyCommand code and prevents some things working with some shells.
-     bz#2471, pointed out by res at qoxp.net.  ok markus@
-    
-    Upstream-ID: a1ead25ae336bfa15fb58d8c6b5589f85b4c33a3
-
-commit 8db134e7f457bcb069ec72bc4ee722e2af557c69
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Oct 29 10:48:23 2015 +1100
-
-    Prevent name collisions with system glob (bz#2463)
-    
-    Move glob.h from includes.h to the only caller (sftp) and override the
-    names for the symbols.  This prevents name collisions with the system glob
-    in the case where something other than ssh uses it (eg kerberos).  With
-    jjelen at redhat.com, ok djm@
-
-commit 86c10dbbef6a5800d2431a66cf7f41a954bb62b5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Oct 23 02:22:01 2015 +0000
-
-    upstream commit
-    
-    Update expected group sizes to match recent code changes.
-    
-    Upstream-Regress-ID: 0004f0ea93428969fe75bcfff0d521c553977794
-
-commit 9ada37d36003a77902e90a3214981e417457cf13
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Oct 24 22:56:19 2015 +0000
-
-    upstream commit
-    
-    fix keyscan output for multiple hosts/addrs on one line
-     when host hashing or a non standard port is in use; bz#2479 ok dtucker@
-    
-    Upstream-ID: 5321dabfaeceba343da3c8a8b5754c6f4a0a307b
-
-commit 44fc7cd7dcef6c52c6b7e9ff830dfa32879bd319
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Oct 24 22:52:22 2015 +0000
-
-    upstream commit
-    
-    skip "Could not chdir to home directory" message when
-     chrooted
-    
-    patch from Christian Hesse in bz#2485 ok dtucker@
-    
-    Upstream-ID: 86783c1953da426dff5b03b03ce46e699d9e5431
-
-commit a820a8618ec44735dabc688fab96fba38ad66bb2
-Author: sthen@openbsd.org <sthen@openbsd.org>
-Date:   Sat Oct 24 08:34:09 2015 +0000
-
-    upstream commit
-    
-    Handle the split of tun(4) "link0" into tap(4) in ssh
-     tun-forwarding. Adapted from portable (using separate devices for this is the
-     normal case in most OS). ok djm@
-    
-    Upstream-ID: 90facf4c59ce73d6741db1bc926e578ef465cd39
-
-commit 66d2e229baa9fe57b868c373b05f7ff3bb20055b
-Author: gsoares@openbsd.org <gsoares@openbsd.org>
-Date:   Wed Oct 21 11:33:03 2015 +0000
-
-    upstream commit
-    
-    fix memory leak in error path ok djm@
-    
-    Upstream-ID: dd2f402b0a0029b755df029fc7f0679e1365ce35
-
-commit 7d6c0362039ceacdc1366b5df29ad5d2693c13e5
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Tue Oct 20 23:24:25 2015 +0000
-
-    upstream commit
-    
-    Compare pointers to NULL rather than 0.
-    
-    ok djm@
-    
-    Upstream-ID: 21616cfea27eda65a06e772cc887530b9a1a27f8
-
-commit f98a09cacff7baad8748c9aa217afd155a4d493f
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Tue Oct 20 03:36:35 2015 +0000
-
-    upstream commit
-    
-    Replace a function-local allocation with stack memory.
-    
-    ok djm@
-    
-    Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e
-
-commit ac908c1eeacccfa85659594d92428659320fd57e
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Oct 22 09:35:24 2015 +1100
-
-    turn off PrintLastLog when --disable-lastlog
-    
-    bz#2278 from Brent Paulson
-
-commit b56deb847f4a0115a8bf488bf6ee8524658162fd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Oct 16 22:32:22 2015 +0000
-
-    upstream commit
-    
-    increase the minimum modulus that we will send or accept in
-     diffie-hellman-group-exchange to 2048 bits; ok markus@
-    
-    Upstream-ID: 06dce7a24c17b999a0f5fadfe95de1ed6a1a9b6a
-
-commit 5ee0063f024bf5b3f3ffb275b8cd20055d62b4b9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Oct 16 18:40:49 2015 +0000
-
-    upstream commit
-    
-    better handle anchored FQDNs (e.g. 'cvs.openbsd.org.') in
-     hostname canonicalisation - treat them as already canonical and remove the
-     trailing '.' before matching ssh_config; ok markus@
-    
-    Upstream-ID: f7619652e074ac3febe8363f19622aa4853b679a
-
-commit e92c499a75477ecfe94dd7b4aed89f20b1fac5a7
-Author: mmcc@openbsd.org <mmcc@openbsd.org>
-Date:   Fri Oct 16 17:07:24 2015 +0000
-
-    upstream commit
-    
-    0 -> NULL when comparing with a char*.
-    
-    ok dtucker@, djm@.
-    
-    Upstream-ID: a928e9c21c0a9020727d99738ff64027c1272300
-
-commit b1d38a3cc6fe349feb8d16a5f520ef12d1de7cb2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Oct 15 23:51:40 2015 +0000
-
-    upstream commit
-    
-    fix some signed/unsigned integer type mismatches in
-     format strings; reported by Nicholas Lemonias
-    
-    Upstream-ID: 78cd55420a0eef68c4095bdfddd1af84afe5f95c
-
-commit 1a2663a15d356bb188196b6414b4c50dc12fd42b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Oct 15 23:08:23 2015 +0000
-
-    upstream commit
-    
-    argument to sshkey_from_private() and sshkey_demote()
-     can't be NULL
-    
-    Upstream-ID: 0111245b1641d387977a9b38da15916820a5fd1f
-
-commit 0f754e29dd3760fc0b172c1220f18b753fb0957e
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Oct 16 10:53:14 2015 +1100
-
-    need va_copy before va_start
-    
-    reported by Nicholas Lemonias
-
-commit eb6c50d82aa1f0d3fc95f5630ea69761e918bfcd
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Oct 15 15:48:28 2015 -0700
-
-    fix compilation on systems without SYMLOOP_MAX
-
-commit fafe1d84a210fb3dae7744f268059cc583db8c12
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 09:22:15 2015 -0700
-
-    s/SANDBOX_TAME/SANDBOX_PLEDGE/g
-
-commit 8f22911027ff6c17d7226d232ccd20727f389310
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:28:19 2015 +1100
-
-    upstream commit
-    
-    revision 1.20
-    date: 2015/10/13 20:55:37;  author: millert;  state: Exp;  lines: +2 -2;  commitid: X39sl5ay1czgFIgp;
-    In rev 1.15 the sizeof argument was fixed in a strlcat() call but
-    the truncation check immediately following it was not updated to
-    match.  Not an issue in practice since the buffers are the same
-    size.  OK deraadt@
-
-commit 23fa695bb735f54f04d46123662609edb6c76767
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:27:51 2015 +1100
-
-    upstream commit
-    
-    revision 1.19
-    date: 2015/01/16 16:48:51;  author: deraadt;  state: Exp;  lines: +3 -3;  commitid: 0DYulI8hhujBHMcR;
-    Move to the <limits.h> universe.
-    review by millert, binary checking process with doug, concept with guenther
-
-commit c71be375a69af00c2d0a0c24d8752bec12d8fd1b
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:27:08 2015 +1100
-
-    upstream commit
-    
-    revision 1.18
-    date: 2014/10/19 03:56:28;  author: doug;  state: Exp;  lines: +9 -9;  commitid: U6QxmtbXrGoc02S5;
-    Revert last commit due to changed semantics found by make release.
-
-commit c39ad23b06e9aecc3ff788e92f787a08472905b1
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:26:24 2015 +1100
-
-    upstream commit
-    
-    revision 1.17
-    date: 2014/10/18 20:43:52;  author: doug;  state: Exp;  lines: +10 -10;  commitid: I74hI1tVZtsspKEt;
-    Better POSIX compliance in realpath(3).
-    
-    millert@ made changes to realpath.c based on FreeBSD's version.  I merged
-    Todd's changes into dl_realpath.c.
-    
-    ok millert@, guenther@
-
-commit e929a43f957dbd1254aca2aaf85c8c00cbfc25f4
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:25:55 2015 +1100
-
-    upstream commit
-    
-    revision 1.16
-    date: 2013/04/05 12:59:54;  author: kurt;  state: Exp;  lines: +3 -1;
-    - Add comments regarding copies of these files also in libexec/ld.so
-    okay guenther@
-
-commit 5225db68e58a1048cb17f0e36e0d33bc4a8fc410
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:25:32 2015 +1100
-
-    upstream commit
-    
-    revision 1.15
-    date: 2012/09/13 15:39:05;  author: deraadt;  state: Exp;  lines: +2 -2;
-    specify the bounds of the dst to strlcat (both values were static and
-    equal, but it is more correct)
-    from Michal Mazurek
-
-commit 7365fe5b4859de2305e40ea132da3823830fa710
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Oct 14 08:25:09 2015 +1100
-
-    upstream commit
-    
-    revision 1.14
-    date: 2011/07/24 21:03:00;  author: miod;  state: Exp;  lines: +35 -13;
-    Recent Single Unix will malloc memory if the second argument of realpath()
-    is NULL, and third-party software is starting to rely upon this.
-    Adapted from FreeBSD via Jona Joachim (jaj ; hcl-club , .lu), with minor
-    tweaks from nicm@ and yours truly.
-
-commit e679c09cd1951f963793aa3d9748d1c3fdcf808f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 13 16:15:21 2015 +0000
-
-    upstream commit
-    
-    apply PubkeyAcceptedKeyTypes filtering earlier, so all
-     skipped keys are noted before pubkey authentication starts. ok dtucker@
-    
-    Upstream-ID: ba4f52f54268a421a2a5f98bb375403f4cb044b8
-
-commit 179c353f564ec7ada64b87730b25fb41107babd7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 13 00:21:27 2015 +0000
-
-    upstream commit
-    
-    free the correct IV length, don't assume it's always the
-     cipher blocksize; ok dtucker@
-    
-    Upstream-ID: c260d9e5ec73628d9ff4b067fbb060eff5a7d298
-
-commit 2539dce2a049a8f6bb0d44cac51f07ad48e691d3
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Oct 9 01:37:08 2015 +0000
-
-    upstream commit
-    
-    Change all tame callers to namechange to pledge(2).
-    
-    Upstream-ID: 17e654fc27ceaf523c60f4ffd9ec7ae4e7efc7f2
-
-commit 9846a2f4067383bb76b4e31a9d2303e0a9c13a73
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Oct 8 04:30:48 2015 +1100
-
-    hook tame(2) sandbox up to build
-    
-    OpenBSD only for now
-
-commit 0c46bbe68b70bdf0d6d20588e5847e71f3739fe6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Oct 7 15:59:12 2015 +0000
-
-    upstream commit
-    
-    include PubkeyAcceptedKeyTypes in ssh -G config dump
-    
-    Upstream-ID: 6c097ce6ffebf6fe393fb7988b5d152a5d6b36bb
-
-commit bdcb73fb7641b1cf73c0065d1a0dd57b1e8b778e
-Author: sobrado@openbsd.org <sobrado@openbsd.org>
-Date:   Wed Oct 7 14:45:30 2015 +0000
-
-    upstream commit
-    
-    UsePrivilegeSeparation defaults to sandbox now.
-    
-    ok djm@
-    
-    Upstream-ID: bff136c38bcae89df82e044d2f42de21e1ad914f
-
-commit 2905d6f99c837bb699b6ebc61711b19acd030709
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Oct 7 00:54:06 2015 +0000
-
-    upstream commit
-    
-    don't try to change tun device flags if they are already
-     what we need; makes it possible to use tun/tap networking as non- root user
-     if device permissions and interface flags are pre-established; based on patch
-     by Ossi Herrala
-    
-    Upstream-ID: 89099ac4634cd477b066865acf54cb230780fd21
-
-commit 0dc74512bdb105b048883f07de538b37e5e024d4
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Oct 5 18:33:05 2015 -0700
-
-    unbreak merge botch
-
-commit fdd020e86439afa7f537e2429d29d4b744c94331
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Oct 6 01:20:59 2015 +0000
-
-    upstream commit
-    
-    adapt to recent sshkey_parse_private_fileblob() API
-     change
-    
-    Upstream-Regress-ID: 5c0d818da511e33e0abf6a92a31bd7163b7ad988
-
-commit 21ae8ee3b630b0925f973db647a1b9aa5fcdd4c5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 24 07:15:39 2015 +0000
-
-    upstream commit
-    
-    fix command-line option to match what was actually
-     committed
-    
-    Upstream-Regress-ID: 3e8c24a2044e8afd37e7ce17b69002ca817ac699
-
-commit e14ac43b75e68f1ffbd3e1a5e44143c8ae578dcd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 24 06:16:53 2015 +0000
-
-    upstream commit
-    
-    regress test for CertificateFile; patch from Meghana Bhat
-     via bz#2436
-    
-    Upstream-Regress-ID: e7a6e980cbe0f8081ba2e83de40d06c17be8bd25
-
-commit 905b054ed24e0d5b4ef226ebf2c8bfc02ae6d4ad
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Oct 5 17:11:21 2015 +0000
-
-    upstream commit
-    
-    some more bzero->explicit_bzero, from Michael McConville
-    
-    Upstream-ID: 17f19545685c33327db2efdc357c1c9225ff00d0
-
-commit b007159a0acdbcf65814b3ee05dbe2cf4ea46011
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Oct 2 15:52:55 2015 +0000
-
-    upstream commit
-    
-    fix email
-    
-    Upstream-ID: 72150f2d54b94de14ebef1ea054ef974281bf834
-
-commit b19e1b4ab11884c4f62aee9f8ab53127a4732658
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Oct 2 01:39:52 2015 +0000
-
-    upstream commit
-    
-    a sandbox using tame ok djm
-    
-    Upstream-ID: 4ca24e47895e72f5daaa02f3e3d3e5ca2d820fa3
-
-commit c61b42f2678f21f05653ac2d3d241b48ab5d59ac
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Oct 2 01:39:26 2015 +0000
-
-    upstream commit
-    
-    re-order system calls in order of risk, ok i'll be
-     honest, ordered this way they look like tame... ok djm
-    
-    Upstream-ID: 42a1e6d251fd8be13c8262bee026059ae6328813
-
-commit c5f7c0843cb6e6074a93c8ac34e49ce33a6f5546
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Sep 25 18:19:54 2015 +0000
-
-    upstream commit
-    
-    some certificatefile tweaks; ok djm
-    
-    Upstream-ID: 0e5a7852c28c05fc193419cc7e50e64c1c535af0
-
-commit 4e44a79a07d4b88b6a4e5e8c1bed5f58c841b1b8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Sep 24 06:15:11 2015 +0000
-
-    upstream commit
-    
-    add ssh_config CertificateFile option to explicitly list
-     a certificate; patch from Meghana Bhat on bz#2436; ok markus@
-    
-    Upstream-ID: 58648ec53c510b41c1f46d8fe293aadc87229ab8
-
-commit e3cbb06ade83c72b640a53728d362bbefa0008e2
-Author: sobrado@openbsd.org <sobrado@openbsd.org>
-Date:   Tue Sep 22 08:33:23 2015 +0000
-
-    upstream commit
-    
-    fix two typos.
-    
-    Upstream-ID: 424402c0d8863a11b51749bacd7f8d932083b709
-
-commit 8408218c1ca88cb17d15278174a24a94a6f65fe1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Sep 21 04:31:00 2015 +0000
-
-    upstream commit
-    
-    fix possible hang on closed output; bz#2469 reported by Tomas
-     Kuthan ok markus@
-    
-    Upstream-ID: f7afd41810f8540f524284f1be6b970859f94fe3
-
-commit 0097248f90a00865082e8c146b905a6555cc146f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 11 04:55:01 2015 +0000
-
-    upstream commit
-    
-    skip if running as root; many systems (inc OpenBSD) allow
-     root to ptrace arbitrary processes
-    
-    Upstream-Regress-ID: be2b925df89360dff36f972951fa0fa793769038
-
-commit 9c06c814aff925e11a5cc592c06929c258a014f6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 11 03:44:21 2015 +0000
-
-    upstream commit
-    
-    try all supported key types here; bz#2455 reported by
-     Jakub Jelen
-    
-    Upstream-Regress-ID: 188cb7d9031cdbac3a0fa58b428b8fa2b2482bba
-
-commit 3c019a936b43f3e2773f3edbde7c114d73caaa4c
-Author: tim@openbsd.org <tim@openbsd.org>
-Date:   Sun Sep 13 14:39:16 2015 +0000
-
-    upstream commit
-    
-    - Fix error message: passphrase needs to be at least 5
-     characters, not 4. - Remove unused function argument. - Remove two
-     unnecessary variables.
-    
-    OK djm@
-    
-    Upstream-ID: 13010c05bfa8b523da1c0dc19e81dd180662bc30
-
-commit 2681cdb6e0de7c1af549dac37a9531af202b4434
-Author: tim@openbsd.org <tim@openbsd.org>
-Date:   Sun Sep 13 13:48:19 2015 +0000
-
-    upstream commit
-    
-    When adding keys to the agent, don't ignore the comment
-     of keys for which the user is prompted for a passphrase.
-    
-    Tweak and OK djm@
-    
-    Upstream-ID: dc737c620a5a8d282cc4f66e3b9b624e9abefbec
-
-commit 14692f7b8251cdda847e648a82735eef8a4d2a33
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Fri Sep 11 08:50:04 2015 +0000
-
-    upstream commit
-    
-    Use explicit_bzero() when zeroing before free()
-    
-    from Michael McConville (mmcconv1 (at) sccs.swarthmore.edu)
-    ok millert@ djm@
-    
-    Upstream-ID: 2e3337db046c3fe70c7369ee31515ac73ec00f50
-
-commit 846f6fa4cfa8483a9195971dbdd162220f199d85
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Sep 11 06:55:46 2015 +0000
-
-    upstream commit
-    
-    sync -Q in usage() to SYNOPSIS; since it's drastically
-     shorter, i've reformatted the block to sync with the man (80 cols) and saved
-     a line;
-    
-    Upstream-ID: 86e2c65c3989a0777a6258a77e589b9f6f354abd
-
-commit 95923e0520a8647417ee6dcdff44694703dfeef0
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Sep 11 06:51:39 2015 +0000
-
-    upstream commit
-    
-    tweak previous;
-    
-    Upstream-ID: f29b3cfcfd9aa31fa140c393e7bd48c1c74139d6
-
-commit 86ac462f833b05d8ed9de9c50ccb295d7faa79ff
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Sep 11 05:27:02 2015 +0000
-
-    upstream commit
-    
-    Update usage to match man page.
-    
-    Upstream-ID: 9e85aefaecfb6aaf34c7cfd0700cd21783a35675
-
-commit 674b3b68c1d36b2562324927cd03857b565e05e8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 11 03:47:28 2015 +0000
-
-    upstream commit
-    
-    expand %i in ControlPath to UID; bz#2449
-    
-    patch from Christian Hesse w/ feedback from dtucker@
-    
-    Upstream-ID: 2ba8d303e555a84e2f2165ab4b324b41e80ab925
-
-commit c0f55db7ee00c8202b05cb4b9ad4ce72cc45df41
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 11 03:42:32 2015 +0000
-
-    upstream commit
-    
-    mention -Q key-plain and -Q key-cert; bz#2455 pointed out
-     by Jakub Jelen
-    
-    Upstream-ID: c8f1f8169332e4fa73ac96b0043e3b84e01d4896
-
-commit cfffbdb10fdf0f02d3f4232232eef7ec3876c383
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Sep 14 16:24:21 2015 +1000
-
-    Use ssh-keygen -A when generating host keys.
-    
-    Use ssh-keygen -A instead of per-keytype invocations when generating host
-    keys.  Add tests when doing host-key-force since we can't use ssh-keygen -A
-    since it can't specify alternate locations.  bz#2459, ok djm@
-
-commit 366bada1e9e124654aac55b72b6ccf878755b0dc
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Sep 11 13:29:22 2015 +1000
-
-    Correct default value for --with-ssh1.
-    
-    bz#2457, from konto-mindrot.org at walimnieto.com.
-
-commit 2bca8a43e7dd9b04d7070824ffebb823c72587b2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 11 03:13:36 2015 +0000
-
-    upstream commit
-    
-    more clarity on what AuthorizedKeysFile=none does; based
-     on diff by Thiebaud Weksteen
-    
-    Upstream-ID: 78ab87f069080f0cc3bc353bb04eddd9e8ad3704
-
-commit 61942ea4a01e6db4fdf37ad61de81312ffe310e9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Sep 9 00:52:44 2015 +0000
-
-    upstream commit
-    
-    openssh_RSA_verify return type is int, so don't make it
-     size_t within the function itself with only negative numbers or zero assigned
-     to it. bz#2460
-    
-    Upstream-ID: b6e794b0c7fc4f9f329509263c8668d35f83ea55
-
-commit 4f7cc2f8cc861a21e6dbd7f6c25652afb38b9b96
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Sep 4 08:21:47 2015 +0000
-
-    upstream commit
-    
-    Plug minor memory leaks when options are used more than
-     once.  bz#2182, patch from Tiago Cunha, ok deraadt djm
-    
-    Upstream-ID: 5b84d0401e27fe1614c10997010cc55933adb48e
-
-commit 7ad8b287c8453a3e61dbc0d34d467632b8b06fc8
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Sep 11 13:11:02 2015 +1000
-
-    Force resolution of _res for correct detection.
-    
-    bz#2259, from sconeu at yahoo.com.
-
-commit 26ad18247213ff72b4438abe7fc660c958810fa2
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Sep 10 10:57:41 2015 +1000
-
-    allow getrandom syscall; from Felix von Leitner
-
-commit 5245bc1e6b129a10a928f73f11c3aa32656c44b4
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Sep 4 06:40:45 2015 +0000
-
-    upstream commit
-    
-    full stop belongs outside the brackets, not inside;
-    
-    Upstream-ID: 99d098287767799ac33d2442a05b5053fa5a551a
-
-commit a85768a9321d74b41219eeb3c9be9f1702cbf6a5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 04:56:09 2015 +0000
-
-    upstream commit
-    
-    add a debug2() right before DNS resolution; it's a place
-     where ssh could previously silently hang for a while. bz#2433
-    
-    Upstream-ID: 52a1a3e0748db66518e7598352c427145692a6a0
-
-commit 46152af8d27aa34d5d26ed1c371dc8aa142d4730
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 04:55:24 2015 +0000
-
-    upstream commit
-    
-    correct function name in error messages
-    
-    Upstream-ID: 92fb2798617ad9561370897f4ab60adef2ff4c0e
-
-commit a954cdb799a4d83c2d40fbf3e7b9f187fbfd72fc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 04:47:50 2015 +0000
-
-    upstream commit
-    
-    better document ExitOnForwardFailure; bz#2444, ok
-     dtucker@
-    
-    Upstream-ID: a126209b5a6d9cb3117ac7ab5bc63d284538bfc2
-
-commit f54d8ac2474b6fc3afa081cf759b48a6c89d3319
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 04:44:08 2015 +0000
-
-    upstream commit
-    
-    don't record hostbased authentication hostkeys as user
-     keys in test for multiple authentication with the same key
-    
-    Upstream-ID: 26b368fa2cff481f47f37e01b8da1ae5b57b1adc
-
-commit ac3451dd65f27ecf85dc045c46d49e2bbcb8dddd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 03:57:38 2015 +0000
-
-    upstream commit
-    
-    remove extra newline in nethack-mode hostkey; from
-     Christian Hesse bz#2686
-    
-    Upstream-ID: 4f56368b1cc47baeea0531912186f66007fd5b92
-
-commit 9e3ed9ebb1a7e47c155c28399ddf09b306ea05df
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Sep 4 04:23:10 2015 +0000
-
-    upstream commit
-    
-    trim junk from end of file; bz#2455 from Jakub Jelen
-    
-    Upstream-Regress-ID: a4e64e8931e40d23874b047074444eff919cdfe6
-
-commit f3a3ea180afff080bab82087ee0b60db9fd84f6c
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Wed Sep 2 07:51:12 2015 +0000
-
-    upstream commit
-    
-    Fix occurrences of "r = func() != 0" which result in the
-     wrong error codes being returned due to != having higher precedence than =.
-    
-    ok deraadt@ markus@
-    
-    Upstream-ID: 5fc35c9fc0319cc6fca243632662d2f06b5fd840
-
-commit f498a98cf83feeb7ea01c15cd1c98b3111361f3a
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Sep 3 09:11:22 2015 +1000
-
-    don't check for yp_match; ok tim@
-
-commit 9690b78b7848b0b376980a61d51b1613e187ddb5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 21 23:57:48 2015 +0000
-
-    upstream commit
-    
-    Improve printing of KEX offers and decisions
-    
-    The debug output now labels the client and server offers and the
-    negotiated options. ok markus@
-    
-    Upstream-ID: 8db921b3f92a4565271b1c1fbce6e7f508e1a2cb
-
-commit 60a92470e21340e1a3fc10f9c7140d8e1519dc55
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 21 23:53:08 2015 +0000
-
-    upstream commit
-    
-    Fix printing (ssh -G ...) of HostKeyAlgorithms=+...
-     Reported by Bryan Drewery
-    
-    Upstream-ID: 19ad20c41bd5971e006289b6f9af829dd46c1293
-
-commit 6310f60fffca2d1e464168e7d1f7e3b6b0268897
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 21 23:52:30 2015 +0000
-
-    upstream commit
-    
-    Fix expansion of HostkeyAlgorithms=+...
-    
-    Reported by Bryan Drewery
-    
-    Upstream-ID: 70ca1deea39d758ba36d36428ae832e28566f78d
-
-commit e774e5ea56237fd626a8161f9005023dff3e76c9
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Aug 21 23:29:31 2015 +0000
-
-    upstream commit
-    
-    Improve size == 0, count == 0 checking in mm_zalloc,
-     which is "array" like. Discussed with tedu, millert, otto.... and ok djm
-    
-    Upstream-ID: 899b021be43b913fad3eca1aef44efe710c53e29
-
-commit 189de02d9ad6f3645417c0ddf359b923aae5f926
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Aug 21 15:45:02 2015 +1000
-
-    expose POLLHUP and POLLNVAL for netcat.c
-
-commit e91346dc2bbf460246df2ab591b7613908c1b0ad
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Aug 21 14:49:03 2015 +1000
-
-    we don't use Github for issues/pull-requests
-
-commit a4f5b507c708cc3dc2c8dd2d02e4416d7514dc23
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Aug 21 14:43:55 2015 +1000
-
-    fix URL for connect.c
-
-commit d026a8d3da0f8186598442997c7d0a28e7275414
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri Aug 21 13:47:10 2015 +1000
-
-    update version numbers for 7.1
-
-commit 78f8f589f0ca1c9f41e5a9bae3cda5ce8a6b42ed
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 21 03:45:26 2015 +0000
-
-    upstream commit
-    
-    openssh-7.1
-    
-    Upstream-ID: ff7b1ef4b06caddfb45e08ba998128c88be3d73f
-
-commit 32a181980c62fce94f7f9ffaf6a79d90f0c309cf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Aug 21 03:42:19 2015 +0000
-
-    upstream commit
-    
-    fix inverted logic that broke PermitRootLogin; reported
-     by Mantas Mikulenas; ok markus@
-    
-    Upstream-ID: 260dd6a904c1bb7e43267e394b1c9cf70bdd5ea5
-
-commit ce445b0ed927e45bd5bdce8f836eb353998dd65c
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Thu Aug 20 22:32:42 2015 +0000
-
-    upstream commit
-    
-    Do not cast result of malloc/calloc/realloc* if stdlib.h
-     is in scope ok krw millert
-    
-    Upstream-ID: 5e50ded78cadf3841556649a16cc4b1cb6c58667
-
-commit 05291e5288704d1a98bacda269eb5a0153599146
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Thu Aug 20 19:20:06 2015 +0000
-
-    upstream commit
-    
-    In the certificates section, be consistent about using
-     "host_key" and "user_key" for the respective key types.  ok sthen@ deraadt@
-    
-    Upstream-ID: 9e037ea3b15577b238604c5533e082a3947f13cb
-
-commit 8543d4ef6f2e9f98c3e6b77c894ceec30c5e4ae4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 19 23:21:42 2015 +0000
-
-    upstream commit
-    
-    Better compat matching for WinSCP, add compat matching
-     for FuTTY (fork of PuTTY); ok markus@ deraadt@
-    
-    Upstream-ID: 24001d1ac115fa3260fbdc329a4b9aeb283c5389
-
-commit ec6eda16ebab771aa3dfc90629b41953b999cb1e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 19 23:19:01 2015 +0000
-
-    upstream commit
-    
-    fix double-free() in error path of DSA key generation
-     reported by Mateusz Kocielski; ok markus@
-    
-    Upstream-ID: 4735d8f888b10599a935fa1b374787089116713c
-
-commit 45b0eb752c94954a6de046bfaaf129e518ad4b5b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 19 23:18:26 2015 +0000
-
-    upstream commit
-    
-    fix free() of uninitialised pointer reported by Mateusz
-     Kocielski; ok markus@
-    
-    Upstream-ID: 519552b050618501a06b7b023de5cb104e2c5663
-
-commit c837643b93509a3ef538cb6624b678c5fe32ff79
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 19 23:17:51 2015 +0000
-
-    upstream commit
-    
-    fixed unlink([uninitialised memory]) reported by Mateusz
-     Kocielski; ok markus@
-    
-    Upstream-ID: 14a0c4e7d891f5a8dabc4b89d4f6b7c0d5a20109
-
-commit 1f8d3d629cd553031021068eb9c646a5f1e50994
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Aug 14 15:32:41 2015 +0000
-
-    upstream commit
-    
-    match myproposal.h order; from brian conway (i snuck in a
-     tweak while here)
-    
-    ok dtucker
-    
-    Upstream-ID: 35174a19b5237ea36aa3798f042bf5933b772c67
-
-commit 1dc8d93ce69d6565747eb44446ed117187621b26
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Thu Aug 6 14:53:21 2015 +0000
-
-    upstream commit
-    
-    add prohibit-password as a synonymn for without-password,
-     since the without-password is causing too many questions.  Harden it to ban
-     all but pubkey, hostbased, and GSSAPI auth (when the latter is enabled) from
-     djm, ok markus
-    
-    Upstream-ID: d53317d7b28942153e6236d3fd6e12ceb482db7a
-
-commit 90a95a4745a531b62b81ce3b025e892bdc434de5
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 11 13:53:41 2015 +1000
-
-    update version in README
-
-commit 318c37743534b58124f1bab37a8a0087a3a9bd2f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 11 13:53:09 2015 +1000
-
-    update versions in *.spec
-
-commit 5e75f5198769056089fb06c4d738ab0e5abc66f7
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 11 13:34:12 2015 +1000
-
-    set sshpam_ctxt to NULL after free
-    
-    Avoids use-after-free in monitor when privsep child is compromised.
-    Reported by Moritz Jodeit; ok dtucker@
-
-commit d4697fe9a28dab7255c60433e4dd23cf7fce8a8b
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Aug 11 13:33:24 2015 +1000
-
-    Don't resend username to PAM; it already has it.
-    
-    Pointed out by Moritz Jodeit; ok dtucker@
-
-commit 88763a6c893bf3dfe951ba9271bf09715e8d91ca
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Mon Jul 27 12:14:25 2015 +1000
-
-    Import updated moduli file from OpenBSD.
-
-commit 55b263fb7cfeacb81aaf1c2036e0394c881637da
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Aug 10 11:13:44 2015 +1000
-
-    let principals-command.sh work for noexec /var/run
-
-commit 2651e34cd11b1aac3a0fe23b86d8c2ff35c07897
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Aug 6 11:43:42 2015 +1000
-
-    work around echo -n / sed behaviour in tests
-
-commit d85dad81778c1aa8106acd46930b25fdf0d15b2a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Aug 5 05:27:33 2015 +0000
-
-    upstream commit
-    
-    adjust for RSA minimum modulus switch; ok deraadt@
-    
-    Upstream-Regress-ID: 5a72c83431b96224d583c573ca281cd3a3ebfdae
-
-commit 57e8e229bad5fe6056b5f1199665f5f7008192c6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Aug 4 05:23:06 2015 +0000
-
-    upstream commit
-    
-    backout SSH_RSA_MINIMUM_MODULUS_SIZE increase for this
-     release; problems spotted by sthen@ ok deraadt@ markus@
-    
-    Upstream-ID: d0bd60dde9e8c3cd7030007680371894c1499822
-
-commit f097d0ea1e0889ca0fa2e53a00214e43ab7fa22a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun Aug 2 09:56:42 2015 +0000
-
-    upstream commit
-    
-    openssh 7.0; ok deraadt@
-    
-    Upstream-ID: c63afdef537f57f28ae84145c5a8e29e9250221f
-
-commit 3d5728a0f6874ce4efb16913a12963595070f3a9
-Author: chris@openbsd.org <chris@openbsd.org>
-Date:   Fri Jul 31 15:38:09 2015 +0000
-
-    upstream commit
-    
-    Allow PermitRootLogin to be overridden by config
-    
-    ok markus@ deeradt@
-    
-    Upstream-ID: 5cf3e26ed702888de84e2dc9d0054ccf4d9125b4
-
-commit 6f941396b6835ad18018845f515b0c4fe20be21a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Jul 30 23:09:15 2015 +0000
-
-    upstream commit
-    
-    fix pty permissions; patch from Nikolay Edigaryev; ok
-     deraadt
-    
-    Upstream-ID: 40ff076d2878b916fbfd8e4f45dbe5bec019e550
-
-commit f4373ed1e8fbc7c8ce3fc4ea97d0ba2e0c1d7ef0
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Thu Jul 30 19:23:02 2015 +0000
-
-    upstream commit
-    
-    change default: PermitRootLogin without-password matching
-     install script changes coming as well ok djm markus
-    
-    Upstream-ID: 0e2a6c4441daf5498b47a61767382bead5eb8ea6
-
-commit 0c30ba91f87fcda7e975e6ff8a057f624e87ea1c
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jul 30 12:31:39 2015 +1000
-
-    downgrade OOM adjustment logging: verbose -> debug
-
-commit f9eca249d4961f28ae4b09186d7dc91de74b5895
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Jul 30 00:01:34 2015 +0000
-
-    upstream commit
-    
-    Allow ssh_config and sshd_config kex parameters options be
-     prefixed by a '+' to indicate that the specified items be appended to the
-     default rather than replacing it.
-    
-    approach suggested by dtucker@, feedback dlg@, ok markus@
-    
-    Upstream-ID: 0f901137298fc17095d5756ff1561a7028e8882a
-
-commit 5cefe769105a2a2e3ca7479d28d9a325d5ef0163
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 29 08:34:54 2015 +0000
-
-    upstream commit
-    
-    fix bug in previous; was printing incorrect string for
-     failed host key algorithms negotiation
-    
-    Upstream-ID: 22c0dc6bc61930513065d92e11f0753adc4c6e6e
-
-commit f319912b0d0e1675b8bb051ed8213792c788bcb2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 29 04:43:06 2015 +0000
-
-    upstream commit
-    
-    include the peer's offer when logging a failure to
-     negotiate a mutual set of algorithms (kex, pubkey, ciphers, etc.) ok markus@
-    
-    Upstream-ID: bbb8caabf5c01790bb845f5ce135565248d7c796
-
-commit b6ea0e573042eb85d84defb19227c89eb74cf05a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jul 28 23:20:42 2015 +0000
-
-    upstream commit
-    
-    add Cisco to the list of clients that choke on the
-     hostkeys update extension. Pointed out by Howard Kash
-    
-    Upstream-ID: c9eadde28ecec056c73d09ee10ba4570dfba7e84
-
-commit 3f628c7b537291c1019ce86af90756fb4e66d0fd
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date:   Mon Jul 27 16:29:23 2015 +0000
-
-    upstream commit
-    
-    Permit kbind(2) use in the sandbox now, to ease testing
-     of ld.so work using it
-    
-    reminded by miod@, ok deraadt@
-    
-    Upstream-ID: 523922e4d1ba7a091e3824e77a8a3c818ee97413
-
-commit ebe27ebe520098bbc0fe58945a87ce8490121edb
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Mon Jul 20 18:44:12 2015 +0000
-
-    upstream commit
-    
-    Move .Pp before .Bl, not after to quiet mandoc -Tlint.
-     Noticed by jmc@
-    
-    Upstream-ID: 59fadbf8407cec4e6931e50c53cfa0214a848e23
-
-commit d5d91d0da819611167782c66ab629159169d94d4
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Mon Jul 20 18:42:35 2015 +0000
-
-    upstream commit
-    
-    Sync usage with SYNOPSIS
-    
-    Upstream-ID: 7a321a170181a54f6450deabaccb6ef60cf3f0b7
-
-commit 79ec2142fbc68dd2ed9688608da355fc0b1ed743
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Mon Jul 20 15:39:52 2015 +0000
-
-    upstream commit
-    
-    Better desciption of Unix domain socket forwarding.
-     bz#2423; ok jmc@
-    
-    Upstream-ID: 85e28874726897e3f26ae50dfa2e8d2de683805d
-
-commit d56fd1828074a4031b18b8faa0bf949669eb18a0
-Author: Damien Miller <djm@mindrot.org>
-Date:   Mon Jul 20 11:19:51 2015 +1000
-
-    make realpath.c compile -Wsign-compare clean
-
-commit c63c9a691dca26bb7648827f5a13668832948929
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jul 20 00:30:01 2015 +0000
-
-    upstream commit
-    
-    mention that the default of UseDNS=no implies that
-     hostnames cannot be used for host matching in sshd_config and
-     authorized_keys; bz#2045, ok dtucker@
-    
-    Upstream-ID: 0812705d5f2dfa59aab01f2764ee800b1741c4e1
-
-commit 63ebcd0005e9894fcd6871b7b80aeea1fec0ff76
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Jul 18 08:02:17 2015 +0000
-
-    upstream commit
-    
-    don't ignore PKCS#11 hosted keys that return empty
-     CKA_ID; patch by Jakub Jelen via bz#2429; ok markus
-    
-    Upstream-ID: 2f7c94744eb0342f8ee8bf97b2351d4e00116485
-
-commit b15fd989c8c62074397160147a8d5bc34b3f3c63
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Jul 18 08:00:21 2015 +0000
-
-    upstream commit
-    
-    skip uninitialised PKCS#11 slots; patch from Jakub Jelen
-     in bz#2427 ok markus@
-    
-    Upstream-ID: 744c1e7796e237ad32992d0d02148e8a18f27d29
-
-commit 5b64f85bb811246c59ebab70aed331f26ba37b18
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sat Jul 18 07:57:14 2015 +0000
-
-    upstream commit
-    
-    only query each keyboard-interactive device once per
-     authentication request regardless of how many times it is listed; ok markus@
-    
-    Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1
-
-commit cd7324d0667794eb5c236d8a4e0f236251babc2d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 17 03:34:27 2015 +0000
-
-    upstream commit
-    
-    remove -u flag to diff (only used for error output) to make
-     things easier for -portable
-    
-    Upstream-Regress-ID: a5d6777d2909540d87afec3039d9bb2414ade548
-
-commit deb8d99ecba70b67f4af7880b11ca8768df9ec3a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 17 03:09:19 2015 +0000
-
-    upstream commit
-    
-    direct-streamlocal@openssh.com Unix domain foward
-     messages do not contain a "reserved for future use" field and in fact,
-     serverloop.c checks that there isn't one. Remove erroneous mention from
-     PROTOCOL description. bz#2421 from Daniel Black
-    
-    Upstream-ID: 3d51a19e64f72f764682f1b08f35a8aa810a43ac
-
-commit 356b61f365405b5257f5b2ab446e5d7bd33a7b52
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 17 03:04:27 2015 +0000
-
-    upstream commit
-    
-    describe magic for setting up Unix domain socket fowards
-     via the mux channel; bz#2422 patch from Daniel Black
-    
-    Upstream-ID: 943080fe3864715c423bdeb7c920bb30c4eee861
-
-commit d3e2aee41487d55b8d7d40f538b84ff1db7989bc
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jul 17 12:52:34 2015 +1000
-
-    Check if realpath works on nonexistent files.
-    
-    On some platforms the native realpath doesn't work with non-existent
-    files (this is actually specified in some versions of POSIX), however
-    the sftp spec says its realpath with "canonicalize any given path name".
-    On those platforms, use realpath from the compat library.
-    
-    In addition, when compiling with -DFORTIFY_SOURCE, glibc redefines
-    the realpath symbol to the checked version, so redefine ours to
-    something else so we pick up the compat version we want.
-    
-    bz#2428, ok djm@
-
-commit 25b14610dab655646a109db5ef8cb4c4bf2a48a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 17 02:47:45 2015 +0000
-
-    upstream commit
-    
-    fix incorrect test for SSH1 keys when compiled without SSH1
-     support
-    
-    Upstream-ID: 6004d720345b8e481c405e8ad05ce2271726e451
-
-commit df56a8035d429b2184ee94aaa7e580c1ff67f73a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 15 08:00:11 2015 +0000
-
-    upstream commit
-    
-    fix NULL-deref when SSH1 reenabled
-    
-    Upstream-ID: f22fd805288c92b3e9646782d15b48894b2d5295
-
-commit 41e38c4d49dd60908484e6703316651333f16b93
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 15 07:19:50 2015 +0000
-
-    upstream commit
-    
-    regen RSA1 test keys; the last batch was missing their
-     private parts
-    
-    Upstream-Regress-ID: 7ccf437305dd63ff0b48dd50c5fd0f4d4230c10a
-
-commit 5bf0933184cb622ca3f96d224bf3299fd2285acc
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Fri Jul 10 06:23:25 2015 +0000
-
-    upstream commit
-    
-    Adapt tests, now that DSA if off by default; use
-     PubkeyAcceptedKeyTypes and PubkeyAcceptedKeyTypes to test DSA.
-    
-    Upstream-Regress-ID: 0ff2a3ff5ac1ce5f92321d27aa07b98656efcc5c
-
-commit 7a6e3fd7b41dbd3756b6bf9acd67954c0b1564cc
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Jul 7 14:54:16 2015 +0000
-
-    upstream commit
-    
-    regen test data after mktestdata.sh changes
-    
-    Upstream-Regress-ID: 3495ecb082b9a7c048a2d7c5c845d3bf181d25a4
-
-commit 7c8c174c69f681d4910fa41c37646763692b28e2
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Jul 7 14:53:30 2015 +0000
-
-    upstream commit
-    
-    adapt tests to new minimum RSA size and default FP format
-    
-    Upstream-Regress-ID: a4b30afd174ce82b96df14eb49fb0b81398ffd0e
-
-commit 6a977a4b68747ade189e43d302f33403fd4a47ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 04:39:23 2015 +0000
-
-    upstream commit
-    
-    legacy v00 certificates are gone; adapt and don't try to
-     test them; "sure" markus@ dtucker@
-    
-    Upstream-Regress-ID: c57321e69b3cd4a3b3396dfcc43f0803d047da12
-
-commit 0c4123ad5e93fb90fee9c6635b13a6cdabaac385
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 23:11:18 2015 +0000
-
-    upstream commit
-    
-    don't expect SSH v.1 in unittests
-    
-    Upstream-Regress-ID: f8812b16668ba78e6a698646b2a652b90b653397
-
-commit 3c099845798a817cdde513c39074ec2063781f18
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jun 15 06:38:50 2015 +0000
-
-    upstream commit
-    
-    turn SSH1 back on to match src/usr.bin/ssh being tested
-    
-    Upstream-Regress-ID: 6c4f763a2f0cc6893bf33983919e9030ae638333
-
-commit b1dc2b33689668c75e95f873a42d5aea1f4af1db
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Jul 13 04:57:14 2015 +0000
-
-    upstream commit
-    
-    Add "PuTTY_Local:" to the clients to which we do not
-     offer DH-GEX. This was the string that was used for development versions
-     prior to September 2014 and they don't do RFC4419 DH-GEX, but unfortunately
-     there are some extant products based on those versions.  bx2424 from Jay
-     Rouman, ok markus@ djm@
-    
-    Upstream-ID: be34d41e18b966832fe09ca243d275b81882e1d5
-
-commit 3a1638dda19bbc73d0ae02b4c251ce08e564b4b9
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Fri Jul 10 06:21:53 2015 +0000
-
-    upstream commit
-    
-    Turn off DSA by default; add HostKeyAlgorithms to the
-     server and PubkeyAcceptedKeyTypes to the client side, so it still can be
-     tested or turned back on; feedback and ok djm@
-    
-    Upstream-ID: 8450a9e6d83f80c9bfed864ff061dfc9323cec21
-
-commit 16db0a7ee9a87945cc594d13863cfcb86038db59
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Thu Jul 9 09:49:46 2015 +0000
-
-    upstream commit
-    
-    re-enable ed25519-certs if compiled w/o openssl; ok djm
-    
-    Upstream-ID: e10c90808b001fd2c7a93778418e9b318f5c4c49
-
-commit c355bf306ac33de6545ce9dac22b84a194601e2f
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Jul 8 20:24:02 2015 +0000
-
-    upstream commit
-    
-    no need to include the old buffer/key API
-    
-    Upstream-ID: fb13c9f7c0bba2545f3eb0a0e69cb0030819f52b
-
-commit a3cc48cdf9853f1e832d78cb29bedfab7adce1ee
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Jul 8 19:09:25 2015 +0000
-
-    upstream commit
-    
-    typedefs for Cipher&CipherContext are unused
-    
-    Upstream-ID: 50e6a18ee92221d23ad173a96d5b6c42207cf9a7
-
-commit a635bd06b5c427a57c3ae760d3a2730bb2c863c0
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Jul 8 19:04:21 2015 +0000
-
-    upstream commit
-    
-    xmalloc.h is unused
-    
-    Upstream-ID: afb532355b7fa7135a60d944ca1e644d1d63cb58
-
-commit 2521cf0e36c7f3f6b19f206da0af134f535e4a31
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Jul 8 19:01:15 2015 +0000
-
-    upstream commit
-    
-    compress.c is gone
-    
-    Upstream-ID: 174fa7faa9b9643cba06164b5e498591356fbced
-
-commit c65a7aa6c43aa7a308ee1ab8a96f216169ae9615
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 04:05:54 2015 +0000
-
-    upstream commit
-    
-    another SSH_RSA_MINIMUM_MODULUS_SIZE that needed
-     cranking
-    
-    Upstream-ID: 9d8826cafe96aab4ae8e2f6fd22800874b7ffef1
-
-commit b1f383da5cd3cb921fc7776f17a14f44b8a31757
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 03:56:25 2015 +0000
-
-    upstream commit
-    
-    add an XXX reminder for getting correct key paths from
-     sshd_config
-    
-    Upstream-ID: feae52b209d7782ad742df04a4260e9fe41741db
-
-commit 933935ce8d093996c34d7efa4d59113163080680
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 03:49:45 2015 +0000
-
-    upstream commit
-    
-    refuse to generate or accept RSA keys smaller than 1024
-     bits; feedback and ok dtucker@
-    
-    Upstream-ID: 7ea3d31271366ba264f06e34a3539bf1ac30f0ba
-
-commit bdfd29f60b74f3e678297269dc6247a5699583c1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 03:47:00 2015 +0000
-
-    upstream commit
-    
-    turn off 1024 bit diffie-hellman-group1-sha1 key
-     exchange method (already off in server, this turns it off in the client by
-     default too) ok dtucker@
-    
-    Upstream-ID: f59b88f449210ab7acf7d9d88f20f1daee97a4fa
-
-commit c28fc62d789d860c75e23a9fa9fb250eb2beca57
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jul 3 03:43:18 2015 +0000
-
-    upstream commit
-    
-    delete support for legacy v00 certificates; "sure"
-     markus@ dtucker@
-    
-    Upstream-ID: b5b9bb5f9202d09e88f912989d74928601b6636f
-
-commit 564d63e1b4a9637a209d42a9d49646781fc9caef
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 23:10:47 2015 +0000
-
-    upstream commit
-    
-    Compile-time disable SSH v.1 again
-    
-    Upstream-ID: 1d4b513a3a06232f02650b73bad25100d1b800af
-
-commit 868109b650504dd9bcccdb1f51d0906f967c20ff
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 02:39:06 2015 +0000
-
-    upstream commit
-    
-    twiddle PermitRootLogin back
-    
-    Upstream-ID: 2bd23976305d0512e9f84d054e1fc23cd70b89f2
-
-commit 7de4b03a6e4071d454b72927ffaf52949fa34545
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 02:32:17 2015 +0000
-
-    upstream commit
-    
-    twiddle; (this commit marks the openssh-6.9 release)
-    
-    Upstream-ID: 78500582819f61dd8adee36ec5cc9b9ac9351234
-
-commit 1bf477d3cdf1a864646d59820878783d42357a1d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 02:26:31 2015 +0000
-
-    upstream commit
-    
-    better refuse ForwardX11Trusted=no connections attempted
-     after ForwardX11Timeout expires; reported by Jann Horn
-    
-    Upstream-ID: bf0fddadc1b46a0334e26c080038313b4b6dea21
-
-commit 47aa7a0f8551b471fcae0447c1d78464f6dba869
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 01:56:13 2015 +0000
-
-    upstream commit
-    
-    put back default PermitRootLogin=no
-    
-    Upstream-ID: 7bdedd5cead99c57ed5571f3b6b7840922d5f728
-
-commit 984b064fe2a23733733262f88d2e1b2a1a501662
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 01:55:13 2015 +0000
-
-    upstream commit
-    
-    openssh-6.9
-    
-    Upstream-ID: 6cfe8e1904812531080e6ab6e752d7001b5b2d45
-
-commit d921082ed670f516652eeba50705e1e9f6325346
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jul 1 01:55:00 2015 +0000
-
-    upstream commit
-    
-    reset default PermitRootLogin to 'yes' (momentarily, for
-     release)
-    
-    Upstream-ID: cad8513527066e65dd7a1c16363d6903e8cefa24
-
-commit 66295e0e1ba860e527f191b6325d2d77dec4dbce
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jul 1 11:49:12 2015 +1000
-
-    crank version numbers for release
-
-commit 37035c07d4f26bb1fbe000d2acf78efdb008681d
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jul 1 10:49:37 2015 +1000
-
-    s/--with-ssh1/--without-ssh1/
-
-commit 629df770dbadc2accfbe1c81b3f31f876d0acd84
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jun 30 05:25:07 2015 +0000
-
-    upstream commit
-    
-    fatal() when a remote window update causes the window
-     value to overflow. Reported by Georg Wicherski, ok markus@
-    
-    Upstream-ID: ead397a9aceb3bf74ebfa5fcaf259d72e569f351
-
-commit f715afebe735d61df3fd30ad72d9ac1c8bd3b5f2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jun 30 05:23:25 2015 +0000
-
-    upstream commit
-    
-    Fix math error in remote window calculations that causes
-     eventual stalls for datagram channels. Reported by Georg Wicherski, ok
-     markus@
-    
-    Upstream-ID: be54059d11bf64e0d85061f7257f53067842e2ab
-
-commit 52fb6b9b034fcfd24bf88cc7be313e9c31de9889
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue Jun 30 16:05:40 2015 +1000
-
-    skip IPv6-related portions on hosts without IPv6
-    
-    with Tim Rice
-
-commit 512caddf590857af6aa12218461b5c0441028cf5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jun 29 22:35:12 2015 +0000
-
-    upstream commit
-    
-    add getpid to sandbox, reachable by grace_alarm_handler
-    
-    reported by Jakub Jelen; bz#2419
-    
-    Upstream-ID: d0da1117c16d4c223954995d35b0f47c8f684cd8
-
-commit 78c2a4f883ea9aba866358e2acd9793a7f42ca93
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jun 26 05:13:20 2015 +0000
-
-    upstream commit
-    
-    Fix \-escaping bug that caused forward path parsing to skip
-     two characters and skip past the end of the string.
-    
-    Based on patch by Salvador Fandino; ok dtucker@
-    
-    Upstream-ID: 7b879dc446335677cbe4cb549495636a0535f3bd
-
-commit bc20205c91c9920361d12b15d253d4997dba494a
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jun 25 09:51:39 2015 +1000
-
-    add missing pselect6
-    
-    patch from Jakub Jelen
-
-commit 9d27fb73b4a4e5e99cb880af790d5b1ce44f720a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Jun 24 23:47:23 2015 +0000
-
-    upstream commit
-    
-    correct test to sshkey_sign(); spotted by Albert S.
-    
-    Upstream-ID: 5f7347f40f0ca6abdaca2edb3bd62f4776518933
-
-commit 7ed01a96a1911d8b4a9ef4f3d064e1923bfad7e3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jun 24 01:49:19 2015 +0000
-
-    upstream commit
-    
-    Revert previous commit.  We still want to call setgroups
-     in the case where there are zero groups to remove any that we might otherwise
-     inherit (as pointed out by grawity at gmail.com) and since the 2nd argument
-     to setgroups is always a static global it's always valid to dereference in
-     this case.  ok deraadt@ djm@
-    
-    Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01
-
-commit 882f8bf94f79528caa65b0ba71c185d705bb7195
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Jun 24 01:49:19 2015 +0000
-
-    upstream commit
-    
-    Revert previous commit.  We still want to call setgroups in
-     the case where there are zero groups to remove any that we might otherwise
-     inherit (as pointed out by grawity at gmail.com) and since the 2nd argument
-     to setgroups is always a static global it's always valid to dereference in
-     this case.  ok deraadt@ djm@
-    
-    Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01
-
-commit 9488538a726951e82b3a4374f3c558d72c80a89b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jun 22 23:42:16 2015 +0000
-
-    upstream commit
-    
-    Don't count successful partial authentication as failures
-     in monitor; this may have caused the monitor to refuse multiple
-     authentications that would otherwise have successfully completed; ok markus@
-    
-    Upstream-ID: eb74b8e506714d0f649bd5c300f762a527af04a3
-
-commit 63b78d003bd8ca111a736e6cea6333da50f5f09b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Jun 22 12:29:57 2015 +0000
-
-    upstream commit
-    
-    Don't call setgroups if we have zero groups; there's no
-     guarantee that it won't try to deref the pointer.  Based on a patch from mail
-     at quitesimple.org, ok djm deraadt
-    
-    Upstream-ID: 2fff85e11d7a9a387ef7fddf41fbfaf566708ab1
-
-commit 5c15e22c691c79a47747bcf5490126656f97cecd
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu Jun 18 15:07:56 2015 +1000
-
-    fix syntax error
-
-commit 596dbca82f3f567fb3d2d69af4b4e1d3ba1e6403
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date:   Mon Jun 15 18:44:22 2015 +0000
-
-    upstream commit
-    
-    If AuthorizedPrincipalsCommand is specified, however
-     AuthorizedPrincipalsFile is not (or is set to "none"), authentication will
-     potentially fail due to key_cert_check_authority() failing to locate a
-     principal that matches the username, even though an authorized principal has
-     already been matched in the output of the subprocess. Fix this by using the
-     same logic to determine if pw->pw_name should be passed, as is used to
-     determine if a authorized principal must be matched earlier on.
-    
-    ok djm@
-    
-    Upstream-ID: 43b42302ec846b0ea68aceb40677245391b9409d
-
-commit aff3e94c0d75d0d0fa84ea392b50ab04f8c57905
-Author: jsing@openbsd.org <jsing@openbsd.org>
-Date:   Mon Jun 15 18:42:19 2015 +0000
-
-    upstream commit
-    
-    Make the arguments to match_principals_command() similar
-     to match_principals_file(), by changing the last argument a struct
-     sshkey_cert * and dereferencing key->cert in the caller.
-    
-    No functional change.
-    
-    ok djm@
-    
-    Upstream-ID: 533f99b844b21b47342b32b62e198dfffcf8651c
-
-commit 97e2e1596c202a4693468378b16b2353fd2d6c5e
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jun 17 14:36:54 2015 +1000
-
-    trivial optimisation for seccomp-bpf
-    
-    When doing arg inspection and the syscall doesn't match, skip
-    past the instruction that reloads the syscall into the accumulator,
-    since the accumulator hasn't been modified at this point.
-
-commit 99f33d7304893bd9fa04d227cb6e870171cded19
-Author: Damien Miller <djm@mindrot.org>
-Date:   Wed Jun 17 10:50:51 2015 +1000
-
-    aarch64 support for seccomp-bpf sandbox
-    
-    Also resort and tidy syscall list. Based on patches by Jakub Jelen
-    bz#2361; ok dtucker@
-
-commit 4ef702e1244633c1025ec7cfe044b9ab267097bf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Jun 15 01:32:50 2015 +0000
-
-    upstream commit
-    
-    return failure on RSA signature error; reported by Albert S
-    
-    Upstream-ID: e61bb93dbe0349625807b0810bc213a6822121fa
-
-commit a170f22baf18af0b1acf2788b8b715605f41a1f9
-Author: Tim Rice <tim@multitalents.net>
-Date:   Tue Jun 9 22:41:13 2015 -0700
-
-    Fix t12 rules for out of tree builds.
-
-commit ec04dc4a5515c913121bc04ed261857e68fa5c18
-Author: millert@openbsd.org <millert@openbsd.org>
-Date:   Fri Jun 5 15:13:13 2015 +0000
-
-    upstream commit
-    
-    For "ssh -L 12345:/tmp/sock" don't fail with "No forward host
-     name." (we have a path, not a host name).  Based on a diff from Jared
-     Yanovich. OK djm@
-    
-    Upstream-ID: 2846b0a8c7de037e33657f95afbd282837fc213f
-
-commit 732d61f417a6aea0aa5308b59cb0f563bcd6edd6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Jun 5 03:44:14 2015 +0000
-
-    upstream commit
-    
-    typo: accidental repetition; bz#2386
-    
-    Upstream-ID: 45e620d99f6bc301e5949d34a54027374991c88b
-
-commit adfb24c69d1b6f5e758db200866c711e25a2ba73
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Jun 5 14:51:40 2015 +1000
-
-    Add Linux powerpc64le and powerpcle entries.
-    
-    Stopgap to resolve bz#2409 because we are so close to release and will
-    update config.guess and friends shortly after the release.  ok djm@
-
-commit a1195a0fdc9eddddb04d3e9e44c4775431cb77da
-Merge: 6397eed d2480bc
-Author: Tim Rice <tim@multitalents.net>
-Date:   Wed Jun 3 21:43:13 2015 -0700
-
-    Merge branch 'master' of git.mindrot.org:/var/git/openssh
-
-commit 6397eedf953b2b973d2d7cbb504ab501a07f8ddc
-Author: Tim Rice <tim@multitalents.net>
-Date:   Wed Jun 3 21:41:11 2015 -0700
-
-    Remove unneeded backslashes. Patch from Ángel González
-
-commit d2480bcac1caf31b03068de877a47d6e1027bf6d
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Jun 4 14:10:55 2015 +1000
-
-    Remove redundant include of stdarg.h.  bz#2410
-
-commit 5e67859a623826ccdf2df284cbb37e2d8e2787eb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Jun 2 09:10:40 2015 +0000
-
-    upstream commit
-    
-    mention CheckHostIP adding addresses to known_hosts;
-     bz#1993; ok dtucker@
-    
-    Upstream-ID: fd44b68440fd0dc29abf9f2d3f703d74a2396cb7
-
-commit d7a58bbac6583e33fd5eca8e2c2cc70c57617818
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Jun 2 20:15:26 2015 +1000
-
-    Replace strcpy with strlcpy.
-    
-    ok djm, sanity check by Corinna Vinschen.
-
-commit 51a1c2115265c6e80ede8a5c9dccada9aeed7143
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri May 29 18:27:21 2015 +1000
-
-    skip, rather than fatal when run without SUDO set
-
-commit 599f01142a376645b15cbc9349d7e8975e1cf245
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri May 29 18:03:15 2015 +1000
-
-    fix merge botch that left ",," in KEX algs
-
-commit 0c2a81dfc21822f2423edd30751e5ec53467b347
-Author: Damien Miller <djm@mindrot.org>
-Date:   Fri May 29 17:08:28 2015 +1000
-
-    re-enable SSH protocol 1 at compile time
-
-commit db438f9285d64282d3ac9e8c0944f59f037c0151
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 29 03:05:13 2015 +0000
-
-    upstream commit
-    
-    make this work without SUDO set; ok dtucker@
-    
-    Upstream-Regress-ID: bca88217b70bce2fe52b23b8e06bdeb82d98c715
-
-commit 1d9a2e2849c9864fe75daabf433436341c968e14
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 28 07:37:31 2015 +0000
-
-    upstream commit
-    
-    wrap all moduli-related code in #ifdef WITH_OPENSSL.
-     based on patch from Reuben Hawkins; bz#2388 feedback and ok dtucker@
-    
-    Upstream-ID: d80cfc8be3e6ec65b3fac9e87c4466533b31b7cf
-
-commit 496aeb25bc2d6c434171292e4714771b594bd00e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu May 28 05:41:29 2015 +0000
-
-    upstream commit
-    
-    Increase the allowed length of the known host file name
-     in the log message to be consistent with other cases.  Part of bz#1993, ok
-     deraadt.
-    
-    Upstream-ID: a9e97567be49f25daf286721450968251ff78397
-
-commit dd2cfeb586c646ff8d70eb93567b2e559ace5b14
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu May 28 05:09:45 2015 +0000
-
-    upstream commit
-    
-    Fix typo (keywork->keyword)
-    
-    Upstream-ID: 8aacd0f4089c0a244cf43417f4f9045dfaeab534
-
-commit 9cc6842493fbf23025ccc1edab064869640d3bec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 28 04:50:53 2015 +0000
-
-    upstream commit
-    
-    add error message on ftruncate failure; bz#2176
-    
-    Upstream-ID: cbcc606e0b748520c74a210d8f3cc9718d3148cf
-
-commit d1958793a0072c22be26d136dbda5ae263e717a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 28 04:40:13 2015 +0000
-
-    upstream commit
-    
-    make ssh-keygen default to ed25519 keys when compiled
-     without OpenSSL; bz#2388, ok dtucker@
-    
-    Upstream-ID: 85a471fa6d3fa57a7b8e882d22cfbfc1d84cdc71
-
-commit 3ecde664c9fc5fb3667aedf9e6671462600f6496
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed May 27 23:51:10 2015 +0000
-
-    upstream commit
-    
-    Reorder client proposal to prefer
-     diffie-hellman-group-exchange-sha1 over diffie-hellman-group14-sha1.  ok djm@
-    
-    Upstream-ID: 552c08d47347c3ee1a9a57d88441ab50abe17058
-
-commit 40f64292b907afd0a674fdbf3e4c2356d17a7d68
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed May 27 23:39:18 2015 +0000
-
-    upstream commit
-    
-    Add a stronger (4k bit) fallback group that sshd can use
-     when the moduli file is missing or broken, sourced from RFC3526.  bz#2302, ok
-     markus@ (earlier version), djm@
-    
-    Upstream-ID: b635215746a25a829d117673d5e5a76d4baee7f4
-
-commit 5ab7d5fa03ad55bc438fab45dfb3aeb30a3c237a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu May 28 10:03:40 2015 +1000
-
-    New moduli file from OpenBSD, removing 1k groups.
-    
-    Remove 1k bit groups.  ok deraadt@, markus@
-
-commit a71ba58adf34e599f30cdda6e9b93ae6e3937eea
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed May 27 05:15:02 2015 +0000
-
-    upstream commit
-    
-    support PKCS#11 devices with external PIN entry devices
-     bz#2240, based on patch from Dirk-Willem van Gulik; feedback and ok dtucker@
-    
-    Upstream-ID: 504568992b55a8fc984375242b1bd505ced61b0d
-
-commit b282fec1aa05246ed3482270eb70fc3ec5f39a00
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 26 23:23:40 2015 +0000
-
-    upstream commit
-    
-    Cap DH-GEX group size at 4kbits for Cisco implementations.
-     Some of them will choke when asked for preferred sizes >4k instead of
-     returning the 4k group that they do have.  bz#2209, ok djm@
-    
-    Upstream-ID: 54b863a19713446b7431f9d06ad0532b4fcfef8d
-
-commit 3e91b4e8b0dc2b4b7e7d42cf6e8994a32e4cb55e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Sun May 24 23:39:16 2015 +0000
-
-    upstream commit
-    
-    add missing 'c' option to getopt(), case statement was
-     already there; from Felix Bolte
-    
-    Upstream-ID: 9b19b4e2e0b54d6fefa0dfac707c51cf4bae3081
-
-commit 64a89ec07660abba4d0da7c0095b7371c98bab62
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Sat May 23 14:28:37 2015 +0000
-
-    upstream commit
-    
-    fix a memory leak in an error path ok markus@ dtucker@
-    
-    Upstream-ID: bc1da0f205494944918533d8780fde65dff6c598
-
-commit f948737449257d2cb83ffcfe7275eb79b677fd4a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 22 05:28:45 2015 +0000
-
-    upstream commit
-    
-    mention ssh-keygen -E for comparing legacy MD5
-     fingerprints; bz#2332
-    
-    Upstream-ID: 079a3669549041dbf10dbc072d9563f0dc3b2859
-
-commit 0882332616e4f0272c31cc47bf2018f9cb258a4e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 22 04:45:52 2015 +0000
-
-    upstream commit
-    
-    Reorder EscapeChar option parsing to avoid a single-byte
-     out- of-bounds read. bz#2396 from Jaak Ristioja; ok dtucker@
-    
-    Upstream-ID: 1dc6b5b63d1c8d9a88619da0b27ade461d79b060
-
-commit d7c31da4d42c115843edee2074d7d501f8804420
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 22 03:50:02 2015 +0000
-
-    upstream commit
-    
-    add knob to relax GSSAPI host credential check for
-     multihomed hosts bz#928, patch by Simon Wilkinson; ok dtucker
-     (kerberos/GSSAPI is not compiled by default on OpenBSD)
-    
-    Upstream-ID: 15ddf1c6f7fd9d98eea9962f480079ae3637285d
-
-commit aa72196a00be6e0b666215edcffbc10af234cb0e
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri May 22 17:49:46 2015 +1000
-
-    Include signal.h for sig_atomic_t, used by kex.h.
-    
-    bz#2402, from tomas.kuthan at oracle com.
-
-commit 8b02481143d75e91c49d1bfae0876ac1fbf9511a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri May 22 12:47:24 2015 +1000
-
-    Import updated moduli file from OpenBSD.
-
-commit 4739e8d5e1c0be49624082bd9f6b077e9e758db9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 12:01:19 2015 +0000
-
-    upstream commit
-    
-    Support "ssh-keygen -lF hostname" to find search known_hosts
-     and print key hashes. Already advertised by ssh-keygen(1), but not delivered
-     by code; ok dtucker@
-    
-    Upstream-ID: 459e0e2bf39825e41b0811c336db2d56a1c23387
-
-commit e97201feca10b5196da35819ae516d0b87cf3a50
-Author: Damien Miller <djm@mindrot.org>
-Date:   Thu May 21 17:55:15 2015 +1000
-
-    conditionalise util.h inclusion
-
-commit 13640798c7dd011ece0a7d02841fe48e94cfa0e0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 06:44:25 2015 +0000
-
-    upstream commit
-    
-    regress test for AuthorizedPrincipalsCommand
-    
-    Upstream-Regress-ID: c658fbf1ab6b6011dc83b73402322e396f1e1219
-
-commit 84452c5d03c21f9bfb28c234e0dc1dc67dd817b1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 06:40:02 2015 +0000
-
-    upstream commit
-    
-    regress test for AuthorizedKeysCommand arguments
-    
-    Upstream-Regress-ID: bbd65c13c6b3be9a442ec115800bff9625898f12
-
-commit bcc50d816187fa9a03907ac1f3a52f04a52e10d1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 06:43:30 2015 +0000
-
-    upstream commit
-    
-    add AuthorizedPrincipalsCommand that allows getting
-     authorized_principals from a subprocess rather than a file, which is quite
-     useful in deployments with large userbases
-    
-    feedback and ok markus@
-    
-    Upstream-ID: aa1bdac7b16fc6d2fa3524ef08f04c7258d247f6
-
-commit 24232a3e5ab467678a86aa67968bbb915caffed4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 06:38:35 2015 +0000
-
-    upstream commit
-    
-    support arguments to AuthorizedKeysCommand
-    
-    bz#2081 loosely based on patch by Sami Hartikainen
-    feedback and ok markus@
-    
-    Upstream-ID: b080387a14aa67dddd8ece67c00f268d626541f7
-
-commit d80fbe41a57c72420c87a628444da16d09d66ca7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu May 21 04:55:51 2015 +0000
-
-    upstream commit
-    
-    refactor: split base64 encoding of pubkey into its own
-     sshkey_to_base64() function and out of sshkey_write(); ok markus@
-    
-    Upstream-ID: 54fc38f5832e9b91028900819bda46c3959a0c1a
-
-commit 7cc44ef74133a473734bbcbd3484f24d6a7328c5
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Mon May 18 15:06:05 2015 +0000
-
-    upstream commit
-    
-    getentropy() and sendsyslog() have been around long
-     enough. openssh-portable may want the #ifdef's but not base. discussed with
-     djm few weeks back
-    
-    Upstream-ID: 0506a4334de108e3fb6c66f8d6e0f9c112866926
-
-commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri May 15 05:44:21 2015 +0000
-
-    upstream commit
-    
-    Use a salted hash of the lock passphrase instead of plain
-     text and do constant-time comparisons of it. Should prevent leaking any
-     information about it via timing, pointed out by Ryan Castellucci.  Add a 0.1s
-     incrementing delay for each failed unlock attempt up to 10s.  ok markus@
-     (earlier version), djm@
-    
-    Upstream-ID: c599fcc325aa1cc65496b25220b622d22208c85f
-
-commit d028d5d3a697c71b21e4066d8672cacab3caa0a8
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue May 5 19:10:58 2015 +1000
-
-    upstream commit
-    
-       - tedu@cvs.openbsd.org 2015/01/12 03:20:04
-         [bcrypt_pbkdf.c]
-         rename blocks to words. bcrypt "blocks" are unrelated to blowfish blocks,
-         nor are they the same size.
-
-commit f6391d4e59b058984163ab28f4e317e7a72478f1
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue May 5 19:10:23 2015 +1000
-
-    upstream commit
-    
-       - deraadt@cvs.openbsd.org 2015/01/08 00:30:07
-         [bcrypt_pbkdf.c]
-         declare a local version of MIN(), call it MINIMUM()
-
-commit 8ac6b13cc9113eb47cd9e86c97d7b26b4b71b77f
-Author: Damien Miller <djm@mindrot.org>
-Date:   Tue May 5 19:09:46 2015 +1000
-
-    upstream commit
-    
-       - djm@cvs.openbsd.org 2014/12/30 01:41:43
-         [bcrypt_pbkdf.c]
-         typo in comment: ouput => output
-
-commit 1f792489d5cf86a4f4e3003e6e9177654033f0f2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 4 06:10:48 2015 +0000
-
-    upstream commit
-    
-    Remove pattern length argument from match_pattern_list(), we
-     only ever use it for strlen(pattern).
-    
-    Prompted by hanno AT hboeck.de pointing an out-of-bound read
-    error caused by an incorrect pattern length found using AFL
-    and his own tools.
-    
-    ok markus@
-
-commit 639d6bc57b1942393ed12fb48f00bc05d4e093e4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 07:10:01 2015 +0000
-
-    upstream commit
-    
-    refactor ssh_dispatch_run_fatal() to use sshpkt_fatal()
-     to better report error conditions. Teach sshpkt_fatal() about ECONNRESET.
-    
-    Improves error messages on TCP connection resets. bz#2257
-    
-    ok dtucker@
-
-commit 9559d7de34c572d4d3fd990ca211f8ec99f62c4d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 07:08:08 2015 +0000
-
-    upstream commit
-    
-    a couple of parse targets were missing activep checks,
-     causing them to be misapplied in match context; bz#2272 diagnosis and
-     original patch from Sami Hartikainen ok dtucker@
-
-commit 7e8528cad04b2775c3b7db08abf8fb42e47e6b2a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 04:17:51 2015 +0000
-
-    upstream commit
-    
-    make handling of AuthorizedPrincipalsFile=none more
-     consistent with other =none options; bz#2288 from Jakub Jelen; ok dtucker@
-
-commit ca430d4d9cc0f62eca3b1fb1e2928395b7ce80f7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 04:03:20 2015 +0000
-
-    upstream commit
-    
-    remove failed remote forwards established by muliplexing
-     from the list of active forwards; bz#2363, patch mostly by Yoann Ricordel; ok
-     dtucker@
-
-commit 8312cfb8ad88657517b3e23ac8c56c8e38eb9792
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 04:01:58 2015 +0000
-
-    upstream commit
-    
-    reduce stderr spam when using ssh -S /path/mux -O forward
-     -R 0:... ok dtucker@
-
-commit 179be0f5e62f1f492462571944e45a3da660d82b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 03:23:51 2015 +0000
-
-    upstream commit
-    
-    prevent authorized_keys options picked up on public key
-     tests without a corresponding private key authentication being applied to
-     other authentication methods. Reported by halex@, ok markus@
-
-commit a42d67be65b719a430b7fcaba2a4e4118382723a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 03:20:54 2015 +0000
-
-    upstream commit
-    
-    Don't make parsing of authorized_keys' environment=
-     option conditional on PermitUserEnv - always parse it, but only use the
-     result if the option is enabled. This prevents the syntax of authorized_keys
-     changing depending on which sshd_config options were enabled.
-    
-    bz#2329; based on patch from coladict AT gmail.com, ok dtucker@
-
-commit e661a86353e11592c7ed6a847e19a83609f49e77
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon May 4 06:10:48 2015 +0000
-
-    upstream commit
-    
-    Remove pattern length argument from match_pattern_list(), we
-     only ever use it for strlen(pattern).
-    
-    Prompted by hanno AT hboeck.de pointing an out-of-bound read
-    error caused by an incorrect pattern length found using AFL
-    and his own tools.
-    
-    ok markus@
-
-commit 0ef1de742be2ee4b10381193fe90730925b7f027
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Apr 23 05:01:19 2015 +0000
-
-    upstream commit
-    
-    Add a simple regression test for sshd's configuration
-     parser.  Right now, all it does is run the output of sshd -T back through
-     itself and ensure the output is valid and invariant.
-
-commit 368f83c793275faa2c52f60eaa9bdac155c4254b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Apr 22 01:38:36 2015 +0000
-
-    upstream commit
-    
-    use correct key for nested certificate test
-
-commit 8d4d1bfddbbd7d21f545dc6997081d1ea1fbc99a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 1 07:11:47 2015 +0000
-
-    upstream commit
-    
-    mention that the user's shell from /etc/passwd is used
-     for commands too; bz#1459 ok dtucker@
-
-commit 5ab283d0016bbc9d4d71e8e5284d011bc5a930cf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 07:29:00 2015 +0000
-
-    upstream commit
-    
-    whitespace
-    
-    Upstream-Regress-ID: 6b708a3e709d5b7fd37890f874bafdff1f597519
-
-commit 8377d5008ad260048192e1e56ad7d15a56d103dd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 07:26:13 2015 +0000
-
-    upstream commit
-    
-    whitespace at EOL
-    
-    Upstream-Regress-ID: 9c48911643d5b05173b36a012041bed4080b8554
-
-commit c28a3436fa8737709ea88e4437f8f23a6ab50359
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 06:45:13 2015 +0000
-
-    upstream commit
-    
-    moar whitespace at eol
-    
-    Upstream-ID: 64eaf872a3ba52ed41e494287e80d40aaba4b515
-
-commit 2b64c490468fd4ca35ac8d5cc31c0520dc1508bb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 06:41:56 2015 +0000
-
-    upstream commit
-    
-    whitespace at EOL
-    
-    Upstream-ID: 57bcf67d666c6fc1ad798aee448fdc3f70f7ec2c
-
-commit 4e636cf201ce6e7e3b9088568218f9d4e2c51712
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 03:56:51 2015 +0000
-
-    upstream commit
-    
-    whitespace at EOL
-
-commit 38b8272f823dc1dd4e29dbcee83943ed48bb12fa
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon May 4 01:47:53 2015 +0000
-
-    upstream commit
-    
-    Use diff w/out -u for better portability
-
-commit 297060f42d5189a4065ea1b6f0afdf6371fb0507
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri May 8 03:25:07 2015 +0000
-
-    upstream commit
-    
-    Use xcalloc for permitted_adm_opens instead of xmalloc to
-     ensure it's zeroed. Fixes post-auth crash with permitopen=none.  bz#2355, ok
-     djm@
-
-commit 63ebf019be863b2d90492a85e248cf55a6e87403
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri May 8 03:17:49 2015 +0000
-
-    upstream commit
-    
-    don't choke on new-format private keys encrypted with an
-     AEAD cipher; bz#2366, patch from Ron Frederick; ok markus@
-
-commit f8484dac678ab3098ae522a5f03bb2530f822987
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed May 6 05:45:17 2015 +0000
-
-    upstream commit
-    
-    Clarify pseudo-terminal request behaviour and use
-     "pseudo-terminal" consistently.  bz#1716, ok jmc@ "I like it" deraadt@.
-
-commit ea139507bef8bad26e86ed99a42c7233ad115c38
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed May 6 04:07:18 2015 +0000
-
-    upstream commit
-    
-    Blacklist DH-GEX for specific PuTTY versions known to
-     send non-RFC4419 DH-GEX messages rather than all versions of PuTTY.
-     According to Simon Tatham, 0.65 and newer versions will send RFC4419 DH-GEX
-     messages.  ok djm@
-
-commit b58234f00ee3872eb84f6e9e572a9a34e902e36e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue May 5 10:17:49 2015 +0000
-
-    upstream commit
-    
-    WinSCP doesn't implement RFC4419 DH-GEX so flag it so we
-     don't offer that KEX method.  ok markus@
-
-commit d5b1507a207253b39e810e91e68f9598691b7a29
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Tue May 5 02:48:17 2015 +0000
-
-    upstream commit
-    
-    use the sizeof the struct not the sizeof a pointer to the
-     struct in ssh_digest_start()
-    
-    This file is only used if ssh is built with OPENSSL=no
-    
-    ok markus@
-
-commit a647b9b8e616c231594b2710c925d31b1b8afea3
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri May 8 11:07:27 2015 +1000
-
-    Put brackets around mblen() compat constant.
-    
-    This might help with the reported problem cross compiling for Android
-    ("error: expected identifier or '(' before numeric constant") but
-    shouldn't hurt in any case.
-
-commit d1680d36e17244d9af3843aeb5025cb8e40d6c07
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Thu Apr 30 09:18:11 2015 +1000
-
-    xrealloc -> xreallocarray in portable code too.
-
-commit 531a57a3893f9fcd4aaaba8c312b612bbbcc021e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Apr 29 03:48:56 2015 +0000
-
-    upstream commit
-    
-    Allow ListenAddress, Port and AddressFamily in any
-     order.  bz#68, ok djm@, jmc@ (for the man page bit).
-
-commit c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Tue Apr 28 13:47:38 2015 +0000
-
-    upstream commit
-    
-    enviroment -> environment: apologies to darren for not
-     spotting that first time round...
-
-commit 43beea053db191cac47c2cd8d3dc1930158aff1a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Apr 28 10:25:15 2015 +0000
-
-    upstream commit
-    
-    Fix typo in previous
-
-commit 85b96ef41374f3ddc9139581f87da09b2cd9199e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Apr 28 10:17:58 2015 +0000
-
-    upstream commit
-    
-    Document that the TERM environment variable is not
-     subject to SendEnv and AcceptEnv.  bz#2386, based loosely on a patch from
-     jjelen at redhat, help and ok jmc@
-
-commit 88a7c598a94ff53f76df228eeaae238d2d467565
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Apr 27 21:42:48 2015 +0000
-
-    upstream commit
-    
-    Make sshd default to PermitRootLogin=no; ok deraadt@
-     rpe@
-
-commit 734226b4480a6c736096c729fcf6f391400599c7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Apr 27 01:52:30 2015 +0000
-
-    upstream commit
-    
-    fix compilation with OPENSSL=no; ok dtucker@
-
-commit a4b9d2ce1eb7703eaf0809b0c8a82ded8aa4f1c6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Mon Apr 27 00:37:53 2015 +0000
-
-    upstream commit
-    
-    Include stdio.h for FILE (used in sshkey.h) so it
-     compiles with OPENSSL=no.
-
-commit dbcc652f4ca11fe04e5930c7ef18a219318c6cda
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Apr 27 00:21:21 2015 +0000
-
-    upstream commit
-    
-    allow "sshd -f none" to skip reading the config file,
-     much like "ssh -F none" does. ok dtucker
-
-commit b7ca276fca316c952f0b90f5adb1448c8481eedc
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Fri Apr 24 06:26:49 2015 +0000
-
-    upstream commit
-    
-    combine -Dd onto one line and update usage();
-
-commit 2ea974630d7017e4c7666d14d9dc939707613e96
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 24 05:26:44 2015 +0000
-
-    upstream commit
-    
-    add ssh-agent -D to leave ssh-agent in foreground
-     without enabling debug mode; bz#2381 ok dtucker@
-
-commit 8ac2ffd7aa06042f6b924c87139f2fea5c5682f7
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Apr 24 01:36:24 2015 +0000
-
-    upstream commit
-    
-    2*len -> use xreallocarray() ok djm
-
-commit 657a5fbc0d0aff309079ff8fb386f17e964963c2
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date:   Fri Apr 24 01:36:00 2015 +0000
-
-    upstream commit
-    
-    rename xrealloc() to xreallocarray() since it follows
-     that form. ok djm
-
-commit 1108ae242fdd2c304307b68ddf46aebe43ebffaa
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Apr 23 04:59:10 2015 +0000
-
-    upstream commit
-    
-    Two small fixes for sshd -T: ListenAddress'es are added
-     to a list head so reverse the order when printing them to ensure the
-     behaviour remains the same, and print StreamLocalBindMask as octal with
-     leading zero.  ok deraadt@
-
-commit bd902b8473e1168f19378d5d0ae68d0c203525df
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Apr 23 04:53:53 2015 +0000
-
-    upstream commit
-    
-    Check for and reject missing arguments for
-     VersionAddendum and ForceCommand. bz#2281, patch from plautrba at redhat com,
-     ok djm@
-
-commit ca42c1758575e592239de1d5755140e054b91a0d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Apr 22 01:24:01 2015 +0000
-
-    upstream commit
-    
-    unknown certificate extensions are non-fatal, so don't
-     fatal when they are encountered; bz#2387 reported by Bob Van Zant; ok
-     dtucker@
-
-commit 39bfbf7caad231cc4bda6909fb1af0705bca04d8
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Tue Apr 21 07:01:00 2015 +0000
-
-    upstream commit
-    
-    Add back a backslash removed in rev 1.42 so
-     KEX_SERVER_ENCRYPT will include aes again.
-    
-    ok deraadt@
-
-commit 6b0d576bb87eca3efd2b309fcfe4edfefc289f9c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 17 13:32:09 2015 +0000
-
-    upstream commit
-    
-    s/recommended/required/ that private keys be og-r this
-     wording change was made a while ago but got accidentally reverted
-
-commit 44a8e7ce6f3ab4c2eb1ae49115c210b98e53c4df
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 17 13:25:52 2015 +0000
-
-    upstream commit
-    
-    don't try to cleanup NULL KEX proposals in
-     kex_prop_free(); found by Jukka Taimisto and Markus Hietava
-
-commit 3038a191872d2882052306098c1810d14835e704
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 17 13:19:22 2015 +0000
-
-    upstream commit
-    
-    use error/logit/fatal instead of fprintf(stderr, ...)
-     and exit(0), fix a few errors that were being printed to stdout instead of
-     stderr and a few non-errors that were going to stderr instead of stdout
-     bz#2325; ok dtucker
-
-commit a58be33cb6cd24441fa7e634db0e5babdd56f07f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 17 13:16:48 2015 +0000
-
-    upstream commit
-    
-    debug log missing DISPLAY environment when X11
-     forwarding requested; bz#1682 ok dtucker@
-
-commit 17d4d9d9fbc8fb80e322f94d95eecc604588a474
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 17 04:32:31 2015 +0000
-
-    upstream commit
-    
-    don't call record_login() in monitor when UseLogin is
-     enabled; bz#278 reported by drk AT sgi.com; ok dtucker
-
-commit 40132ff87b6cbc3dc05fb5df2e9d8e3afa06aafd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Apr 17 04:12:35 2015 +0000
-
-    upstream commit
-    
-    Add some missing options to sshd -T and fix the output
-     of VersionAddendum HostCertificate.  bz#2346, patch from jjelen at redhat
-     com, ok djm.
-
-commit 6cc7cfa936afde2d829e56ee6528c7ea47a42441
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Thu Apr 16 23:25:50 2015 +0000
-
-    upstream commit
-    
-    Document "none" for PidFile XAuthLocation
-     TrustedUserCAKeys and RevokedKeys. bz#2382, feedback from jmc@, ok djm@
-
-commit 15fdfc9b1c6808b26bc54d4d61a38b54541763ed
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Wed Apr 15 23:23:25 2015 +0000
-
-    upstream commit
-    
-    Plug leak of address passed to logging.  bz#2373, patch
-     from jjelen at redhat, ok markus@
-
-commit bb2289e2a47d465eaaaeff3dee2a6b7777b4c291
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Tue Apr 14 04:17:03 2015 +0000
-
-    upstream commit
-    
-    Output remote username in debug output since with Host
-     and Match it's not always obvious what it will be.  bz#2368, ok djm@
-
-commit 70860b6d07461906730632f9758ff1b7c98c695a
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Apr 17 10:56:13 2015 +1000
-
-    Format UsePAM setting when using sshd -T.
-    
-    Part of bz#2346, patch from jjelen at redhat com.
-
-commit ee15d9c9f0720f5a8b0b34e4b10ecf21f9824814
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Apr 17 10:40:23 2015 +1000
-
-    Wrap endian.h include inside ifdef (bz#2370).
-
-commit 408f4c2ad4a4c41baa7b9b2b7423d875abbfa70b
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Fri Apr 17 09:39:58 2015 +1000
-
-    Look for '${host}-ar' before 'ar'.
-    
-    This changes configure.ac to look for '${host}-ar' as set by
-    AC_CANONICAL_HOST before looking for the unprefixed 'ar'.
-    Useful when cross-compiling when all your binutils are prefixed.
-    
-    Patch from moben at exherbo org via astrand at lysator liu se and
-    bz#2352.
-
-commit 673a1c16ad078d41558247ce739fe812c960acc8
-Author: Damien Miller <djm@google.com>
-Date:   Thu Apr 16 11:40:20 2015 +1000
-
-    remove dependency on arpa/telnet.h
-
-commit 202d443eeda1829d336595a3cfc07827e49f45ed
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Wed Apr 15 15:59:49 2015 +1000
-
-    Remove duplicate include of pwd.h.  bz#2337, patch from Mordy Ovits.
-
-commit 597986493412c499f2bc2209420cb195f97b3668
-Author: Damien Miller <djm@google.com>
-Date:   Thu Apr 9 10:14:48 2015 +1000
-
-    platform's with openpty don't need pty_release
-
-commit 318be28cda1fd9108f2e6f2f86b0b7589ba2aed0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Apr 13 02:04:08 2015 +0000
-
-    upstream commit
-    
-    deprecate ancient, pre-RFC4419 and undocumented
-     SSH2_MSG_KEX_DH_GEX_REQUEST_OLD message; ok markus@ deraadt@ "seems
-     reasonable" dtucker@
-
-commit d8f391caef62378463a0e6b36f940170dadfe605
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date:   Fri Apr 10 05:16:50 2015 +0000
-
-    upstream commit
-    
-    Don't send hostkey advertisments
-     (hostkeys-00@openssh.com) to current versions of Tera Term as they can't
-     handle them.  Newer versions should be OK.  Patch from Bryan Drewery and
-     IWAMOTO Kouichi, ok djm@
-
-commit 2c2cfe1a1c97eb9a08cc9817fd0678209680c636
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 10 00:08:55 2015 +0000
-
-    upstream commit
-    
-    include port number if a non-default one has been
-     specified; based on patch from Michael Handler
-
-commit 4492a4f222da4cf1e8eab12689196322e27b08c4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Apr 7 23:00:42 2015 +0000
-
-    upstream commit
-    
-    treat Protocol=1,2|2,1 as Protocol=2 when compiled
-     without SSH1 support; ok dtucker@ millert@
-
-commit c265e2e6e932efc6d86f6cc885dea33637a67564
-Author: miod@openbsd.org <miod@openbsd.org>
-Date:   Sun Apr 5 15:43:43 2015 +0000
-
-    upstream commit
-    
-    Do not use int for sig_atomic_t; spotted by
-     christos@netbsd; ok markus@
-
-commit e7bf3a5eda6a1b02bef6096fed78527ee11e54cc
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Apr 7 10:48:04 2015 +1000
-
-    Use do{}while(0) for no-op functions.
-    
-    From FreeBSD.
-
-commit bb99844abae2b6447272f79e7fa84134802eb4df
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Apr 7 10:47:15 2015 +1000
-
-    Wrap blf.h include in ifdef.  From FreeBSD.
-
-commit d9b9b43656091cf0ad55c122f08fadb07dad0abd
-Author: Darren Tucker <dtucker@zip.com.au>
-Date:   Tue Apr 7 09:10:00 2015 +1000
-
-    Fix misspellings of regress CONFOPTS env variables.
-    
-    Patch from Bryan Drewery.
-
-commit 3f4ea3c9ab1d32d43c9222c4351f58ca11144156
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Fri Apr 3 22:17:27 2015 +0000
-
-    upstream commit
-    
-    correct return value in pubkey parsing, spotted by Ben Hawkes
-     ok markus@
-
-commit 7da2be0cb9601ed25460c83aa4d44052b967ba0f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 31 22:59:01 2015 +0000
-
-    upstream commit
-    
-    adapt to recent hostfile.c change: when parsing
-     known_hosts without fully parsing the keys therein, hostkeys_foreach() will
-     now correctly identify KEY_RSA1 keys; ok markus@ miod@
-
-commit 9e1777a0d1c706714b055811c12ab8cc21033e4a
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Mar 24 20:19:15 2015 +0000
-
-    upstream commit
-    
-    use ${SSH} for -Q instead of installed ssh
-
-commit ce1b358ea414a2cc88e4430cd5a2ea7fecd9de57
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 16 22:46:14 2015 +0000
-
-    upstream commit
-    
-    make CLEANFILES clean up more of the tests' droppings
-
-commit 398f9ef192d820b67beba01ec234d66faca65775
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 31 22:57:06 2015 +0000
-
-    upstream commit
-    
-    downgrade error() for known_hosts parse errors to debug()
-     to quiet warnings from ssh1 keys present when compiled !ssh1.
-    
-    also identify ssh1 keys when scanning, even when compiled !ssh1
-    
-    ok markus@ miod@
-
-commit 9a47ab80030a31f2d122b8fd95bd48c408b9fcd9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 31 22:55:50 2015 +0000
-
-    upstream commit
-    
-    fd leak for !ssh1 case; found by unittests; ok markus@
-
-commit c9a0805a6280681901c270755a7cd630d7c5280e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 31 22:55:24 2015 +0000
-
-    upstream commit
-    
-    don't fatal when a !ssh1 sshd is reexeced from a w/ssh1
-     listener; reported by miod@; ok miod@ markus@
-
-commit 704d8c88988cae38fb755a6243b119731d223222
-Author: tobias@openbsd.org <tobias@openbsd.org>
-Date:   Tue Mar 31 11:06:49 2015 +0000
-
-    upstream commit
-    
-    Comments are only supported for RSA1 keys. If a user
-     tried to add one and entered his passphrase, explicitly clear it before exit.
-     This is done in all other error paths, too.
-    
-    ok djm
-
-commit 78de1673c05ea2c33e0d4a4b64ecb5186b6ea2e9
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date:   Mon Mar 30 18:28:37 2015 +0000
-
-    upstream commit
-    
-    ssh-askpass(1) is the default, overridden by SSH_ASKPASS;
-     diff originally from jiri b;
-
-commit 26e0bcf766fadb4a44fb6199386fb1dcab65ad00
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 30 00:00:29 2015 +0000
-
-    upstream commit
-    
-    fix uninitialised memory read when parsing a config file
-     consisting of a single nul byte. Found by hanno AT hboeck.de using AFL; ok
-     dtucker
-
-commit fecede00a76fbb33a349f5121c0b2f9fbc04a777
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Thu Mar 26 19:32:19 2015 +0000
-
-    upstream commit
-    
-    sigp and lenp are not optional in ssh_agent_sign(); ok
-     djm@
-
-commit 1b0ef3813244c78669e6d4d54c624f600945327d
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date:   Thu Mar 26 12:32:38 2015 +0000
-
-    upstream commit
-    
-    don't try to load .ssh/identity by default if SSH1 is
-     disabled; ok markus@
-
-commit f9b78852379b74a2d14e6fc94fe52af30b7e9c31
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Mar 26 07:00:04 2015 +0000
-
-    upstream commit
-    
-    ban all-zero curve25519 keys as recommended by latest
-     CFRG curves draft; ok markus
-
-commit b8afbe2c1aaf573565e4da775261dfafc8b1ba9c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Thu Mar 26 06:59:28 2015 +0000
-
-    upstream commit
-    
-    relax bits needed check to allow
-     diffie-hellman-group1-sha1 key exchange to complete for chacha20-poly1305 was
-     selected as symmetric cipher; ok markus
-
-commit 47842f71e31da130555353c1d57a1e5a8937f1c0
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Mar 25 19:29:58 2015 +0000
-
-    upstream commit
-    
-    ignore v1 errors on ssh-add -D; only try v2 keys on
-     -l/-L (unless WITH_SSH1) ok djm@
-
-commit 5f57e77f91bf2230c09eca96eb5ecec39e5f2da6
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Wed Mar 25 19:21:48 2015 +0000
-
-    upstream commit
-    
-    unbreak ssh_agent_sign (lenp vs *lenp)
-
-commit 4daeb67181054f2a377677fac919ee8f9ed3490e
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Mar 24 20:10:08 2015 +0000
-
-    upstream commit
-    
-    don't leak 'setp' on error; noted by Nicholas Lemonias;
-     ok djm@
-
-commit 7d4f96f9de2a18af0d9fa75ea89a4990de0344f5
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Mar 24 20:09:11 2015 +0000
-
-    upstream commit
-    
-    consistent check for NULL as noted by Nicholas
-     Lemonias; ok djm@
-
-commit df100be51354e447d9345cf1ec22e6013c0eed50
-Author: markus@openbsd.org <markus@openbsd.org>
-Date:   Tue Mar 24 20:03:44 2015 +0000
-
-    upstream commit
-    
-    correct fmt-string for size_t as noted by Nicholas
-     Lemonias; ok djm@
-
-commit a22b9ef21285e81775732436f7c84a27bd3f71e0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 24 09:17:21 2015 +0000
-
-    upstream commit
-    
-    promote chacha20-poly1305@openssh.com to be the default
-     cipher; ok markus
-
-commit 2aa9da1a3b360cf7b13e96fe1521534b91501fb5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 24 01:29:19 2015 +0000
-
-    upstream commit
-    
-    Compile-time disable SSH protocol 1. You can turn it
-     back on using the Makefile.inc knob if you need it to talk to ancient
-     devices.
-
-commit 53097b2022154edf96b4e8526af5666f979503f7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Tue Mar 24 01:11:12 2015 +0000
-
-    upstream commit
-    
-    fix double-negative error message "ssh1 is not
-     unsupported"
-
-commit 5c27e3b6ec2db711dfcd40e6359c0bcdd0b62ea9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 23 06:06:38 2015 +0000
-
-    upstream commit
-    
-    for ssh-keygen -A, don't try (and fail) to generate ssh
-     v.1 keys when compiled without SSH1 support RSA/DSA/ECDSA keys when compiled
-     without OpenSSL based on patch by Mike Frysinger; bz#2369
-
-commit 725fd22a8c41db7de73a638539a5157b7e4424ae
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Wed Mar 18 01:44:21 2015 +0000
-
-    upstream commit
-    
-    KRL support doesn't need OpenSSL anymore, remove #ifdefs
-     from around call
-
-commit b07011c18e0b2e172c5fd09d21fb159a0bf5fcc7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date:   Mon Mar 16 11:09:52 2015 +0000
-
-    upstream commit
-    
-    #if 0 some more arrays used only for decrypting (we don't
-     use since we only need encrypt for AES-CTR)
-
-commit 1cb3016635898d287e9d58b50c430995652d5358
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date:   Wed Mar 11 00:48:39 2015 +0000
-
-    upstream commit
-    
-    add back the changes from rev 1.206, djm reverted this by
-     mistake in rev 1.207
diff -ruN openssh-7.5p1/channels.c openssh-7.5p1+x509-10.2/channels.c
--- openssh-7.5p1/channels.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/channels.c	2017-05-20 21:07:01.000000000 +0300
@@ -2265,7 +2265,7 @@
 	n = MAXIMUM(*maxfdp, channel_max_fd);
 
 	nfdset = howmany(n+1, NFDBITS);
-	/* Explicitly test here, because xrealloc isn't always called */
+	/* Explicitly test here, because xreallocarray isn't always called */
 	if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask))
 		fatal("channel_prepare_select: max_fd (%d) is too large", n);
 	sz = nfdset * sizeof(fd_mask);
@@ -3806,6 +3806,45 @@
 }
 
 /*
+ * This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
+ * listening for the port, and sends back a success reply (or disconnect
+ * message if there was an error).
+ */
+int
+channel_input_port_forward_request(int is_root, struct ForwardOptions *fwd_opts)
+{
+	int success = 0;
+	struct Forward fwd;
+
+	/* Get arguments from the packet. */
+	memset(&fwd, 0, sizeof(fwd));
+	fwd.listen_port = packet_get_int();
+	fwd.connect_host = packet_get_string(NULL);
+	fwd.connect_port = packet_get_int();
+
+#ifndef HAVE_CYGWIN
+	/*
+	 * Check that an unprivileged user is not trying to forward a
+	 * privileged port.
+	 */
+	if (fwd.listen_port < IPPORT_RESERVED && !is_root)
+		packet_disconnect(
+		    "Requested forwarding of port %d but user is not root.",
+		    fwd.listen_port);
+	if (fwd.connect_port == 0)
+		packet_disconnect("Dynamic forwarding denied.");
+#endif
+
+	/* Initiate forwarding */
+	success = channel_setup_local_fwd_listener(&fwd, fwd_opts);
+
+	/* Free the argument string. */
+	free(fwd.connect_host);
+
+	return (success ? 0 : -1);
+}
+
+/*
  * Permits opening to any host/port if permitted_opens[] is empty.  This is
  * usually called by the server, because the user could connect to any port
  * anyway, and the server has no way to know but to trust the client anyway.
diff -ruN openssh-7.5p1/channels.h openssh-7.5p1+x509-10.2/channels.h
--- openssh-7.5p1/channels.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/channels.h	2017-05-20 21:07:00.000000000 +0300
@@ -275,6 +275,7 @@
 void	 channel_clear_permitted_opens(void);
 void	 channel_clear_adm_permitted_opens(void);
 void 	 channel_print_adm_permitted_opens(void);
+int      channel_input_port_forward_request(int, struct ForwardOptions *);
 Channel	*channel_connect_to_port(const char *, u_short, char *, char *, int *,
 	     const char **);
 Channel *channel_connect_to_path(const char *, char *, char *);
diff -ruN openssh-7.5p1/cipher-3des1.c openssh-7.5p1+x509-10.2/cipher-3des1.c
--- openssh-7.5p1/cipher-3des1.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/cipher-3des1.c	2017-05-20 21:07:01.000000000 +0300
@@ -22,6 +22,9 @@
 
 #ifdef WITH_SSH1
 
+#include "openbsd-compat/openssl-compat.h"
+#include "evp-compat.h"
+
 #include <sys/types.h>
 #include <string.h>
 #include <openssl/evp.h>
@@ -44,7 +47,7 @@
  */
 struct ssh1_3des_ctx
 {
-	EVP_CIPHER_CTX	k1, k2, k3;
+	EVP_CIPHER_CTX	*k1, *k2, *k3;
 };
 
 const EVP_CIPHER * evp_ssh1_3des(void);
@@ -65,7 +68,7 @@
 	if (key == NULL)
 		return 1;
 	if (enc == -1)
-		enc = ctx->encrypt;
+		enc = EVP_CIPHER_CTX_encrypting(ctx);
 	k1 = k2 = k3 = (u_char *) key;
 	k2 += 8;
 	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
@@ -74,12 +77,12 @@
 		else
 			k1 += 16;
 	}
-	EVP_CIPHER_CTX_init(&c->k1);
-	EVP_CIPHER_CTX_init(&c->k2);
-	EVP_CIPHER_CTX_init(&c->k3);
-	if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
-	    EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
-	    EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
+	c->k1 = EVP_CIPHER_CTX_new();
+	c->k2 = EVP_CIPHER_CTX_new();
+	c->k3 = EVP_CIPHER_CTX_new();
+	if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
+	    EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
+	    EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
 		explicit_bzero(c, sizeof(*c));
 		free(c);
 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
@@ -95,9 +98,9 @@
 
 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
 		return 0;
-	if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
-	    EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
-	    EVP_Cipher(&c->k3, dest, dest, len) == 0)
+	if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
+	    EVP_Cipher(c->k2, dest, dest, len) == 0 ||
+	    EVP_Cipher(c->k3, dest, dest, len) == 0)
 		return 0;
 	return 1;
 }
@@ -108,9 +111,9 @@
 	struct ssh1_3des_ctx *c;
 
 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-		EVP_CIPHER_CTX_cleanup(&c->k1);
-		EVP_CIPHER_CTX_cleanup(&c->k2);
-		EVP_CIPHER_CTX_cleanup(&c->k3);
+		EVP_CIPHER_CTX_free(c->k1); c->k1 = NULL;
+		EVP_CIPHER_CTX_free(c->k2); c->k2 = NULL;
+		EVP_CIPHER_CTX_free(c->k3); c->k3 = NULL;
 		explicit_bzero(c, sizeof(*c));
 		free(c);
 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
@@ -128,13 +131,13 @@
 	if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
 		return SSH_ERR_INTERNAL_ERROR;
 	if (doset) {
-		memcpy(c->k1.iv, iv, 8);
-		memcpy(c->k2.iv, iv + 8, 8);
-		memcpy(c->k3.iv, iv + 16, 8);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv     , 8);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8 , 8);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
 	} else {
-		memcpy(iv, c->k1.iv, 8);
-		memcpy(iv + 8, c->k2.iv, 8);
-		memcpy(iv + 16, c->k3.iv, 8);
+		memcpy(iv     , EVP_CIPHER_CTX_iv(c->k1), 8);
+		memcpy(iv + 8 , EVP_CIPHER_CTX_iv(c->k2), 8);
+		memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
 	}
 	return 0;
 }
@@ -142,17 +145,17 @@
 const EVP_CIPHER *
 evp_ssh1_3des(void)
 {
-	static EVP_CIPHER ssh1_3des;
+	static EVP_CIPHER *ssh1_3des = NULL;
+
+	if (ssh1_3des != NULL) return ssh1_3des;
+
+	ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16);
+
+	(void) EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init);
+	(void) EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup);
+	(void) EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc);
+	(void) EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
 
-	memset(&ssh1_3des, 0, sizeof(ssh1_3des));
-	ssh1_3des.nid = NID_undef;
-	ssh1_3des.block_size = 8;
-	ssh1_3des.iv_len = 0;
-	ssh1_3des.key_len = 16;
-	ssh1_3des.init = ssh1_3des_init;
-	ssh1_3des.cleanup = ssh1_3des_cleanup;
-	ssh1_3des.do_cipher = ssh1_3des_cbc;
-	ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
-	return &ssh1_3des;
+	return ssh1_3des;
 }
 #endif /* WITH_SSH1 */
diff -ruN openssh-7.5p1/cipher-bf1.c openssh-7.5p1+x509-10.2/cipher-bf1.c
--- openssh-7.5p1/cipher-bf1.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/cipher-bf1.c	2017-05-20 21:07:01.000000000 +0300
@@ -31,6 +31,7 @@
 #include <openssl/evp.h>
 
 #include "openbsd-compat/openssl-compat.h"
+#include "evp-compat.h"
 
 /*
  * SSH1 uses a variation on Blowfish, all bytes must be swapped before
@@ -89,17 +90,19 @@
 const EVP_CIPHER *
 evp_ssh1_bf(void)
 {
-	static EVP_CIPHER ssh1_bf;
+	static EVP_CIPHER *ssh1_bf = NULL;
 
-	memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
-	orig_bf = ssh1_bf.do_cipher;
-	ssh1_bf.nid = NID_undef;
+	if (ssh1_bf != NULL) return ssh1_bf;
+
+	ssh1_bf = EVP_CIPHER_meth_dup(EVP_bf_cbc());
+
+	orig_bf = EVP_CIPHER_meth_get_do_cipher(ssh1_bf);
 #ifdef SSH_OLD_EVP
-	ssh1_bf.init = bf_ssh1_init;
+	(void) EVP_CIPHER_meth_set_init(ssh1_bf, bf_ssh1_init);
 #endif
-	ssh1_bf.do_cipher = bf_ssh1_cipher;
-	ssh1_bf.key_len = 32;
-	return (&ssh1_bf);
+	(void) EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_cipher);
+
+	return ssh1_bf;
 }
 #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */
 
diff -ruN openssh-7.5p1/cipher.c openssh-7.5p1+x509-10.2/cipher.c
--- openssh-7.5p1/cipher.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/cipher.c	2017-05-20 21:07:01.000000000 +0300
@@ -13,6 +13,7 @@
  *
  * Copyright (c) 1999 Niels Provos.  All rights reserved.
  * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,11 +46,23 @@
 
 #include "cipher.h"
 #include "misc.h"
+#include "xmalloc.h"
+#include "log.h"
 #include "sshbuf.h"
 #include "ssherr.h"
 #include "digest.h"
 
 #include "openbsd-compat/openssl-compat.h"
+#include "evp-compat.h"
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
+/* TODO: OpenSSL 1.1 resets EVP_CIPHER_CTX on each call of
+ * EVP_CipherInit - it is init function ;)!
+ * Lets use single init before to be fixed in OpenSSH.
+ */
+#  define SINGLE_EVP_CIPHERINIT_CALL
+#endif
+
 
 #ifdef WITH_SSH1
 extern const EVP_CIPHER *evp_ssh1_bf(void);
@@ -138,6 +151,23 @@
 
 /*--*/
 
+static inline int/*bool*/
+cipher_allowed(const struct sshcipher *c) {
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		const EVP_CIPHER *evp = NULL;
+		if (c->evptype == NULL) return(0);
+		evp = c->evptype();
+		if (evp == NULL) return(0);
+		if ((EVP_CIPHER_flags(evp) & EVP_CIPH_FLAG_FIPS) == 0)
+			return(0);
+	}
+#else
+	(void) c;
+#endif
+	return(1);
+}
+
 /* Returns a comma-separated list of supported ciphers. */
 char *
 cipher_alg_list(char sep, int auth_only)
@@ -151,6 +181,8 @@
 			continue;
 		if (auth_only && c->auth_len == 0)
 			continue;
+		if (!cipher_allowed(c))
+			continue;
 		if (ret != NULL)
 			ret[rlen++] = sep;
 		nlen = strlen(c->name);
@@ -244,7 +276,11 @@
 	const struct sshcipher *c;
 	for (c = ciphers; c->name != NULL; c++)
 		if (strcmp(c->name, name) == 0)
+		{
+			if (!cipher_allowed(c))
+				continue;
 			return c;
+		}
 	return NULL;
 }
 
@@ -254,7 +290,11 @@
 	const struct sshcipher *c;
 	for (c = ciphers; c->name != NULL; c++)
 		if (c->number == id)
+		{
+			if (!cipher_allowed(c))
+				continue;
 			return c;
+		}
 	return NULL;
 }
 
@@ -282,6 +322,41 @@
 	return 1;
 }
 
+#ifdef OPENSSL_FIPS
+char*
+only_fips_valid_ciphers(const char* names)
+{
+	Buffer b;
+	char *fips_names, *cp, *p;
+
+	if (names == NULL || *names == '\0')
+		return NULL;
+
+	buffer_init(&b);
+
+	/* default set in myproposals.h */
+	cp = xstrdup(names);
+	for (p = strsep(&cp, CIPHER_SEP);
+	     p && *p != '\0';
+	     p = strsep(&cp, CIPHER_SEP)
+	) {
+		if (cipher_by_name(p) == NULL) continue;
+
+		if (buffer_len(&b) > 0)
+			buffer_append(&b, ",", 1);
+		buffer_append(&b, p, strlen(p));
+	}
+	buffer_append(&b, "\0", 1);
+
+	fips_names = xstrdup(buffer_ptr(&b));
+
+	buffer_free(&b);
+
+	debug3("%s: ciphers: [%s]", __func__, fips_names);
+	return fips_names;
+}
+#endif
+
 /*
  * Parses the name of the cipher.  Returns the number of the corresponding
  * cipher, or -1 on error.
@@ -295,7 +370,11 @@
 		return -1;
 	for (c = ciphers; c->name != NULL; c++)
 		if (strcasecmp(c->name, name) == 0)
+		{
+			if (!cipher_allowed(c))
+				continue;
 			return c->number;
+		}
 	return -1;
 }
 
@@ -372,7 +451,11 @@
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
+#ifndef SINGLE_EVP_CIPHERINIT_CALL
 	if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
+#else
+	if (EVP_CipherInit(cc->evp, type, key, (u_char *)iv,
+#endif /*ndef SINGLE_EVP_CIPHERINIT_CALL*/
 	    (do_encrypt == CIPHER_ENCRYPT)) == 0) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
@@ -390,10 +473,12 @@
 			goto out;
 		}
 	}
+#ifndef SINGLE_EVP_CIPHERINIT_CALL
 	if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
+#endif /*ndef SINGLE_EVP_CIPHERINIT_CALL*/
 
 	if (cipher->discard_len > 0) {
 		if ((junk = malloc(cipher->discard_len)) == NULL ||
@@ -420,8 +505,8 @@
 	} else {
 		if (cc != NULL) {
 #ifdef WITH_OPENSSL
-			if (cc->evp != NULL)
-				EVP_CIPHER_CTX_free(cc->evp);
+			EVP_CIPHER_CTX_free(cc->evp);
+			cc->evp = NULL;
 #endif /* WITH_OPENSSL */
 			explicit_bzero(cc, sizeof(*cc));
 			free(cc);
@@ -526,10 +611,8 @@
 	else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
 		explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
 #ifdef WITH_OPENSSL
-	if (cc->evp != NULL) {
-		EVP_CIPHER_CTX_free(cc->evp);
-		cc->evp = NULL;
-	}
+	EVP_CIPHER_CTX_free(cc->evp);
+	cc->evp = NULL;
 #endif
 	explicit_bzero(cc, sizeof(*cc));
 	free(cc);
@@ -625,7 +708,7 @@
 			   len, iv))
 			       return SSH_ERR_LIBCRYPTO_ERROR;
 		} else
-			memcpy(iv, cc->evp->iv, len);
+			memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
 		break;
 #endif
 #ifdef WITH_SSH1
@@ -671,7 +754,7 @@
 			    EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
 				return SSH_ERR_LIBCRYPTO_ERROR;
 		} else
-			memcpy(cc->evp->iv, iv, evplen);
+			memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen);
 		break;
 #endif
 #ifdef WITH_SSH1
@@ -685,8 +768,8 @@
 }
 
 #ifdef WITH_OPENSSL
-#define EVP_X_STATE(evp)	(evp)->cipher_data
-#define EVP_X_STATE_LEN(evp)	(evp)->cipher->ctx_size
+#define EVP_X_STATE(evp)	EVP_CIPHER_CTX_get_cipher_data(evp)
+#define EVP_X_STATE_LEN(evp)	EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp))
 #endif
 
 int
diff -ruN openssh-7.5p1/cipher-ctr.c openssh-7.5p1+x509-10.2/cipher-ctr.c
--- openssh-7.5p1/cipher-ctr.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/cipher-ctr.c	2017-05-20 21:07:01.000000000 +0300
@@ -138,6 +138,9 @@
 	aes_ctr.do_cipher = ssh_aes_ctr;
 #ifndef SSH_OLD_EVP
 	aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
+#ifdef EVP_CIPH_FLAG_FIPS
+	    EVP_CIPH_FLAG_FIPS |
+#endif
 	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
 #endif
 	return (&aes_ctr);
diff -ruN openssh-7.5p1/cipher.h openssh-7.5p1+x509-10.2/cipher.h
--- openssh-7.5p1/cipher.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/cipher.h	2017-05-20 21:07:00.000000000 +0300
@@ -12,6 +12,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  *
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -73,6 +74,9 @@
 const char *cipher_warning_message(const struct sshcipher_ctx *);
 int	 ciphers_valid(const char *);
 char	*cipher_alg_list(char, int);
+#ifdef OPENSSL_FIPS
+extern char*	only_fips_valid_ciphers(const char*);
+#endif
 int	 cipher_init(struct sshcipher_ctx **, const struct sshcipher *,
     const u_char *, u_int, const u_char *, u_int, int);
 int	 cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
diff -ruN openssh-7.5p1/clientloop.c openssh-7.5p1+x509-10.2/clientloop.c
--- openssh-7.5p1/clientloop.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/clientloop.c	2017-05-20 21:07:01.000000000 +0300
@@ -38,6 +38,9 @@
  * SSH2 support added by Markus Friedl.
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -92,11 +95,10 @@
 #include "ssh1.h"
 #include "ssh2.h"
 #include "packet.h"
-#include "buffer.h"
+#include "ssh-x509.h"
 #include "compat.h"
 #include "channels.h"
 #include "dispatch.h"
-#include "key.h"
 #include "cipher.h"
 #include "kex.h"
 #include "myproposal.h"
@@ -2185,6 +2187,7 @@
 	 * keys_seen is filled in by hostkeys_find() and later (for new
 	 * keys) by client_global_hostkeys_private_confirm().
 	 */
+	char **algs;
 	struct sshkey **keys;
 	int *keys_seen;
 	size_t nkeys;
@@ -2208,6 +2211,9 @@
 	if (ctx == NULL)
 		return;
 	for (i = 0; i < ctx->nkeys; i++)
+		free(ctx->algs[i]);
+	free(ctx->algs);
+	for (i = 0; i < ctx->nkeys; i++)
 		sshkey_free(ctx->keys[i]);
 	free(ctx->keys);
 	free(ctx->keys_seen);
@@ -2352,15 +2358,18 @@
 	 * ctx->keys where the corresponding ctx->keys_seen[i] == 0.
 	 */
 	for (ndone = i = 0; i < ctx->nkeys; i++) {
+		const char *pkalg;
 		if (ctx->keys_seen[i])
 			continue;
+
+		pkalg = sshkey_ssh_name(ctx->keys[i]);
 		/* Prepare data to be signed: session ID, unique string, key */
 		sshbuf_reset(signdata);
 		if ( (r = sshbuf_put_cstring(signdata,
 		    "hostkeys-prove-00@openssh.com")) != 0 ||
 		    (r = sshbuf_put_string(signdata, ssh->kex->session_id,
 		    ssh->kex->session_id_len)) != 0 ||
-		    (r = sshkey_puts(ctx->keys[i], signdata)) != 0)
+		    (r = Xkey_puts(pkalg, ctx->keys[i], signdata)) != 0)
 			fatal("%s: failed to prepare signature: %s",
 			    __func__, ssh_err(r));
 		/* Extract and verify signature */
@@ -2369,12 +2378,16 @@
 			    __func__, ssh_err(r));
 			goto out;
 		}
-		if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
-		    sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) {
+	{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_verify compat */
+		ssh_sign_ctx verify_ctx = { pkalg, ctx->keys[i], &ctx_compat };
+
+		r = Xkey_verify(&verify_ctx, sig, siglen, sshbuf_ptr(signdata), sshbuf_len(signdata));
+		if (r != 0) {
 			error("%s: server gave bad signature for %s key %zu",
 			    __func__, sshkey_type(ctx->keys[i]), i);
 			goto out;
 		}
+	}
 		/* Key is good. Mark it as 'seen' */
 		ctx->keys_seen[i] = 2;
 		ndone++;
@@ -2391,26 +2404,6 @@
 }
 
 /*
- * Returns non-zero if the key is accepted by HostkeyAlgorithms.
- * Made slightly less trivial by the multiple RSA signature algorithm names.
- */
-static int
-key_accepted_by_hostkeyalgs(const struct sshkey *key)
-{
-	const char *ktype = sshkey_ssh_name(key);
-	const char *hostkeyalgs = options.hostkeyalgorithms != NULL ?
-	    options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG;
-
-	if (key == NULL || key->type == KEY_UNSPEC)
-		return 0;
-	if (key->type == KEY_RSA &&
-	    (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 ||
-	    match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1))
-		return 1;
-	return match_pattern_list(ktype, hostkeyalgs, 0) == 1;
-}
-
-/*
  * Handle hostkeys-00@openssh.com global request to inform the client of all
  * the server's hostkeys. The keys are checked against the user's
  * HostkeyAlgorithms preference before they are accepted.
@@ -2423,6 +2416,7 @@
 	size_t i, len = 0;
 	struct sshbuf *buf = NULL;
 	struct sshkey *key = NULL, **tmp;
+	char *pkalg = NULL, **algtmp;
 	int r;
 	char *fp;
 	static int hostkeys_seen = 0; /* XXX use struct ssh */
@@ -2441,12 +2435,14 @@
 	while (ssh_packet_remaining(ssh) > 0) {
 		sshkey_free(key);
 		key = NULL;
+		free(pkalg);
+		pkalg = NULL;
 		if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) {
 			error("%s: couldn't parse message: %s",
 			    __func__, ssh_err(r));
 			goto out;
 		}
-		if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
+		if ((r = parse_key_from_blob(blob, len, &key, &pkalg)) != 0) {
 			error("%s: parse key: %s", __func__, ssh_err(r));
 			goto out;
 		}
@@ -2456,22 +2452,25 @@
 		    sshkey_type(key), fp);
 		free(fp);
 
-		if (!key_accepted_by_hostkeyalgs(key)) {
+		/* Check that the key is accepted in HostkeyAlgorithms */
+		if (match_pattern_list(pkalg,
+		    options.hostkeyalgorithms ? options.hostkeyalgorithms :
+		    KEX_DEFAULT_PK_ALG, 0) != 1) {
 			debug3("%s: %s key not permitted by HostkeyAlgorithms",
-			    __func__, sshkey_ssh_name(key));
+			    __func__, pkalg);
 			continue;
 		}
 		/* Skip certs */
 		if (sshkey_is_cert(key)) {
 			debug3("%s: %s key is a certificate; skipping",
-			    __func__, sshkey_ssh_name(key));
+			    __func__, pkalg);
 			continue;
 		}
 		/* Ensure keys are unique */
 		for (i = 0; i < ctx->nkeys; i++) {
 			if (sshkey_equal(key, ctx->keys[i])) {
 				error("%s: received duplicated %s host key",
-				    __func__, sshkey_ssh_name(key));
+				    __func__, pkalg);
 				goto out;
 			}
 		}
@@ -2480,6 +2479,13 @@
 		    sizeof(*ctx->keys))) == NULL)
 			fatal("%s: reallocarray failed nkeys = %zu",
 			    __func__, ctx->nkeys);
+		algtmp = reallocarray(ctx->algs, ctx->nkeys + 1, sizeof(*ctx->algs));
+		if (algtmp == NULL)
+			fatal("%s: reallocarray failed nalgs = %zu",
+			    __func__, ctx->nkeys);
+		ctx->algs = algtmp;
+		ctx->algs[ctx->nkeys] = pkalg;
+		pkalg = NULL;
 		ctx->keys = tmp;
 		ctx->keys[ctx->nkeys++] = key;
 		key = NULL;
@@ -2539,8 +2545,8 @@
 			if (ctx->keys_seen[i])
 				continue;
 			sshbuf_reset(buf);
-			if ((r = sshkey_putb(ctx->keys[i], buf)) != 0)
-				fatal("%s: sshkey_putb: %s",
+			if ((r = Xkey_putb(ctx->algs[i], ctx->keys[i], buf)) != 0)
+				fatal("%s: Xkey_putb: %s",
 				    __func__, ssh_err(r));
 			if ((r = sshpkt_put_stringb(ssh, buf)) != 0)
 				fatal("%s: sshpkt_put_string: %s",
@@ -2556,6 +2562,7 @@
 	/* Success */
  out:
 	hostkeys_update_ctx_free(ctx);
+	free(pkalg);
 	sshkey_free(key);
 	sshbuf_free(buf);
 	/*
diff -ruN openssh-7.5p1/compat.c openssh-7.5p1+x509-10.2/compat.c
--- openssh-7.5p1/compat.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/compat.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support:
+ * Copyright (c) 2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -57,8 +60,9 @@
 	debug("Enabling compatibility mode for protocol 1.3");
 	compat13 = 1;
 }
+
 /* datafellows bug compatibility */
-u_int
+static u_int
 compat_datafellows(const char *version)
 {
 	int i;
@@ -301,3 +305,87 @@
 	return p;
 }
 
+
+struct sshx_compatibility_st {
+	int/*boolean*/ flag;
+	const char *pattern;
+};
+typedef struct sshx_compatibility_st sshx_compatibility;
+
+
+static sshx_compatibility*
+xkey_compatibility_find(
+    const char *remote_version,
+    sshx_compatibility *compatibility_info
+) {
+	sshx_compatibility *p;
+
+	for (p = compatibility_info; p->pattern; p++) {
+		if (match_pattern_list(remote_version, p->pattern, 0) == 1)
+			break;
+	}
+	return p;
+}
+
+
+int xcompat = 0;
+
+static u_int
+xkey_compatibility(const char *remote_version) {
+	u_int res = 0;
+	sshx_compatibility *p;
+
+/* Process each table and stop on first match.
+   Order of compatibility info is important!
+*/
+{	static sshx_compatibility info[] = {
+		{ 0, "OpenSSH*PKIX[??.*" /* 10.+ first correct */ },
+		{ 0, "OpenSSH*PKIX[X.*" /* developlement */ },
+		{ 1, "OpenSSH*" /* PKIX pre 10.0 */ },
+		{ 1, "SecureNetTerm-3.1" /* same as PKIX pre 10.0 */},
+		{ 0, NULL } };
+	p = xkey_compatibility_find(remote_version, info);
+}
+	if (p->flag != 0) {
+		res |= SSHX_RFC6187_MISSING_KEY_IDENTIFIER;
+		res |= SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE;
+	}
+	debug("x.509 compatibility rfc6187_missing_key_identifier=%s: pattern '%s' match '%s'",
+	    (p->flag != 0 ? "yes": "no"),
+	    (p->pattern != NULL ? p->pattern : "*"),
+	    remote_version);
+	debug("x.509 compatibility rfc6187_asn1_opaque_ecdsa_signature=%s: pattern '%s' match '%s'",
+	    (p->flag != 0 ? "yes": "no"),
+	    (p->pattern != NULL ? p->pattern : "*"),
+	    remote_version);
+
+{	static sshx_compatibility info[] = {
+		{ 0, "OpenSSH*PKIX*" /* all correct */ },
+		{ 1, "OpenSSH_7.3*" /* list only rsa-sha2-256 and rsa-sha2-512 */ },
+		{ 1, "OpenSSH_7.4*" /* list without rsa-sha2-256 and rsa-sha2-512 */ },
+		{ 0, NULL } };
+	p = xkey_compatibility_find(remote_version, info);
+}
+	if (p->flag != 0) {
+		res |= SSHX_OPENSSH_BROKEN_ALGO_INFO;
+	}
+	debug("x.509 compatibility broken list with accepted publickey algorithms=%s: pattern '%s' match '%s'",
+	    (p->flag != 0 ? "yes": "no"),
+	    (p->pattern != NULL ? p->pattern : "*"),
+	    remote_version);
+
+	xcompat = res; /* TODO */
+	return res;
+}
+
+
+void
+ssh_compatibility(ssh_compat *flags, const char *remote_version) {
+	if (remote_version == NULL) {
+		flags->datafellows = 0;
+		flags->xcompat = 0;
+		return;
+	}
+	flags->datafellows = compat_datafellows(remote_version);
+	flags->xcompat = xkey_compatibility(remote_version);
+}
diff -ruN openssh-7.5p1/compat.h openssh-7.5p1+x509-10.2/compat.h
--- openssh-7.5p1/compat.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/compat.h	2017-05-20 21:07:00.000000000 +0300
@@ -3,6 +3,9 @@
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support:
+ * Copyright (c) 2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -65,7 +68,6 @@
 
 void     enable_compat13(void);
 void     enable_compat20(void);
-u_int    compat_datafellows(const char *);
 int	 proto_spec(const char *);
 char	*compat_cipher_proposal(char *);
 char	*compat_pkalg_proposal(char *);
@@ -74,4 +76,39 @@
 extern int compat13;
 extern int compat20;
 extern int datafellows;
+
+
+/* compatibility for X.509 keys */
+extern int xcompat;
+
+#define SSHX_RFC6187_MISSING_KEY_IDENTIFIER		0x00000001U
+#define SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE	0x00000002U
+#define SSHX_OPENSSH_BROKEN_ALGO_INFO			0x00000003U
+
+
+/* enhanced secure shell compatibility */
+struct ssh_compat_st {
+	u_int datafellows;
+	u_int xcompat;	/* X.509 key compatibility */
+};
+
+void ssh_compatibility(ssh_compat *flags, const char *remote_version);
+
+/* TODO ssh_compat in struct ssh */
+#define SSH_XCOMPATIBILITY(ssh, remote_version) { \
+  ssh_compat compat; \
+  ssh_compatibility(&compat, remote_version); \
+  ssh->compat = compat.datafellows; }
+
+
+static inline int/*bool*/
+check_compat_datafellows(ssh_compat *compat, u_int flag) {
+	return compat != NULL ? (flag & compat->datafellows) != 0 : 0;
+}
+
+static inline int/*bool*/
+check_compat_x509(ssh_compat *compat, u_int flag) {
+	return compat != NULL ? (flag & compat->xcompat) != 0 : 0;
+}
+
 #endif
diff -ruN openssh-7.5p1/config.guess openssh-7.5p1+x509-10.2/config.guess
--- openssh-7.5p1/config.guess	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/config.guess	2017-05-20 21:07:00.000000000 +0300
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2016 Free Software Foundation, Inc.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
 
-timestamp='2016-05-15'
+timestamp='2017-05-11'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -837,10 +837,11 @@
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
 	case ${UNAME_PROCESSOR} in
 	    amd64)
-		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	    *)
-		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+		UNAME_PROCESSOR=x86_64 ;;
+	    i386)
+		UNAME_PROCESSOR=i586 ;;
 	esac
+	echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
 	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
@@ -1000,6 +1001,9 @@
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
+    mips64el:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     openrisc*:Linux:*:*)
 	echo or1k-unknown-linux-${LIBC}
 	exit ;;
@@ -1032,6 +1036,9 @@
     ppcle:Linux:*:*)
 	echo powerpcle-unknown-linux-${LIBC}
 	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
 	exit ;;
@@ -1328,15 +1335,18 @@
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit ;;
-    NEO-?:NONSTOP_KERNEL:*:*)
+    NEO-*:NONSTOP_KERNEL:*:*)
 	echo neo-tandem-nsk${UNAME_RELEASE}
 	exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
+    NSR-*:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
 	exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+	echo nsx-tandem-nsk${UNAME_RELEASE}
+	exit ;;
     *:NonStop-UX:*:*)
 	echo mips-compaq-nonstopux
 	exit ;;
diff -ruN openssh-7.5p1/config.h.in openssh-7.5p1+x509-10.2/config.h.in
--- openssh-7.5p1/config.h.in	2017-03-20 11:53:08.000000000 +0200
+++ openssh-7.5p1+x509-10.2/config.h.in	2017-05-20 21:07:01.000000000 +0300
@@ -10,6 +10,9 @@
 /* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
 #undef AIX_LOGINFAILED_4ARG
 
+/* Define as const if ASN1_STRING_CONST() declare const argument */
+#undef ASN1_STRING_LENGTH_CONST
+
 /* System only supports IPv4 audit records */
 #undef AU_IPv4
 
@@ -189,6 +192,12 @@
 /* Define to 1 if you have the `arc4random_uniform' function. */
 #undef HAVE_ARC4RANDOM_UNIFORM
 
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
+#undef HAVE_ASN1_STRING_GET0_DATA
+
 /* Define to 1 if you have the `asprintf' function. */
 #undef HAVE_ASPRINTF
 
@@ -240,6 +249,9 @@
 /* Define to 1 if you have the `Blowfish_stream2word' function. */
 #undef HAVE_BLOWFISH_STREAM2WORD
 
+/* Define to 1 if you have the `BN_is_negative' function. */
+#undef HAVE_BN_IS_NEGATIVE
+
 /* Define to 1 if you have the `BN_is_prime_ex' function. */
 #undef HAVE_BN_IS_PRIME_EX
 
@@ -292,6 +304,22 @@
    you don't. */
 #undef HAVE_DECL_AI_NUMERICSERV
 
+/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
+   don't. */
+#undef HAVE_DECL_ARC4RANDOM
+
+/* Define to 1 if you have the declaration of `arc4random_buf', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ARC4RANDOM_BUF
+
+/* Define to 1 if you have the declaration of `arc4random_stir', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ARC4RANDOM_STIR
+
+/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0
+   if you don't. */
+#undef HAVE_DECL_ARC4RANDOM_UNIFORM
+
 /* Define to 1 if you have the declaration of `authenticate', and to 0 if you
    don't. */
 #undef HAVE_DECL_AUTHENTICATE
@@ -352,6 +380,10 @@
    don't. */
 #undef HAVE_DECL_SHUT_RD
 
+/* Define to 1 if you have the declaration of `UTF8_getc', and to 0 if you
+   don't. */
+#undef HAVE_DECL_UTF8_GETC
+
 /* Define to 1 if you have the declaration of `writev', and to 0 if you don't.
    */
 #undef HAVE_DECL_WRITEV
@@ -373,6 +405,9 @@
 /* Define if you have /dev/ptc */
 #undef HAVE_DEV_PTS_AND_PTC
 
+/* Define to 1 if you have the `DH_get0_key' function. */
+#undef HAVE_DH_GET0_KEY
+
 /* Define to 1 if you have the <dirent.h> header file. */
 #undef HAVE_DIRENT_H
 
@@ -385,6 +420,30 @@
 /* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
 #undef HAVE_DSA_GENERATE_PARAMETERS_EX
 
+/* Define to 1 if you have the `DSA_meth_new' function. */
+#undef HAVE_DSA_METH_NEW
+
+/* Define to 1 if you have the `DSA_SIG_get0' function. */
+#undef HAVE_DSA_SIG_GET0
+
+/* Define to 1 if you have the `DSA_SIG_set0' function. */
+#undef HAVE_DSA_SIG_SET0
+
+/* Define to 1 if `name' is a member of `ECDSA_METHOD'. */
+#undef HAVE_ECDSA_METHOD_NAME
+
+/* Define to 1 if you have the `ECDSA_METHOD_new' function. */
+#undef HAVE_ECDSA_METHOD_NEW
+
+/* Define to 1 if you have the `ECDSA_SIG_get0' function. */
+#undef HAVE_ECDSA_SIG_GET0
+
+/* Define to 1 if you have the `ECDSA_SIG_set0' function. */
+#undef HAVE_ECDSA_SIG_SET0
+
+/* Define to 1 if you have the `EC_KEY_METHOD_new' function. */
+#undef HAVE_EC_KEY_METHOD_NEW
+
 /* Define to 1 if you have the <elf.h> header file. */
 #undef HAVE_ELF_H
 
@@ -409,20 +468,32 @@
 /* Define to 1 if you have the <err.h> header file. */
 #undef HAVE_ERR_H
 
+/* Define to 1 if you have the `ERR_remove_thread_state' function. */
+#undef HAVE_ERR_REMOVE_THREAD_STATE
+
 /* Define if your system has /etc/default/login */
 #undef HAVE_ETC_DEFAULT_LOGIN
 
 /* Define if libcrypto has EVP_CIPHER_CTX_ctrl */
 #undef HAVE_EVP_CIPHER_CTX_CTRL
 
+/* Define to 1 if you have the `EVP_CIPHER_CTX_iv' function. */
+#undef HAVE_EVP_CIPHER_CTX_IV
+
+/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
+#undef HAVE_EVP_CIPHER_CTX_NEW
+
+/* Define to 1 if you have the `EVP_CIPHER_meth_new' function. */
+#undef HAVE_EVP_CIPHER_METH_NEW
+
 /* Define to 1 if you have the `EVP_DigestFinal_ex' function. */
 #undef HAVE_EVP_DIGESTFINAL_EX
 
 /* Define to 1 if you have the `EVP_DigestInit_ex' function. */
 #undef HAVE_EVP_DIGESTINIT_EX
 
-/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */
-#undef HAVE_EVP_MD_CTX_CLEANUP
+/* Define to 1 if you have the `EVP_dss1' function. */
+#undef HAVE_EVP_DSS1
 
 /* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
 #undef HAVE_EVP_MD_CTX_COPY_EX
@@ -430,6 +501,18 @@
 /* Define to 1 if you have the `EVP_MD_CTX_init' function. */
 #undef HAVE_EVP_MD_CTX_INIT
 
+/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
+#undef HAVE_EVP_MD_CTX_NEW
+
+/* Define to 1 if you have the `EVP_MD_flags' function. */
+#undef HAVE_EVP_MD_FLAGS
+
+/* Define to 1 if you have the `EVP_PKEY_get0_EC_KEY' function. */
+#undef HAVE_EVP_PKEY_GET0_EC_KEY
+
+/* Define to 1 if you have the `EVP_PKEY_id' function. */
+#undef HAVE_EVP_PKEY_ID
+
 /* Define to 1 if you have the `EVP_ripemd160' function. */
 #undef HAVE_EVP_RIPEMD160
 
@@ -460,6 +543,9 @@
 /* Define to 1 if you have the <features.h> header file. */
 #undef HAVE_FEATURES_H
 
+/* Define to 1 if you have the <fipscheck.h> header file. */
+#undef HAVE_FIPSCHECK_H
+
 /* Define to 1 if you have the <floatingpoint.h> header file. */
 #undef HAVE_FLOATINGPOINT_H
 
@@ -682,6 +768,24 @@
 /* Define to 1 if you have the <lastlog.h> header file. */
 #undef HAVE_LASTLOG_H
 
+/* Define to 1 if you have the <lber.h> header file. */
+#undef HAVE_LBER_H
+
+/* Define to 1 if you have the <ldap.h> header file. */
+#undef HAVE_LDAP_H
+
+/* Define to 1 if you have the `ldap_initialize' function. */
+#undef HAVE_LDAP_INITIALIZE
+
+/* Define to 1 if you have the `ldap_parse_result' function. */
+#undef HAVE_LDAP_PARSE_RESULT
+
+/* Define to 1 if you have the `ldap_sasl_bind_s' function. */
+#undef HAVE_LDAP_SASL_BIND_S
+
+/* Define to 1 if you have the `ldap_search_ext_s' function. */
+#undef HAVE_LDAP_SEARCH_EXT_S
+
 /* Define if you want ldns support */
 #undef HAVE_LDNS
 
@@ -736,9 +840,6 @@
 /* Define to 1 if you have the <linux/seccomp.h> header file. */
 #undef HAVE_LINUX_SECCOMP_H
 
-/* Define to 1 if you have the `llabs' function. */
-#undef HAVE_LLABS
-
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
@@ -811,6 +912,9 @@
 /* Define to 1 if you have the <net/if_tun.h> header file. */
 #undef HAVE_NET_IF_TUN_H
 
+/* Define to 1 if you have the <net/if_utun.h> header file. */
+#undef HAVE_NET_IF_UTUN_H
+
 /* Define if you are on NeXT */
 #undef HAVE_NEXT
 
@@ -823,6 +927,9 @@
 /* Define to 1 if you have the `nsleep' function. */
 #undef HAVE_NSLEEP
 
+/* Define to 1 if you have the `OCSP_sendreq_bio' function. */
+#undef HAVE_OCSP_SENDREQ_BIO
+
 /* Define to 1 if you have the `ogetaddrinfo' function. */
 #undef HAVE_OGETADDRINFO
 
@@ -839,6 +946,15 @@
 /* Define if your ssl headers are included with #include <openssl/header.h> */
 #undef HAVE_OPENSSL
 
+/* Define to 1 if you have the <openssl/ec.h> header file. */
+#undef HAVE_OPENSSL_EC_H
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#undef HAVE_OPENSSL_ENGINE_H
+
+/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
+#undef HAVE_OPENSSL_INIT_CRYPTO
+
 /* Define if you have Digital Unix Security Integration Architecture */
 #undef HAVE_OSF_SIA
 
@@ -923,6 +1039,12 @@
 /* Define to 1 if you have the `RSA_get_default_method' function. */
 #undef HAVE_RSA_GET_DEFAULT_METHOD
 
+/* Define to 1 if you have the `RSA_meth_new' function. */
+#undef HAVE_RSA_METH_NEW
+
+/* Define to 1 if you have the `RSA_PKCS1_OpenSSL' function. */
+#undef HAVE_RSA_PKCS1_OPENSSL
+
 /* Define to 1 if you have the <sandbox.h> header file. */
 #undef HAVE_SANDBOX_H
 
@@ -1043,6 +1165,9 @@
 /* define if you have size_t data type */
 #undef HAVE_SIZE_T
 
+/* Define to 1 if you have the 'sk_OPENSSL_STRING_new_null' function. */
+#undef HAVE_SK_OPENSSL_STRING_NEW_NULL
+
 /* Define to 1 if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
@@ -1163,6 +1288,9 @@
 /* define if you have struct timeval */
 #undef HAVE_STRUCT_TIMEVAL
 
+/* Define to 1 if the system has the type `struct x509_lookup_method_st'. */
+#undef HAVE_STRUCT_X509_LOOKUP_METHOD_ST
+
 /* Define to 1 if you have the `swap32' function. */
 #undef HAVE_SWAP32
 
@@ -1223,6 +1351,9 @@
 /* Define to 1 if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#undef HAVE_SYS_STATFS_H
+
 /* Define to 1 if you have the <sys/statvfs.h> header file. */
 #undef HAVE_SYS_STATVFS_H
 
@@ -1331,6 +1462,9 @@
 /* Define to 1 if you have the `usleep' function. */
 #undef HAVE_USLEEP
 
+/* Define to 1 if you have the `UTF8_getc' function. */
+#undef HAVE_UTF8_GETC
+
 /* Define to 1 if you have the <util.h> header file. */
 #undef HAVE_UTIL_H
 
@@ -1388,6 +1522,30 @@
 /* Define to 1 if you have the `wcwidth' function. */
 #undef HAVE_WCWIDTH
 
+/* Define to 1 if you have the `X509_CRL_get0_lastUpdate' function. */
+#undef HAVE_X509_CRL_GET0_LASTUPDATE
+
+/* Define to 1 if you have the `X509_get0_tbs_sigalg' function. */
+#undef HAVE_X509_GET0_TBS_SIGALG
+
+/* Define to 1 if you have the `X509_get_key_usage' function. */
+#undef HAVE_X509_GET_KEY_USAGE
+
+/* Define to 1 if you have the `X509_OBJECT_new' function. */
+#undef HAVE_X509_OBJECT_NEW
+
+/* Define to 1 if you have the `X509_STORE_CTX_get0_param' function. */
+#undef HAVE_X509_STORE_CTX_GET0_PARAM
+
+/* Define to 1 if you have the `X509_STORE_get0_objects' function. */
+#undef HAVE_X509_STORE_GET0_OBJECTS
+
+/* Define to 1 if you have the `X509_STORE_lock' function. */
+#undef HAVE_X509_STORE_LOCK
+
+/* Define to 1 if you have the `X509_STORE_set_verify_cb' function. */
+#undef HAVE_X509_STORE_SET_VERIFY_CB
+
 /* Define to 1 if you have the `_getlong' function. */
 #undef HAVE__GETLONG
 
@@ -1439,6 +1597,12 @@
 /* Define if pututxline updates lastlog too */
 #undef LASTLOG_WRITE_PUTUTXLINE
 
+/* Define if you want to enable LDAP queries */
+#undef LDAP_ENABLED
+
+/* Define if you want TCP Wrappers support */
+#undef LIBWRAP
+
 /* Define to whatever link() returns for "not supported" if it doesn't return
    EOPNOTSUPP. */
 #undef LINK_OPNOTSUPP_ERRNO
@@ -1482,8 +1646,8 @@
 /* Define if X11 doesn't support AF_UNIX sockets on that system */
 #undef NO_X11_UNIX_SOCKETS
 
-/* Define if EVP_DigestUpdate returns void */
-#undef OPENSSL_EVP_DIGESTUPDATE_VOID
+/* Define if OpenSSH use memory BIO buffer to read/write keys */
+#undef OPENSSH_KEYS_USE_BIO
 
 /* OpenSSL has ECC */
 #undef OPENSSL_HAS_ECC
@@ -1610,6 +1774,9 @@
    bsd-setproctitle.c */
 #undef SPT_TYPE
 
+/* Specify location of ssh CA root */
+#undef SSHCADIR
+
 /* Define if sshd somehow reacquires a controlling TTY after setsid() */
 #undef SSHD_ACQUIRES_CTTY
 
@@ -1625,12 +1792,22 @@
 /* Windows is sensitive to read buffer size */
 #undef SSH_IOBUFSZ
 
+/* Define if you don't want to validate X.509 certificates with OCSP */
+#undef SSH_OCSP_ENABLED
+
+/* Define if your openssl library don't support Email in X.509 'Distinguished
+   Name' */
+#undef SSH_OPENSSL_DN_WITHOUT_EMAIL
+
 /* non-privileged user for privilege separation */
 #undef SSH_PRIVSEP_USER
 
 /* Use tunnel device compatibility to OpenBSD */
 #undef SSH_TUN_COMPAT_AF
 
+/* Open tunnel devices the Darwin way */
+#undef SSH_TUN_DARWIN
+
 /* Open tunnel devices the FreeBSD way */
 #undef SSH_TUN_FREEBSD
 
diff -ruN openssh-7.5p1/config.sub openssh-7.5p1+x509-10.2/config.sub
--- openssh-7.5p1/config.sub	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/config.sub	2017-05-20 21:07:00.000000000 +0300
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2016 Free Software Foundation, Inc.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
 
-timestamp='2016-06-20'
+timestamp='2017-04-02'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -67,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2016 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -263,7 +263,7 @@
 	| fido | fr30 | frv | ft32 \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
-	| i370 | i860 | i960 | ia64 \
+	| i370 | i860 | i960 | ia16 | ia64 \
 	| ip2k | iq2000 \
 	| k1om \
 	| le32 | le64 \
@@ -301,6 +301,7 @@
 	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pru \
 	| pyramid \
 	| riscv32 | riscv64 \
 	| rl78 | rx \
@@ -314,6 +315,7 @@
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
 	| visium \
+	| wasm32 \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -387,7 +389,7 @@
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia64-* \
+	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
 	| ip2k-* | iq2000-* \
 	| k1om-* \
 	| le32-* | le64-* \
@@ -428,6 +430,7 @@
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pru-* \
 	| pyramid-* \
 	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
@@ -444,6 +447,7 @@
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
 	| visium-* \
+	| wasm32-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -946,6 +950,9 @@
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
+	nsx-tandem)
+		basic_machine=nsx-tandem
+		;;
 	op50n-* | op60c-*)
 		basic_machine=hppa1.1-oki
 		os=-proelf
@@ -1030,7 +1037,7 @@
 	ppc-* | ppcbe-*)
 		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppcle | powerpclittle | ppc-le | powerpc-little)
+	ppcle | powerpclittle)
 		basic_machine=powerpcle-unknown
 		;;
 	ppcle-* | powerpclittle-*)
@@ -1040,7 +1047,7 @@
 		;;
 	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+	ppc64le | powerpc64little)
 		basic_machine=powerpc64le-unknown
 		;;
 	ppc64le-* | powerpc64little-*)
@@ -1241,6 +1248,9 @@
 		basic_machine=a29k-wrs
 		os=-vxworks
 		;;
+	wasm32)
+		basic_machine=wasm32-unknown
+		;;
 	w65*)
 		basic_machine=w65-wdc
 		os=-none
@@ -1395,7 +1405,7 @@
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
@@ -1407,7 +1417,7 @@
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
 	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix*)
+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1636,6 +1646,9 @@
 	sparc-* | *-sun)
 		os=-sunos4.1.1
 		;;
+	pru-*)
+		os=-elf
+		;;
 	*-be)
 		os=-beos
 		;;
diff -ruN openssh-7.5p1/configure openssh-7.5p1+x509-10.2/configure
--- openssh-7.5p1/configure	2017-03-20 11:53:05.000000000 +0200
+++ openssh-7.5p1+x509-10.2/configure	2017-05-20 21:07:02.000000000 +0300
@@ -1,9 +1,8 @@
 #! /bin/sh
-# From configure.ac Revision: 1.583 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenSSH Portable.
+# Generated by GNU Autoconf 2.69 for PKIX-SSH 10.2.
 #
-# Report bugs to <openssh-unix-dev@mindrot.org>.
+# Report bugs to <ssh_x509@roumenpetrov.info>.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -267,11 +266,11 @@
     $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: openssh-unix-dev@mindrot.org about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and ssh_x509@roumenpetrov.info
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
   fi
   exit 1
 fi
@@ -579,12 +578,12 @@
 MAKEFLAGS=
 
 # Identity of this package.
-PACKAGE_NAME='OpenSSH'
+PACKAGE_NAME='PKIX-SSH'
 PACKAGE_TARNAME='openssh'
-PACKAGE_VERSION='Portable'
-PACKAGE_STRING='OpenSSH Portable'
-PACKAGE_BUGREPORT='openssh-unix-dev@mindrot.org'
-PACKAGE_URL=''
+PACKAGE_VERSION='10.2'
+PACKAGE_STRING='PKIX-SSH 10.2'
+PACKAGE_BUGREPORT='ssh_x509@roumenpetrov.info'
+PACKAGE_URL='http://roumenpetrov.info/secsh'
 
 ac_unique_file="ssh.c"
 # Factoring default headers for most tests.
@@ -630,6 +629,23 @@
 TEST_SSH_UTF8
 TEST_SSH_IPV6
 piddir
+FIPSHMAC
+FIPS_LIBS
+OPENSSL_FIPS_MODE
+FIPSLD_CC
+LDAPADD
+LDAP_OFF
+LDAP_ON
+LDAP_LIBS
+LDAP_CPPFLAGS
+LDAP_LDFLAGS
+LDAP_SYSCONFDIR
+LDAP_LIBEXECDIR
+LDAP_BINDIR
+OCSP_OFF
+OCSP_ON
+LIBOCSP
+sshcadir
 user_path
 mansubdir
 MANTYPE
@@ -645,9 +661,12 @@
 SSH_PRIVSEP_USER
 COMMENT_OUT_ECC
 TEST_SSH_ECC
+COMMENT_OUT_ECC521
+COMMENT_OUT_ECC384
+COMMENT_OUT_ECC256
 LIBEDIT
 PKGCONFIG
-LDNSCONFIG
+XLDFLAGS
 COMMENT_OUT_RSA1
 LD
 PATH_PASSWD_PROG
@@ -736,6 +755,7 @@
 enable_largefile
 with_openssl
 with_ssh1
+enable_ssh1
 with_stackprotect
 with_hardening
 with_rpath
@@ -751,6 +771,7 @@
 with_zlib
 with_zlib_version_check
 with_skey
+with_tcp_wrappers
 with_ldns
 with_libedit
 with_audit
@@ -780,6 +801,17 @@
 with_superuser_path
 with_4in6
 with_bsd_auth
+with_sshca_dir
+enable_ocsp
+enable_ldap
+with_ldap_prefix
+with_ldap_bindir
+with_ldap_libexecdir
+with_ldap_sysconfdir
+with_ldap_libdir
+with_ldap_includedir
+with_ldap_libs
+enable_openssl_fips
 with_pid_dir
 enable_lastlog
 enable_utmp
@@ -799,7 +831,8 @@
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP'
+CPP
+FIPSLD_CC'
 
 
 # Initialize some variables set by options.
@@ -1340,7 +1373,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures OpenSSH Portable to adapt to many kinds of systems.
+\`configure' configures PKIX-SSH 10.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1405,7 +1438,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenSSH Portable:";;
+     short | recursive ) echo "Configuration of PKIX-SSH 10.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1414,9 +1447,13 @@
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-largefile     omit support for large files
+  --enable-ssh1           Enable support for SSH protocol 1
   --disable-pkcs11        disable PKCS#11 support code [no]
   --disable-strip         Disable calling strip(1) on install
   --disable-etc-default-login Disable using PATH from /etc/default/login no
+  --disable-ocsp          Disable OCSP validation
+  --enable-ldap           Enable LDAP queries
+  --enable-openssl-fips   Enable build with FIPS-enabled openssl
   --disable-lastlog       disable use of lastlog even if detected no
   --disable-utmp          disable use of utmp even if detected no
   --disable-utmpx         disable use of utmpx even if detected no
@@ -1429,8 +1466,10 @@
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --without-openssl       Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL**
-  --with-ssh1             Enable support for SSH protocol 1
+  --without-openssl       Disable use of OpenSSL; use only limited internal
+                          crypto **EXPERIMENTAL**
+  --with-ssh1             Enable support for SSH protocol 1; overriden by
+                          --enable-ssh1
   --without-stackprotect  Don't use compiler's stack protection
   --without-hardening     Don't use toolchain hardening flags
   --without-rpath         Disable auto-added -R linker paths
@@ -1446,6 +1485,8 @@
   --with-zlib=PATH        Use zlib in PATH
   --without-zlib-version-check Disable zlib version check
   --with-skey[=PATH]      Enable S/Key support (optionally in PATH)
+  --with-tcp-wrappers[=PATH]
+                          Enable tcpwrappers support (optionally in PATH)
   --with-ldns[=PATH]      Use ldns for DNSSEC support (optionally in PATH)
   --with-libedit[=PATH]   Enable libedit support for sftp
   --with-audit=module     Enable audit support (modules=debug,bsm,linux)
@@ -1472,6 +1513,22 @@
   --with-superuser-path=  Specify different path for super-user
   --with-4in6             Check for and convert IPv4 in IPv6 mapped addresses
   --with-bsd-auth         Enable BSD auth support
+  --with-sshca-dir=PATH   Specify location of ssh CA root
+  --with-ldap-prefix=PATH Prefix where LDAP is installed (optional)
+  --with-ldap-bindir=PATH Prefix where LDAP user executables are installed
+                          (optional)
+  --with-ldap-libexecdir=PATH
+                          Prefix where LDAP program executables are installed
+                          (optional)
+  --with-ldap-sysconfdir=PATH
+                          Prefix where LDAP single-machine data are installed
+                          (optional)
+  --with-ldap-libdir=PATH Prefix where LDAP libaries are installed (optional)
+  --with-ldap-includedir=PATH
+                          Prefix where LDAP header files are installed
+                          (optional)
+  --with-ldap-libs=LIBS   Specify LDAP libraries to link with.
+                            (default is -lldap -llber -lssl -lcrypto)
   --with-pid-dir=PATH     Specify location of ssh.pid file
   --with-lastlog=FILE|DIR specify lastlog location common locations
 
@@ -1484,11 +1541,13 @@
   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
+  FIPSLD_CC   actual compiler to be used by openssl fips compiler
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <openssh-unix-dev@mindrot.org>.
+Report bugs to <ssh_x509@roumenpetrov.info>.
+PKIX-SSH home page: <http://roumenpetrov.info/secsh>.
 _ACEOF
 ac_status=$?
 fi
@@ -1551,7 +1610,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenSSH configure Portable
+PKIX-SSH configure 10.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1875,9 +1934,9 @@
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------- ##
-## Report this to openssh-unix-dev@mindrot.org ##
-## ------------------------------------------- ##"
+( $as_echo "## ----------------------------------------- ##
+## Report this to ssh_x509@roumenpetrov.info ##
+## ----------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -2260,7 +2319,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by OpenSSH $as_me Portable, which was
+It was created by PKIX-SSH $as_me 10.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2609,6 +2668,18 @@
 
 
 
+# Options to build with LDAP
+#
+# Author: Roumen Petrov
+# Revision: 7 Dec 2011
+#
+
+
+
+
+# AC_LDAP_FUNCS(FUNCTION...)
+# --------------------------------
+
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -5619,7 +5690,7 @@
 "
 if test "x$ac_cv_have_decl_RLIMIT_NPROC" = xyes; then :
 
-$as_echo "#define HAVE_RLIMIT_NPROC /**/" >>confdefs.h
+$as_echo "#define HAVE_RLIMIT_NPROC 1" >>confdefs.h
 
 fi
 
@@ -5633,68 +5704,67 @@
 fi
 
 
-openssl=yes
-ssh1=no
-COMMENT_OUT_RSA1="#no ssh1#"
 
 # Check whether --with-openssl was given.
 if test "${with_openssl+set}" = set; then :
-  withval=$with_openssl;   if test "x$withval" = "xno" ; then
-		openssl=no
-		ssh1=no
-	   fi
-
+  withval=$with_openssl;
+else
+  with_openssl=yes
 
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL will be used for cryptography" >&5
 $as_echo_n "checking whether OpenSSL will be used for cryptography... " >&6; }
-if test "x$openssl" = "xyes" ; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define WITH_OPENSSL 1
-_ACEOF
-
-else
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_openssl" >&5
+$as_echo "$with_openssl" >&6; }
+if test "x$with_openssl" != "xyes"; then
+	as_fn_error $? "build with OpenSSL is required" "$LINENO" 5
 fi
 
 
 # Check whether --with-ssh1 was given.
 if test "${with_ssh1+set}" = set; then :
   withval=$with_ssh1;
-		if test "x$withval" = "xyes" ; then
-			if test "x$openssl" = "xno" ; then
-				as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5
-			fi
-			ssh1=yes
-			COMMENT_OUT_RSA1=""
-		elif test "x$withval" = "xno" ; then
-			ssh1=no
-		else
-			as_fn_error $? "unknown --with-ssh1 argument" "$LINENO" 5
-		fi
+else
+  with_ssh1=no
+
+fi
+
+case "x$with_ssh1" in
+  "xyes"|"xno");;
+  *) as_fn_error $? "unknown --with-ssh1 argument" "$LINENO" 5;;
+esac
 
+openssl=yes
+
+cat >>confdefs.h <<_ACEOF
+#define WITH_OPENSSL 1
+_ACEOF
+
+
+# Check whether --enable-ssh1 was given.
+if test "${enable_ssh1+set}" = set; then :
+  enableval=$enable_ssh1; ssh1=$enableval
+else
+  ssh1=$with_ssh1
 
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSH protocol 1 support is enabled" >&5
 $as_echo_n "checking whether SSH protocol 1 support is enabled... " >&6; }
-if test "x$ssh1" = "xyes" ; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ssh1" >&5
+$as_echo "ssh1" >&6; }
+
+
+if test "x$ssh1" != "xno" ; then
+	COMMENT_OUT_RSA1=
 
 cat >>confdefs.h <<_ACEOF
 #define WITH_SSH1 1
 _ACEOF
 
-
 else
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+	COMMENT_OUT_RSA1="#no ssh1#"
 fi
 
 use_stack_protector=1
@@ -5726,7 +5796,14 @@
 CFLAGS="$CFLAGS -Werror"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-int main(void) { return 0; }
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -5754,15 +5831,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -5797,15 +5875,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -5840,15 +5919,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -5883,15 +5963,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -5926,15 +6007,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -5969,15 +6051,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6012,15 +6095,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6055,15 +6139,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6098,15 +6183,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6141,15 +6227,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6184,15 +6271,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6227,15 +6315,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -6271,7 +6360,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -6279,8 +6369,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
@@ -6308,7 +6398,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -6316,8 +6407,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
@@ -6345,7 +6436,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -6353,8 +6445,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
@@ -6387,7 +6479,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -6395,8 +6488,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long int p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
@@ -6670,6 +6763,22 @@
 fi
 
 
+
+case "$host" in
+*-*-linux-android*)
+		ac_cv_func_getpagesize=yes
+
+	ac_cv_file_dev_ptmx=yes
+
+			ac_cv_func_openpty=no
+	ac_cv_search_openpty=no
+
+			ac_cv_header_sys_statvfs_h=ignore
+	ac_cv_func_fstatvfs=use_bsd_port
+	ac_cv_func_statvfs=use_bsd_port
+	;;
+esac
+
 for ac_header in  \
 	blf.h \
 	bstring.h \
@@ -6726,6 +6835,7 @@
 	sys/stream.h \
 	sys/stropts.h \
 	sys/strtio.h \
+	sys/statfs.h \
 	sys/statvfs.h \
 	sys/sysmacros.h \
 	sys/time.h \
@@ -7137,14 +7247,6 @@
 $as_echo "#define PLATFORM_SYS_DIR_UID 2" >>confdefs.h
 
 	;;
-*-*-android*)
-
-$as_echo "#define DISABLE_UTMP 1" >>confdefs.h
-
-
-$as_echo "#define DISABLE_WTMP 1" >>confdefs.h
-
-	;;
 *-*-cygwin*)
 	check_for_libcrypt_later=1
 	LIBS="$LIBS /usr/lib/textreadmode.o"
@@ -7186,15 +7288,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -7276,16 +7379,34 @@
 #define BIND_8_COMPAT 1
 _ACEOF
 
+	for ac_header in net/if_utun.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "net/if_utun.h" "ac_cv_header_net_if_utun_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_if_utun_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NET_IF_UTUN_H 1
+_ACEOF
+
+fi
 
-$as_echo "#define SSH_TUN_FREEBSD 1" >>confdefs.h
+done
 
+	if test "x$ac_cv_header_net_if_utun_h" = "xyes" ; then
 
-$as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h
+$as_echo "#define SSH_TUN_DARWIN 1" >>confdefs.h
+
+	else
+
+$as_echo "#define SSH_TUN_FREEBSD 1" >>confdefs.h
 
 
 $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h
 
 
+$as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h
+
+	fi
+
 	ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default"
 if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then :
 
@@ -7518,7 +7639,7 @@
 
 $as_echo "#define HAVE_SECUREWARE 1" >>confdefs.h
 
-		disable_ptmx_check=yes
+		ac_cv_file_dev_ptmx=disable
 		LIBS="$LIBS -lsecpw"
 		;;
 	esac
@@ -7590,7 +7711,11 @@
 
 	;;
 *-*-linux*)
-	no_dev_ptmx=1
+	case "$host" in
+	*-*-linux-android*) ;;
+	*)
+		ac_cv_file_dev_ptmx=ignore;;
+	esac
 	use_pie=auto
 	check_for_libcrypt_later=1
 	check_for_openpty_ctty_bug=1
@@ -7606,14 +7731,27 @@
 
 $as_echo "#define LINK_OPNOTSUPP_ERRNO EPERM" >>confdefs.h
 
+	case "$host" in
+	*-*-linux-android*) ;;
+	*)
 
 $as_echo "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h
 
 	$as_echo "#define USE_BTMP 1" >>confdefs.h
 
+		;;
+	esac
 
 $as_echo "#define LINUX_OOM_ADJUST 1" >>confdefs.h
 
+
+	case "$host" in
+	*-*-linux-android*)
+		LIBS="$LIBS -llog"
+		XLDFLAGS='-Wl,--wrap=open -Wl,--wrap=fopen'
+		;;
+	esac
+
 	inet6_default_4in6=yes
 	case `uname -r` in
 	1.*|2.0.*)
@@ -8289,11 +8427,11 @@
 	;;
 # SCO OpenServer 5.x
 *-*-sco3.2v5*)
+	ac_cv_file_dev_ptmx=ignore
 	if test -z "$GCC"; then
 		CFLAGS="$CFLAGS -belf"
 	fi
 	LIBS="$LIBS -lprot -lx -ltinfo -lm"
-	no_dev_ptmx=1
 	$as_echo "#define USE_PIPES 1" >>confdefs.h
 
 	$as_echo "#define HAVE_SECUREWARE 1" >>confdefs.h
@@ -8475,6 +8613,11 @@
 	;;
 esac
 
+if test -n "$CONFIG_SHELL"; then
+		TEST_SHELL=$CONFIG_SHELL
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler and flags for sanity" >&5
 $as_echo_n "checking compiler and flags for sanity... " >&6; }
 if test "$cross_compiling" = yes; then :
@@ -9811,13 +9954,12 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct dirent allocates space for d_name" >&5
 $as_echo_n "checking whether struct dirent allocates space for d_name... " >&6; }
-if test "$cross_compiling" = yes; then :
-
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&5
-$as_echo "$as_me: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&2;}
-		$as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h
-
+if ${ssh_cv_dirent_allocates_space_for_d_name+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
 
+if test "$cross_compiling" = yes; then :
+  ssh_cv_dirent_allocates_space_for_d_name=cross
 
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9837,22 +9979,32 @@
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  ssh_cv_dirent_allocates_space_for_d_name=yes
 else
-
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-$as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h
-
-
+  ssh_cv_dirent_allocates_space_for_d_name=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
 
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssh_cv_dirent_allocates_space_for_d_name" >&5
+$as_echo "$ssh_cv_dirent_allocates_space_for_d_name" >&6; }
+case $ssh_cv_dirent_allocates_space_for_d_name in
+	no)
+
+$as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h
+
+		;;
+	cross)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&5
+$as_echo "$as_me: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&2;}
+		$as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h
+
+		;;
+esac
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc/pid/fd directory" >&5
 $as_echo_n "checking for /proc/pid/fd directory... " >&6; }
 if test -d "/proc/$$/fd" ; then
@@ -9954,163 +10106,150 @@
 fi
 
 
-# Check whether user wants to use ldns
-LDNS_MSG="no"
+# Check whether user wants TCP wrappers support
+TCPW_MSG="no"
+
+# Check whether --with-tcp-wrappers was given.
+if test "${with_tcp_wrappers+set}" = set; then :
+  withval=$with_tcp_wrappers; if test "x$withval" != "xno"; then :
+
+		saved_LIBS="$LIBS"
+		saved_LDFLAGS="$LDFLAGS"
+		saved_CPPFLAGS="$CPPFLAGS"
+
+		if test -n "${withval}" && \
+		    test "x${withval}" != "xyes"; then :
+
+			if test -d "${withval}/lib"; then :
+
+				if test -n "${need_dash_r}"; then
+					LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+				fi
 
-# Check whether --with-ldns was given.
-if test "${with_ldns+set}" = set; then :
-  withval=$with_ldns;
-	ldns=""
-	if test "x$withval" = "xyes" ; then
-		if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ldns-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ldns-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_LDNSCONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
 else
-  case $LDNSCONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_LDNSCONFIG="$LDNSCONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_LDNSCONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
 
-  ;;
-esac
+				if test -n "${need_dash_r}"; then
+					LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval} ${LDFLAGS}"
+				fi
+
 fi
-LDNSCONFIG=$ac_cv_path_LDNSCONFIG
-if test -n "$LDNSCONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDNSCONFIG" >&5
-$as_echo "$LDNSCONFIG" >&6; }
+			if test -d "${withval}/include"; then :
+
+				CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
 
+				CPPFLAGS="-I${withval} ${CPPFLAGS}"
 
 fi
-if test -z "$ac_cv_path_LDNSCONFIG"; then
-  ac_pt_LDNSCONFIG=$LDNSCONFIG
-  # Extract the first word of "ldns-config", so it can be a program name with args.
-set dummy ldns-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_LDNSCONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ac_pt_LDNSCONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_LDNSCONFIG="$ac_pt_LDNSCONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ac_pt_LDNSCONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
 
-  ;;
-esac
-fi
-ac_pt_LDNSCONFIG=$ac_cv_path_ac_pt_LDNSCONFIG
-if test -n "$ac_pt_LDNSCONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LDNSCONFIG" >&5
-$as_echo "$ac_pt_LDNSCONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 fi
 
-  if test "x$ac_pt_LDNSCONFIG" = x; then
-    LDNSCONFIG="no"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    LDNSCONFIG=$ac_pt_LDNSCONFIG
-  fi
-else
-  LDNSCONFIG="$ac_cv_path_LDNSCONFIG"
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with wrap library" >&5
+$as_echo_n "checking how to link with wrap library... " >&6; }
+		# libwrap may require libnsl
+		for WRAPLIBS in "-lwrap" "-lwrap -lnsl"; do
+			LIBS="$WRAPLIBS $saved_LIBS"
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <tcpd.h>
+int deny_severity = 0, allow_severity = 0;
+int
+main ()
+{
+
+	hosts_access(0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+				TCPW_MSG=yes
+
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+			test $TCPW_MSG = yes && break
+		done
 
-		if test "x$PKGCONFIG" = "xno"; then
-			CPPFLAGS="$CPPFLAGS -I${withval}/include"
-			LDFLAGS="$LDFLAGS -L${withval}/lib"
-			LIBS="-lldns $LIBS"
-			ldns=yes
+		if test $TCPW_MSG = yes; then
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $WRAPLIBS" >&5
+$as_echo "$WRAPLIBS" >&6; }
+
+$as_echo "#define LIBWRAP 1" >>confdefs.h
+
+			SSHDLIBS="$SSHDLIBS $WRAPLIBS"
 		else
-			LIBS="$LIBS `$LDNSCONFIG --libs`"
-			CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
+			as_fn_error $? "cannot link" "$LINENO" 5
 		fi
-	elif test "x$withval" != "xno" ; then
-			CPPFLAGS="$CPPFLAGS -I${withval}/include"
-			LDFLAGS="$LDFLAGS -L${withval}/lib"
-			LIBS="-lldns $LIBS"
-			ldns=yes
-	fi
 
-	# Verify that it works.
-	if test "x$ldns" = "xyes" ; then
+		LIBS="$saved_LIBS"
+
+fi
 
-$as_echo "#define HAVE_LDNS 1" >>confdefs.h
+fi
+
+
+# Check whether user wants to use ldns
+LDNS_MSG="no"
 
+# Check whether --with-ldns was given.
+if test "${with_ldns+set}" = set; then :
+  withval=$with_ldns;
+	if test "x$withval" != "xno" ; then
+		if test "x$withval" != "xyes" ; then
+			CPPFLAGS="$CPPFLAGS -I$withval/include"
+			LDFLAGS="$LDFLAGS -L$withval/lib"
+		fi
+		LIBS="-lldns $LIBS"
 		LDNS_MSG="yes"
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns support" >&5
+	fi
+
+fi
+
+# Verify that ldns works.
+if test "x$LDNS_MSG" = "xyes" ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns support" >&5
 $as_echo_n "checking for ldns support... " >&6; }
-		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <ldns/ldns.h>
-int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
-
-
+int main() {
+  ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL);
+  status = LDNS_STATUS_OK;
+  exit(0);
+}
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 else
 
-					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-					as_fn_error $? "** Incomplete or missing ldns libraries." "$LINENO" 5
+		as_fn_error $? "** Incomplete or missing ldns libraries." "$LINENO" 5
 
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-	fi
 
-fi
+$as_echo "#define HAVE_LDNS 1" >>confdefs.h
 
+fi
 
 # Check whether user wants libedit support
 LIBEDIT_MSG="no"
@@ -10539,15 +10678,16 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
 	double m = l / 0.5;
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
@@ -10582,7 +10722,8 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-int main(int argc, char **argv) {
+int
+main(int argc, char *argv[]) {
 	/* Some math to catch -ftrapv problems in the toolchain */
 	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
 	float l = i * 2.1;
@@ -10590,8 +10731,8 @@
 	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
 	long long p = n * o;
 	printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
-	exit(0);
-}
+(void) argv;
+return 0; }
 
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
@@ -10668,7 +10809,6 @@
 	inet_ntoa \
 	inet_ntop \
 	innetgr \
-	llabs \
 	login_getcapbool \
 	md5_crypt \
 	memmove \
@@ -10890,7 +11030,7 @@
 if test "$ac_res" != no; then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
-$as_echo "#define ENABLE_PKCS11 /**/" >>confdefs.h
+$as_echo "#define ENABLE_PKCS11 1" >>confdefs.h
 
 
 fi
@@ -12286,22 +12426,23 @@
 fi
 
 
-openssl_engine=no
 
 # Check whether --with-ssl-engine was given.
 if test "${with_ssl_engine+set}" = set; then :
   withval=$with_ssl_engine;
-		if test "x$withval" != "xno" ; then
-			if test "x$openssl" = "xno" ; then
-				as_fn_error $? "cannot use --with-ssl-engine when OpenSSL disabled" "$LINENO" 5
-			fi
-			openssl_engine=yes
-		fi
-
+else
+  with_ssl_engine=check
 
 fi
 
 
+COMMENT_OUT_ECC256="#no ecc256#"
+COMMENT_OUT_ECC384="#no ecc384#"
+COMMENT_OUT_ECC521="#no ecc521#"
+
+
+
+
 if test "x$openssl" = "xyes" ; then
 	LIBS="-lcrypto $LIBS"
 	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12479,13 +12620,6 @@
 if ac_fn_c_try_run "$LINENO"; then :
 
 			ssl_library_ver=`cat conftest.ssllibver`
-			# Check version is supported.
-			case "$ssl_library_ver" in
-				10000*|0*)
-					as_fn_error $? "OpenSSL >= 1.0.1 required (have \"$ssl_library_ver\")" "$LINENO" 5
-			                ;;
-			        *) ;;
-			esac
 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5
 $as_echo "$ssl_library_ver" >&6; }
 
@@ -12567,7 +12701,7 @@
 int
 main ()
 {
- SSLeay_add_all_algorithms();
+ OpenSSL_add_all_algorithms();
   ;
   return 0;
 }
@@ -12591,7 +12725,7 @@
 int
 main ()
 {
- SSLeay_add_all_algorithms();
+ OpenSSL_add_all_algorithms();
   ;
   return 0;
 }
@@ -12617,13 +12751,24 @@
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 
+	for ac_header in openssl/ec.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openssl/ec.h" "ac_cv_header_openssl_ec_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_ec_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENSSL_EC_H 1
+_ACEOF
+
+fi
+
+done
+
 	for ac_func in  \
+		BN_is_negative \
 		BN_is_prime_ex \
 		DSA_generate_parameters_ex \
 		EVP_DigestInit_ex \
 		EVP_DigestFinal_ex \
-		EVP_MD_CTX_init \
-		EVP_MD_CTX_cleanup \
 		EVP_MD_CTX_copy_ex \
 		HMAC_CTX_init \
 		RSA_generate_key_ex \
@@ -12641,7 +12786,19 @@
 done
 
 
-	if test "x$openssl_engine" = "xyes" ; then
+	if test "x$with_ssl_engine" != "xno" ; then
+		for ac_header in openssl/engine.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_engine_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENSSL_ENGINE_H 1
+_ACEOF
+
+fi
+
+done
+
 		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL ENGINE support" >&5
 $as_echo_n "checking for OpenSSL ENGINE support... " >&6; }
 		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12855,43 +13012,6 @@
 fi
 
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if EVP_DigestUpdate returns an int" >&5
-$as_echo_n "checking if EVP_DigestUpdate returns an int... " >&6; }
-	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-	#include <string.h>
-	#include <openssl/evp.h>
-
-int
-main ()
-{
-
-		if(EVP_DigestUpdate(NULL, NULL,0))
-			exit(0);
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-else
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-$as_echo "#define OPENSSL_EVP_DIGESTUPDATE_VOID 1" >>confdefs.h
-
-
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-
 	# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
 	# because the system crypt() is more featureful.
 	if test "x$check_for_libcrypt_before" = "x1"; then
@@ -13013,6 +13133,9 @@
   unsupported_algorithms="$unsupported_algorithms \
 		hmac-sha2-256 \
 		hmac-sha2-512 \
+		diffie-hellman-group14-sha256 \
+		diffie-hellman-group16-sha512 \
+		diffie-hellman-group18-sha512 \
 		diffie-hellman-group-exchange-sha256 \
 		hmac-sha2-256-etm@openssh.com \
 		hmac-sha2-512-etm@openssh.com"
@@ -13056,6 +13179,11 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 
 int
 main ()
@@ -13094,6 +13222,11 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 
 int
 main ()
@@ -13132,6 +13265,11 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 
 int
 main ()
@@ -13149,11 +13287,15 @@
 $as_echo "yes" >&6; }
 		  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL's NID_secp521r1 is functional" >&5
 $as_echo_n "checking if OpenSSL's NID_secp521r1 is functional... " >&6; }
-		  if test "$cross_compiling" = yes; then :
-   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross-compiling: assuming yes" >&5
-$as_echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;}
-			  enable_nistp521=1
+if ${ssh_cv_working_secp521r1+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
 
+		  if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -13178,17 +13320,22 @@
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-			  enable_nistp521=1
+  ssh_cv_working_secp521r1=yes
 else
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ssh_cv_working_secp521r1=no
+
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssh_cv_working_secp521r1" >&5
+$as_echo "$ssh_cv_working_secp521r1" >&6; }
+		  if test "x$ssh_cv_working_secp521r1" = xyes ; then
+			enable_nistp521=1
+		  fi
+
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
@@ -13212,6 +13359,7 @@
 
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC256=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdsa-sha2-nistp256 \
@@ -13224,6 +13372,7 @@
 
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC384=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdsa-sha2-nistp384 \
@@ -13236,6 +13385,7 @@
 
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC521=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdh-sha2-nistp521 \
@@ -13299,6 +13449,50 @@
 
 fi
 
+ac_fn_c_check_decl "$LINENO" "arc4random" "ac_cv_have_decl_arc4random" "$ac_includes_default"
+if test "x$ac_cv_have_decl_arc4random" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ARC4RANDOM $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "arc4random_buf" "ac_cv_have_decl_arc4random_buf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_arc4random_buf" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ARC4RANDOM_BUF $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "arc4random_stir" "ac_cv_have_decl_arc4random_stir" "$ac_includes_default"
+if test "x$ac_cv_have_decl_arc4random_stir" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ARC4RANDOM_STIR $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "arc4random_uniform" "ac_cv_have_decl_arc4random_uniform" "$ac_includes_default"
+if test "x$ac_cv_have_decl_arc4random_uniform" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ARC4RANDOM_UNIFORM $ac_have_decl
+_ACEOF
+
 for ac_func in  \
 	arc4random \
 	arc4random_buf \
@@ -14995,7 +15189,22 @@
 fi
 
 
+for ac_header in arpa/inet.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ARPA_INET_H 1
+_ACEOF
+
+fi
+
+done
+
 ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#include <sys/types.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 #include <netinet/in.h>
 "
 if test "x$ac_cv_type_in_addr_t" = xyes; then :
@@ -15007,6 +15216,9 @@
 
 fi
 ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" "#include <sys/types.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 #include <netinet/in.h>
 "
 if test "x$ac_cv_type_in_port_t" = xyes; then :
@@ -18095,13 +18307,20 @@
 fi
  # maildir
 
-if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
+if test "${ac_cv_file_dev_ptmx+set}" != set && test "x$cross_compiling" = "xyes"; then
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Disabling /dev/ptmx test" >&5
 $as_echo "$as_me: WARNING: cross compiling: Disabling /dev/ptmx test" >&2;}
-	disable_ptmx_check=yes
+	ac_cv_file_dev_ptmx=cross
+else
+	if test "${ac_cv_file_dev_ptmx+set}" = set ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/dev/ptmx\"" >&5
+$as_echo_n "checking for \"/dev/ptmx\"... " >&6; }
+if ${ac_cv_file_dev_ptmx+:} false; then :
+  $as_echo_n "(cached) " >&6
 fi
-if test -z "$no_dev_ptmx" ; then
-	if test "x$disable_ptmx_check" != "xyes" ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file_dev_ptmx" >&5
+$as_echo "$ac_cv_file_dev_ptmx" >&6; }
+	else
 		as_ac_File=`$as_echo "ac_cv_file_"/dev/ptmx"" | $as_tr_sh`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/dev/ptmx\"" >&5
 $as_echo_n "checking for \"/dev/ptmx\"... " >&6; }
@@ -18121,17 +18340,16 @@
 $as_echo "$ac_res" >&6; }
 if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
 
+fi
+
+	fi
+fi
+if test "x$ac_cv_file_dev_ptmx" = xyes ; then
 
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DEV_PTMX 1
 _ACEOF
 
-				have_dev_ptmx=1
-
-
-fi
-
-	fi
 fi
 
 if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then
@@ -18595,27 +18813,33 @@
 fi
 
 
-# Where to place sshd.pid
-piddir=/var/run
-# make sure the directory exists
-if test ! -d $piddir ; then
-	piddir=`eval echo ${sysconfdir}`
-	case $piddir in
-		NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
-	esac
-fi
+# X.509 support
+ssh_x509=yes
 
+# Starting from version 5.7 OpenSSH use memory BIO buffer
+# to read/write keys instead file streams.
 
-# Check whether --with-pid-dir was given.
-if test "${with_pid_dir+set}" = set; then :
-  withval=$with_pid_dir;
-		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
-		    test "x${withval}" != "xyes"; then
-			piddir=$withval
-			if test ! -d $piddir ; then
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ** no $piddir directory on this system **" >&5
-$as_echo "$as_me: WARNING: ** no $piddir directory on this system **" >&2;}
-			fi
+$as_echo "#define OPENSSH_KEYS_USE_BIO 1" >>confdefs.h
+
+# Reserved for future use
+#AC_DEFINE(
+#    [X509_DISABLED], [1],
+#    [Define if you want to disable X.509 certificates])
+
+# Where to place ssh CA root
+sshcadir='${sysconfdir}/ca'
+sshcadir=`eval echo ${sshcadir}`
+sshcadir=`eval echo ${sshcadir}`
+case $sshcadir in
+	NONE/*) sshcadir=`echo $sshcadir | sed "s~NONE~$ac_default_prefix~"` ;;
+esac
+
+
+# Check whether --with-sshca-dir was given.
+if test "${with_sshca_dir+set}" = set; then :
+  withval=$with_sshca_dir;
+		if test "x$withval" != "xno" ; then
+			sshcadir=$withval
 		fi
 
 
@@ -18624,23 +18848,902 @@
 
 
 cat >>confdefs.h <<_ACEOF
-#define _PATH_SSH_PIDDIR "$piddir"
+#define SSHCADIR "$sshcadir"
 _ACEOF
 
 
 
-# Check whether --enable-lastlog was given.
-if test "${enable_lastlog+set}" = set; then :
-  enableval=$enable_lastlog;
-		if test "x$enableval" = "xno" ; then
-			$as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h
-
-		fi
 
+ssh_x509store=yes #required since PKIX-SSH 9.0
 
-fi
 
-# Check whether --enable-utmp was given.
+# enable/disable OCSP requests
+# Check whether --enable-ocsp was given.
+if test "${enable_ocsp+set}" = set; then :
+  enableval=$enable_ocsp;
+	if test "x$enableval" = "xyes"; then
+		if test "x$ssh_x509store" != "xyes"; then
+			as_fn_error $? "cannot enable OCSP when x509store is disabled" "$LINENO" 5
+		fi
+		ssh_ocsp=yes
+	else
+		ssh_ocsp=no
+	fi
+
+else
+
+	if test "x$ssh_x509store" = "xyes"; then
+		ssh_ocsp=yes
+	else
+		ssh_ocsp=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: x509store is disabled - skiping OCSP" >&5
+$as_echo "$as_me: x509store is disabled - skiping OCSP" >&6;}
+	fi
+
+fi
+
+if test "x$ssh_ocsp" = "xyes"; then
+	for ac_func in OCSP_sendreq_bio
+do :
+  ac_fn_c_check_func "$LINENO" "OCSP_sendreq_bio" "ac_cv_func_OCSP_sendreq_bio"
+if test "x$ac_cv_func_OCSP_sendreq_bio" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OCSP_SENDREQ_BIO 1
+_ACEOF
+
+		ac_fn_c_check_header_mongrel "$LINENO" "openssl/ocsp.h" "ac_cv_header_openssl_ocsp_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_ocsp_h" = xyes; then :
+
+else
+
+			ssh_ocsp=no
+			as_fn_error $? "OCSP header not found" "$LINENO" 5
+
+fi
+
+
+
+else
+
+		ssh_ocsp=no
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find OCSP functions - OCSP is disabled" >&5
+$as_echo "$as_me: WARNING: Cannot find OCSP functions - OCSP is disabled" >&2;}
+
+fi
+done
+
+fi
+if test "x$ssh_ocsp" = "xyes"; then
+
+$as_echo "#define SSH_OCSP_ENABLED 1" >>confdefs.h
+
+	LIBOCSP='-lssl'
+	OCSP_ON=''
+	OCSP_OFF='#'
+else
+	LIBOCSP=
+	OCSP_ON='#'
+	OCSP_OFF=''
+fi
+
+
+
+
+
+# enable LDAP queries
+LDAP_MSG=no
+if test "x$ssh_x509store" = "xyes"; then
+
+
+ac_ldap=none
+# Check whether --enable-ldap was given.
+if test "${enable_ldap+set}" = set; then :
+  enableval=$enable_ldap; ac_ldap=$enableval
+
+fi
+
+
+if test "x$ac_ldap" = xyes; then
+  ac_ldap_prefix=""
+
+# Check whether --with-ldap-prefix was given.
+if test "${with_ldap_prefix+set}" = set; then :
+  withval=$with_ldap_prefix; ac_ldap_prefix=$withval
+
+fi
+
+
+
+# Check whether --with-ldap-bindir was given.
+if test "${with_ldap_bindir+set}" = set; then :
+  withval=$with_ldap_bindir; LDAP_BINDIR=$withval
+else
+
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_BINDIR="$ac_ldap_prefix/bin"
+      fi
+
+
+fi
+
+
+
+
+# Check whether --with-ldap-libexecdir was given.
+if test "${with_ldap_libexecdir+set}" = set; then :
+  withval=$with_ldap_libexecdir; LDAP_LIBEXECDIR=$withval
+else
+
+      if test "x$ac_ldap_prefix" = "x"; then
+        LDAP_LIBEXECDIR="/usr/libexec"
+      else
+        LDAP_LIBEXECDIR="$ac_ldap_prefix/libexec"
+      fi
+
+
+fi
+
+
+
+
+# Check whether --with-ldap-sysconfdir was given.
+if test "${with_ldap_sysconfdir+set}" = set; then :
+  withval=$with_ldap_sysconfdir; LDAP_SYSCONFDIR=$withval
+else
+  LDAP_SYSCONFDIR="$ac_ldap_prefix/etc/openldap"
+
+fi
+
+
+
+
+
+# Check whether --with-ldap-libdir was given.
+if test "${with_ldap_libdir+set}" = set; then :
+  withval=$with_ldap_libdir; LDAP_LDFLAGS="-L$withval"
+else
+
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_LDFLAGS="-L$ac_ldap_prefix/lib"
+      else
+        LDAP_LDFLAGS=""
+      fi
+
+
+fi
+
+
+
+
+# Check whether --with-ldap-includedir was given.
+if test "${with_ldap_includedir+set}" = set; then :
+  withval=$with_ldap_includedir; LDAP_CPPFLAGS="-I$withval"
+else
+
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_CPPFLAGS="-I$ac_ldap_prefix/include"
+      else
+        LDAP_CPPFLAGS=""
+      fi
+
+
+fi
+
+
+
+
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS"
+  for ac_header in lber.h ldap.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+
+      as_fn_error $? "cannot found LDAP headers" "$LINENO" 5
+
+
+fi
+
+done
+
+  CPPFLAGS="$ac_save_CPPFLAGS"
+
+  ac_ldap_libs=""
+
+# Check whether --with-ldap-libs was given.
+if test "${with_ldap_libs+set}" = set; then :
+  withval=$with_ldap_libs; ac_ldap_libs="$withval"
+
+fi
+
+
+### Try to link with LDAP libs
+  ac_save_LDFLAGS="$LDFLAGS"
+  ac_save_LIBS="$LIBS"
+
+  LDFLAGS="$LDAP_LDFLAGS $LDFLAGS"
+  ac_LDAP_LINK=""
+  if test "x$ac_ldap_libs" != "x"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking to link with specified LDAP libs" >&5
+$as_echo_n "checking to link with specified LDAP libs... " >&6; }
+
+    LDAP_LIBS="$ac_ldap_libs"
+    LIBS="$LDAP_LIBS $ac_save_LIBS"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_init ();
+int
+main ()
+{
+return ldap_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_LDAP_LINK="yes"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    if test "x$ac_LDAP_LINK" != "xyes"; then
+      as_fn_error $? "cannot link with specified LDAP libs" "$LINENO" 5
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link LDAP libs" >&5
+$as_echo_n "checking how to link LDAP libs... " >&6; }
+
+    LDAP_LIBS="-lldap"
+    for L in lber ssl crypto; do
+      LDAP_LIBS="$LDAP_LIBS -l$L"
+      LIBS="$LDAP_LIBS $ac_save_LIBS"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_init ();
+int
+main ()
+{
+return ldap_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_LDAP_LINK="yes"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+      if test "x$ac_LDAP_LINK" = "xyes"; then
+        break
+      fi
+    done
+    if test "x$ac_LDAP_LINK" != "xyes"; then
+      as_fn_error $? "cannot link with default LDAP libs" "$LINENO" 5
+    fi
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+  LIBS="$ac_save_LIBS"
+  LDFLAGS="$ac_save_LDFLAGS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: LDAP is disabled" >&5
+$as_echo "$as_me: LDAP is disabled" >&6;}
+fi
+
+if test "x$ac_ldap" = "xyes"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LDAP_ENABLED 1
+_ACEOF
+
+	LDAP_ON=''
+	LDAP_OFF='#'
+else
+	LDAP_ON='#'
+	LDAP_OFF=''
+fi
+
+
+
+	if test "x$LDAP_ON" = "x"; then
+		LDAP_MSG=yes
+		for ac_prog in openldapadd ldapadd
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LDAPADD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LDAPADD"; then
+  ac_cv_prog_LDAPADD="$LDAPADD" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="PATH="$LDAP_BINDIR:$PATH""
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LDAPADD="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LDAPADD=$ac_cv_prog_LDAPADD
+if test -n "$LDAPADD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDAPADD" >&5
+$as_echo "$LDAPADD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$LDAPADD" && break
+done
+test -n "$LDAPADD" || LDAPADD="false"
+
+	fi
+
+
+if test "x$ac_ldap" = "xyes"; then
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  ac_save_LDFLAGS="$LDFLAGS"
+  ac_save_LIBS="$LIBS"
+  CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS"
+  LDFLAGS="$LDFLAGS $LDAP_LDFLAGS"
+  LIBS="$LDAP_LIBS $LIBS"
+  for ac_func in \
+		ldap_initialize \
+		ldap_parse_result \
+		ldap_sasl_bind_s \
+		ldap_search_ext_s \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+  LIBS="$ac_save_LIBS"
+  LDFLAGS="$ac_save_LDFLAGS"
+  CPPFLAGS="$ac_save_CPPFLAGS"
+fi
+
+else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: x509store is disabled - skiping LDAP" >&5
+$as_echo "$as_me: x509store is disabled - skiping LDAP" >&6;}
+fi
+
+
+ssh_x509dn_email=yes
+if test "x$ssh_x509store" = "xyes"; then
+	# Check for Email in X.509 'Distinguished Name'
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Email in X.509 'Distinguished Name'" >&5
+$as_echo_n "checking for Email in X.509 'Distinguished Name'... " >&6; }
+	if test "$cross_compiling" = yes; then :
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming no" >&5
+$as_echo "$as_me: WARNING: cross compiling: assuming no" >&2;}
+		ssh_x509dn_email=no
+
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <openssl/evp.h>
+
+int main(void) {
+  int nid;
+  nid = OBJ_txt2nid("Email");
+  if (nid == NID_undef)
+    exit (1);
+  exit (0);
+  return (0);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		ssh_x509dn_email=no
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	# Check for the existence of "X509_VERIFY_PARAM *param" (OpenSSL 0.9.8+)
+	# OpenSSL v1.1 change X509_STORE_CTX to opaque structure
+	# Instead to check for member param we check for get functions
+		for ac_func in X509_STORE_CTX_get0_param
+do :
+  ac_fn_c_check_func "$LINENO" "X509_STORE_CTX_get0_param" "ac_cv_func_X509_STORE_CTX_get0_param"
+if test "x$ac_cv_func_X509_STORE_CTX_get0_param" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_X509_STORE_CTX_GET0_PARAM 1
+_ACEOF
+
+fi
+done
+
+fi
+if test "x$ssh_x509dn_email" = "xno"; then
+
+$as_echo "#define SSH_OPENSSL_DN_WITHOUT_EMAIL 1" >>confdefs.h
+
+fi
+
+# check for openssl 0.9.7+ functions ...
+for ac_func in  \
+  EVP_MD_CTX_init \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# check for openssl 0.9.8+ functions ...
+for ac_func in  \
+  EVP_CIPHER_CTX_new \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# check for openssl 1.0+ functions ...
+for ac_func in  \
+  ERR_remove_thread_state \
+  EVP_MD_flags \
+  EVP_PKEY_id \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# check for some structures
+ac_fn_c_check_member "$LINENO" "ECDSA_METHOD" "name" "ac_cv_member_ECDSA_METHOD_name" "#include <openssl/ecdsa.h>
+
+"
+if test "x$ac_cv_member_ECDSA_METHOD_name" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ECDSA_METHOD_NAME 1
+_ACEOF
+
+
+fi
+
+
+# check for openssl 1.0.0+ functions ...
+for ac_func in  \
+  X509_STORE_set_verify_cb \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# check for openssl 1.0.2+ functions ...
+for ac_func in  \
+  ECDSA_METHOD_new \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# check for openssl 1.1+ functions ...
+for ac_func in  \
+  ASN1_STRING_get0_data \
+  DH_get0_key \
+  DSA_meth_new \
+  DSA_SIG_get0 \
+  DSA_SIG_set0 \
+  EC_KEY_METHOD_new \
+  ECDSA_SIG_get0 \
+  ECDSA_SIG_set0 \
+  EVP_CIPHER_CTX_iv \
+  EVP_CIPHER_meth_new \
+  EVP_MD_CTX_new \
+  EVP_PKEY_get0_EC_KEY \
+  OPENSSL_init_crypto \
+  RSA_meth_new \
+  RSA_PKCS1_OpenSSL \
+  X509_CRL_get0_lastUpdate \
+  X509_get0_tbs_sigalg \
+  X509_get_key_usage \
+  X509_OBJECT_new \
+  X509_STORE_get0_objects \
+  X509_STORE_lock
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# check for removed in openssl 1.1+ functions ...
+for ac_func in  \
+  EVP_dss1 \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# check for openssl 1.1+ opaque structures ...
+ac_fn_c_check_type "$LINENO" "struct x509_lookup_method_st" "ac_cv_type_struct_x509_lookup_method_st" "
+#include <openssl/x509_vfy.h>
+
+"
+if test "x$ac_cv_type_struct_x509_lookup_method_st" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_X509_LOOKUP_METHOD_ST 1
+_ACEOF
+
+
+fi
+
+
+# functions hidden in openssl compatible libraries
+ac_fn_c_check_decl "$LINENO" "UTF8_getc" "ac_cv_have_decl_UTF8_getc" "$ac_includes_default"
+if test "x$ac_cv_have_decl_UTF8_getc" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_UTF8_GETC $ac_have_decl
+_ACEOF
+
+for ac_func in UTF8_getc
+do :
+  ac_fn_c_check_func "$LINENO" "UTF8_getc" "ac_cv_func_UTF8_getc"
+if test "x$ac_cv_func_UTF8_getc" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UTF8_GETC 1
+_ACEOF
+
+fi
+done
+
+
+# ASN1_STRING_length const argument >= 1.0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ASN1_STRING_length declare const argument" >&5
+$as_echo_n "checking whether ASN1_STRING_length declare const argument... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <openssl/asn1.h>
+int ASN1_STRING_length(const ASN1_STRING *x) {
+  (void) x; return 0;
+}
+
+int
+main ()
+{
+
+  ASN1_STRING_length(NULL);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  asn1_string_length_const="const"
+
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  asn1_string_length_const="/* not const */"
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat >>confdefs.h <<_ACEOF
+#define ASN1_STRING_LENGTH_CONST $asn1_string_length_const
+_ACEOF
+
+
+# check for function sk_OPENSSL_STRING_new_null inlined in openssl 1.1+ ...
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sk_OPENSSL_STRING_new_null" >&5
+$as_echo_n "checking for sk_OPENSSL_STRING_new_null... " >&6; }
+if ${ac_cv_func_sk_OPENSSL_STRING_new_null+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #include <openssl/safestack.h>
+
+int
+main ()
+{
+
+      void *q;
+      q = sk_OPENSSL_STRING_new_null();
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+   ac_cv_func_sk_OPENSSL_STRING_new_null=yes
+else
+   ac_cv_func_sk_OPENSSL_STRING_new_null=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_sk_OPENSSL_STRING_new_null" >&5
+$as_echo "$ac_cv_func_sk_OPENSSL_STRING_new_null" >&6; }
+if test "x$ac_cv_func_sk_OPENSSL_STRING_new_null" = xyes; then
+
+$as_echo "#define HAVE_SK_OPENSSL_STRING_NEW_NULL 1" >>confdefs.h
+
+fi
+
+
+# test FIPS enabled openssl
+
+OPENSSL_FIPS_MODE=no
+# Check whether --enable-openssl-fips was given.
+if test "${enable_openssl_fips+set}" = set; then :
+  enableval=$enable_openssl_fips; ac_openssl_fips=$enableval
+else
+  ac_openssl_fips=none
+
+fi
+
+
+if test yes = $ac_openssl_fips; then
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <openssl/opensslconf.h>
+
+int
+main ()
+{
+
+#ifndef OPENSSL_FIPS
+error OPENSSL_FIPS is not defined
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  as_fn_error $? "cannot found fips capable openssl header" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+if test yes = $ac_openssl_fips; then
+  ac_fn_c_check_func "$LINENO" "FIPS_mode" "ac_cv_func_FIPS_mode"
+if test "x$ac_cv_func_FIPS_mode" = xyes; then :
+
+else
+  as_fn_error $? "cannot found fips capable openssl library" "$LINENO" 5
+
+fi
+
+fi
+if test yes = $ac_openssl_fips; then
+  OPENSSL_FIPS_MODE=yes
+fi
+
+
+FIPS_LIBS=
+FIPSHMAC=':'
+if test yes = $OPENSSL_FIPS_MODE; then
+  # check for Red Hat specific fips library
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FIPSCHECK_verify in -lfipscheck" >&5
+$as_echo_n "checking for FIPSCHECK_verify in -lfipscheck... " >&6; }
+if ${ac_cv_lib_fipscheck_FIPSCHECK_verify+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfipscheck  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char FIPSCHECK_verify ();
+int
+main ()
+{
+return FIPSCHECK_verify ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_fipscheck_FIPSCHECK_verify=yes
+else
+  ac_cv_lib_fipscheck_FIPSCHECK_verify=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fipscheck_FIPSCHECK_verify" >&5
+$as_echo "$ac_cv_lib_fipscheck_FIPSCHECK_verify" >&6; }
+if test "x$ac_cv_lib_fipscheck_FIPSCHECK_verify" = xyes; then :
+
+    FIPS_LIBS="-lfipscheck"
+    for ac_header in fipscheck.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fipscheck.h" "ac_cv_header_fipscheck_h" "$ac_includes_default"
+if test "x$ac_cv_header_fipscheck_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FIPSCHECK_H 1
+_ACEOF
+
+fi
+
+done
+
+    FIPSHMAC=fipshmac
+
+fi
+
+fi
+
+
+
+
+# Where to place sshd.pid
+piddir=/var/run
+# make sure the directory exists
+if test ! -d $piddir ; then
+	piddir=`eval echo ${sysconfdir}`
+	case $piddir in
+		NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
+	esac
+fi
+
+
+# Check whether --with-pid-dir was given.
+if test "${with_pid_dir+set}" = set; then :
+  withval=$with_pid_dir;
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			piddir=$withval
+			if test ! -d $piddir ; then
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ** no $piddir directory on this system **" >&5
+$as_echo "$as_me: WARNING: ** no $piddir directory on this system **" >&2;}
+			fi
+		fi
+
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define _PATH_SSH_PIDDIR "$piddir"
+_ACEOF
+
+
+
+# Check whether --enable-lastlog was given.
+if test "${enable_lastlog+set}" = set; then :
+  enableval=$enable_lastlog;
+		if test "x$enableval" = "xno" ; then
+			$as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h
+
+		fi
+
+
+fi
+
+# Check whether --enable-utmp was given.
 if test "${enable_utmp+set}" = set; then :
   enableval=$enable_utmp;
 		if test "x$enableval" = "xno" ; then
@@ -18651,18 +19754,23 @@
 
 fi
 
+ssh_disable_utmpx=no
 # Check whether --enable-utmpx was given.
 if test "${enable_utmpx+set}" = set; then :
   enableval=$enable_utmpx;
-		if test "x$enableval" = "xno" ; then
-
-$as_echo "#define DISABLE_UTMPX 1" >>confdefs.h
+		ssh_disable_utmpx=$enableval
 
-		fi
 
+fi
 
+if test no = $ac_cv_header_utmpx_h; then
+		ssh_disable_utmpx=yes
 fi
+if test yes = $ssh_disable_utmpx; then
+
+$as_echo "#define DISABLE_UTMPX 1" >>confdefs.h
 
+fi
 # Check whether --enable-wtmp was given.
 if test "${enable_wtmp+set}" = set; then :
   enableval=$enable_wtmp;
@@ -18838,6 +19946,10 @@
 #ifdef HAVE_PATHS_H
 #  include <paths.h>
 #endif
+/* Compatibility names for the strings of the canonical file names */
+#ifndef UTMP_FILE
+#define UTMP_FILE	_PATH_UTMP
+#endif
 
 int
 main ()
@@ -18888,6 +20000,10 @@
 #ifdef HAVE_PATHS_H
 #  include <paths.h>
 #endif
+/* Compatibility names for the strings of the canonical file names */
+#ifndef WTMP_FILE
+#define WTMP_FILE	_PATH_WTMP
+#endif
 
 int
 main ()
@@ -19056,8 +20172,14 @@
 
 
 
-ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile survey.sh"
+ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile tests/CA/Makefile tests/CA/env survey.sh"
 
+if test yes = $OPENSSL_FIPS_MODE; then
+  if test -n "$FIPSLD_CC"; then
+    CC='FIPSLD_CC=$(FIPSLD_CC) '$CC
+    LD='FIPSLD_CC=$(FIPSLD_CC) '$LD
+  fi
+fi
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -19565,7 +20687,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by OpenSSH $as_me Portable, which was
+This file was extended by PKIX-SSH $as_me 10.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19621,13 +20743,14 @@
 Configuration headers:
 $config_headers
 
-Report bugs to <openssh-unix-dev@mindrot.org>."
+Report bugs to <ssh_x509@roumenpetrov.info>.
+PKIX-SSH home page: <http://roumenpetrov.info/secsh>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-OpenSSH config.status Portable
+PKIX-SSH config.status 10.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -19757,6 +20880,8 @@
     "openssh.xml") CONFIG_FILES="$CONFIG_FILES openssh.xml" ;;
     "openbsd-compat/Makefile") CONFIG_FILES="$CONFIG_FILES openbsd-compat/Makefile" ;;
     "openbsd-compat/regress/Makefile") CONFIG_FILES="$CONFIG_FILES openbsd-compat/regress/Makefile" ;;
+    "tests/CA/Makefile") CONFIG_FILES="$CONFIG_FILES tests/CA/Makefile" ;;
+    "tests/CA/env") CONFIG_FILES="$CONFIG_FILES tests/CA/env" ;;
     "survey.sh") CONFIG_FILES="$CONFIG_FILES survey.sh" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -20364,6 +21489,7 @@
 echo "                     User binaries: $B"
 echo "                   System binaries: $C"
 echo "               Configuration files: $D"
+echo "                           CA root: $sshcadir"
 echo "                   Askpass program: $E"
 echo "                      Manual pages: $F"
 echo "                          PID file: $G"
@@ -20388,7 +21514,11 @@
 echo "                   SELinux support: $SELINUX_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
+echo "              TCP Wrappers support: $TCPW_MSG"
 echo "              MD5 password support: $MD5_MSG"
+echo "               X.509 store support: $ssh_x509store"
+echo "                      OCSP support: $ssh_ocsp"
+echo "                      LDAP queries: $LDAP_MSG"
 echo "                   libedit support: $LIBEDIT_MSG"
 echo "                   libldns support: $LDNS_MSG"
 echo "  Solaris process contract support: $SPC_MSG"
@@ -20399,10 +21529,14 @@
 echo "                  BSD Auth support: $BSD_AUTH_MSG"
 echo "              Random number source: $RAND_MSG"
 echo "             Privsep sandbox style: $SANDBOX_STYLE"
+echo "                FIPS capable build: $OPENSSL_FIPS_MODE"
 
 echo ""
 
 echo "              Host: ${host}"
+if test yes = $OPENSSL_FIPS_MODE; then
+echo "   Actual compiler: $FIPSLD_CC"
+fi
 echo "          Compiler: ${CC}"
 echo "    Compiler flags: ${CFLAGS}"
 echo "Preprocessor flags: ${CPPFLAGS}"
@@ -20422,6 +21556,25 @@
 	echo ""
 fi
 
+if test "x$LDAP_MSG" = "xyes" ; then
+echo "Extra LDAP flags:"
+echo "    LDAP compiler flags: ${LDAP_CFLAGS}"
+echo "LDAP preprocessor flags: ${LDAP_CPPFLAGS}"
+echo "      LDAP linker flags: ${LDAP_LDFLAGS}"
+echo "         LDAP libraries: ${LDAP_LIBS}"
+echo ""
+echo "LDAP paths(used only in tests):"
+echo "     LDAP sysconfig dir: ${LDAP_SYSCONFDIR}"
+echo "       LDAP libexec dir: ${LDAP_LIBEXECDIR}"
+echo "           LDAP bin dir: ${LDAP_BINDIR}"
+echo ""
+fi
+
+if test yes = $OPENSSL_FIPS_MODE; then
+echo "    FIPS libraries: $FIPS_LIBS"
+echo ""
+fi
+
 if test "x$PAM_MSG" = "xyes" ; then
 	echo "PAM is enabled. You may need to install a PAM control file "
 	echo "for sshd, otherwise password authentication may fail. "
diff -ruN openssh-7.5p1/configure.ac openssh-7.5p1+x509-10.2/configure.ac
--- openssh-7.5p1/configure.ac	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/configure.ac	2017-05-20 21:07:00.000000000 +0300
@@ -1,6 +1,7 @@
 # $Id: configure.ac,v 1.583 2014/08/26 20:32:01 djm Exp $
 #
 # Copyright (c) 1999-2004 Damien Miller
+# Copyright (c) 2002-2017 Roumen Petrov
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -14,9 +15,12 @@
 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
-AC_REVISION($Revision: 1.583 $)
+AC_PREREQ([2.61])
+m4_include([version.m4])
+
+AC_INIT([SSH_PACKAGE], [SSH_VERSION], [SSH_BUGREPORT], [openssh], [SSH_URL])
 AC_CONFIG_SRCDIR([ssh.c])
+m4_include([m4/ldap.m4])
 AC_LANG([C])
 
 AC_CONFIG_HEADER([config.h])
@@ -99,7 +103,7 @@
 	#include <dev/systrace.h>
 ])
 AC_CHECK_DECL([RLIMIT_NPROC],
-    [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [
+    [AC_DEFINE([HAVE_RLIMIT_NPROC], [1], [sys/resource.h has RLIMIT_NPROC])], , [
 	#include <sys/types.h>
 	#include <sys/resource.h>
 ])
@@ -108,48 +112,49 @@
 	#include <linux/prctl.h>
 ])
 
-openssl=yes
-ssh1=no
-COMMENT_OUT_RSA1="#no ssh1#"
+dnl compatibility argument
 AC_ARG_WITH([openssl],
-	[  --without-openssl       Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
-	[  if test "x$withval" = "xno" ; then
-		openssl=no
-		ssh1=no
-	   fi
-	]
+	[AS_HELP_STRING([--without-openssl],
+		[Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ])],
+	[],
+	[with_openssl=yes]
 )
 AC_MSG_CHECKING([whether OpenSSL will be used for cryptography])
-if test "x$openssl" = "xyes" ; then
-	AC_MSG_RESULT([yes])
-	AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
-else
-	AC_MSG_RESULT([no])
+AC_MSG_RESULT([$with_openssl])
+if test "x$with_openssl" != "xyes"; then
+	AC_MSG_ERROR([build with OpenSSL is required])
 fi
 
+dnl compatibility argument
 AC_ARG_WITH([ssh1],
-	[  --with-ssh1             Enable support for SSH protocol 1],
-	[
-		if test "x$withval" = "xyes" ; then
-			if test "x$openssl" = "xno" ; then
-				AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled])
-			fi
-			ssh1=yes
-			COMMENT_OUT_RSA1=""
-		elif test "x$withval" = "xno" ; then
-			ssh1=no
-		else
-			AC_MSG_ERROR([unknown --with-ssh1 argument])
-		fi
-	]
+	[AS_HELP_STRING([--with-ssh1],
+		[Enable support for SSH protocol 1; overriden by --enable-ssh1])],
+	[],
+	[with_ssh1=no]
+)
+case "x$with_ssh1" in
+  "xyes"|"xno");;
+  *) AC_MSG_ERROR([unknown --with-ssh1 argument]);;
+esac
+
+openssl=yes
+AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
+
+AC_ARG_ENABLE([ssh1],
+	[AS_HELP_STRING([--enable-ssh1],
+		[Enable support for SSH protocol 1])],
+	[ssh1=$enableval],
+	[ssh1=$with_ssh1]
 )
 AC_MSG_CHECKING([whether SSH protocol 1 support is enabled])
-if test "x$ssh1" = "xyes" ; then
-	AC_MSG_RESULT([yes])
+AC_MSG_RESULT([ssh1])
+
+AC_SUBST([COMMENT_OUT_RSA1])
+if test "x$ssh1" != "xno" ; then
+	COMMENT_OUT_RSA1=
 	AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support])
-	AC_SUBST([COMMENT_OUT_RSA1])
 else
-	AC_MSG_RESULT([no])
+	COMMENT_OUT_RSA1="#no ssh1#"
 fi
 
 use_stack_protector=1
@@ -170,7 +175,7 @@
 AC_MSG_CHECKING([if $CC supports -Werror])
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
 	[ AC_MSG_RESULT([yes])
 	  WERROR="-Werror"],
 	[ AC_MSG_RESULT([no])
@@ -355,6 +360,27 @@
 	]
 )
 
+AC_SUBST([XLDFLAGS])
+case "$host" in
+*-*-linux-android*)
+	dnl inline function, i.e. not-detectable
+	ac_cv_func_getpagesize=yes
+
+	ac_cv_file_dev_ptmx=yes
+
+	dnl openpty is detected by configure for API 23+, but declared
+	dnl => use bsd port, based on /dev/ptmx for consistency
+	ac_cv_func_openpty=no
+	ac_cv_search_openpty=no
+
+	dnl API 21+ define statvfs, fstatvfs and adds sys/statvfs.h
+	dnl => use bsd port for consistency
+	ac_cv_header_sys_statvfs_h=ignore
+	ac_cv_func_fstatvfs=use_bsd_port
+	ac_cv_func_statvfs=use_bsd_port
+	;;
+esac
+
 AC_CHECK_HEADERS([ \
 	blf.h \
 	bstring.h \
@@ -411,6 +437,7 @@
 	sys/stream.h \
 	sys/stropts.h \
 	sys/strtio.h \
+	sys/statfs.h \
 	sys/statvfs.h \
 	sys/sysmacros.h \
 	sys/time.h \
@@ -565,10 +592,6 @@
 	AC_DEFINE([PTY_ZEROREAD], [1], [read(1) can return 0 for a non-closed fd])
 	AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)])
 	;;
-*-*-android*)
-	AC_DEFINE([DISABLE_UTMP], [1], [Define if you don't want to use utmp])
-	AC_DEFINE([DISABLE_WTMP], [1], [Define if you don't want to use wtmp])
-	;;
 *-*-cygwin*)
 	check_for_libcrypt_later=1
 	LIBS="$LIBS /usr/lib/textreadmode.o"
@@ -618,11 +641,18 @@
 	AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect])
 	AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1],
 		[Define if your resolver libs need this for getrrsetbyname])
-	AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
-	AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
-	    [Use tunnel device compatibility to OpenBSD])
-	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
-	    [Prepend the address family to IP tunnel traffic])
+	AC_CHECK_HEADERS([net/if_utun.h])
+	if test "x$ac_cv_header_net_if_utun_h" = "xyes" ; then
+		AC_DEFINE([SSH_TUN_DARWIN], [1],
+		    [Open tunnel devices the Darwin way])
+	else
+		AC_DEFINE([SSH_TUN_FREEBSD], [1],
+		    [Open tunnel devices the FreeBSD way])
+		AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
+		    [Prepend the address family to IP tunnel traffic])
+		AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
+		    [Use tunnel device compatibility to OpenBSD])
+	fi
 	m4_pattern_allow([AU_IPv])
 	AC_CHECK_DECL([AU_IPv4], [],
 	    AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
@@ -690,7 +720,7 @@
 		AC_DEFINE([HAVE_SECUREWARE], [1],
 			[Define if you have SecureWare-based
 			protected password database])
-		disable_ptmx_check=yes
+		ac_cv_file_dev_ptmx=disable
 		LIBS="$LIBS -lsecpw"
 		;;
 	esac
@@ -736,7 +766,11 @@
 	AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
 	;;
 *-*-linux*)
-	no_dev_ptmx=1
+	case "$host" in
+	*-*-linux-android*) ;;
+	*)
+		ac_cv_file_dev_ptmx=ignore;;
+	esac
 	use_pie=auto
 	check_for_libcrypt_later=1
 	check_for_openpty_ctty_bug=1
@@ -751,9 +785,22 @@
 	AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM],
 		[Define to whatever link() returns for "not supported"
 		if it doesn't return EOPNOTSUPP.])
+	case "$host" in
+	*-*-linux-android*) ;;
+	*)
 	AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
 	AC_DEFINE([USE_BTMP])
+		;;
+	esac
 	AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])
+
+	case "$host" in
+	*-*-linux-android*)
+		LIBS="$LIBS -llog"
+		XLDFLAGS='-Wl,--wrap=open -Wl,--wrap=fopen'
+		;;
+	esac
+
 	inet6_default_4in6=yes
 	case `uname -r` in
 	1.*|2.0.*)
@@ -1033,11 +1080,11 @@
 	;;
 # SCO OpenServer 5.x
 *-*-sco3.2v5*)
+	ac_cv_file_dev_ptmx=ignore
 	if test -z "$GCC"; then
 		CFLAGS="$CFLAGS -belf"
 	fi
 	LIBS="$LIBS -lprot -lx -ltinfo -lm"
-	no_dev_ptmx=1
 	AC_DEFINE([USE_PIPES])
 	AC_DEFINE([HAVE_SECUREWARE])
 	AC_DEFINE([DISABLE_SHADOW])
@@ -1152,6 +1199,13 @@
 	;;
 esac
 
+dnl adjust TEST_SHELL to autotools norms:
+if test -n "$CONFIG_SHELL"; then
+	dnl set(overide) TEST_SHELL to the autoconf one
+	TEST_SHELL=$CONFIG_SHELL
+fi
+
+
 AC_MSG_CHECKING([compiler and flags for sanity])
 AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]], [[ exit(0); ]])],
 	[	AC_MSG_RESULT([yes]) ],
@@ -1391,7 +1445,8 @@
 AC_CHECK_DECL([VIS_ALL], ,
     AC_DEFINE(BROKEN_STRNVIS, 1, [missing VIS_ALL]), [#include <vis.h>])
 
-AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
+AC_CACHE_CHECK([whether struct dirent allocates space for d_name],
+	[ssh_cv_dirent_allocates_space_for_d_name],[
 AC_RUN_IFELSE(
 	[AC_LANG_PROGRAM([[
 #include <sys/types.h>
@@ -1400,18 +1455,22 @@
 	struct dirent d;
 	exit(sizeof(d.d_name)<=sizeof(char));
 	]])],
-	[AC_MSG_RESULT([yes])],
-	[
-		AC_MSG_RESULT([no])
+	[ssh_cv_dirent_allocates_space_for_d_name=yes],
+	[ssh_cv_dirent_allocates_space_for_d_name=no],
+	[ssh_cv_dirent_allocates_space_for_d_name=cross]
+)
+])
+case $ssh_cv_dirent_allocates_space_for_d_name in
+	no)
 		AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME], [1],
 			[Define if your struct dirent expects you to
 			allocate extra space for d_name])
-	],
-	[
+		;;
+	cross)
 		AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME])
 		AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME])
-	]
-)
+		;;
+esac
 
 AC_MSG_CHECKING([for /proc/pid/fd directory])
 if test -d "/proc/$$/fd" ; then
@@ -1470,51 +1529,103 @@
 	]
 )
 
+# Check whether user wants TCP wrappers support
+TCPW_MSG="no"
+AC_ARG_WITH([tcp-wrappers],
+	[AS_HELP_STRING([--with-tcp-wrappers@<:@=PATH@:>@],
+		[Enable tcpwrappers support (optionally in PATH)])],
+	[AS_IF([test "x$withval" != "xno"],[
+		saved_LIBS="$LIBS"
+		saved_LDFLAGS="$LDFLAGS"
+		saved_CPPFLAGS="$CPPFLAGS"
+
+		AS_IF([test -n "${withval}" && \
+		    test "x${withval}" != "xyes"], [
+			AS_IF([test -d "${withval}/lib"], [
+				if test -n "${need_dash_r}"; then
+					LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+				fi
+			], [
+				if test -n "${need_dash_r}"; then
+					LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval} ${LDFLAGS}"
+				fi
+			])
+			AS_IF([test -d "${withval}/include"], [
+				CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+			], [
+				CPPFLAGS="-I${withval} ${CPPFLAGS}"
+			])
+		])
+
+		AC_MSG_CHECKING([how to link with wrap library])
+		# libwrap may require libnsl
+		for WRAPLIBS in "-lwrap" "-lwrap -lnsl"; do
+			LIBS="$WRAPLIBS $saved_LIBS"
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <tcpd.h>
+int deny_severity = 0, allow_severity = 0;]], [[
+	hosts_access(0);]]
+			)], [
+				TCPW_MSG=yes
+			])
+			test $TCPW_MSG = yes && break
+		done
+
+		if test $TCPW_MSG = yes; then
+			AC_MSG_RESULT([$WRAPLIBS])
+			AC_DEFINE([LIBWRAP], [1],
+				[Define if you want TCP Wrappers support])
+			SSHDLIBS="$SSHDLIBS $WRAPLIBS"
+		else
+			AC_MSG_ERROR([cannot link])
+		fi
+
+		LIBS="$saved_LIBS"
+	])]
+)
+
 # Check whether user wants to use ldns
 LDNS_MSG="no"
 AC_ARG_WITH(ldns,
-	[  --with-ldns[[=PATH]]      Use ldns for DNSSEC support (optionally in PATH)],
-	[
-	ldns=""
-	if test "x$withval" = "xyes" ; then
-		AC_PATH_TOOL([LDNSCONFIG], [ldns-config], [no])
-		if test "x$PKGCONFIG" = "xno"; then
-			CPPFLAGS="$CPPFLAGS -I${withval}/include"
-			LDFLAGS="$LDFLAGS -L${withval}/lib"
-			LIBS="-lldns $LIBS"
-			ldns=yes
-		else
-			LIBS="$LIBS `$LDNSCONFIG --libs`"
-			CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
+	[AS_HELP_STRING([--with-ldns@<:@=PATH@:>@],
+		[Use ldns for DNSSEC support (optionally in PATH)])],
+[
+	if test "x$withval" != "xno" ; then
+		if test "x$withval" != "xyes" ; then
+			CPPFLAGS="$CPPFLAGS -I$withval/include"
+			LDFLAGS="$LDFLAGS -L$withval/lib"
 		fi
-	elif test "x$withval" != "xno" ; then
-			CPPFLAGS="$CPPFLAGS -I${withval}/include"
-			LDFLAGS="$LDFLAGS -L${withval}/lib"
-			LIBS="-lldns $LIBS"
-			ldns=yes
-	fi
-
-	# Verify that it works.
-	if test "x$ldns" = "xyes" ; then
-		AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support])
+		LIBS="-lldns $LIBS"
 		LDNS_MSG="yes"
-		AC_MSG_CHECKING([for ldns support])
-		AC_LINK_IFELSE(
-			[AC_LANG_SOURCE([[
+	fi
+])
+# Verify that ldns works.
+if test "x$LDNS_MSG" = "xyes" ; then
+	AC_MSG_CHECKING([for ldns support])
+	AC_LINK_IFELSE([AC_LANG_SOURCE([[
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <ldns/ldns.h>
-int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
-			]])
-		],
-			[AC_MSG_RESULT(yes)],
-				[
-					AC_MSG_RESULT(no)
-					AC_MSG_ERROR([** Incomplete or missing ldns libraries.])
-				])
-	fi
-])
+int main() {
+  ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL);
+  status = LDNS_STATUS_OK;
+  exit(0);
+}]])],
+	[AC_MSG_RESULT(yes)],
+	[
+		AC_MSG_RESULT(no)
+		AC_MSG_ERROR([** Incomplete or missing ldns libraries.])
+	])
+	AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support])
+fi
 
 # Check whether user wants libedit support
 LIBEDIT_MSG="no"
@@ -1717,7 +1828,6 @@
 	inet_ntoa \
 	inet_ntop \
 	innetgr \
-	llabs \
 	login_getcapbool \
 	md5_crypt \
 	memmove \
@@ -1828,7 +1938,7 @@
 if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then
 	# PKCS#11 support requires dlopen() and co
 	AC_SEARCH_LIBS([dlopen], [dl],
-	    [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])]
+	    [AC_DEFINE([ENABLE_PKCS11], [1], [Enable for PKCS#11 support])]
 	)
 fi
 
@@ -2432,19 +2542,20 @@
 	]
 )
 
-openssl_engine=no
 AC_ARG_WITH([ssl-engine],
-	[  --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support ],
-	[
-		if test "x$withval" != "xno" ; then
-			if test "x$openssl" = "xno" ; then
-				AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
-			fi
-			openssl_engine=yes
-		fi
-	]
+	[AS_HELP_STRING([--with-ssl-engine],
+		[Enable OpenSSL (hardware) ENGINE support])],
+	[],
+	[with_ssl_engine=check]
 )
 
+COMMENT_OUT_ECC256="#no ecc256#"
+COMMENT_OUT_ECC384="#no ecc384#"
+COMMENT_OUT_ECC521="#no ecc521#"
+AC_SUBST([COMMENT_OUT_ECC256])
+AC_SUBST([COMMENT_OUT_ECC384])
+AC_SUBST([COMMENT_OUT_ECC521])
+
 if test "x$openssl" = "xyes" ; then
 	LIBS="-lcrypto $LIBS"
 	AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1],
@@ -2530,13 +2641,6 @@
 		]])],
 		[
 			ssl_library_ver=`cat conftest.ssllibver`
-			# Check version is supported.
-			case "$ssl_library_ver" in
-				10000*|0*)
-					AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
-			                ;;
-			        *) ;;
-			esac
 			AC_MSG_RESULT([$ssl_library_ver])
 		],
 		[
@@ -2584,7 +2688,7 @@
 	AC_MSG_CHECKING([if programs using OpenSSL functions will link])
 	AC_LINK_IFELSE(
 		[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
-		[[ SSLeay_add_all_algorithms(); ]])],
+		[[ OpenSSL_add_all_algorithms(); ]])],
 		[
 			AC_MSG_RESULT([yes])
 		],
@@ -2595,7 +2699,7 @@
 			AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
 			AC_LINK_IFELSE(
 				[AC_LANG_PROGRAM([[ #include <openssl/evp.h> ]],
-				[[ SSLeay_add_all_algorithms(); ]])],
+				[[ OpenSSL_add_all_algorithms(); ]])],
 				[
 					AC_MSG_RESULT([yes])
 				],
@@ -2607,20 +2711,21 @@
 		]
 	)
 
+	AC_CHECK_HEADERS([openssl/ec.h])
 	AC_CHECK_FUNCS([ \
+		BN_is_negative \
 		BN_is_prime_ex \
 		DSA_generate_parameters_ex \
 		EVP_DigestInit_ex \
 		EVP_DigestFinal_ex \
-		EVP_MD_CTX_init \
-		EVP_MD_CTX_cleanup \
 		EVP_MD_CTX_copy_ex \
 		HMAC_CTX_init \
 		RSA_generate_key_ex \
 		RSA_get_default_method \
 	])
 
-	if test "x$openssl_engine" = "xyes" ; then
+	if test "x$with_ssl_engine" != "xno" ; then
+		AC_CHECK_HEADERS([openssl/engine.h])
 		AC_MSG_CHECKING([for OpenSSL ENGINE support])
 		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 	#include <openssl/engine.h>
@@ -2707,25 +2812,6 @@
 		[AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
 		    [Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
 
-	AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
-	AC_LINK_IFELSE(
-		[AC_LANG_PROGRAM([[
-	#include <string.h>
-	#include <openssl/evp.h>
-		]], [[
-		if(EVP_DigestUpdate(NULL, NULL,0))
-			exit(0);
-		]])],
-		[
-			AC_MSG_RESULT([yes])
-		],
-		[
-			AC_MSG_RESULT([no])
-			AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1],
-			    [Define if EVP_DigestUpdate returns void])
-		]
-	)
-
 	# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
 	# because the system crypt() is more featureful.
 	if test "x$check_for_libcrypt_before" = "x1"; then
@@ -2744,6 +2830,9 @@
 	    [unsupported_algorithms="$unsupported_algorithms \
 		hmac-sha2-256 \
 		hmac-sha2-512 \
+		diffie-hellman-group14-sha256 \
+		diffie-hellman-group16-sha512 \
+		diffie-hellman-group18-sha512 \
 		diffie-hellman-group-exchange-sha256 \
 		hmac-sha2-256-etm@openssh.com \
 		hmac-sha2-512-etm@openssh.com"
@@ -2771,6 +2860,11 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
 		const EVP_MD *m = EVP_sha256(); /* We need this too */
@@ -2792,6 +2886,11 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
 		const EVP_MD *m = EVP_sha384(); /* We need this too */
@@ -2813,12 +2912,17 @@
 	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
 	# error "OpenSSL < 0.9.8g has unreliable ECC code"
 	#endif
+	#ifdef OPENSSL_FIPS
+	# if OPENSSL_VERSION_NUMBER < 0x00908fff /* 0.9.8* */
+	#  error "OpenSSL <= 0.9.8* has unreliable ECC code in FIPS build"
+	# endif
+	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
 		const EVP_MD *m = EVP_sha512(); /* We need this too */
 		]])],
 		[ AC_MSG_RESULT([yes])
-		  AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
+		  AC_CACHE_CHECK([if OpenSSL's NID_secp521r1 is functional],[ssh_cv_working_secp521r1],[
 		  AC_RUN_IFELSE(
 			[AC_LANG_PROGRAM([[
 	#include <openssl/ec.h>
@@ -2832,12 +2936,13 @@
 			const EVP_MD *m = EVP_sha512(); /* We need this too */
 			exit(e == NULL || m == NULL);
 			]])],
-			[ AC_MSG_RESULT([yes])
-			  enable_nistp521=1 ],
-			[ AC_MSG_RESULT([no]) ],
-			[ AC_MSG_WARN([cross-compiling: assuming yes])
-			  enable_nistp521=1 ]
-		  )],
+			[ssh_cv_working_secp521r1=yes],
+			[ssh_cv_working_secp521r1=no]
+		  )])
+		  if test "x$ssh_cv_working_secp521r1" = xyes ; then
+			enable_nistp521=1
+		  fi
+		],
 		AC_MSG_RESULT([no])
 	)
 
@@ -2853,6 +2958,7 @@
 		    [libcrypto has NID_X9_62_prime256v1])
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC256=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdsa-sha2-nistp256 \
@@ -2863,6 +2969,7 @@
 		AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1])
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC384=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdsa-sha2-nistp384 \
@@ -2873,6 +2980,7 @@
 		AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1])
 		TEST_SSH_ECC=yes
 		COMMENT_OUT_ECC=""
+		COMMENT_OUT_ECC521=
 	else
 		unsupported_algorithms="$unsupported_algorithms \
 			ecdh-sha2-nistp521 \
@@ -2887,6 +2995,10 @@
 	AC_CHECK_FUNCS([crypt])
 fi
 
+AC_CHECK_DECLS([arc4random])
+AC_CHECK_DECLS([arc4random_buf])
+AC_CHECK_DECLS([arc4random_stir])
+AC_CHECK_DECLS([arc4random_uniform])
 AC_CHECK_FUNCS([ \
 	arc4random \
 	arc4random_buf \
@@ -3630,8 +3742,13 @@
 #endif
 ])
 
+dnl on Android netinet/in.h define __in_addr_t and arpa/inet.h define in_addr_t
+AC_CHECK_HEADERS([arpa/inet.h])
 AC_CHECK_TYPES([in_addr_t, in_port_t], , ,
 [#include <sys/types.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 #include <netinet/in.h>])
 
 AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [
@@ -4434,21 +4551,20 @@
     ]
 ) # maildir
 
-if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
+if test "${ac_cv_file_dev_ptmx+set}" != set && test "x$cross_compiling" = "xyes"; then
 	AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test])
-	disable_ptmx_check=yes
-fi
-if test -z "$no_dev_ptmx" ; then
-	if test "x$disable_ptmx_check" != "xyes" ; then
-		AC_CHECK_FILE(["/dev/ptmx"],
-			[
-				AC_DEFINE_UNQUOTED([HAVE_DEV_PTMX], [1],
-					[Define if you have /dev/ptmx])
-				have_dev_ptmx=1
-			]
-		)
+	ac_cv_file_dev_ptmx=cross
+else
+	if test "${ac_cv_file_dev_ptmx+set}" = set ; then
+		AC_CACHE_CHECK([for "/dev/ptmx"],[ac_cv_file_dev_ptmx])
+	else
+		AC_CHECK_FILE(["/dev/ptmx"])
 	fi
 fi
+if test "x$ac_cv_file_dev_ptmx" = xyes ; then
+	AC_DEFINE_UNQUOTED([HAVE_DEV_PTMX], [1],
+		[Define if you have /dev/ptmx])
+fi
 
 if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then
 	AC_CHECK_FILE(["/dev/ptc"],
@@ -4731,6 +4847,320 @@
 	]
 )
 
+# X.509 support
+ssh_x509=yes
+
+# Starting from version 5.7 OpenSSH use memory BIO buffer
+# to read/write keys instead file streams.
+AC_DEFINE(
+    [OPENSSH_KEYS_USE_BIO], [1],
+    [Define if OpenSSH use memory BIO buffer to read/write keys])
+# Reserved for future use
+#AC_DEFINE(
+#    [X509_DISABLED], [1],
+#    [Define if you want to disable X.509 certificates])
+
+# Where to place ssh CA root
+sshcadir='${sysconfdir}/ca'
+sshcadir=`eval echo ${sshcadir}`
+sshcadir=`eval echo ${sshcadir}`
+case $sshcadir in
+	NONE/*) sshcadir=`echo $sshcadir | sed "s~NONE~$ac_default_prefix~"` ;;
+esac
+
+AC_ARG_WITH([sshca-dir],
+	[AS_HELP_STRING([--with-sshca-dir=PATH], [Specify location of ssh CA root])],
+	[
+		if test "x$withval" != "xno" ; then
+			sshcadir=$withval
+		fi
+	]
+)
+
+AC_DEFINE_UNQUOTED([SSHCADIR], ["$sshcadir"], [Specify location of ssh CA root])
+AC_SUBST([sshcadir])
+
+
+ssh_x509store=yes #required since PKIX-SSH 9.0
+
+
+# enable/disable OCSP requests
+AC_ARG_ENABLE([ocsp],
+	[AS_HELP_STRING([--disable-ocsp], [Disable OCSP validation])],
+	[
+	if test "x$enableval" = "xyes"; then
+		if test "x$ssh_x509store" != "xyes"; then
+			AC_MSG_ERROR([cannot enable OCSP when x509store is disabled])
+		fi
+		ssh_ocsp=yes
+	else
+		ssh_ocsp=no
+	fi
+	],
+	[
+	if test "x$ssh_x509store" = "xyes"; then
+		ssh_ocsp=yes
+	else
+		ssh_ocsp=no
+		AC_MSG_NOTICE([x509store is disabled - skiping OCSP])
+	fi
+	])
+if test "x$ssh_ocsp" = "xyes"; then
+	AC_CHECK_FUNCS([OCSP_sendreq_bio],
+	[
+		AC_CHECK_HEADER([openssl/ocsp.h],
+		[],
+		[
+			ssh_ocsp=no
+			AC_MSG_ERROR([OCSP header not found])
+		])
+	],
+	[
+		ssh_ocsp=no
+		AC_MSG_WARN([Cannot find OCSP functions - OCSP is disabled])
+	])
+fi
+if test "x$ssh_ocsp" = "xyes"; then
+	AC_DEFINE(
+		[SSH_OCSP_ENABLED], [1],
+		[Define if you don't want to validate X.509 certificates with OCSP])
+	LIBOCSP='-lssl'
+	OCSP_ON=''
+	OCSP_OFF='#'
+else
+	LIBOCSP=
+	OCSP_ON='#'
+	OCSP_OFF=''
+fi
+AC_SUBST([LIBOCSP])
+AC_SUBST([OCSP_ON])
+AC_SUBST([OCSP_OFF])
+
+
+# enable LDAP queries
+LDAP_MSG=no
+if test "x$ssh_x509store" = "xyes"; then
+	AC_WITH_LDAP
+	if test "x$LDAP_ON" = "x"; then
+		LDAP_MSG=yes
+		AC_CHECK_PROGS([LDAPADD],
+			[openldapadd ldapadd], [false],
+			[PATH="$LDAP_BINDIR:$PATH"])
+	fi
+	AC_LDAP_FUNCS([\
+		ldap_initialize \
+		ldap_parse_result \
+		ldap_sasl_bind_s \
+		ldap_search_ext_s \
+	])
+else
+	AC_MSG_NOTICE([x509store is disabled - skiping LDAP])
+fi
+
+
+ssh_x509dn_email=yes
+if test "x$ssh_x509store" = "xyes"; then
+	# Check for Email in X.509 'Distinguished Name'
+	AC_MSG_CHECKING([for Email in X.509 'Distinguished Name'])
+	AC_RUN_IFELSE(
+	[AC_LANG_SOURCE([
+#include <openssl/evp.h>
+
+int main(void) {
+  int nid;
+  nid = OBJ_txt2nid("Email");
+  if (nid == NID_undef)
+    exit (1);
+  exit (0);
+  return (0);
+}
+	])],
+	[	AC_MSG_RESULT(yes)	],
+	[
+		AC_MSG_RESULT(no)
+		ssh_x509dn_email=no
+	],
+	[
+		AC_MSG_WARN([cross compiling: assuming no])
+		ssh_x509dn_email=no
+	]
+)
+	# Check for the existence of "X509_VERIFY_PARAM *param" (OpenSSL 0.9.8+)
+	# OpenSSL v1.1 change X509_STORE_CTX to opaque structure
+	# Instead to check for member param we check for get functions
+	dnl AC_CHECK_MEMBERS([X509_STORE_CTX.param],,,[#include <openssl/x509_vfy.h>])
+	AC_CHECK_FUNCS([X509_STORE_CTX_get0_param])
+fi
+if test "x$ssh_x509dn_email" = "xno"; then
+	AC_DEFINE(
+		[SSH_OPENSSL_DN_WITHOUT_EMAIL], [1],
+		[Define if your openssl library don't support Email in X.509 'Distinguished Name'])
+fi
+
+# check for openssl 0.9.7+ functions ...
+AC_CHECK_FUNCS([ \
+  EVP_MD_CTX_init \
+])
+
+# check for openssl 0.9.8+ functions ...
+AC_CHECK_FUNCS([ \
+  EVP_CIPHER_CTX_new \
+])
+
+# check for openssl 1.0+ functions ...
+AC_CHECK_FUNCS([ \
+  ERR_remove_thread_state \
+  EVP_MD_flags \
+  EVP_PKEY_id \
+])
+
+# check for some structures
+AC_CHECK_MEMBERS([ECDSA_METHOD.name], [], [],
+[#include <openssl/ecdsa.h>]
+)
+
+# check for openssl 1.0.0+ functions ...
+AC_CHECK_FUNCS([ \
+  X509_STORE_set_verify_cb \
+])
+
+# check for openssl 1.0.2+ functions ...
+AC_CHECK_FUNCS([ \
+  ECDSA_METHOD_new \
+])
+
+# check for openssl 1.1+ functions ...
+AC_CHECK_FUNCS([ \
+  ASN1_STRING_get0_data \
+  DH_get0_key \
+  DSA_meth_new \
+  DSA_SIG_get0 \
+  DSA_SIG_set0 \
+  EC_KEY_METHOD_new \
+  ECDSA_SIG_get0 \
+  ECDSA_SIG_set0 \
+  EVP_CIPHER_CTX_iv \
+  EVP_CIPHER_meth_new \
+  EVP_MD_CTX_new \
+  EVP_PKEY_get0_EC_KEY \
+  OPENSSL_init_crypto \
+  RSA_meth_new \
+  RSA_PKCS1_OpenSSL \
+  X509_CRL_get0_lastUpdate \
+  X509_get0_tbs_sigalg \
+  X509_get_key_usage \
+  X509_OBJECT_new \
+  X509_STORE_get0_objects \
+  X509_STORE_lock
+])
+# check for removed in openssl 1.1+ functions ...
+AC_CHECK_FUNCS([ \
+  EVP_dss1 \
+])
+# check for openssl 1.1+ opaque structures ...
+AC_CHECK_TYPES([struct x509_lookup_method_st], [], [], [
+#include <openssl/x509_vfy.h>
+])
+
+# functions hidden in openssl compatible libraries
+AC_CHECK_DECLS([UTF8_getc])
+AC_CHECK_FUNCS([UTF8_getc])
+
+# ASN1_STRING_length const argument >= 1.0
+AC_MSG_CHECKING([whether ASN1_STRING_length declare const argument])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <openssl/asn1.h>
+int ASN1_STRING_length(const ASN1_STRING *x) {
+  (void) x; return 0;
+}
+]], [[
+  ASN1_STRING_length(NULL);
+]])],
+[ AC_MSG_RESULT([yes])
+  asn1_string_length_const="const"
+],
+[ AC_MSG_RESULT([no])
+  asn1_string_length_const="/* not const */"
+]
+)
+AC_DEFINE_UNQUOTED([ASN1_STRING_LENGTH_CONST], [$asn1_string_length_const],
+  [Define as const if ASN1_STRING_CONST() declare const argument]
+)
+
+# check for function sk_OPENSSL_STRING_new_null inlined in openssl 1.1+ ...
+AC_CACHE_CHECK(
+  [for sk_OPENSSL_STRING_new_null],
+  [ac_cv_func_sk_OPENSSL_STRING_new_null],
+  AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM(
+      [[
+      #include <openssl/safestack.h>
+      ]],[[
+      void *q;
+      q = sk_OPENSSL_STRING_new_null();
+      ]])
+    ],
+    [ ac_cv_func_sk_OPENSSL_STRING_new_null=yes ],
+    [ ac_cv_func_sk_OPENSSL_STRING_new_null=no ]
+  )
+)
+if test "x$ac_cv_func_sk_OPENSSL_STRING_new_null" = xyes; then
+  AC_DEFINE(
+    [HAVE_SK_OPENSSL_STRING_NEW_NULL],
+    [1],
+    [Define to 1 if you have the 'sk_OPENSSL_STRING_new_null' function.]
+  )
+fi
+
+
+# test FIPS enabled openssl
+AC_ARG_VAR([FIPSLD_CC],[actual compiler to be used by openssl fips compiler])
+OPENSSL_FIPS_MODE=no
+AC_ARG_ENABLE([openssl-fips],
+  [AS_HELP_STRING([--enable-openssl-fips], [Enable build with FIPS-enabled openssl])],
+  [ac_openssl_fips=$enableval],
+  [ac_openssl_fips=none]
+)
+
+if test yes = $ac_openssl_fips; then
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <openssl/opensslconf.h>
+    ]],[[
+#ifndef OPENSSL_FIPS
+error OPENSSL_FIPS is not defined
+#endif
+    ]])],
+    [],
+    [AC_MSG_ERROR([cannot found fips capable openssl header])]
+  )
+fi
+if test yes = $ac_openssl_fips; then
+  AC_CHECK_FUNC(
+    [FIPS_mode],
+    [],
+    [AC_MSG_ERROR([cannot found fips capable openssl library])]
+  )
+fi
+if test yes = $ac_openssl_fips; then
+  OPENSSL_FIPS_MODE=yes
+fi
+AC_SUBST([OPENSSL_FIPS_MODE])
+
+FIPS_LIBS=
+FIPSHMAC=':'
+if test yes = $OPENSSL_FIPS_MODE; then
+  # check for Red Hat specific fips library
+  AC_CHECK_LIB([fipscheck], [FIPSCHECK_verify],
+  [
+    FIPS_LIBS="-lfipscheck"
+    AC_CHECK_HEADERS([fipscheck.h])
+    FIPSHMAC=fipshmac
+  ])
+fi
+AC_SUBST([FIPS_LIBS])
+AC_SUBST([FIPSHMAC])
+
+
 # Where to place sshd.pid
 piddir=/var/run
 # make sure the directory exists
@@ -4775,15 +5205,21 @@
 		fi
 	]
 )
+ssh_disable_utmpx=no
 AC_ARG_ENABLE([utmpx],
 	[  --disable-utmpx         disable use of utmpx even if detected [no]],
 	[
-		if test "x$enableval" = "xno" ; then
-			AC_DEFINE([DISABLE_UTMPX], [1],
-				[Define if you don't want to use utmpx])
-		fi
+		ssh_disable_utmpx=$enableval
 	]
 )
+if test no = $ac_cv_header_utmpx_h; then
+	dnl Always disable utmpx if missing header utmpx.h (Android)
+	ssh_disable_utmpx=yes
+fi
+if test yes = $ssh_disable_utmpx; then
+	AC_DEFINE([DISABLE_UTMPX], [1],
+		[Define if you don't want to use utmpx])
+fi
 AC_ARG_ENABLE([wtmp],
 	[  --disable-wtmp          disable use of wtmp even if detected [no]],
 	[
@@ -4909,6 +5345,10 @@
 #ifdef HAVE_PATHS_H
 #  include <paths.h>
 #endif
+/* Compatibility names for the strings of the canonical file names */
+#ifndef UTMP_FILE
+#define UTMP_FILE	_PATH_UTMP
+#endif
 	]], [[ char *utmp = UTMP_FILE; ]])],
 	[ AC_MSG_RESULT([yes]) ],
 	[ AC_MSG_RESULT([no])
@@ -4939,6 +5379,10 @@
 #ifdef HAVE_PATHS_H
 #  include <paths.h>
 #endif
+/* Compatibility names for the strings of the canonical file names */
+#ifndef WTMP_FILE
+#define WTMP_FILE	_PATH_WTMP
+#endif
 	]], [[ char *wtmp = WTMP_FILE; ]])],
 	[ AC_MSG_RESULT([yes]) ],
 	[ AC_MSG_RESULT([no])
@@ -5047,7 +5491,14 @@
 AC_EXEEXT
 AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
 	openbsd-compat/Makefile openbsd-compat/regress/Makefile \
+	tests/CA/Makefile tests/CA/env \
 	survey.sh])
+if test yes = $OPENSSL_FIPS_MODE; then
+  if test -n "$FIPSLD_CC"; then
+    CC='FIPSLD_CC=$(FIPSLD_CC) '$CC
+    LD='FIPSLD_CC=$(FIPSLD_CC) '$LD
+  fi
+fi
 AC_OUTPUT
 
 # Print summary of options
@@ -5069,6 +5520,7 @@
 echo "                     User binaries: $B"
 echo "                   System binaries: $C"
 echo "               Configuration files: $D"
+echo "                           CA root: $sshcadir"
 echo "                   Askpass program: $E"
 echo "                      Manual pages: $F"
 echo "                          PID file: $G"
@@ -5093,7 +5545,11 @@
 echo "                   SELinux support: $SELINUX_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
+echo "              TCP Wrappers support: $TCPW_MSG"
 echo "              MD5 password support: $MD5_MSG"
+echo "               X.509 store support: $ssh_x509store"
+echo "                      OCSP support: $ssh_ocsp"
+echo "                      LDAP queries: $LDAP_MSG"
 echo "                   libedit support: $LIBEDIT_MSG"
 echo "                   libldns support: $LDNS_MSG"
 echo "  Solaris process contract support: $SPC_MSG"
@@ -5104,10 +5560,14 @@
 echo "                  BSD Auth support: $BSD_AUTH_MSG"
 echo "              Random number source: $RAND_MSG"
 echo "             Privsep sandbox style: $SANDBOX_STYLE"
+echo "                FIPS capable build: $OPENSSL_FIPS_MODE"
 
 echo ""
 
 echo "              Host: ${host}"
+if test yes = $OPENSSL_FIPS_MODE; then
+echo "   Actual compiler: $FIPSLD_CC"
+fi
 echo "          Compiler: ${CC}"
 echo "    Compiler flags: ${CFLAGS}"
 echo "Preprocessor flags: ${CPPFLAGS}"
@@ -5127,6 +5587,25 @@
 	echo ""
 fi
 
+if test "x$LDAP_MSG" = "xyes" ; then
+echo "Extra LDAP flags:"
+echo "    LDAP compiler flags: ${LDAP_CFLAGS}"
+echo "LDAP preprocessor flags: ${LDAP_CPPFLAGS}"
+echo "      LDAP linker flags: ${LDAP_LDFLAGS}"
+echo "         LDAP libraries: ${LDAP_LIBS}"
+echo ""
+echo "LDAP paths(used only in tests):"
+echo "     LDAP sysconfig dir: ${LDAP_SYSCONFDIR}"
+echo "       LDAP libexec dir: ${LDAP_LIBEXECDIR}"
+echo "           LDAP bin dir: ${LDAP_BINDIR}"
+echo ""
+fi
+
+if test yes = $OPENSSL_FIPS_MODE; then
+echo "    FIPS libraries: $FIPS_LIBS"
+echo ""
+fi
+
 if test "x$PAM_MSG" = "xyes" ; then
 	echo "PAM is enabled. You may need to install a PAM control file "
 	echo "for sshd, otherwise password authentication may fail. "
diff -ruN openssh-7.5p1/defines.h openssh-7.5p1+x509-10.2/defines.h
--- openssh-7.5p1/defines.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/defines.h	2017-05-20 21:07:00.000000000 +0300
@@ -1,6 +1,9 @@
 /*
  * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2011-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -839,13 +842,24 @@
  */
 #define DEF_WEAK(x)
 
-/*
- * Platforms that have arc4random_uniform() and not arc4random_stir()
- * shouldn't need the latter.
- */
-#if defined(HAVE_ARC4RANDOM) && defined(HAVE_ARC4RANDOM_UNIFORM) && \
-    !defined(HAVE_ARC4RANDOM_STIR)
-# define arc4random_stir()
+/* Write by owner (BSD compatible)  */
+#ifndef S_IWRITE
+# ifdef S_IWUSR
+#  define S_IWRITE S_IWUSR
+# endif
+#endif
+
+#ifdef OPENSSL_FIPS
+# undef HAVE_ARC4RANDOM
+# undef HAVE_ARC4RANDOM_BUF
+# undef HAVE_ARC4RANDOM_UNIFORM
+#endif
+
+#ifndef HAVE_ARC4RANDOM_STIR
+# ifdef HAVE_ARC4RANDOM
+#  define HAVE_ARC4RANDOM_STIR 1
+   static inline void arc4random_stir(void) {}
+# endif
 #endif
 
 #ifndef HAVE_VA_COPY
@@ -874,4 +888,9 @@
 # define USE_SYSTEM_GLOB
 #endif
 
+
+/* secure shell typedefs */
+typedef struct ssh_compat_st ssh_compat;
+typedef struct ssh_signature_context_st ssh_sign_ctx;
+
 #endif /* _DEFINES_H */
diff -ruN openssh-7.5p1/dh.c openssh-7.5p1+x509-10.2/dh.c
--- openssh-7.5p1/dh.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/dh.c	2017-05-20 21:07:01.000000000 +0300
@@ -28,6 +28,7 @@
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
+#include "openbsd-compat/openssl-compat.h"
 
 #include <errno.h>
 #include <stdarg.h>
@@ -36,6 +37,7 @@
 #include <string.h>
 #include <limits.h>
 
+#include "evp-compat.h"
 #include "dh.h"
 #include "pathnames.h"
 #include "log.h"
@@ -212,14 +214,15 @@
 /* diffie-hellman-groupN-sha1 */
 
 int
-dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+dh_pub_is_valid(DH *dh, const BIGNUM *dh_pub)
 {
 	int i;
 	int n = BN_num_bits(dh_pub);
 	int bits_set = 0;
 	BIGNUM *tmp;
+	const BIGNUM *p;
 
-	if (dh_pub->neg) {
+	if (BN_is_negative(dh_pub)) {
 		logit("invalid public DH value: negative");
 		return 0;
 	}
@@ -232,7 +235,11 @@
 		error("%s: BN_new failed", __func__);
 		return 0;
 	}
-	if (!BN_sub(tmp, dh->p, BN_value_one()) ||
+
+	p = NULL;
+	DH_get0_pqg(dh, &p, NULL, NULL);
+
+	if (!BN_sub(tmp, p, BN_value_one()) ||
 	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
 		BN_clear_free(tmp);
 		logit("invalid public DH value: >= p-1");
@@ -243,14 +250,14 @@
 	for (i = 0; i <= n; i++)
 		if (BN_is_bit_set(dh_pub, i))
 			bits_set++;
-	debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+	debug2("bits set: %d/%d", bits_set, BN_num_bits(p));
 
 	/*
 	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
 	 */
 	if (bits_set < 4) {
 		logit("invalid public DH value (%d/%d)",
-		   bits_set, BN_num_bits(dh->p));
+		   bits_set, BN_num_bits(p));
 		return 0;
 	}
 	return 1;
@@ -261,22 +268,38 @@
 {
 	int pbits;
 
-	if (need < 0 || dh->p == NULL ||
-	    (pbits = BN_num_bits(dh->p)) <= 0 ||
+{	const BIGNUM *p = NULL;
+
+	DH_get0_pqg(dh, &p, NULL, NULL);
+
+	if (need < 0 || p == NULL ||
+	    (pbits = BN_num_bits(p)) <= 0 ||
 	    need > INT_MAX / 2 || 2 * need > pbits)
 		return SSH_ERR_INVALID_ARGUMENT;
+}
+
 	if (need < 256)
 		need = 256;
 	/*
 	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
 	 * so double requested need here.
 	 */
-	dh->length = MINIMUM(need * 2, pbits - 1);
-	if (DH_generate_key(dh) == 0 ||
-	    !dh_pub_is_valid(dh, dh->pub_key)) {
-		BN_clear_free(dh->priv_key);
+
+	DH_set_length(dh, MINIMUM(need * 2, pbits - 1));
+	if (DH_generate_key(dh) == 0)
+		return SSH_ERR_LIBCRYPTO_ERROR;
+
+{	const BIGNUM *pub_key = NULL;
+	BIGNUM *priv_key = NULL;
+
+	DH_get0_key(dh, &pub_key, (const BIGNUM**)&priv_key);
+
+	if (!dh_pub_is_valid(dh, pub_key)) {
+		BN_clear(priv_key);
 		return SSH_ERR_LIBCRYPTO_ERROR;
 	}
+}
+
 	return 0;
 }
 
@@ -284,11 +307,18 @@
 dh_new_group_asc(const char *gen, const char *modulus)
 {
 	DH *dh;
+	BIGNUM *p = NULL, *g = NULL;
 
 	if ((dh = DH_new()) == NULL)
 		return NULL;
-	if (BN_hex2bn(&dh->p, modulus) == 0 ||
-	    BN_hex2bn(&dh->g, gen) == 0) {
+	if (BN_hex2bn(&p, modulus) == 0 ||
+	    BN_hex2bn(&g, gen) == 0) {
+		BN_free(p);
+		BN_free(g);
+		DH_free(dh);
+		return NULL;
+	}
+	if (!DH_set0_pqg(dh, p, NULL, g)) {
 		DH_free(dh);
 		return NULL;
 	}
@@ -307,8 +337,11 @@
 
 	if ((dh = DH_new()) == NULL)
 		return NULL;
-	dh->p = modulus;
-	dh->g = gen;
+
+	if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
+		DH_free(dh);
+		return NULL;
+	}
 
 	return (dh);
 }
diff -ruN openssh-7.5p1/dh.h openssh-7.5p1+x509-10.2/dh.h
--- openssh-7.5p1/dh.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/dh.h	2017-05-20 21:07:00.000000000 +0300
@@ -42,7 +42,7 @@
 DH	*dh_new_group_fallback(int);
 
 int	 dh_gen_key(DH *, int);
-int	 dh_pub_is_valid(DH *, BIGNUM *);
+int	 dh_pub_is_valid(DH *, const BIGNUM *);
 
 u_int	 dh_estimate(int);
 
diff -ruN openssh-7.5p1/digest-libc.c openssh-7.5p1+x509-10.2/digest-libc.c
--- openssh-7.5p1/digest-libc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/digest-libc.c	2017-05-20 21:07:01.000000000 +0300
@@ -123,6 +123,9 @@
 static const struct ssh_digest *
 ssh_digest_by_alg(int alg)
 {
+#ifdef OPENSSL_FIPS
+#  include "use openssl based digest for FIPS build"
+#endif
 	if (alg < 0 || alg >= SSH_DIGEST_MAX)
 		return NULL;
 	if (digests[alg].id != alg) /* sanity */
diff -ruN openssh-7.5p1/digest-openssl.c openssh-7.5p1+x509-10.2/digest-openssl.c
--- openssh-7.5p1/digest-openssl.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/digest-openssl.c	2017-05-20 21:07:01.000000000 +0300
@@ -30,6 +30,7 @@
 
 #include "sshbuf.h"
 #include "digest.h"
+#include "evp-compat.h"
 #include "ssherr.h"
 
 #ifndef HAVE_EVP_RIPEMD160
@@ -43,7 +44,7 @@
 
 struct ssh_digest_ctx {
 	int alg;
-	EVP_MD_CTX mdctx;
+	EVP_MD_CTX *mdctx;
 };
 
 struct ssh_digest {
@@ -73,6 +74,13 @@
 		return NULL;
 	if (digests[alg].mdfunc == NULL)
 		return NULL;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		const EVP_MD *md = digests[alg].mdfunc();
+		if ((EVP_MD_flags(md) & EVP_MD_FLAG_FIPS) == 0)
+			return NULL;
+	}
+#endif
 	return &(digests[alg]);
 }
 
@@ -107,7 +115,7 @@
 size_t
 ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
 {
-	return EVP_MD_CTX_block_size(&ctx->mdctx);
+	return EVP_MD_CTX_block_size(ctx->mdctx);
 }
 
 struct ssh_digest_ctx *
@@ -119,8 +127,12 @@
 	if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
 		return NULL;
 	ret->alg = alg;
-	EVP_MD_CTX_init(&ret->mdctx);
-	if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
+	ret->mdctx = EVP_MD_CTX_new();
+	if (ret->mdctx == NULL) {
+		free(ret);
+		return NULL;
+	}
+	if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
 		free(ret);
 		return NULL;
 	}
@@ -133,7 +145,7 @@
 	if (from->alg != to->alg)
 		return SSH_ERR_INVALID_ARGUMENT;
 	/* we have bcopy-style order while openssl has memcpy-style */
-	if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
+	if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
 		return SSH_ERR_LIBCRYPTO_ERROR;
 	return 0;
 }
@@ -141,7 +153,7 @@
 int
 ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
 {
-	if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
+	if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
 		return SSH_ERR_LIBCRYPTO_ERROR;
 	return 0;
 }
@@ -162,7 +174,7 @@
 		return SSH_ERR_INVALID_ARGUMENT;
 	if (dlen < digest->digest_len) /* No truncation allowed */
 		return SSH_ERR_INVALID_ARGUMENT;
-	if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
+	if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
 		return SSH_ERR_LIBCRYPTO_ERROR;
 	if (l != digest->digest_len) /* sanity */
 		return SSH_ERR_INTERNAL_ERROR;
@@ -173,7 +185,7 @@
 ssh_digest_free(struct ssh_digest_ctx *ctx)
 {
 	if (ctx != NULL) {
-		EVP_MD_CTX_cleanup(&ctx->mdctx);
+		EVP_MD_CTX_free(ctx->mdctx);
 		explicit_bzero(ctx, sizeof(*ctx));
 		free(ctx);
 	}
diff -ruN openssh-7.5p1/dns.c openssh-7.5p1+x509-10.2/dns.c
--- openssh-7.5p1/dns.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/dns.c	2017-05-20 21:07:01.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
  * Copyright (c) 2003 Jakob Schlyter. All rights reserved.
  *
+ * X.509 certificates support:
+ * Copyright (c) 2005,2011,2012 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -36,14 +39,31 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <openssl/x509.h>
 
 #include "xmalloc.h"
 #include "sshkey.h"
 #include "ssherr.h"
+#include "ssh-x509.h"
+#include "uuencode.h"
 #include "dns.h"
 #include "log.h"
 #include "digest.h"
 
+
+struct ssh_dns_cert_param_s {
+	int     cert_type;
+	int     key_tag;
+	int     algo;
+	u_char *cert_data;
+	size_t  cert_len;
+	u_char *b64_data;
+	size_t  b64_len;
+};
+
+typedef struct ssh_dns_cert_param_s ssh_dns_cert_param;
+
+
 static const char *errset_text[] = {
 	"success",		/* 0 ERRSET_SUCCESS */
 	"out of memory",	/* 1 ERRSET_NOMEMORY */
@@ -136,6 +156,161 @@
 	return success;
 }
 
+static void
+cert_param_clean(ssh_dns_cert_param *param) {
+	if (param == NULL) return;
+
+	if (param->cert_data) {
+		param->cert_len = 0;
+		free(param->cert_data);
+		param->cert_data = NULL;
+	}
+	if (param->b64_data) {
+		param->b64_len = 0;
+		free(param->b64_data);
+		param->b64_data = NULL;
+	}
+}
+
+static const char*
+bind_cert_type(const ssh_dns_cert_param *param) {
+	switch(param->cert_type) {
+	case DNS_CERT_TYPE_PKIX: return("PKIX");
+#if 0
+	case DNS_CERT_TYPE_SPKI: return("SPKI");
+	case DNS_CERT_TYPE_PGP : return("PGP");
+	case DNS_CERT_TYPE_URI : return("URI");
+	case DNS_CERT_TYPE_OID : return("OID");
+#endif
+	default:
+		break;
+	}
+	return("<UNSUPPORTED>");
+}
+
+static const char*
+bind_key_algo(const ssh_dns_cert_param *param) {
+	switch(param->algo) {
+#if 0
+	case DNS_KEY_ALGO_UNKNOWN: /*specific case for CERT RR*/
+				    return("????");
+#endif
+	case DNS_KEY_ALGO_RSAMD5  : return("RSAMD5");
+	case DNS_KEY_ALGO_DSA     : return("DSA");
+	case DNS_KEY_ALGO_RSASHA1 : return("RSASHA1");
+	}
+	return("<UNSUPPORTED>");
+}
+
+static u_int16_t
+calc_dns_key_tag(X509 *x509) {
+	/* [RFC 2535] Appendix C: Key Tag Calculation */
+
+	/* TODO: to be implemented or not ?
+	 * I'm happy without this.
+	 */
+	return(1);
+}
+
+static inline const X509_ALGOR*
+ssh_X509_get0_tbs_sigalg(X509 *x509) {
+	if (x509 == NULL) return(NULL);
+
+#ifdef HAVE_X509_GET0_TBS_SIGALG
+	return(X509_get0_tbs_sigalg(x509));
+#else
+{
+	X509_CINF *ci = x509->cert_info;
+	return(ci != NULL ? ci->signature: NULL);
+}
+#endif
+}
+
+static u_int8_t
+get_dns_sign_algo(X509 *x509) {
+	int rsa_algo = DNS_KEY_ALGO_UNKNOWN;
+	int algo_nid;
+
+	const X509_ALGOR *sig;
+	ASN1_OBJECT *alg;
+
+	sig = ssh_X509_get0_tbs_sigalg(x509);
+	if (sig == NULL) goto done;
+
+	alg = sig->algorithm;
+	if (alg == NULL) goto done;
+
+	algo_nid = OBJ_obj2nid(alg);
+	debug3("get_dns_sign_algo: nid=%d(%s)\n", algo_nid, OBJ_nid2ln(algo_nid));
+
+	switch(algo_nid) {
+	case NID_md5WithRSAEncryption:
+		rsa_algo = DNS_KEY_ALGO_RSAMD5;
+		break;
+	case NID_sha1WithRSAEncryption:
+		rsa_algo = DNS_KEY_ALGO_RSASHA1;
+		break;
+	case NID_md2WithRSAEncryption:
+	case NID_md4WithRSAEncryption:
+	case NID_ripemd160WithRSA:
+		/* not defined in [RFC 2535] ! */
+		rsa_algo = DNS_KEY_ALGO_UNKNOWN;
+		break;
+	case NID_dsaWithSHA1:
+		rsa_algo = DNS_KEY_ALGO_DSA;
+		break;
+	default:
+		rsa_algo = DNS_KEY_ALGO_UNKNOWN;
+	}
+
+done:
+	return(rsa_algo);
+}
+
+/*
+ * Read CERT parameters from key buffer.
+ */
+static int/*bool*/
+dns_read_cert(ssh_dns_cert_param *param, const Key *key)
+{
+	int   ret = 0;
+	X509 *x509;
+	BIO  *bio = NULL;
+	int   k = 0;
+
+	if (param == NULL) goto done;
+	if (key   == NULL) goto done;
+
+	x509 = SSH_X509_get_cert(key->x509_data);
+	if (x509 == NULL) goto done;
+
+	bio = BIO_new(BIO_s_mem());
+	if (bio == NULL) goto done;
+
+	i2d_X509_bio(bio, x509);
+	(void)BIO_flush(bio);
+
+	cert_param_clean(param);
+
+	k = BIO_pending(bio);
+	param->cert_data = xmalloc(k + 1); /*fatal on error*/
+	param->cert_len = BIO_read(bio, param->cert_data, k);
+
+	k = param->cert_len << 1;
+	param->b64_data = xmalloc(k); /*fatal on error*/
+	param->b64_len = uuencode(param->cert_data, param->cert_len, (char*)param->b64_data, k);
+
+	param->algo = get_dns_sign_algo(x509);
+	param->key_tag = calc_dns_key_tag(x509);
+	param->cert_type = DNS_CERT_TYPE_PKIX;
+
+	ret = 1;
+
+done:
+	if (bio) BIO_free_all(bio);
+	return(ret);
+}
+
 /*
  * Read SSHFP parameters from rdata buffer.
  */
@@ -197,6 +372,127 @@
 }
 
 /*
+ * Read CERT parameters from rdata buffer.
+ */
+static int/*bool*/
+dns_read_cert_rdata(ssh_dns_cert_param *param, u_char *rdata, int rdata_len)
+{
+	size_t len ;
+
+	cert_param_clean(param);
+
+	if (rdata_len < 5) return(0);
+
+	param->cert_type = (rdata[0] << 8) + rdata[1];
+	param->key_tag   = (rdata[2] << 8) + rdata[3];
+	param->algo      = rdata[4];
+
+	len = rdata_len - 5;
+	param->cert_len = len;
+	if (len > 0) {
+		param->cert_data = (u_char *) xmalloc(len);
+		memcpy(param->cert_data, rdata + 5, len);
+	}
+	return(1);
+}
+
+/*
+ * Verify the given hostname, address and host key using DNS.
+ * Returns 0 if lookup succeeds, -1 otherwise
+ */
+static int
+verify_hostcert_dns(const char *hostname, const Key *hostkey, int *flags)
+{
+	u_int counter;
+	int result;
+	struct rrsetinfo *certs = NULL;
+
+	ssh_dns_cert_param hostkey_param;
+	ssh_dns_cert_param dnskey_param;
+
+	debug3("verify_hostcert_dns");
+
+	memset(&hostkey_param, 0, sizeof(hostkey_param));
+	memset(&dnskey_param , 0, sizeof(dnskey_param ));
+
+	result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
+	    DNS_RDATATYPE_CERT, 0, &certs);
+	if (result) {
+		verbose("DNS lookup error: %s", dns_result_totext(result));
+		return(-1);
+	}
+
+	if (certs->rri_flags & RRSET_VALIDATED) {
+		*flags |= DNS_VERIFY_SECURE;
+		debug("found %d secure certificates in DNS",
+		    certs->rri_nrdatas);
+	} else {
+		debug("found %d insecure certificates in DNS",
+		    certs->rri_nrdatas);
+	}
+
+	/* Initialize host key parameters */
+	if (!dns_read_cert(&hostkey_param, hostkey)) {
+		error("Error calculating host key certificate.");
+		cert_param_clean(&hostkey_param);
+		freerrset(certs);
+		return(-1);
+	}
+
+	if (certs->rri_nrdatas)
+		*flags |= DNS_VERIFY_FOUND;
+
+	for (counter = 0 ; counter < certs->rri_nrdatas ; counter++)  {
+		Key* dns_cert = NULL;
+		/*
+		 * Extract the key from the answer. Ignore any badly
+		 * formatted certificates.
+		 */
+		if (!dns_read_cert_rdata(&dnskey_param,
+		    certs->rri_rdatas[counter].rdi_data,
+		    certs->rri_rdatas[counter].rdi_length
+		)) {
+			verbose("Error parsing certificate from DNS.");
+			goto next;
+		}
+
+		if (hostkey_param.cert_type != dnskey_param.cert_type) continue;
+
+		/* We will skip useless "key tag" */
+
+		/* We will ignore "algorithm" since number of
+		 * algorithms defined in [RFC 2535] is limited.
+		 */
+		dns_cert = x509key_from_blob(dnskey_param.cert_data, dnskey_param.cert_len);
+		if (dns_cert == NULL) {
+			verbose("Invalid certificate from DNS.");
+			goto next;
+		}
+		if (ssh_x509_cmp_cert(hostkey, dns_cert) == 0) {
+			*flags |= DNS_VERIFY_MATCH;
+		}
+		key_free(dns_cert);
+		dns_cert = NULL;
+
+next:
+		cert_param_clean(&dnskey_param);
+	}
+
+	cert_param_clean(&hostkey_param);
+	freerrset(certs);
+
+	if (*flags & DNS_VERIFY_FOUND)
+		if (*flags & DNS_VERIFY_MATCH)
+			debug("matching host key certificate found in DNS");
+		else
+			debug("mismatching host key certificate found in DNS");
+	else
+		debug("no host key certificate found in DNS");
+
+	return(0);
+}
+
+/*
  * Verify the given hostname, address and host key using DNS.
  * Returns 0 if lookup succeeds, -1 otherwise
  */
@@ -229,6 +525,14 @@
 		return -1;
 	}
 
+	if (key_is_x509(hostkey)) {
+		result = verify_hostcert_dns(hostname, hostkey, flags);
+		if (*flags & DNS_VERIFY_FOUND) {
+			return(result);
+		}
+		/*try to found SSHFP RR*/
+	}
+
 	result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
 	    DNS_RDATATYPE_SSHFP, 0, &fingerprints);
 	if (result) {
@@ -319,8 +623,55 @@
 	u_int8_t dtype;
 	u_char *rdata_digest;
 	size_t i, rdata_digest_len;
+	ssh_dns_cert_param cert_param;
 	int success = 0;
 
+	memset(&cert_param, 0, sizeof(cert_param));
+
+	if (dns_read_cert(&cert_param, key)) {
+		u_char *p;
+		int k;
+
+		if (generic || (cert_param.algo == DNS_KEY_ALGO_UNKNOWN)) {
+			fprintf(f, "%s\tIN\tTYPE%d \\# %d %04x %04x %02x (\n\t"
+			    , hostname
+			    , DNS_RDATATYPE_CERT
+			    , (int)(5 + cert_param.cert_len)
+			    , cert_param.cert_type
+			    , cert_param.key_tag
+			    , cert_param.algo
+			);
+			p = cert_param.cert_data;
+			i = cert_param.cert_len;
+			k = 32;
+			for (; i > 0; i--, p++) {
+				fprintf(f, "%02x", (int) *p);
+				if (--k <= 0) {
+					fprintf(f, "\n\t");
+					k = 32;
+				}
+			}
+		} else {
+			fprintf(f, "%s\tIN\tCERT\t%s %d %s (\n\t"
+			    , hostname
+			    , bind_cert_type(&cert_param)
+			    , cert_param.key_tag
+			    , bind_key_algo(&cert_param)
+			);
+			p = cert_param.b64_data;
+			i = cert_param.b64_len;
+			k = 64;
+			for (; i > 0; i--, p++) {
+				fprintf(f, "%c", *p);
+				if (--k <= 0) {
+					fprintf(f, "\n\t");
+					k = 64;
+				}
+			}
+		}
+		fprintf(f, "\n\t)\n");
+		success = 1;
+	} else
 	for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) {
 		rdata_digest_type = dtype;
 		if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
@@ -347,5 +698,6 @@
 		error("%s: unsupported algorithm and/or digest_type", __func__);
 	}
 
+	cert_param_clean(&cert_param);
 	return success;
 }
diff -ruN openssh-7.5p1/dns.h openssh-7.5p1+x509-10.2/dns.h
--- openssh-7.5p1/dns.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/dns.h	2017-05-20 21:07:00.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
  * Copyright (c) 2003 Jakob Schlyter. All rights reserved.
  *
+ * X.509 certificates support:
+ * Copyright (c) 2005 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -36,6 +39,18 @@
 	SSHFP_KEY_ED25519 = 4
 };
 
+enum dns_cert_types {
+	DNS_CERT_TYPE_RESERVER =   0,
+	DNS_CERT_TYPE_PKIX     =   1, /* X.509 as per PKIX */
+	DNS_CERT_TYPE_SPKI     =   2, /* SPKI cert */
+	DNS_CERT_TYPE_PGP      =   3, /* PGP cert */
+/* 4-252  available for IANA assignment */
+	DNS_CERT_TYPE_URI      = 253, /* URI private */
+	DNS_CERT_TYPE_OID      = 254, /* OID private */
+/* 255-65534  available for IANA assignment */
+	DNS_CERT_TYPE_RESERVER2 = 65535
+};
+
 enum sshfp_hashes {
 	SSHFP_HASH_RESERVED = 0,
 	SSHFP_HASH_SHA1 = 1,
@@ -43,7 +58,24 @@
 	SSHFP_HASH_MAX = 3
 };
 
+enum dns_key_algo {
+	DNS_KEY_ALGO_RESERVED   =   0, /* reserved, see [RFC 2535] Section 11 */
+	DNS_KEY_ALGO_UNKNOWN    =   0, /* when algorithm is unknown to a secure DNS [RFC 2538] */
+	DNS_KEY_ALGO_RSAMD5     =   1, /* RSA/MD5 [RFC 2537] */
+	DNS_KEY_ALGO_DH         =   2, /* Diffie-Hellman [RFC 2539] */
+	DNS_KEY_ALGO_DSA        =   3, /* DSA [RFC 2536] */
+	DNS_KEY_ALGO_ECC        =   4, /* reserved for elliptic curve crypto */
+/* 5-251  available, see [RFC 2535] Section 11 */
+	DNS_KEY_ALGO_RSASHA1    =   5, /* RSA/SHA1 [RFC 4034] */
+/* 6-251  available, see [RFC 4034] Section A.1. */
+	DNS_KEY_ALGO_INDIRECT   = 252, /* reserved for indirect keys */
+	DNS_KEY_ALGO_PRIVATEDNS = 253, /* private - domain name (see [RFC 2535]) */
+	DNS_KEY_ALGO_PRIVATEOID = 254, /* private - OID (see [RFC 2535]) */
+	DNS_KEY_ALGO_RESERVED2  = 255  /* reserved, see [RFC 2535] Section 11 */
+};
+
 #define DNS_RDATACLASS_IN	1
+#define DNS_RDATATYPE_CERT	37
 #define DNS_RDATATYPE_SSHFP	44
 
 #define DNS_VERIFY_FOUND	0x00000001
diff -ruN openssh-7.5p1/evp-compat.h openssh-7.5p1+x509-10.2/evp-compat.h
--- openssh-7.5p1/evp-compat.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/evp-compat.h	2017-03-30 21:33:33.000000000 +0300
@@ -0,0 +1,747 @@
+#ifndef EVP_COMPAT_H
+#define EVP_COMPAT_H
+/*
+ * Copyright (c) 2011-2016 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include "openbsd-compat/openssl-compat.h"
+#ifdef OPENSSL_HAS_ECC
+# include <openssl/ec.h>
+# include <openssl/ecdsa.h>
+#endif
+#include <string.h>	/*for memset*/
+#include <openssl/buffer.h>	/*for BUF_strdup*/
+
+
+#ifndef HAVE_EVP_MD_CTX_NEW		/* OpenSSL < 1.1 */
+static inline EVP_MD_CTX*
+EVP_MD_CTX_new(void) {
+	EVP_MD_CTX *ctx;
+
+	ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX));
+	if (ctx != NULL) {
+		EVP_MD_CTX_init(ctx);
+	}
+	return(ctx);
+}
+
+
+static inline void
+EVP_MD_CTX_free(EVP_MD_CTX *ctx) {
+	EVP_MD_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+}
+#endif/* ndef HAVE_EVP_MD_CTX_NEW	OpenSSL < 1.1 */
+
+
+#ifndef HAVE_EVP_MD_FLAGS		/* OpenSSL < 1.0 */
+static inline unsigned long
+EVP_MD_flags(const EVP_MD *md) {
+	return md->flags;
+}
+#endif /* ndef HAVE_EVP_MD_FLAGS	OpenSSL < 1.0 */
+
+
+#ifndef HAVE_EVP_CIPHER_CTX_NEW		/* OpenSSL < 0.9.8 */
+static inline EVP_CIPHER_CTX*
+EVP_CIPHER_CTX_new(void) {
+	EVP_CIPHER_CTX *ctx;
+
+	ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
+	if (ctx != NULL) {
+		EVP_CIPHER_CTX_init(ctx);
+	}
+	return(ctx);
+}
+
+
+static inline void
+EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
+	if (ctx == NULL) return;
+
+	EVP_CIPHER_CTX_cleanup(ctx);
+	OPENSSL_free(ctx);
+}
+#endif /* ndef HAVE_EVP_CIPHER_CTX_NEW	OpenSSL < 0.9.8 */
+
+
+#ifndef HAVE_EVP_CIPHER_CTX_IV		/* OpenSSL < 1.1 */
+static inline const unsigned char*
+EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) {
+	return(ctx->iv);
+}
+
+
+static inline unsigned char*
+EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
+{
+	return(ctx->iv);
+}
+
+
+static inline int
+EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
+{
+	return(ctx->encrypt);
+}
+
+
+static inline void*
+EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx)
+{
+	return(ctx->cipher_data);
+}
+#endif /* ndef HAVE_EVP_CIPHER_CTX_IV	OpenSSL < 1.1 */
+
+
+#ifndef HAVE_EVP_CIPHER_METH_NEW	/* OpenSSL < 1.1 */
+static inline int
+EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
+{
+	return(e->ctx_size);
+}
+
+
+static inline EVP_CIPHER*
+EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
+{
+	EVP_CIPHER *cipher = (EVP_CIPHER*) OPENSSL_malloc(sizeof(EVP_CIPHER));
+
+	if (cipher != NULL) {
+		memset(cipher, 0, sizeof(*cipher));
+		cipher->nid = cipher_type;
+		cipher->block_size = block_size;
+		cipher->key_len = key_len;
+	}
+	return(cipher);
+}
+
+
+static inline EVP_CIPHER*
+EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
+{
+	EVP_CIPHER *to = (EVP_CIPHER*) OPENSSL_malloc(sizeof(EVP_CIPHER));
+
+	if (to != NULL)
+		memcpy(to, cipher, sizeof(*to));
+	return(to);
+}
+
+
+static inline int
+EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
+{
+	cipher->iv_len = iv_len;
+	return(1);
+}
+
+
+static inline int
+EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) {
+	cipher->flags = flags;
+	return(1);
+}
+
+
+static inline int
+EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
+	int (*init) (EVP_CIPHER_CTX *ctx,
+		const unsigned char *key,
+		const unsigned char *iv,
+		int enc)
+) {
+    cipher->init = init;
+	return(1);
+}
+
+
+typedef int (*do_cipher_f) (EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, LIBCRYPTO_EVP_INL_TYPE inl);
+
+
+static inline int
+EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, do_cipher_f do_cipher) {
+	cipher->do_cipher = do_cipher;
+	return(1);
+}
+
+
+static inline do_cipher_f
+EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher) {
+	return cipher->do_cipher;
+}
+
+static inline int
+EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, int (*cleanup) (EVP_CIPHER_CTX*)) {
+	cipher->cleanup = cleanup;
+	return(1);
+}
+#endif /* ndef HAVE_EVP_CIPHER_METH_NEW		OpenSSL < 1.1 */
+
+
+#ifndef OPENSSL_NO_RSA
+#ifndef HAVE_RSA_METH_NEW		/* OpenSSL < 1.1 */
+/* Partial backport of opaque RSA from OpenSSL >= 1.1 by commits
+ * "Make the RSA_METHOD structure opaque", "RSA, DSA, DH: Allow some
+ * given input to be NULL on already initialised keys" and etc.
+ */
+
+/* opaque RSA method structure */
+static inline RSA_METHOD*
+RSA_meth_new(const char *name, int flags) {
+	RSA_METHOD *meth;
+
+	meth = OPENSSL_malloc(sizeof(RSA_METHOD));
+	if (meth == NULL) return NULL;
+
+	memset(meth, 0, sizeof(*meth));
+	/* unlike OPENSSL_strdup (0.8.k+), BUF_strdup is defined in
+	 * all OpenSSL versions (SSLeay 0.8.1) */
+	meth->name = BUF_strdup(name);
+	meth->flags = flags;
+
+	return(meth);
+}
+
+
+static inline void
+RSA_meth_free(RSA_METHOD *meth) {
+	if (meth == NULL) return;
+
+	if (meth->name != NULL)
+		OPENSSL_free((char*)meth->name);
+	OPENSSL_free(meth);
+}
+
+
+static inline RSA_METHOD*
+RSA_meth_dup(const RSA_METHOD *meth) {
+	RSA_METHOD *ret;
+
+	if (meth == NULL) return NULL;
+
+	ret = OPENSSL_malloc(sizeof(RSA_METHOD));
+	if (ret == NULL) return NULL;
+
+	memcpy(ret, meth, sizeof(*meth));
+	ret->name = BUF_strdup(meth->name);
+
+	return(ret);
+}
+
+
+static inline int
+RSA_meth_set1_name(RSA_METHOD *meth, const char *name) {
+	if (meth->name != NULL)
+		OPENSSL_free((char*)meth->name);
+	meth->name = BUF_strdup(name);
+
+	return meth->name != NULL;
+}
+
+
+typedef int (*priv_enc_f) (int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+
+static inline int
+RSA_meth_set_priv_enc(RSA_METHOD *meth, priv_enc_f priv_enc) {
+	meth->rsa_priv_enc = priv_enc;
+	return 1;
+}
+
+
+typedef int (*priv_dec_f) (int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+
+static inline int
+RSA_meth_set_priv_dec(RSA_METHOD *meth, priv_dec_f priv_dec) {
+	meth->rsa_priv_dec = priv_dec;
+	return 1;
+}
+
+
+typedef int (*finish_f) (RSA *rsa);
+
+static inline int
+RSA_meth_set_finish(RSA_METHOD *meth, finish_f finish) {
+	meth->finish = finish;
+	return 1;
+}
+
+
+typedef int (*pub_enc_f) (int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+
+static inline pub_enc_f
+RSA_meth_get_pub_enc(const RSA_METHOD *meth) { return meth->rsa_pub_enc; }
+
+static inline int
+RSA_meth_set_pub_enc(RSA_METHOD *meth, pub_enc_f pub_enc) {
+	meth->rsa_pub_enc = pub_enc;
+	return 1;
+}
+
+
+typedef int (*pub_dec_f) (int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+
+static inline pub_dec_f
+RSA_meth_get_pub_dec(const RSA_METHOD *meth) { return meth->rsa_pub_dec; }
+
+static inline int
+RSA_meth_set_pub_dec(RSA_METHOD *meth, pub_dec_f pub_dec) {
+	meth->rsa_pub_dec = pub_dec;
+	return 1;
+}
+
+
+typedef int (*rsa_mod_exp_f) (BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+	BN_CTX *ctx);
+
+static inline rsa_mod_exp_f
+RSA_meth_get_mod_exp(const RSA_METHOD *meth) { return meth->rsa_mod_exp; }
+
+static inline int
+RSA_meth_set_mod_exp(RSA_METHOD *meth, rsa_mod_exp_f rsa_mod_exp ) {
+	meth->rsa_mod_exp = rsa_mod_exp;
+	return 1;
+}
+
+
+typedef int (*rsa_bn_mod_exp_f) (BIGNUM *r, const BIGNUM *a,
+	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+	BN_MONT_CTX *m_ctx);
+
+static inline rsa_bn_mod_exp_f
+RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth) { return meth->bn_mod_exp; }
+
+static inline int
+RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, rsa_bn_mod_exp_f bn_mod_exp) {
+	meth->bn_mod_exp = bn_mod_exp;
+	return 1;
+}
+
+
+/* opaque RSA key structure */
+static inline void
+RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) {
+	if (n != NULL) *n = rsa->n;
+	if (e != NULL) *e = rsa->e;
+	if (d != NULL) *d = rsa->d;
+}
+
+static inline int
+RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
+/* If the fields in r are NULL, the corresponding input parameters MUST
+ * be non-NULL for n and e.  d may be left NULL (in case only the
+ * public key is used).
+ *
+ * It is an error to give the results from get0 on r as input
+ * parameters.
+ */
+	if (n == rsa->n || e == rsa->e
+	|| (rsa->d != NULL && d == rsa->d))
+		return 0;
+
+	if (n != NULL) { BN_free(rsa->n); rsa->n = n; }
+	if (e != NULL) { BN_free(rsa->e); rsa->e = e; }
+	if (d != NULL) { BN_free(rsa->d); rsa->d = d; }
+
+	return 1;
+}
+
+
+static inline void
+RSA_get0_crt_params(const RSA *rsa, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) {
+	if (dmp1 != NULL) *dmp1 = rsa->dmp1;
+	if (dmq1 != NULL) *dmq1 = rsa->dmq1;
+	if (iqmp != NULL) *iqmp = rsa->iqmp;
+}
+
+static inline int
+RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
+/* If the fields in r are NULL, the corresponding input parameters MUST
+ * be non-NULL.
+ *
+ * It is an error to give the results from get0 on r as input
+ * parameters.
+ */
+	if (dmp1 == rsa->dmp1 || dmq1 == rsa->dmq1 || iqmp == rsa->iqmp)
+		return 0;
+
+	if (dmp1 != NULL) { BN_free(rsa->dmp1); rsa->dmp1 = dmp1; }
+	if (dmq1 != NULL) { BN_free(rsa->dmq1); rsa->dmq1 = dmq1; }
+	if (iqmp != NULL) { BN_free(rsa->iqmp); rsa->iqmp = iqmp; }
+
+	return 1;
+}
+
+
+static inline void
+RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q) {
+	if (p != NULL) *p = rsa->p;
+	if (q != NULL) *q = rsa->q;
+}
+
+
+static inline int
+RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) {
+/* If the fields in r are NULL, the corresponding input parameters MUST
+ * be non-NULL.
+ *
+ * It is an error to give the results from get0 on r as input
+ * parameters.
+ */
+	if (p == rsa->p || q == rsa->q)
+		return 0;
+
+	if (p != NULL) { BN_free(rsa->p); rsa->p = p; }
+	if (q != NULL) { BN_free(rsa->q); rsa->q = q; }
+
+	return 1;
+}
+#endif /*ndef HAVE_RSA_METH_NEW*/
+#endif /*ndef OPENSSL_NO_RSA*/
+
+
+#ifndef OPENSSL_NO_DSA
+#ifndef HAVE_DSA_METH_NEW		/* OpenSSL < 1.1 */
+/* Partial backport of opaque DSA from OpenSSL >= 1.1, commits
+ * "Make DSA_METHOD opaque", "Various DSA opacity fixups",
+ * "RSA, DSA, DH: Allow some given input to be NULL on already
+ * initialised keys" and etc.
+ */
+
+/* opaque DSA method structure */
+static inline DSA_METHOD*
+DSA_meth_new(const char *name, int flags) {
+	DSA_METHOD *meth;
+
+	meth = OPENSSL_malloc(sizeof(DSA_METHOD));
+	if (meth == NULL) return NULL;
+
+	memset(meth, 0, sizeof(*meth));
+	/* unlike OPENSSL_strdup (0.8.k+), BUF_strdup is defined in
+	 * all OpenSSL versions (SSLeay 0.8.1) */
+	meth->name = BUF_strdup(name);
+	meth->flags = flags;
+
+	return(meth);
+}
+
+
+static inline void
+DSA_meth_free(DSA_METHOD *meth) {
+	if (meth == NULL) return;
+
+	if (meth->name != NULL)
+		OPENSSL_free((char*)meth->name);
+	OPENSSL_free(meth);
+}
+
+
+typedef DSA_SIG* (*dsa_sign_f) (const unsigned char*, int, DSA*);
+
+static inline int
+DSA_meth_set_sign(DSA_METHOD *meth, dsa_sign_f sign) {
+	meth->dsa_do_sign = sign;
+	return 1;
+}
+
+
+typedef int (*dsa_verify_f) (const unsigned char*, int, DSA_SIG*, DSA*);
+
+static inline dsa_verify_f
+DSA_meth_get_verify(const DSA_METHOD *meth) { return meth->dsa_do_verify; }
+
+static inline int
+DSA_meth_set_verify(DSA_METHOD *meth, dsa_verify_f verify) {
+	meth->dsa_do_verify = verify;
+	return 1;
+}
+
+
+typedef int (*mod_exp_f) (DSA*, BIGNUM*, BIGNUM*, BIGNUM*,
+	BIGNUM*, BIGNUM*, BIGNUM*, BN_CTX*, BN_MONT_CTX*);
+
+static inline mod_exp_f
+DSA_meth_get_mod_exp(const DSA_METHOD *meth) { return meth->dsa_mod_exp; }
+
+static inline int
+DSA_meth_set_mod_exp(DSA_METHOD *meth, mod_exp_f mod_exp) {
+	meth->dsa_mod_exp = mod_exp;
+	return 1;
+}
+
+
+typedef int (*bn_mod_exp_f) (DSA*, BIGNUM*, BIGNUM*,
+	const BIGNUM*, const BIGNUM*, BN_CTX*, BN_MONT_CTX*);
+
+static inline bn_mod_exp_f
+DSA_meth_get_bn_mod_exp(const DSA_METHOD *meth) { return meth->bn_mod_exp; }
+
+static inline int
+DSA_meth_set_bn_mod_exp(DSA_METHOD *meth, bn_mod_exp_f bn_mod_exp) {
+	meth->bn_mod_exp = bn_mod_exp;
+	return 1;
+}
+
+
+typedef int (*dsa_finish_f) (DSA*);
+
+static inline int
+DSA_meth_set_finish(DSA_METHOD *meth, dsa_finish_f finish) {
+	meth->finish = finish;
+	return 1;
+}
+
+
+/* opaque DSA key structure */
+static inline void
+DSA_get0_key(const DSA *dsa, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+	if (pub_key  != NULL) *pub_key  = dsa->pub_key;
+	if (priv_key != NULL) *priv_key = dsa->priv_key;
+}
+
+static inline int
+DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) {
+/* If the pub_key in d is NULL, the corresponding input parameters MUST
+ * be non-NULL.  The priv_key field may be left NULL.
+ *
+ * It is an error to give the results from get0 on d as input
+ * parameters.
+ */
+	if (pub_key == dsa->pub_key
+	|| (dsa->priv_key != NULL && priv_key == dsa->priv_key)
+	)
+		return 0;
+
+	if (pub_key  != NULL) { BN_free(dsa->pub_key ); dsa->pub_key  = pub_key ; }
+	if (priv_key != NULL) { BN_free(dsa->priv_key); dsa->priv_key = priv_key; }
+
+	return 1;
+}
+
+
+static inline void
+DSA_get0_pqg(const DSA *dsa, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+	if (p != NULL) *p = dsa->p;
+	if (q != NULL) *q = dsa->q;
+	if (g != NULL) *g = dsa->g;
+}
+
+static inline int
+DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+	/* If the fields in d are NULL, the corresponding input
+	 * parameters MUST be non-NULL.
+	 *
+	 * It is an error to give the results from get0 on d
+	 * as input parameters.
+	 */
+	if (p == dsa->p || q == dsa->q || g == dsa->g)
+		return 0;
+
+	if (p != NULL) { BN_free(dsa->p); dsa->p = p; }
+	if (q != NULL) { BN_free(dsa->q); dsa->q = q; }
+	if (g != NULL) { BN_free(dsa->g); dsa->g = g; }
+
+	return 1;
+}
+#endif /*ndef HAVE_DSA_METH_NEW*/
+
+#ifndef HAVE_DSA_SIG_GET0		/* OpenSSL < 1.1 */
+static inline void
+DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {
+	if (pr != NULL) *pr = sig->r;
+	if (ps != NULL) *ps = sig->s;
+}
+#endif /*ndef HAVE_DSA_SIG_GET0	OpenSSL < 1.1 */
+
+#ifndef HAVE_DSA_SIG_SET0		/* OpenSSL < 1.1 */
+static inline int/*bool*/
+DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
+	if (r == NULL || s == NULL) return 0;
+
+	BN_clear_free(sig->r);
+	BN_clear_free(sig->s);
+
+	sig->r = r;
+	sig->s = s;
+	return 1;
+}
+#endif /*ndef HAVE_DSA_SIG_SET0	OpenSSL < 1.1 */
+#endif /*ndef OPENSSL_NO_DSA*/
+
+
+#ifdef OPENSSL_HAS_ECC
+#ifndef HAVE_ECDSA_SIG_GET0		/* OpenSSL < 1.1 */
+static inline void
+ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {
+    if (pr != NULL) *pr = sig->r;
+    if (ps != NULL) *ps = sig->s;
+}
+#endif /*ndef HAVE_ECDSA_SIG_GET0	OpenSSL < 1.1 */
+
+#ifndef HAVE_ECDSA_SIG_SET0		/* OpenSSL < 1.1 */
+static inline int/*bool*/
+ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
+	if (r == NULL || s == NULL) return 0;
+
+	BN_clear_free(sig->r);
+	BN_clear_free(sig->s);
+
+	sig->r = r;
+	sig->s = s;
+	return 1;
+}
+#endif /*ndef HAVE_ECDSA_SIG_SET0	OpenSSL < 1.1 */
+#endif /*OPENSSL_HAS_ECC*/
+
+
+#ifdef OPENSSL_HAS_ECC
+# ifndef HAVE_EC_KEY_METHOD_NEW		/* OpenSSL < 1.1 */
+#  ifndef HAVE_ECDSA_METHOD_NEW		/* OpenSSL < 1.0.2 */
+
+#   ifndef HAVE_ECDSA_METHOD_NAME
+/*declared in some OpenSSL compatible headers*/
+struct ecdsa_method {
+    const char *name;
+    ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len,
+                                 const BIGNUM *inv, const BIGNUM *rp,
+                                 EC_KEY *eckey);
+    int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+                             BIGNUM **r);
+    int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len,
+                            const ECDSA_SIG *sig, EC_KEY *eckey);
+# if 0
+    int (*init) (EC_KEY *eckey);
+    int (*finish) (EC_KEY *eckey);
+# endif
+    int flags;
+    void *app_data;
+};
+#   endif /*ndef HAVE_ECDSA_METHOD_NAME*/
+
+
+static inline ECDSA_METHOD*
+ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method)
+{
+    (void)ecdsa_method;
+    return(OPENSSL_malloc(sizeof(ECDSA_METHOD)));
+}
+
+static inline void
+ECDSA_METHOD_set_sign(
+    ECDSA_METHOD *ecdsa_method,
+    ECDSA_SIG *(*ecdsa_do_sign) (
+        const unsigned char *dgst, int dgst_len,
+        const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey)
+) {
+    ecdsa_method->ecdsa_do_sign = ecdsa_do_sign;
+}
+
+#  endif /*ndef HAVE_ECDSA_METHOD_NEW		OpenSSL < 1.0.2 */
+# endif /*ndef HAVE_EC_KEY_METHOD_NEW		OpenSSL < 1.1 */
+#endif /*OPENSSL_HAS_ECC*/
+
+
+#ifndef HAVE_DH_GET0_KEY		/* OpenSSL < 1.1 */
+/* Partial backport of opaque DH from OpenSSL >= 1.1, commits
+ * "Make DH opaque", "RSA, DSA, DH: Allow some given input to be NULL
+ * on already initialised keys" and etc.
+ */
+
+static inline void
+DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) {
+	if (pub_key  != NULL) *pub_key  = dh->pub_key;
+	if (priv_key != NULL) *priv_key = dh->priv_key;
+}
+
+
+static int
+DH_set_length(DH *dh, long length) {
+	dh->length = length;
+	return 1;
+}
+
+
+static inline void
+DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
+	if (p != NULL) *p = dh->p;
+	if (q != NULL) *q = dh->q;
+	if (g != NULL) *g = dh->g;
+}
+
+
+static inline int
+DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
+/* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL.  q may remain NULL.
+ *
+ * It is an error to give the results from get0 on d as input
+ * parameters.
+ */
+	if (p == dh->p || (dh->q != NULL && q == dh->q) || g == dh->g)
+		return 0;
+
+	if (p != NULL) { BN_free(dh->p); dh->p = p; }
+	if (q != NULL) { BN_free(dh->q); dh->q = q; }
+	if (g != NULL) { BN_free(dh->g); dh->g = g; }
+
+	if (q != NULL)
+	        (void)DH_set_length(dh, BN_num_bits(q));
+
+	return 1;
+}
+#endif /*ndef HAVE_DH_GET0_KEY*/
+
+
+#ifndef HAVE_EVP_PKEY_ID
+/* OpenSSL >= 1.0 */
+static inline int EVP_PKEY_id(const EVP_PKEY *pkey) { return(pkey->type); }
+#endif /*ndef HAVE_EVP_PKEY_ID */
+
+
+#ifndef HAVE_EVP_PKEY_GET0_EC_KEY
+/* OpenSSL >= 1.1 by commit "Add EVP_PKEY_get0_* functions." */
+#ifdef OPENSSL_HAS_ECC
+static inline EC_KEY* EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { return(pkey->pkey.ec ); }
+#endif
+static inline DSA*    EVP_PKEY_get0_DSA   (EVP_PKEY *pkey) { return(pkey->pkey.dsa); }
+static inline RSA*    EVP_PKEY_get0_RSA   (EVP_PKEY *pkey) { return(pkey->pkey.rsa); }
+#endif /*ndef HAVE_EVP_PKEY_GET0_EC_KEY*/
+
+
+#ifndef HAVE_EVP_DSS1
+/* removed in OpenSSL 1.1 */
+static inline const EVP_MD* EVP_dss1(void) { return EVP_sha1(); }
+#endif
+
+#if !HAVE_DECL_UTF8_GETC
+/* hidden in some OpenSSL compatible libraries */
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+#endif
+
+#endif /* ndef EVP_COMPAT_H*/
diff -ruN openssh-7.5p1/hostfile.c openssh-7.5p1+x509-10.2/hostfile.c
--- openssh-7.5p1/hostfile.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/hostfile.c	2017-05-20 21:07:01.000000000 +0300
@@ -14,6 +14,8 @@
  *
  * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 1999 Niels Provos.  All rights reserved.
+ * X.509 certificates support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,6 +63,7 @@
 #include "ssherr.h"
 #include "digest.h"
 #include "hmac.h"
+#include "ssh-x509.h"
 
 struct hostkeys {
 	struct hostkey_entry *entries;
@@ -178,8 +181,15 @@
 
 	/* Return results. */
 	*cpp = cp;
-	if (bitsp != NULL)
-		*bitsp = sshkey_size(ret);
+	if (bitsp != NULL) {
+		if ((*bitsp = sshkey_size(ret)) <= 0) {
+			/* Note key may contain only X.509 distinguished name.
+			 * Return 1 in this case. */
+			if (sshkey_is_x509(ret))
+				return 1;
+			return 0;
+		}
+	}
 	return 1;
 }
 
@@ -323,6 +333,18 @@
 	return 0;
 }
 
+static int/*bool*/
+hostkey_match(const struct sshkey *key, const struct sshkey *found) {
+	if (sshkey_is_x509(key)) {
+		/* compare X.509 keys by distiguished name
+		 * if "X.509 store" is enabled otherwise
+		 * compare public parts
+		 */
+		return(sshkey_equal_public(key, found));
+	}
+	return(sshkey_equal(key, found));
+}
+
 /*
  * Match keys against a specified key, or look one up by key type.
  *
@@ -339,8 +361,8 @@
  * Finally, check any found key is not revoked.
  */
 static HostStatus
-check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
-    struct sshkey *k, int keytype, const struct hostkey_entry **found)
+check_hostkeys_by_key_or_types(struct hostkeys *hostkeys,
+    struct sshkey *k, int keytype, int subtype, const struct hostkey_entry **found)
 {
 	u_int i;
 	HostStatus end_return = HOST_NEW;
@@ -348,6 +370,7 @@
 	HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
 	int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;
 
+	if (k)	subtype = k->ecdsa_nid;
 	if (found != NULL)
 		*found = NULL;
 
@@ -359,7 +382,10 @@
 		if (hostkeys->entries[i].marker != want_marker)
 			continue;
 		if (k == NULL) {
-			if (hostkeys->entries[i].key->type != keytype)
+			if (X509KEY_BASETYPE(hostkeys->entries[i].key) != keytype)
+				continue;
+			/* NOTE ecdsa_nid is -1 for non ECC keys */
+			if (subtype != -1 && subtype != hostkeys->entries[i].key->ecdsa_nid)
 				continue;
 			end_return = HOST_FOUND;
 			if (found != NULL)
@@ -377,7 +403,7 @@
 				break;
 			}
 		} else {
-			if (sshkey_equal(k, hostkeys->entries[i].key)) {
+			if (hostkey_match(k, hostkeys->entries[i].key)) {
 				end_return = HOST_OK;
 				if (found != NULL)
 					*found = hostkeys->entries + i;
@@ -403,14 +429,14 @@
 {
 	if (key == NULL)
 		fatal("no key to look up");
-	return check_hostkeys_by_key_or_type(hostkeys, key, 0, found);
+	return check_hostkeys_by_key_or_types(hostkeys, key, 0, -1, found);
 }
 
 int
-lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype,
+lookup_key_in_hostkeys_by_types(struct hostkeys *hostkeys, int keytype, int subtype,
     const struct hostkey_entry **found)
 {
-	return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype,
+	return (check_hostkeys_by_key_or_types(hostkeys, NULL, keytype, subtype,
 	    found) == HOST_FOUND);
 }
 
@@ -437,7 +463,14 @@
 		fprintf(f, "%s ", lhost);
 	}
 	free(lhost);
-	if ((r = sshkey_write(key, f)) == 0)
+	if (sshkey_is_x509(key)) {
+		/* key_write prints x509 certificate in blob format :-( */
+		r = Xkey_write_subject(NULL, key, f)
+		    ? SSH_ERR_SUCCESS
+		    : SSH_ERR_INTERNAL_ERROR;
+	} else
+		r = sshkey_write(key, f);
+	if (r == 0)
 		success = 1;
 	else
 		error("%s: sshkey_write failed: %s", __func__, ssh_err(r));
diff -ruN openssh-7.5p1/hostfile.h openssh-7.5p1+x509-10.2/hostfile.h
--- openssh-7.5p1/hostfile.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/hostfile.h	2017-05-20 21:07:00.000000000 +0300
@@ -37,7 +37,7 @@
 
 HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *,
     const struct hostkey_entry **);
-int	 lookup_key_in_hostkeys_by_type(struct hostkeys *, int,
+int	 lookup_key_in_hostkeys_by_types(struct hostkeys *, int /*keytype*/, int /*subtype*/,
     const struct hostkey_entry **);
 
 int	 hostfile_read_key(char **, u_int *, struct sshkey *);
diff -ruN openssh-7.5p1/INSTALL openssh-7.5p1+x509-10.2/INSTALL
--- openssh-7.5p1/INSTALL	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/INSTALL	2017-05-20 21:07:00.000000000 +0300
@@ -7,26 +7,25 @@
  - clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
   (CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)
 
-You will need working installations of Zlib and libcrypto (LibreSSL /
-OpenSSL)
+You will need working installations of Zlib and libcrypto (OpenSSL
+or compatible)
 
 Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
 http://www.gzip.org/zlib/
 
-libcrypto (LibreSSL or OpenSSL >= 0.9.8f < 1.1.0)
-LibreSSL http://www.libressl.org/ ; or
-OpenSSL http://www.openssl.org/
+libcrypto (OpenSSL or compatible)
+OpenSSL http://www.openssl.org/ ; or
+LibreSSL http://www.libressl.org/
 
-LibreSSL/OpenSSL should be compiled as a position-independent library
+libcrypto should be compiled as a position-independent library
 (i.e. with -fPIC) otherwise OpenSSH will not be able to link with it.
 If you must use a non-position-independent libcrypto, then you may need
-to configure OpenSSH --without-pie.  Note that because of API changes,
-OpenSSL 1.1.x is not currently supported.
+to configure OpenSSH --without-pie.
 
 The remaining items are optional.
 
 NB. If you operating system supports /dev/random, you should configure
-libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
+libcrypto to use it. OpenSSH relies on libcrypto's
 direct support of /dev/random, or failing that, either prngd or egd
 
 PRNGD:
@@ -104,6 +103,9 @@
 implementation (http://www.openbsm.org).
 
 
+X.509 certificate support:
+http://roumenpetrov.info/openssh
+
 2. Building / Installation
 --------------------------
 
@@ -212,6 +214,9 @@
 --with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
 real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
 
+--with-sshca-dir=PATH   allows you to specify location of ssh CA root
+used by ssh "x509 store" to verify certificates.
+
 If you need to pass special options to the compiler or linker, you
 can specify these as environment variables before running ./configure.
 For example:
diff -ruN openssh-7.5p1/kex.c openssh-7.5p1+x509-10.2/kex.c
--- openssh-7.5p1/kex.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kex.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,8 @@
 /* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +39,7 @@
 #include <openssl/dh.h>
 #endif
 
+#include "xmalloc.h"
 #include "ssh2.h"
 #include "packet.h"
 #include "compat.h"
@@ -62,6 +65,10 @@
 # endif
 #endif
 
+const char *srv_extinfo_pkalgs = "publickey-algorithms@roumenpetrov.info";
+char *server_pkalgs = NULL;
+char *server_sigalgs = NULL;
+
 /* prototype */
 static int kex_choose_conf(struct ssh *);
 static int kex_input_newkeys(int, u_int32_t, void *);
@@ -89,9 +96,11 @@
 #ifdef WITH_OPENSSL
 	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
 	{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
+#ifdef HAVE_EVP_SHA256
 	{ 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 },
+#endif /* HAVE_EVP_SHA256 */
 	{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
 #ifdef HAVE_EVP_SHA256
 	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
@@ -347,20 +356,23 @@
 kex_send_ext_info(struct ssh *ssh)
 {
 	int r;
-	char *algs;
 
-	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
-		return SSH_ERR_ALLOC_FAIL;
-	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
-	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
+	if (server_pkalgs == NULL || server_sigalgs == NULL)
+		return 0;
+
+	if (
+	    (r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
+	    (r = sshpkt_put_u32(ssh, 2)) != 0 ||
+	    (r = sshpkt_put_cstring(ssh, srv_extinfo_pkalgs)) != 0 ||
+	    (r = sshpkt_put_cstring(ssh, server_pkalgs)) != 0 ||
+	    /* send server-sig-algs for compatibility */
 	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
-	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
-	    (r = sshpkt_send(ssh)) != 0)
-		goto out;
-	/* success */
-	r = 0;
- out:
-	free(algs);
+	    (r = sshpkt_put_cstring(ssh, server_sigalgs)) != 0
+	) goto out;
+
+	r = sshpkt_send(ssh);
+
+out:
 	return r;
 }
 
@@ -382,13 +394,68 @@
 	return 0;
 }
 
+static void
+preset_pkalgs(struct kex *kex, char *pkalgs) {
+	size_t n = 0;
+
+	free(kex->pkalgs);
+	kex->pkalgs = NULL;
+
+	if (pkalgs == NULL) return;
+
+{	char *alg, *q = pkalgs, *new_pkalgs = NULL;
+
+	for (alg = strsep(&q, ","); alg != NULL; alg = strsep(&q, ",")) {
+		size_t len;
+		int type = sshkey_type_from_name(alg);
+
+		if (type == KEY_RSA1) continue;
+		if (type == KEY_UNSPEC) {
+			debug3("%s: unsupported public-key algorithm", __func__);
+			continue;
+		}
+
+		len = strlen(alg);
+		new_pkalgs = realloc(new_pkalgs, n + len + 1);
+		if (new_pkalgs == NULL) goto done;
+
+		memmove(new_pkalgs + n, alg, len);
+		n += len;
+		new_pkalgs[n++] = ',';
+	}
+	if (new_pkalgs != NULL)
+		new_pkalgs[--n] = '\0';
+
+	kex->pkalgs = new_pkalgs;
+#ifdef HAVE_EVP_SHA256
+	if (new_pkalgs != NULL) {
+		char *found;
+
+		found = match_list("rsa-sha2-512", new_pkalgs, NULL);
+		if (found != NULL) {
+			kex->rsa_sha2 = 512;
+			free(found);
+		}
+		found = match_list("rsa-sha2-256", new_pkalgs, NULL);
+		if (found != NULL) {
+			kex->rsa_sha2 = 256;
+			free(found);
+		}
+	}
+#endif /*def HAVE_EVP_SHA256*/
+done:
+	free(pkalgs);
+}
+}
+
 int
 kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
 {
 	struct ssh *ssh = ctxt;
 	struct kex *kex = ssh->kex;
 	u_int32_t i, ninfo;
-	char *name, *val, *found;
+	char *name, *val;
+	char *pkalgs = NULL, *sigalgs = NULL;
 	int r;
 
 	debug("SSH2_MSG_EXT_INFO received");
@@ -403,21 +470,34 @@
 			return r;
 		}
 		debug("%s: %s=<%s>", __func__, name, val);
+		if (strcmp(name, srv_extinfo_pkalgs) == 0) {
+			pkalgs = val;
+			free(name);
+			continue;
+		}
 		if (strcmp(name, "server-sig-algs") == 0) {
-			found = match_list("rsa-sha2-256", val, NULL);
-			if (found) {
-				kex->rsa_sha2 = 256;
-				free(found);
-			}
-			found = match_list("rsa-sha2-512", val, NULL);
-			if (found) {
-				kex->rsa_sha2 = 512;
-				free(found);
-			}
+			sigalgs = val;
+			free(name);
+			continue;
 		}
 		free(name);
 		free(val);
 	}
+	if (pkalgs != NULL) {
+		free(sigalgs);
+		preset_pkalgs(kex, pkalgs);
+	} else {
+		ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO compat */
+		if (check_compat_x509(&ctx_compat, SSHX_OPENSSH_BROKEN_ALGO_INFO)) {
+			free(sigalgs);
+			/* use list as is properly announced in OpenSSH 7.5 */
+			sigalgs = strdup(
+				"ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,"
+				"ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521");
+		}
+		preset_pkalgs(kex, sigalgs);
+	}
+
 	return sshpkt_get_end(ssh);
 }
 
@@ -439,6 +519,10 @@
 	sshbuf_reset(kex->peer);
 	/* sshbuf_reset(kex->my); */
 	kex->flags &= ~KEX_INIT_SENT;
+
+	free(kex->hostkey_alg);
+	kex->hostkey_alg = NULL;
+
 	free(kex->name);
 	kex->name = NULL;
 	return 0;
@@ -609,6 +693,7 @@
 	free(kex->server_version_string);
 	free(kex->failed_choice);
 	free(kex->hostkey_alg);
+	free(kex->pkalgs);
 	free(kex->name);
 	free(kex);
 }
@@ -736,10 +821,8 @@
 	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
 	if (k->hostkey_alg == NULL)
 		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
-	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
-	if (k->hostkey_type == KEY_UNSPEC)
+	if (sshkey_type_from_name(k->hostkey_alg) == KEY_UNSPEC)
 		return SSH_ERR_INTERNAL_ERROR;
-	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
 	return 0;
 }
 
@@ -868,13 +951,13 @@
 	/* XXX need runden? */
 	kex->we_need = need;
 	kex->dh_need = dh_need;
+	r = 0;
 
+ out:
 	/* ignore the next message if the proposals do not match */
 	if (first_kex_follows && !proposals_match(my, peer) &&
 	    !(ssh->compat & SSH_BUG_FIRSTKEX))
 		ssh->dispatch_skip_packets = 1;
-	r = 0;
- out:
 	kex_prop_free(my);
 	kex_prop_free(peer);
 	return r;
@@ -988,9 +1071,37 @@
 }
 #endif
 
+int
+kex_load_host_keys(struct kex *kex, struct ssh *ssh, struct sshkey **hostpub, struct sshkey **hostpriv) {
+	int r;
+
+	if (hostpub == NULL || hostpriv == NULL) {
+		r = SSH_ERR_INVALID_ARGUMENT;
+		goto done;
+	}
+
+	if (kex->find_host_public_key == NULL ||
+	    kex->find_host_private_key == NULL) {
+		r = SSH_ERR_INVALID_ARGUMENT;
+		goto done;
+	}
+
+	*hostpub = kex->find_host_public_key(kex->hostkey_alg, ssh);
+	*hostpriv = kex->find_host_private_key(kex->hostkey_alg, ssh);
+
+	/* Only public part is required, private is optional and
+	 * caller is responsible to check private part
+	 */
+	r = (*hostpub != NULL)
+		? SSH_ERR_SUCCESS
+		: SSH_ERR_NO_HOSTKEY_LOADED;
+done:
+	return r;
+}
+
 #ifdef WITH_SSH1
 int
-derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
+derive_ssh1_session_id(const BIGNUM *host_modulus, const BIGNUM *server_modulus,
     u_int8_t cookie[8], u_int8_t id[16])
 {
 	u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
diff -ruN openssh-7.5p1/kexc25519c.c openssh-7.5p1+x509-10.2/kexc25519c.c
--- openssh-7.5p1/kexc25519c.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexc25519c.c	2017-05-20 21:07:01.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
  * Copyright (c) 2013 Aris Adamantiadis.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -33,7 +36,8 @@
 #include <string.h>
 #include <signal.h>
 
-#include "sshkey.h"
+#include "ssh-x509.h"
+#include "compat.h"
 #include "cipher.h"
 #include "kex.h"
 #include "log.h"
@@ -87,14 +91,13 @@
 	}
 
 	/* hostkey */
-	if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
-	    &sbloblen)) != 0 ||
-	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
-	    &server_host_key)) != 0)
-		goto out;
-	if (server_host_key->type != kex->hostkey_type ||
-	    (kex->hostkey_type == KEY_ECDSA &&
-	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
+	r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen);
+	if (r != 0) goto out;
+
+	r = Xkey_from_blob(kex->hostkey_alg, server_host_key_blob, sbloblen, &server_host_key);
+	if (r != SSH_ERR_SUCCESS) goto out;
+
+	if (!sshkey_match_pkalg(server_host_key, kex->hostkey_alg)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
@@ -141,9 +144,12 @@
 	    hash, &hashlen)) < 0)
 		goto out;
 
-	if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
-	    ssh->compat)) != 0)
-		goto out;
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_verify compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_key, &ctx_compat };
+
+	r = Xkey_verify(&ctx, signature, slen, hash, hashlen);
+	if (r != 0) goto out;
+}
 
 	/* save session id */
 	if (kex->session_id == NULL) {
diff -ruN openssh-7.5p1/kexc25519s.c openssh-7.5p1+x509-10.2/kexc25519s.c
--- openssh-7.5p1/kexc25519s.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexc25519s.c	2017-05-20 21:07:01.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
  * Copyright (c) 2013 Aris Adamantiadis.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
@@ -32,12 +35,14 @@
 #include <signal.h>
 
 #include "sshkey.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
 #include "ssh2.h"
+#include "compat.h"
 #include "sshbuf.h"
 #include "ssherr.h"
 
@@ -71,19 +76,10 @@
 #ifdef DEBUG_KEXECDH
 	dump_digest("server private key:", server_key, sizeof(server_key));
 #endif
-	if (kex->load_host_public_key == NULL ||
-	    kex->load_host_private_key == NULL) {
-		r = SSH_ERR_INVALID_ARGUMENT;
-		goto out;
-	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	if (server_host_public == NULL) {
-		r = SSH_ERR_NO_HOSTKEY_LOADED;
+
+	r = kex_load_host_keys(kex, ssh, &server_host_public, &server_host_private);
+	if (r != SSH_ERR_SUCCESS)
 		goto out;
-	}
 
 	if ((r = sshpkt_get_string(ssh, &client_pubkey, &pklen)) != 0 ||
 	    (r = sshpkt_get_end(ssh)) != 0)
@@ -105,9 +101,12 @@
 		goto out;
 
 	/* calc H */
-	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
-	    &sbloblen)) != 0)
-		goto out;
+	r = Xkey_to_blob(kex->hostkey_alg, server_host_public, &server_host_key_blob, &sbloblen);
+	if (r != SSH_ERR_SUCCESS) goto out;
+#ifdef DEBUG_KEXECDH
+	dump_digest("server public key:", server_host_key_blob, sbloblen);
+#endif
+
 	hashlen = sizeof(hash);
 	if ((r = kex_c25519_hash(
 	    kex->hash_alg,
@@ -134,9 +133,13 @@
 	}
 
 	/* sign H */
-	if ((r = kex->sign(server_host_private, server_host_public, &signature,
-	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_sign compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_private, &ctx_compat };
+
+	r = kex->xsign(&ctx, server_host_public, &signature, &slen, hash, hashlen);
+	if (r != 0)
 		goto out;
+}
 
 	/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
diff -ruN openssh-7.5p1/kexdhc.c openssh-7.5p1+x509-10.2/kexdhc.c
--- openssh-7.5p1/kexdhc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexdhc.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -36,7 +39,8 @@
 #include <string.h>
 #include <signal.h>
 
-#include "sshkey.h"
+#include "evp-compat.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -56,6 +60,7 @@
 {
 	struct kex *kex = ssh->kex;
 	int r;
+	const BIGNUM *pub_key;
 
 	/* generate and send 'e', client DH public key */
 	switch (kex->kex_type) {
@@ -81,15 +86,18 @@
 		goto out;
 	}
 	debug("sending SSH2_MSG_KEXDH_INIT");
-	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
-	    (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
+	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
+		goto out;
+	pub_key = NULL;
+	DH_get0_key(kex->dh, &pub_key, NULL);
+	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
+	    (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
 	    (r = sshpkt_send(ssh)) != 0)
 		goto out;
 #ifdef DEBUG_KEXDH
 	DHparams_print_fp(stderr, kex->dh);
 	fprintf(stderr, "pub= ");
-	BN_print_fp(stderr, kex->dh->pub_key);
+	BN_print_fp(stderr, pub_key);
 	fprintf(stderr, "\n");
 #endif
 	debug("expecting SSH2_MSG_KEXDH_REPLY");
@@ -116,14 +124,13 @@
 		goto out;
 	}
 	/* key, cert */
-	if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
-	    &sbloblen)) != 0 ||
-	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
-	    &server_host_key)) != 0)
-		goto out;
-	if (server_host_key->type != kex->hostkey_type ||
-	    (kex->hostkey_type == KEY_ECDSA &&
-	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
+	r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen);
+	if (r != 0) goto out;
+
+	r = Xkey_from_blob(kex->hostkey_alg, server_host_key_blob, sbloblen, &server_host_key);
+	if (r != SSH_ERR_SUCCESS) goto out;
+
+	if (!sshkey_match_pkalg(server_host_key, kex->hostkey_alg)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
@@ -168,6 +175,11 @@
 	dump_digest("shared secret", kbuf, kout);
 #endif
 
+{
+	const BIGNUM *pub_key = NULL;
+
+	DH_get0_key(kex->dh, &pub_key, NULL);
+
 	/* calc and verify H */
 	hashlen = sizeof(hash);
 	if ((r = kex_dh_hash(
@@ -177,15 +189,19 @@
 	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
 	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
 	    server_host_key_blob, sbloblen,
-	    kex->dh->pub_key,
+	    pub_key,
 	    dh_server_pub,
 	    shared_secret,
 	    hash, &hashlen)) != 0)
 		goto out;
+}
 
-	if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
-	    ssh->compat)) != 0)
-		goto out;
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_verify compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_key, &ctx_compat };
+
+	r = Xkey_verify(&ctx, signature, slen, hash, hashlen);
+	if (r != 0) goto out;
+}
 
 	/* save session id */
 	if (kex->session_id == NULL) {
diff -ruN openssh-7.5p1/kexdhs.c openssh-7.5p1+x509-10.2/kexdhs.c
--- openssh-7.5p1/kexdhs.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexdhs.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -35,7 +38,9 @@
 
 #include <openssl/dh.h>
 
+#include "evp-compat.h"
 #include "sshkey.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -96,6 +101,7 @@
 	struct ssh *ssh = ctxt;
 	struct kex *kex = ssh->kex;
 	BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+	const BIGNUM *pub_key = NULL;
 	struct sshkey *server_host_public, *server_host_private;
 	u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
 	u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -103,19 +109,9 @@
 	size_t klen = 0, hashlen;
 	int kout, r;
 
-	if (kex->load_host_public_key == NULL ||
-	    kex->load_host_private_key == NULL) {
-		r = SSH_ERR_INVALID_ARGUMENT;
-		goto out;
-	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	if (server_host_public == NULL) {
-		r = SSH_ERR_NO_HOSTKEY_LOADED;
+	r = kex_load_host_keys(kex, ssh, &server_host_public, &server_host_private);
+	if (r != SSH_ERR_SUCCESS)
 		goto out;
-	}
 
 	/* key, cert */
 	if ((dh_client_pub = BN_new()) == NULL) {
@@ -133,10 +129,12 @@
 	debug("bits %d", BN_num_bits(dh_client_pub));
 #endif
 
+	DH_get0_key(kex->dh, &pub_key, NULL);
+
 #ifdef DEBUG_KEXDH
 	DHparams_print_fp(stderr, kex->dh);
 	fprintf(stderr, "pub= ");
-	BN_print_fp(stderr, kex->dh->pub_key);
+	BN_print_fp(stderr, pub_key);
 	fprintf(stderr, "\n");
 #endif
 	if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -159,9 +157,12 @@
 #ifdef DEBUG_KEXDH
 	dump_digest("shared secret", kbuf, kout);
 #endif
-	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
-	    &sbloblen)) != 0)
-		goto out;
+	r = Xkey_to_blob(kex->hostkey_alg, server_host_public, &server_host_key_blob, &sbloblen);
+	if (r != SSH_ERR_SUCCESS) goto out;
+#ifdef DEBUG_KEXDH
+	dump_digest("server public key:", server_host_key_blob, sbloblen);
+#endif
+
 	/* calc H */
 	hashlen = sizeof(hash);
 	if ((r = kex_dh_hash(
@@ -172,7 +173,7 @@
 	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
 	    server_host_key_blob, sbloblen,
 	    dh_client_pub,
-	    kex->dh->pub_key,
+	    pub_key,
 	    shared_secret,
 	    hash, &hashlen)) != 0)
 		goto out;
@@ -189,16 +190,20 @@
 	}
 
 	/* sign H */
-	if ((r = kex->sign(server_host_private, server_host_public, &signature,
-	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_sign compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_private, &ctx_compat };
+
+	r = kex->xsign(&ctx, server_host_public, &signature, &slen, hash, hashlen);
+	if (r != 0)
 		goto out;
+}
 
 	/* destroy_sensitive_data(); */
 
 	/* send server hostkey, DH pubkey 'f' and singed H */
 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
 	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||	/* f */
+	    (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||	/* f */
 	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
 	    (r = sshpkt_send(ssh)) != 0)
 		goto out;
diff -ruN openssh-7.5p1/kexecdhc.c openssh-7.5p1+x509-10.2/kexecdhc.c
--- openssh-7.5p1/kexecdhc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexecdhc.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,9 @@
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -36,7 +39,7 @@
 
 #include <openssl/ecdh.h>
 
-#include "sshkey.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -119,14 +122,13 @@
 	client_key = kex->ec_client_key;
 
 	/* hostkey */
-	if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
-	    &sbloblen)) != 0 ||
-	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
-	    &server_host_key)) != 0)
-		goto out;
-	if (server_host_key->type != kex->hostkey_type ||
-	    (kex->hostkey_type == KEY_ECDSA &&
-	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
+	r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen);
+	if (r != 0) goto out;
+
+	r = Xkey_from_blob(kex->hostkey_alg, server_host_key_blob, sbloblen, &server_host_key);
+	if (r != SSH_ERR_SUCCESS) goto out;
+
+	if (!sshkey_match_pkalg(server_host_key, kex->hostkey_alg)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
@@ -188,9 +190,12 @@
 	    hash, &hashlen)) != 0)
 		goto out;
 
-	if ((r = sshkey_verify(server_host_key, signature, slen, hash,
-	    hashlen, ssh->compat)) != 0)
-		goto out;
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_verify compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_key, &ctx_compat };
+
+	r = Xkey_verify(&ctx, signature, slen, hash, hashlen);
+	if (r != 0) goto out;
+}
 
 	/* save session id */
 	if (kex->session_id == NULL) {
diff -ruN openssh-7.5p1/kexecdhs.c openssh-7.5p1+x509-10.2/kexecdhs.c
--- openssh-7.5p1/kexecdhs.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexecdhs.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,9 @@
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -35,6 +38,7 @@
 #include <openssl/ecdh.h>
 
 #include "sshkey.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -90,19 +94,10 @@
 	sshkey_dump_ec_key(server_key);
 #endif
 
-	if (kex->load_host_public_key == NULL ||
-	    kex->load_host_private_key == NULL) {
-		r = SSH_ERR_INVALID_ARGUMENT;
-		goto out;
-	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	if (server_host_public == NULL) {
-		r = SSH_ERR_NO_HOSTKEY_LOADED;
+	r = kex_load_host_keys(kex, ssh, &server_host_public, &server_host_private);
+	if (r != SSH_ERR_SUCCESS)
 		goto out;
-	}
+
 	if ((client_public = EC_POINT_new(group)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
@@ -139,9 +134,12 @@
 	dump_digest("shared secret", kbuf, klen);
 #endif
 	/* calc H */
-	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
-	    &sbloblen)) != 0)
-		goto out;
+	r = Xkey_to_blob(kex->hostkey_alg, server_host_public, &server_host_key_blob, &sbloblen);
+	if (r != SSH_ERR_SUCCESS) goto out;
+#ifdef DEBUG_KEXECDH
+	dump_digest("server public key:", server_host_key_blob, sbloblen);
+#endif
+
 	hashlen = sizeof(hash);
 	if ((r = kex_ecdh_hash(
 	    kex->hash_alg,
@@ -169,9 +167,13 @@
 	}
 
 	/* sign H */
-	if ((r = kex->sign(server_host_private, server_host_public, &signature,
-	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_sign compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_private, &ctx_compat };
+
+	r = kex->xsign(&ctx, server_host_public, &signature, &slen, hash, hashlen);
+	if (r != 0)
 		goto out;
+}
 
 	/* destroy_sensitive_data(); */
 
diff -ruN openssh-7.5p1/kexgexc.c openssh-7.5p1+x509-10.2/kexgexc.c
--- openssh-7.5p1/kexgexc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexgexc.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,9 @@
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -37,7 +40,8 @@
 #include <string.h>
 #include <signal.h>
 
-#include "sshkey.h"
+#include "evp-compat.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -118,19 +122,25 @@
 	}
 	p = g = NULL; /* belong to kex->dh now */
 
+{
 	/* generate and send 'e', client DH public key */
-	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
-	    (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
+	const BIGNUM *pub_key = NULL;
+
+	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)))
+		goto out;
+	DH_get0_key(kex->dh, &pub_key, NULL);
+	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
+	    (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
 	    (r = sshpkt_send(ssh)) != 0)
 		goto out;
 	debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
 #ifdef DEBUG_KEXDH
 	DHparams_print_fp(stderr, kex->dh);
 	fprintf(stderr, "pub= ");
-	BN_print_fp(stderr, kex->dh->pub_key);
+	BN_print_fp(stderr, pub_key);
 	fprintf(stderr, "\n");
 #endif
+}
 	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
 	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
 	r = 0;
@@ -160,18 +170,13 @@
 		goto out;
 	}
 	/* key, cert */
-	if ((r = sshpkt_get_string(ssh, &server_host_key_blob,
-	    &sbloblen)) != 0 ||
-	    (r = sshkey_from_blob(server_host_key_blob, sbloblen,
-	    &server_host_key)) != 0)
-		goto out;
-	if (server_host_key->type != kex->hostkey_type) {
-		r = SSH_ERR_KEY_TYPE_MISMATCH;
-		goto out;
-	}
-	if (server_host_key->type != kex->hostkey_type ||
-	    (kex->hostkey_type == KEY_ECDSA &&
-	    server_host_key->ecdsa_nid != kex->hostkey_nid)) {
+	r = sshpkt_get_string(ssh, &server_host_key_blob, &sbloblen);
+	if (r != 0) goto out;
+
+	r = Xkey_from_blob(kex->hostkey_alg, server_host_key_blob, sbloblen, &server_host_key);
+	if (r != SSH_ERR_SUCCESS) goto out;
+
+	if (!sshkey_match_pkalg(server_host_key, kex->hostkey_alg)) {
 		r = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
@@ -218,6 +223,12 @@
 	if (ssh->compat & SSH_OLD_DHGEX)
 		kex->min = kex->max = -1;
 
+{
+	const BIGNUM *p = NULL, *g = NULL, *pub_key = NULL;
+
+	DH_get0_pqg(kex->dh, &p, NULL, &g);
+	DH_get0_key(kex->dh, &pub_key, NULL);
+
 	/* calc and verify H */
 	hashlen = sizeof(hash);
 	if ((r = kexgex_hash(
@@ -228,16 +239,20 @@
 	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
 	    server_host_key_blob, sbloblen,
 	    kex->min, kex->nbits, kex->max,
-	    kex->dh->p, kex->dh->g,
-	    kex->dh->pub_key,
+	    p, g,
+	    pub_key,
 	    dh_server_pub,
 	    shared_secret,
 	    hash, &hashlen)) != 0)
 		goto out;
+}
 
-	if ((r = sshkey_verify(server_host_key, signature, slen, hash,
-	    hashlen, ssh->compat)) != 0)
-		goto out;
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_verify compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_key, &ctx_compat };
+
+	r = Xkey_verify(&ctx, signature, slen, hash, hashlen);
+	if (r != 0) goto out;
+}
 
 	/* save session id */
 	if (kex->session_id == NULL) {
diff -ruN openssh-7.5p1/kexgexs.c openssh-7.5p1+x509-10.2/kexgexs.c
--- openssh-7.5p1/kexgexs.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kexgexs.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,9 @@
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -36,7 +39,9 @@
 
 #include <openssl/dh.h>
 
+#include "evp-compat.h"
 #include "sshkey.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "digest.h"
 #include "kex.h"
@@ -102,11 +107,17 @@
 		goto out;
 	}
 	debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
+{
+	const BIGNUM *p = NULL, *g = NULL;
+
+	DH_get0_pqg(kex->dh, &p, NULL, &g);
+
 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
+	    (r = sshpkt_put_bignum2(ssh, p)) != 0 ||
+	    (r = sshpkt_put_bignum2(ssh, g)) != 0 ||
 	    (r = sshpkt_send(ssh)) != 0)
 		goto out;
+}
 
 	/* Compute our exchange value in parallel with the client */
 	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
@@ -125,6 +136,7 @@
 	struct ssh *ssh = ctxt;
 	struct kex *kex = ssh->kex;
 	BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+	const BIGNUM *pub_key = NULL;
 	struct sshkey *server_host_public, *server_host_private;
 	u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
 	u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -132,19 +144,9 @@
 	size_t klen = 0, hashlen;
 	int kout, r;
 
-	if (kex->load_host_public_key == NULL ||
-	    kex->load_host_private_key == NULL) {
-		r = SSH_ERR_INVALID_ARGUMENT;
+	r = kex_load_host_keys(kex, ssh, &server_host_public, &server_host_private);
+	if (r != SSH_ERR_SUCCESS)
 		goto out;
-	}
-	server_host_public = kex->load_host_public_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	server_host_private = kex->load_host_private_key(kex->hostkey_type,
-	    kex->hostkey_nid, ssh);
-	if (server_host_public == NULL) {
-		r = SSH_ERR_NO_HOSTKEY_LOADED;
-		goto out;
-	}
 
 	/* key, cert */
 	if ((dh_client_pub = BN_new()) == NULL) {
@@ -162,10 +164,12 @@
 	debug("bits %d", BN_num_bits(dh_client_pub));
 #endif
 
+	DH_get0_key(kex->dh, &pub_key, NULL);
+
 #ifdef DEBUG_KEXDH
 	DHparams_print_fp(stderr, kex->dh);
 	fprintf(stderr, "pub= ");
-	BN_print_fp(stderr, kex->dh->pub_key);
+	BN_print_fp(stderr, pub_key);
 	fprintf(stderr, "\n");
 #endif
 	if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -188,9 +192,18 @@
 #ifdef DEBUG_KEXDH
 	dump_digest("shared secret", kbuf, kout);
 #endif
-	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
-	    &sbloblen)) != 0)
-		goto out;
+
+	r = Xkey_to_blob(kex->hostkey_alg, server_host_public, &server_host_key_blob, &sbloblen);
+	if (r != SSH_ERR_SUCCESS) goto out;
+#ifdef DEBUG_KEXDH
+	dump_digest("server public key:", server_host_key_blob, sbloblen);
+#endif
+
+{
+	const BIGNUM *p = NULL, *g = NULL;
+
+	DH_get0_pqg(kex->dh, &p, NULL, &g);
+
 	/* calc H */
 	hashlen = sizeof(hash);
 	if ((r = kexgex_hash(
@@ -201,12 +214,13 @@
 	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
 	    server_host_key_blob, sbloblen,
 	    kex->min, kex->nbits, kex->max,
-	    kex->dh->p, kex->dh->g,
+	    p, g,
 	    dh_client_pub,
-	    kex->dh->pub_key,
+	    pub_key,
 	    shared_secret,
 	    hash, &hashlen)) != 0)
 		goto out;
+}
 
 	/* save session id := H */
 	if (kex->session_id == NULL) {
@@ -220,16 +234,20 @@
 	}
 
 	/* sign H */
-	if ((r = kex->sign(server_host_private, server_host_public, &signature,
-	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
+{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_sign compat */
+	ssh_sign_ctx ctx = { kex->hostkey_alg, server_host_private, &ctx_compat };
+
+	r = kex->xsign(&ctx, server_host_public, &signature, &slen, hash, hashlen);
+	if (r != 0)
 		goto out;
+}
 
 	/* destroy_sensitive_data(); */
 
 	/* send server hostkey, DH pubkey 'f' and singed H */
 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
 	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
-	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||     /* f */
+	    (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||     /* f */
 	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
 	    (r = sshpkt_send(ssh)) != 0)
 		goto out;
diff -ruN openssh-7.5p1/kex.h openssh-7.5p1+x509-10.2/kex.h
--- openssh-7.5p1/kex.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/kex.h	2017-05-20 21:07:00.000000000 +0300
@@ -3,6 +3,9 @@
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -28,7 +31,7 @@
 
 #include "mac.h"
 #include "buffer.h" /* XXX for typedef */
-#include "key.h" /* XXX for typedef */
+#include "ssh-x509.h"
 
 #ifdef WITH_LEAKMALLOC
 #include "leakmalloc.h"
@@ -136,9 +139,8 @@
 	int	server;
 	char	*name;
 	char	*hostkey_alg;
-	int	hostkey_type;
-	int	hostkey_nid;
 	u_int	kex_type;
+	char	*pkalgs;
 	int	rsa_sha2;
 	int	ext_info_c;
 	struct sshbuf *my;
@@ -151,11 +153,11 @@
 	char	*server_version_string;
 	char	*failed_choice;
 	int	(*verify_host_key)(struct sshkey *, struct ssh *);
-	struct sshkey *(*load_host_public_key)(int, int, struct ssh *);
-	struct sshkey *(*load_host_private_key)(int, int, struct ssh *);
+	struct sshkey *(*find_host_public_key)(const char* pkalg, struct ssh *);
+	struct sshkey *(*find_host_private_key)(const char* pkalg, struct ssh *);
 	int	(*host_key_index)(struct sshkey *, int, struct ssh *);
-	int	(*sign)(struct sshkey *, struct sshkey *, u_char **, size_t *,
-	    const u_char *, size_t, const char *, u_int);
+	int	(*xsign)(ssh_sign_ctx *ctx, struct sshkey *pub,
+	    u_char **sigp, size_t *lenp, const u_char *data, size_t datalen);
 	int	(*kex[KEX_MAX])(struct ssh *);
 	/* kex specific state */
 	DH	*dh;			/* DH */
@@ -188,6 +190,9 @@
 int	 kex_send_newkeys(struct ssh *);
 int	 kex_start_rekex(struct ssh *);
 
+int	 kex_load_host_keys(struct kex *kex, struct ssh *ssh, struct sshkey **hostpub, struct sshkey **hostpriv);
+
+
 int	 kexdh_client(struct ssh *);
 int	 kexdh_server(struct ssh *);
 int	 kexgex_client(struct ssh *);
@@ -226,7 +231,7 @@
 	__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
 
 int
-derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
+derive_ssh1_session_id(const BIGNUM *, const BIGNUM *, u_int8_t[8], u_int8_t[16]);
 
 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
 void	dump_digest(char *, u_char *, int);
diff -ruN openssh-7.5p1/key.c openssh-7.5p1+x509-10.2/key.c
--- openssh-7.5p1/key.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/key.c	2017-05-20 21:07:01.000000000 +0300
@@ -130,48 +130,6 @@
 	return blen;
 }
 
-int
-key_sign(const Key *key, u_char **sigp, u_int *lenp,
-    const u_char *data, u_int datalen, const char *alg)
-{
-	int r;
-	u_char *sig;
-	size_t siglen;
-
-	if (sigp != NULL)
-		*sigp = NULL;
-	if (lenp != NULL)
-		*lenp = 0;
-	if ((r = sshkey_sign(key, &sig, &siglen,
-	    data, datalen, alg, datafellows)) != 0) {
-		fatal_on_fatal_errors(r, __func__, 0);
-		error("%s: %s", __func__, ssh_err(r));
-		return -1;
-	}
-	if (siglen > INT_MAX)
-		fatal("%s: giant len %zu", __func__, siglen);
-	if (sigp != NULL)
-		*sigp = sig;
-	if (lenp != NULL)
-		*lenp = siglen;
-	return 0;
-}
-
-int
-key_verify(const Key *key, const u_char *signature, u_int signaturelen,
-    const u_char *data, u_int datalen)
-{
-	int r;
-
-	if ((r = sshkey_verify(key, signature, signaturelen,
-	    data, datalen, datafellows)) != 0) {
-		fatal_on_fatal_errors(r, __func__, 0);
-		error("%s: %s", __func__, ssh_err(r));
-		return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
-	}
-	return 1;
-}
-
 Key *
 key_demote(const Key *k)
 {
@@ -347,7 +305,8 @@
 	if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
 		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
 		/* Old authfile.c ignored all file errors. */
-		if (r == SSH_ERR_SYSTEM_ERROR)
+		if (r == SSH_ERR_SYSTEM_ERROR ||
+		    r == SSH_ERR_INVALID_FORMAT)
 			debug("%s: %s", __func__, ssh_err(r));
 		else
 			error("%s: %s", __func__, ssh_err(r));
@@ -388,6 +347,8 @@
 		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
 		/* Old authfile.c ignored all file errors. */
 		if (r == SSH_ERR_SYSTEM_ERROR ||
+		    r == SSH_ERR_INVALID_FORMAT ||
+		    r == SSH_ERR_INVALID_ARGUMENT ||
 		    r == SSH_ERR_KEY_WRONG_PASSPHRASE)
 			debug("%s: %s", __func__, ssh_err(r));
 		else
@@ -409,6 +370,8 @@
 		fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
 		/* Old authfile.c ignored all file errors. */
 		if (r == SSH_ERR_SYSTEM_ERROR ||
+		    r == SSH_ERR_INVALID_FORMAT ||
+		    r == SSH_ERR_INVALID_ARGUMENT ||
 		    (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
 			debug("%s: %s", __func__, ssh_err(r));
 		else
diff -ruN openssh-7.5p1/key-eng.c openssh-7.5p1+x509-10.2/key-eng.c
--- openssh-7.5p1/key-eng.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/key-eng.c	2016-12-19 17:16:42.161651680 +0200
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2011-2015 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#ifdef USE_OPENSSL_ENGINE
+#include <string.h>
+#include <openssl/ui.h>
+#include "evp-compat.h"
+
+#include "key-eng.h"
+#include "ssh-x509.h"
+
+#include "misc.h"
+#include "log.h"
+#include "xmalloc.h"
+#include "ssherr.h"
+
+
+/* structure reserved for future use */
+typedef struct ssh_pw_cb_data {
+	const void *password;
+} SSH_PW_CB_DATA;
+
+
+static UI_METHOD *ssh_ui_method = NULL;
+
+/**/
+static int
+ui_open(UI *ui) {
+	return(UI_method_get_opener(UI_OpenSSL())(ui));
+}
+
+
+static int
+ui_read(UI *ui, UI_STRING *uis) {
+	enum UI_string_types  uis_type;
+	int ui_flags;
+
+	ui_flags = UI_get_input_flags(uis);
+	uis_type = UI_get_string_type(uis);
+
+	if (ui_flags & UI_INPUT_FLAG_DEFAULT_PWD) {
+		SSH_PW_CB_DATA* cb_data = (SSH_PW_CB_DATA*)UI_get0_user_data(ui);
+		if (cb_data != NULL) {
+			switch(uis_type) {
+			case UIT_PROMPT:
+			case UIT_VERIFY: {
+				const char *password = cb_data->password;
+				if (password && password[0] != '\0') {
+					UI_set_result(ui, uis, password);
+					return(1);
+				}
+				} break;
+			default:
+				break;
+			}
+		}
+	}
+
+{ /* use own method to prompt properly */
+	int flags = RP_USE_ASKPASS | RP_ALLOW_STDIN;
+	if (ui_flags & UI_INPUT_FLAG_ECHO)
+		flags |= RP_ECHO;
+
+	switch(uis_type) {
+	case UIT_PROMPT:
+	case UIT_VERIFY: {
+		const char *prompt;
+		char *password;
+
+		prompt = UI_get0_output_string(uis);
+		debug3("%s: read_passphrase prompt=%s", __func__, prompt);
+		password = read_passphrase(prompt, flags);
+		UI_set_result(ui, uis, password);
+		memset(password, 'x', strlen(password));
+		free(password);
+		return(1);
+		} break;
+	case UIT_INFO: {
+		const char *s = UI_get0_output_string(uis);
+		verbose("%s: UIT_INFO '%s'", __func__, s);
+		return(1);
+		} break;
+	case UIT_ERROR: {
+		const char *s = UI_get0_output_string(uis);
+		error("%s: UIT_ERROR '%s'", __func__, s);
+		return(1);
+		} break;
+	default:
+		break;
+	}
+}
+
+	return(UI_method_get_reader(UI_OpenSSL())(ui, uis));
+}
+
+
+static int
+ui_write(UI *ui, UI_STRING *uis) {
+	enum UI_string_types  uis_type;
+	int ui_flags;
+
+	ui_flags = UI_get_input_flags(uis);
+	uis_type = UI_get_string_type(uis);
+
+	if (ui_flags & UI_INPUT_FLAG_DEFAULT_PWD) {
+		SSH_PW_CB_DATA* cb_data = (SSH_PW_CB_DATA*)UI_get0_user_data(ui);
+		if (cb_data != NULL) {
+			switch(uis_type) {
+			case UIT_PROMPT:
+			case UIT_VERIFY: {
+				const char *password = cb_data->password;
+				if (password && password[0] != '\0') {
+					return(1);
+				}
+				} break;
+			default:
+				break;
+			}
+		}
+	}
+	switch(uis_type) {
+	case UIT_INFO: {
+		const char *s = UI_get0_output_string(uis);
+		verbose("%s: UIT_INFO '%s'", __func__, s);
+		return(1);
+		} break;
+	case UIT_ERROR: {
+		const char *s = UI_get0_output_string(uis);
+		error("%s: UIT_ERROR '%s'", __func__, s);
+		return(1);
+		} break;
+	default:
+		break;
+	}
+	return(UI_method_get_writer(UI_OpenSSL())(ui, uis));
+}
+
+
+static int
+ui_close(UI *ui) {
+	return(UI_method_get_closer(UI_OpenSSL())(ui));
+}
+
+
+static int/*bool*/setup_ssh_ui_method(void);
+static void destroy_ssh_ui_method(void);
+
+
+static int/*bool*/
+setup_ssh_ui_method() {
+	ssh_ui_method = UI_create_method("PKIX-SSH application user interface");
+
+	if (ssh_ui_method == NULL) return(0);
+
+	if ((UI_method_set_opener(ssh_ui_method, ui_open ) < 0)
+	||  (UI_method_set_reader(ssh_ui_method, ui_read ) < 0)
+	||  (UI_method_set_writer(ssh_ui_method, ui_write) < 0)
+	||  (UI_method_set_closer(ssh_ui_method, ui_close) < 0)) {
+		destroy_ssh_ui_method();
+		return(0);
+	}
+	return(1);
+}
+
+
+static void
+destroy_ssh_ui_method() {
+	if (ssh_ui_method == NULL) return;
+
+	UI_destroy_method(ssh_ui_method);
+	ssh_ui_method = NULL;
+}
+
+
+static void
+eng_try_load_cert(ENGINE *e, const char *keyid, EVP_PKEY *pk, Key *k) {
+	X509*	x509 = NULL;
+	int ctrl_ret = 0;
+
+	if (e == NULL)
+		return;
+
+	if ((k->type != KEY_RSA) &&
+#ifdef OPENSSL_HAS_ECC
+	    (k->type != KEY_ECDSA) &&
+#endif
+	    (k->type != KEY_DSA))
+		return;
+
+	/* try to load certificate with LOAD_CERT_EVP command */
+	{
+		struct {
+			EVP_PKEY *pkey;
+			X509 *x509;
+		} param = {NULL, NULL};
+		param.pkey = pk;
+
+		ctrl_ret = ENGINE_ctrl_cmd(e, "LOAD_CERT_EVP", 0, &param, 0, 0);
+		debug3("%s: eng cmd LOAD_CERT_EVP return %d", __func__, ctrl_ret);
+		if (ctrl_ret == 1)
+			x509 = param.x509;
+	}
+
+	/* try to load certificate with LOAD_CERT_CTRL command */
+	if (ctrl_ret != 1) {
+		struct {
+			const char *keyid;
+			X509 *x509;
+		} param = {NULL, NULL};
+		param.keyid = keyid;
+
+		ctrl_ret = ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &param, 0, 0);
+		debug3("%s: eng cmd LOAD_CERT_CTRL return %d", __func__, ctrl_ret);
+		if (ctrl_ret == 1)
+			x509 = param.x509;
+	}
+	debug3("%s: eng certificate=%p", __func__, (void*)x509);
+
+	if (x509 == NULL)
+		return;
+
+	if (!ssh_x509_set_cert(k, x509)) {
+		error("%s: can not set X.509 certificate to key ", __func__);
+	}
+
+	x509key_build_chain(k);
+}
+
+
+static ENGINE*
+split_eng_keyid(const char *keyid, char **engkeyid) {
+	ENGINE* e = NULL;
+	char *p, *q;
+
+	q = xstrdup(keyid);	/*fatal on error*/
+
+	p = strchr(q, ':');
+	if (p == NULL) {
+		fatal("%s missing engine identifier", __func__);
+		goto done; /*;-)*/
+	}
+	*p = '\0';
+	p++;
+	if (*p == '\0') {
+		fatal("%s missing key identifier", __func__);
+		goto done; /*;-)*/
+	}
+
+	e = ENGINE_by_id(q);
+	if (e != NULL) {
+		*engkeyid = xstrdup(p);
+	}
+done:
+	free(q);
+	return(e);
+}
+
+
+int
+eng_key_load_private_type(int type, const char *keyid,
+	const char *passphrase, struct sshkey **keyp, char **commentp
+) {
+	char *engkeyid;
+	const char *name = "<no key>";
+	ENGINE *e = NULL;
+	EVP_PKEY *pk = NULL;
+	Key *prv = NULL;
+
+	e = split_eng_keyid(keyid, &engkeyid);
+	if (e == NULL)
+		goto done;
+
+	(void)passphrase;
+	pk = ENGINE_load_private_key(e, engkeyid, ssh_ui_method, NULL);
+	if (pk == NULL) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: ENGINE_load_private_key(%s) fail with errormsg='%.*s'"
+		, __func__, ENGINE_get_id(e)
+		, (int)sizeof(ebuf), ebuf);
+		goto done;
+	}
+
+	/* NOTE do not set flags |= KEY_FLAG_EXT !!! */
+
+	if (EVP_PKEY_id(pk) == EVP_PKEY_RSA
+	&&  (type == KEY_UNSPEC || type == KEY_RSA)) {
+		prv = key_new(KEY_UNSPEC);
+		prv->rsa = EVP_PKEY_get1_RSA(pk);
+		prv->type = KEY_RSA;
+		name = "rsa(nss)";
+#ifdef DEBUG_PK
+		RSA_print_fp(stderr, prv->rsa, 8);
+#endif
+		if (RSA_blinding_on(prv->rsa, NULL) != 1) {
+			error("%s: RSA_blinding_on failed", __func__);
+			key_free(prv);
+			prv = NULL;
+		}
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA
+	&&  (type == KEY_UNSPEC || type == KEY_DSA)) {
+		prv = key_new(KEY_UNSPEC);
+		prv->dsa = EVP_PKEY_get1_DSA(pk);
+		prv->type = KEY_DSA;
+		name = "dsa(nss)";
+#ifdef DEBUG_PK
+		DSA_print_fp(stderr, prv->dsa, 8);
+#endif
+#ifdef OPENSSL_HAS_ECC
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_EC
+	&&  (type == KEY_UNSPEC || type == KEY_ECDSA)) {
+		const EC_POINT *q = NULL;
+		int ec_err = 0;
+
+		prv = key_new(KEY_UNSPEC);
+		prv->type = KEY_ECDSA;
+		prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
+		prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa);
+		if (prv->ecdsa_nid < 0) {
+			error("%s: unsupported elliptic curve", __func__);
+			ec_err = 1;
+		}
+		q = EC_KEY_get0_public_key(prv->ecdsa);
+		if (!ec_err &&
+		    (q == NULL)
+		) {
+			error("%s: cannot get public ec key ", __func__);
+			ec_err = 1;
+		}
+		if (!ec_err &&
+		   (key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), q) < 0)
+		) {
+			debug3("%s: cannot validate public ec key ", __func__);
+			ec_err = 1;
+		}
+		name = "ecdsa(nss)";
+#ifdef DEBUG_PK
+		key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
+#endif
+		if (ec_err) {
+			key_free(prv);
+			prv = NULL;
+		}
+#endif /*def OPENSSL_HAS_ECC*/
+	} else {
+		error("%s: mismatch or "
+		    "unknown EVP_PKEY type %d", __func__, EVP_PKEY_id(pk));
+	}
+
+	if ((pk != NULL) && (prv != NULL))
+		eng_try_load_cert(e, engkeyid, pk, prv);
+
+	if (pk != NULL)
+		EVP_PKEY_free(pk);
+
+	if (prv != NULL) {
+		if (keyp!= NULL)
+			*keyp = prv;
+		if (commentp!= NULL)
+			*commentp = xstrdup(name);
+	}
+
+done:
+	free(engkeyid);
+	if (e != NULL)
+		ENGINE_free(e);
+	debug("read ENGINE private key done: type %s", (prv ? key_type(prv) : "<not found>"));
+	return prv
+		? SSH_ERR_SUCCESS
+		: SSH_ERR_LIBCRYPTO_ERROR;
+}
+
+
+int
+eng_key_try_load_public(struct sshkey *k, const char *filename, char **commentp) {
+	int ret = SSH_ERR_INTERNAL_ERROR;
+	char *keyid = NULL;
+	char *engkeyid;
+	ENGINE *e = NULL;
+	EVP_PKEY *pk = NULL;
+
+	if (k->type != KEY_UNSPEC)
+		return SSH_ERR_INVALID_ARGUMENT;
+
+	debug3("%s filename=%s", __func__, filename);
+{ /* magic to ignore suffixes in file name*/
+	size_t len = strlen(filename);
+	if (len <= 4)
+		goto done;
+
+	{ /* skip bogus certificates "-cert" */
+		const char sfx[5] = "-cert";
+		if (len >= sizeof(sfx)) {
+			const char *s = filename + len - sizeof(sfx);
+			if (strncmp(s, sfx, sizeof(sfx)) == 0)
+				return SSH_ERR_INVALID_FORMAT;
+		}
+	}
+	{ /* skip bogus certificates "-cert.pub" */
+		const char sfx[9] = "-cert.pub";
+		if (len >= sizeof(sfx)) {
+			const char *s = filename + len - sizeof(sfx);
+			if (strncmp(s, sfx, sizeof(sfx)) == 0)
+				return SSH_ERR_INVALID_FORMAT;
+		}
+	}
+
+	keyid = xstrdup(filename); /*fatal on error*/
+	{ /* drop suffix ".pub" on copy */
+		char *s = keyid + len - 4;
+		if (strncmp(s, ".pub", 4) == 0)
+			*s = '\0';
+	}
+}
+	debug3("%s keyid=%s", __func__, keyid);
+
+	e = split_eng_keyid(keyid, &engkeyid);
+	if (e == NULL)
+		goto done;
+
+	pk = ENGINE_load_public_key(e, engkeyid, ssh_ui_method, NULL);
+	if (pk == NULL) {
+		char ebuf[512];
+		/* fatal here to avoid PIN lock, for instance
+		 * when ssh-askpass program is missing.
+		 * NOTE programs still try to load public key many times!
+		 */
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		fatal("%s: ENGINE_load_public_key(%s) fail with errormsg='%.*s'"
+		, __func__, ENGINE_get_id(e)
+		, (int)sizeof(ebuf), ebuf);
+		/* TODO library mode in case of failure */
+		ret = SSH_ERR_INTERNAL_ERROR;
+		goto done;
+	}
+
+	/* NOTE do not set flags |= KEY_FLAG_EXT !!! */
+	if (EVP_PKEY_id(pk) == EVP_PKEY_RSA) {
+		k->rsa = EVP_PKEY_get1_RSA(pk);
+		k->type = KEY_RSA;
+#ifdef DEBUG_PK
+		RSA_print_fp(stderr, k->rsa, 8);
+#endif
+		if (RSA_blinding_on(k->rsa, NULL) == 1) {
+			ret = SSH_ERR_SUCCESS;
+		}
+		else {
+			ret = SSH_ERR_LIBCRYPTO_ERROR;
+			error("%s: RSA_blinding_on failed", __func__);
+		}
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA) {
+		k->dsa = EVP_PKEY_get1_DSA(pk);
+		k->type = KEY_DSA;
+#ifdef DEBUG_PK
+		DSA_print_fp(stderr, k->dsa, 8);
+#endif
+		ret = SSH_ERR_SUCCESS;
+#ifdef OPENSSL_HAS_ECC
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_EC) {
+		const EC_POINT *q = NULL;
+
+		ret = SSH_ERR_SUCCESS;
+
+		k->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
+		k->type = KEY_ECDSA;
+		k->ecdsa_nid = key_ecdsa_key_to_nid(k->ecdsa);
+
+		if (k->ecdsa_nid < 0) {
+			error("%s: unsupported elliptic curve", __func__);
+			ret = SSH_ERR_INVALID_FORMAT;
+		}
+		q = EC_KEY_get0_public_key(k->ecdsa);
+		if ((ret == SSH_ERR_SUCCESS) &&
+		    (q == NULL)
+		) {
+			error("%s: cannot get public ec key ", __func__);
+			ret = SSH_ERR_LIBCRYPTO_ERROR;
+		}
+		if ((ret == SSH_ERR_SUCCESS) &&
+		    (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), q) < 0)
+		) {
+			debug3("%s: cannot validate public ec key ", __func__);
+			ret = SSH_ERR_KEY_INVALID_EC_VALUE;
+		}
+#ifdef DEBUG_PK
+		key_dump_ec_point(EC_KEY_get0_group(k->ecdsa), q);
+#endif
+#endif /*def OPENSSL_HAS_ECC*/
+	} else {
+		ret = SSH_ERR_KEY_TYPE_UNKNOWN;
+		error("%s: mismatch or "
+		    "unknown EVP_PKEY type %d", __func__, EVP_PKEY_id(pk));
+	}
+
+	if (ret == SSH_ERR_SUCCESS) {
+		if (pk != NULL)
+			eng_try_load_cert(e, engkeyid, pk, k);
+
+		debug3("ENGINE key type: %s", key_type(k));
+
+		if (commentp != NULL)
+			*commentp = xstrdup(engkeyid);
+	}
+
+	if (pk != NULL)
+		EVP_PKEY_free(pk);
+
+done:
+	free(engkeyid);
+	free(keyid);
+	if (e != NULL)
+		ENGINE_free(e);
+	return(ret);
+}
+
+
+static ENGINE*
+try_load_engine(const char *engine) {
+	ENGINE *e = NULL;
+	int self_registered = 0;
+
+	if (engine == NULL) {
+		fatal("%s: engine is NULL", __func__);
+		return(NULL); /* ;-) */
+	}
+
+	/* Check if engine is not already loaded by openssl
+	 * (as internal or from config file).
+	 * If is not loaded we will call ENGINE_add to keep it
+	 * loaded and registered for subsequent use.
+	 */
+	for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
+		if (strcmp(engine, ENGINE_get_id(e)) == 0) {
+			/* with increase of structural reference */
+			goto done;
+		}
+	}
+
+	e = ENGINE_by_id(engine);
+	if (e == NULL) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		fatal("%s(%s): setup fail with last error '%.*s'"
+		    , __func__, engine
+		    , (int)sizeof(ebuf), ebuf);
+		return(NULL); /* ;-) */
+	}
+
+{	/* OpenSSL 1.0.1g start to register engines internaly!
+	 * So we try to find our engine in internal list and if not
+	 * found we use ENGINE_add to register it for compatibility
+	 * with previous OpenSSL versions.
+	 * Loop on all entries to avoid increase of structural
+	 * reference.
+	 */
+	ENGINE *g;
+	for (g = ENGINE_get_first(); g != NULL; g = ENGINE_get_next(g)) {
+		if (strcmp(engine, ENGINE_get_id(g)) == 0)
+			self_registered = 1;
+	}
+}
+
+	if (!self_registered && !ENGINE_add(e)) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		fatal("%s(%s): registration fail with last error '%.*s'"
+		    , __func__, engine
+		    , (int)sizeof(ebuf), ebuf);
+		return(NULL); /* ;-) */
+	}
+
+done:
+	debug3("%s: engine '%s' loaded", __func__, ENGINE_get_name(e));
+	return(e);
+}
+
+
+static ENGINE*
+ssh_engine_setup(const char *engine) {
+	int ctrl_ret;
+	ENGINE *e = NULL;
+
+	e = try_load_engine(engine); /* fatal on error */
+
+	if (!ENGINE_init(e)) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		fatal("%s(%s): ENGINE_init fail with last error '%.*s'"
+		    , __func__, engine
+		    , (int)sizeof(ebuf), ebuf);
+		return(NULL); /* ;-) */
+	}
+
+	ctrl_ret = ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ssh_ui_method, 0, 1);
+	if (!ctrl_ret) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		debug3("%s(%s): unsupported engine command SET_USER_INTERFACE: %.*s"
+		    , __func__, engine
+		    , (int)sizeof(ebuf), ebuf);
+	}
+
+	if (!ENGINE_free(e)) {
+		e = NULL;
+	}
+
+	return(e);
+}
+
+
+static void
+ssh_engine_reset(const char *engine) {
+	ENGINE *e = NULL;
+
+	e = ENGINE_by_id(engine);
+	if (e == NULL) return;
+
+	/* decrease functional&structural reference from load - ENGINE_init */
+	ENGINE_finish(e);
+
+	/* decrease structural reference from above - ENGINE_by_id */
+	ENGINE_free(e);
+}
+
+
+#define WHITESPACE " \t\r\n"
+/* hold list with names of used engines to free at shutdown */
+static Buffer	eng_list;
+
+/* name of currect engine to process */
+static char *eng_name = NULL;
+
+
+int/*bool*/
+process_engconfig_line(char *line, const char *filename, int linenum) {
+	int ret = 1;
+	size_t len;
+	char *s, *keyword, *arg;
+	ENGINE *e;
+	int ctrl_ret;
+
+	/* strip trailing whitespace */
+	len = strlen(line);
+	s = line + len - 1;
+	for (; len > 0; s--, len--) {
+		int ch = (unsigned char)*s;
+		if (strchr(WHITESPACE, ch) == NULL)
+			break;
+		*s = '\0';
+	}
+
+	/* ignore leading whitespace */
+	s = line;
+	if (*s == '\0')
+		return(1);
+	keyword = strdelim(&s);
+	if (keyword == NULL)
+		return(1);
+	if (*keyword == '\0')
+		keyword = strdelim(&s);
+	if (keyword == NULL)
+		return(1);
+
+	/* ignore comments */
+	if (*keyword == '#')
+		return(1);
+
+	if (strcasecmp(keyword, "engine") == 0) {
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0') {
+			fatal("%.200s line %d: missing engine identifier"
+			    , filename, linenum);
+			goto done;
+		}
+
+		e = ssh_engine_setup(arg);
+		if (e == NULL) {
+			char ebuf[512];
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			fatal("%.200s line %d: cannot load engine '%s':%.*s"
+			    , filename, linenum, arg
+			    , (int)sizeof(ebuf), ebuf);
+		}
+		if (eng_name != NULL)
+			free(eng_name);
+		eng_name = xstrdup(arg); /*fatal on error*/
+		buffer_put_cstring(&eng_list, eng_name);
+	}
+	else {
+		if (eng_name == NULL)
+			fatal("%.200s line %d: engine is not specified"
+			    , filename, linenum);
+
+		e = ENGINE_by_id(eng_name);
+		if (e == NULL)
+			fatal("%.200s line %d: engine(%s) not found"
+			    , filename, linenum, eng_name);
+
+		arg = strdelim(&s);
+
+		ctrl_ret = ENGINE_ctrl_cmd_string(e, keyword, arg, 0);
+		if (!ctrl_ret) {
+			char ebuf[512];
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			fatal("%.200s line %d: engine command fail"
+			    " with errormsg='%.*s'"
+			    , filename, linenum
+			    , (int)sizeof(ebuf), ebuf);
+			ret = 0;
+		}
+
+		ENGINE_free(e);
+	}
+
+done:
+	/* check that there is no garbage at end of line */
+	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
+		fatal("%.200s line %d: garbage at end of line - '%.200s'.",
+		    filename, linenum, arg);
+	}
+
+	return(ret);
+}
+#endif /*def USE_OPENSSL_ENGINE*/
+
+
+void
+ssh_engines_startup() {
+#ifdef USE_OPENSSL_ENGINE
+	buffer_init(&eng_list);
+
+	(void) setup_ssh_ui_method();
+#endif
+}
+
+
+void
+ssh_engines_shutdown() {
+#ifdef USE_OPENSSL_ENGINE
+	free(eng_name);
+	eng_name = NULL;
+
+	while (buffer_len(&eng_list) > 0) {
+		u_int   k = 0;
+		char    *s;
+
+		s = buffer_get_cstring_ret(&eng_list, &k);
+		ssh_engine_reset(s);
+		free(s);
+	};
+	buffer_free(&eng_list);
+
+	destroy_ssh_ui_method();
+#endif
+}
diff -ruN openssh-7.5p1/key-eng.h openssh-7.5p1+x509-10.2/key-eng.h
--- openssh-7.5p1/key-eng.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/key-eng.h	2015-03-18 21:57:02.056641147 +0200
@@ -0,0 +1,46 @@
+#ifndef KEY_ENG_H
+#define KEY_ENG_H
+/*
+ * Copyright (c) 2011,2012 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include "sshkey.h"
+
+extern void ssh_engines_startup(void);
+extern void ssh_engines_shutdown(void);
+
+#ifdef	USE_OPENSSL_ENGINE
+
+#include <openssl/engine.h>
+
+extern int/*bool*/
+process_engconfig_line(char *line, const char *filename, int linenum);
+
+extern void ssh_load_engines(void);
+
+extern int eng_key_load_private_type(int type, const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp);
+extern int eng_key_try_load_public(struct sshkey *k, const char *filename, char **commentp);
+#endif /*ndef USE_OPENSSL_ENGINE*/
+
+#endif /*ndef KEY_ENG_H*/
diff -ruN openssh-7.5p1/key.h openssh-7.5p1+x509-10.2/key.h
--- openssh-7.5p1/key.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/key.h	2017-05-20 21:07:00.000000000 +0300
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * X.509 certificates support,
+ * Copyright (c) 2002,2012 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,11 +46,13 @@
 #define key_ssh_name		sshkey_ssh_name
 #define key_ssh_name_plain	sshkey_ssh_name_plain
 #define key_type_from_name	sshkey_type_from_name
+#define key_types_from_name	sshkey_types_from_name
 #define key_ecdsa_nid_from_name	sshkey_ecdsa_nid_from_name
 #define key_type_is_cert	sshkey_type_is_cert
 #define key_size		sshkey_size
 #define key_ecdsa_bits_to_nid	sshkey_ecdsa_bits_to_nid
 #define key_ecdsa_key_to_nid	sshkey_ecdsa_key_to_nid
+#define key_is_x509		sshkey_is_x509
 #define key_is_cert		sshkey_is_cert
 #define key_type_plain		sshkey_type_plain
 #define key_curve_name_to_nid	sshkey_curve_name_to_nid
@@ -83,10 +87,6 @@
 Key	*key_from_blob(const u_char *, u_int);
 int	 key_to_blob(const Key *, u_char **, u_int *);
 
-int	 key_sign(const Key *, u_char **, u_int *, const u_char *, u_int,
-    const char *);
-int	 key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
-
 void     key_private_serialize(const Key *, struct sshbuf *);
 Key	*key_private_deserialize(struct sshbuf *);
 
diff -ruN openssh-7.5p1/LICENCE openssh-7.5p1+x509-10.2/LICENCE
--- openssh-7.5p1/LICENCE	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/LICENCE	2017-05-20 21:07:00.000000000 +0300
@@ -181,6 +181,7 @@
 	Per Allansson
 	Nils Nordman
 	Simon Wilkinson
+	Roumen Petrov
 
     Portable OpenSSH additionally includes code from the following copyright
     holders, also under the 2-term BSD license:
diff -ruN openssh-7.5p1/log.c openssh-7.5p1+x509-10.2/log.c
--- openssh-7.5p1/log.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/log.c	2017-05-20 21:07:01.000000000 +0300
@@ -12,6 +12,7 @@
  */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2004,2011 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,6 +52,7 @@
 #endif
 
 #include "log.h"
+#include <openssl/err.h>
 
 static LogLevel log_level = SYSLOG_LEVEL_INFO;
 static int log_on_stderr = 1;
@@ -65,6 +67,32 @@
 #define LOG_SYSLOG_VIS	(VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL)
 #define LOG_STDERR_VIS	(VIS_SAFE|VIS_OCTAL)
 
+#ifdef __ANDROID__
+#include <android/log.h>
+
+static void
+android_log(LogLevel level, const char *msg, void *ctx) {
+	android_LogPriority a;
+
+	(void)ctx;
+
+	switch (level) {
+	case SYSLOG_LEVEL_QUIET		: a = ANDROID_LOG_SILENT	; break;
+	case SYSLOG_LEVEL_FATAL		: a = ANDROID_LOG_FATAL		; break;
+	case SYSLOG_LEVEL_ERROR		: a = ANDROID_LOG_ERROR		; break;
+	case SYSLOG_LEVEL_INFO		: a = ANDROID_LOG_WARN		; break;
+	case SYSLOG_LEVEL_VERBOSE	: a = ANDROID_LOG_INFO		; break;
+	case SYSLOG_LEVEL_DEBUG1	: a = ANDROID_LOG_DEBUG		; break;
+	case SYSLOG_LEVEL_DEBUG2	: a = ANDROID_LOG_DEBUG		; break;
+	case SYSLOG_LEVEL_DEBUG3	: a = ANDROID_LOG_VERBOSE	; break;
+	default				: a = ANDROID_LOG_UNKNOWN	; break;
+	}
+
+	if (a != ANDROID_LOG_UNKNOWN)
+		__android_log_write(a, __progname, msg);
+}
+#endif /*def __ANDROID__*/
+
 /* textual representation of log-facilities/levels */
 
 static struct {
@@ -280,6 +308,9 @@
 	if (on_stderr)
 		return;
 
+#ifdef __ANDROID__
+	log_handler = android_log;
+#endif
 	switch (facility) {
 	case SYSLOG_FACILITY_DAEMON:
 		log_facility = LOG_DAEMON;
@@ -369,6 +400,22 @@
 	log_stderr_fd = fd;
 }
 
+LogLevel
+get_log_level(void) {
+	return log_level;
+}
+
+
+char*
+openssl_errormsg(char *buf, size_t len) {
+	ERR_error_string_n(ERR_get_error(), buf, len);
+
+	/* clear rest of errors in OpenSSL "error buffer" */
+	ERR_clear_error();
+	return(buf);
+}
+
+
 #define MSGBUFSIZ 1024
 
 void
@@ -459,11 +506,11 @@
 	} else {
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
 		openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
-		syslog_r(pri, &sdata, "%.500s", fmtbuf);
+		syslog_r(pri, &sdata, "%.1000s", fmtbuf);
 		closelog_r(&sdata);
 #else
 		openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
-		syslog(pri, "%.500s", fmtbuf);
+		syslog(pri, "%.1000s", fmtbuf);
 		closelog();
 #endif
 	}
diff -ruN openssh-7.5p1/log.h openssh-7.5p1+x509-10.2/log.h
--- openssh-7.5p1/log.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/log.h	2017-05-20 21:07:00.000000000 +0300
@@ -52,6 +52,8 @@
 void     log_change_level(LogLevel);
 int      log_is_on_stderr(void);
 void     log_redirect_stderr_to(const char *);
+LogLevel get_log_level(void);
+char*    openssl_errormsg(char *buf, size_t len);
 
 SyslogFacility	log_facility_number(char *);
 const char * 	log_facility_name(SyslogFacility);
diff -ruN openssh-7.5p1/loginrec.c openssh-7.5p1+x509-10.2/loginrec.c
--- openssh-7.5p1/loginrec.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/loginrec.c	2017-05-20 21:07:01.000000000 +0300
@@ -215,6 +215,16 @@
 /* pick the shortest string */
 #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2))
 
+#if defined(__ANDROID__)
+/* Android define only user process */
+#ifndef DEAD_PROCESS
+#  define DEAD_PROCESS	USER_PROCESS
+#endif
+#ifndef LOGIN_PROCESS
+#  define LOGIN_PROCESS	USER_PROCESS
+#endif
+#endif
+
 /**
  ** platform-independent login functions
  **/
@@ -435,6 +445,9 @@
 int
 login_write(struct logininfo *li)
 {
+#if defined(__ANDROID__)
+	return 0;
+#endif
 #ifndef HAVE_CYGWIN
 	if (geteuid() != 0) {
 		logit("Attempt to write login records by non-root user (aborting)");
diff -ruN openssh-7.5p1/m4/ldap.m4 openssh-7.5p1+x509-10.2/m4/ldap.m4
--- openssh-7.5p1/m4/ldap.m4	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/m4/ldap.m4	2011-12-29 02:47:46.000000000 +0200
@@ -0,0 +1,217 @@
+# Options to build with LDAP
+#
+# Author: Roumen Petrov
+# Revision: 7 Dec 2011
+#
+dnl The variables provided are :
+dnl - build flags:
+dnl     LDAP_LDFLAGS
+dnl     LDAP_LIBS
+dnl     LDAP_CPPFLAGS
+dnl - conditional:
+dnl     LDAP_ON   (e.g. '' or '#')
+dnl     LDAP_OFF  (e.g. '#' or '' - oposite of LDAP_ON)
+dnl - paths:
+dnl     LDAP_BINDIR
+dnl     LDAP_LIBEXECDIR
+dnl     LDAP_SYSCONFDIR
+
+AC_DEFUN([AC_WITH_LDAP],
+[
+dnl
+dnl Get the ldap paths
+dnl
+
+ac_ldap=none
+AC_ARG_ENABLE([ldap],
+  [AS_HELP_STRING([--enable-ldap], [Enable LDAP queries])],
+  [ac_ldap=$enableval]
+)
+
+if test "x$ac_ldap" = xyes; then
+  ac_ldap_prefix=""
+  AC_ARG_WITH([ldap-prefix],
+    [AS_HELP_STRING([--with-ldap-prefix=PATH], [Prefix where LDAP is installed (optional)])],
+    [ac_ldap_prefix=$withval]
+  )
+
+  AC_ARG_WITH([ldap-bindir],
+    [AS_HELP_STRING([--with-ldap-bindir=PATH], [Prefix where LDAP user executables are installed (optional)])],
+    [LDAP_BINDIR=$withval],
+    [
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_BINDIR="$ac_ldap_prefix/bin"
+      fi
+    ]
+  )
+  AC_SUBST(LDAP_BINDIR)
+
+  AC_ARG_WITH([ldap-libexecdir],
+    [AS_HELP_STRING([--with-ldap-libexecdir=PATH], [Prefix where LDAP program executables are installed (optional)])],
+    [LDAP_LIBEXECDIR=$withval],
+    [
+      if test "x$ac_ldap_prefix" = "x"; then
+        LDAP_LIBEXECDIR="/usr/libexec"
+      else
+        LDAP_LIBEXECDIR="$ac_ldap_prefix/libexec"
+      fi
+    ]
+  )
+  AC_SUBST([LDAP_LIBEXECDIR])
+dnl### Check for slapd
+dnl  if test "x$cross_compiling" = "xyes" ; then
+dnl    AC_MSG_NOTICE([cannot check for LDAP daemon when cross compiling])
+dnl  else
+dnl    AC_CHECK_FILES(
+dnl      [
+dnl        $LDAP_LIBEXECDIR/slapd
+dnl      ]
+dnl    )
+dnl  fi
+
+  AC_ARG_WITH([ldap-sysconfdir],
+    [AS_HELP_STRING([--with-ldap-sysconfdir=PATH], [Prefix where LDAP single-machine data are installed (optional)])],
+    [LDAP_SYSCONFDIR=$withval],
+    [LDAP_SYSCONFDIR="$ac_ldap_prefix/etc/openldap"]
+  )
+  AC_SUBST([LDAP_SYSCONFDIR])
+dnl### Check for schema files
+dnl  if test "x$cross_compiling" = "xyes" ; then
+dnl    AC_MSG_NOTICE([cannot check for schema files existence when cross compiling])
+dnl  else
+dnl    AC_CHECK_FILES(
+dnl      [
+dnl        $LDAP_SYSCONFDIR/schema/core.schema
+dnl        $LDAP_SYSCONFDIR/schema/cosine.schema
+dnl        $LDAP_SYSCONFDIR/schema/inetorgperson.schema
+dnl      ]
+dnl    )
+dnl  fi
+
+
+  AC_ARG_WITH([ldap-libdir],
+    [AS_HELP_STRING([--with-ldap-libdir=PATH], [Prefix where LDAP libaries are installed (optional)])],
+    [LDAP_LDFLAGS="-L$withval"],
+    [
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_LDFLAGS="-L$ac_ldap_prefix/lib"
+      else
+        LDAP_LDFLAGS=""
+      fi
+    ]
+  )
+  AC_SUBST(LDAP_LDFLAGS)
+
+  AC_ARG_WITH([ldap-includedir],
+    [AS_HELP_STRING([--with-ldap-includedir=PATH], [Prefix where LDAP header files are installed (optional)])],
+    [LDAP_CPPFLAGS="-I$withval"],
+    [
+      if test "x$ac_ldap_prefix" != "x"; then
+        LDAP_CPPFLAGS="-I$ac_ldap_prefix/include"
+      else
+        LDAP_CPPFLAGS=""
+      fi
+    ]
+  )
+  AC_SUBST([LDAP_CPPFLAGS])
+
+
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS"
+  AC_CHECK_HEADERS(
+    [lber.h ldap.h],
+    [],
+    [
+      AC_MSG_ERROR([cannot found LDAP headers])
+    ]
+  )
+  CPPFLAGS="$ac_save_CPPFLAGS"
+
+  ac_ldap_libs=""
+  AC_ARG_WITH([ldap-libs],
+    [  --with-ldap-libs=LIBS   Specify LDAP libraries to link with.
+                            (default is -lldap -llber -lssl -lcrypto)],
+    [ac_ldap_libs="$withval"]
+  )
+
+### Try to link with LDAP libs
+  ac_save_LDFLAGS="$LDFLAGS"
+  ac_save_LIBS="$LIBS"
+
+  LDFLAGS="$LDAP_LDFLAGS $LDFLAGS"
+  ac_LDAP_LINK=""
+  if test "x$ac_ldap_libs" != "x"; then
+    AC_MSG_CHECKING([to link with specified LDAP libs])
+
+    LDAP_LIBS="$ac_ldap_libs"
+    LIBS="$LDAP_LIBS $ac_save_LIBS"
+    AC_LINK_IFELSE(
+      [AC_LANG_CALL([], [ldap_init])],
+      [ac_LDAP_LINK="yes"]
+    )
+    if test "x$ac_LDAP_LINK" != "xyes"; then
+      AC_MSG_ERROR([cannot link with specified LDAP libs])
+    fi
+  else
+    AC_MSG_CHECKING([how to link LDAP libs])
+
+    LDAP_LIBS="-lldap"
+    for L in lber ssl crypto; do
+      LDAP_LIBS="$LDAP_LIBS -l$L"
+      LIBS="$LDAP_LIBS $ac_save_LIBS"
+      AC_LINK_IFELSE(
+        [AC_LANG_CALL([], [ldap_init])],
+        [ac_LDAP_LINK="yes"]
+      )
+      if test "x$ac_LDAP_LINK" = "xyes"; then
+        break
+      fi
+    done
+    if test "x$ac_LDAP_LINK" != "xyes"; then
+      AC_MSG_ERROR([cannot link with default LDAP libs])
+    fi
+  fi
+  AC_MSG_RESULT([done])
+  LIBS="$ac_save_LIBS"
+  LDFLAGS="$ac_save_LDFLAGS"
+  AC_SUBST([LDAP_LIBS])
+else
+  AC_MSG_NOTICE([LDAP is disabled])
+fi
+
+if test "x$ac_ldap" = "xyes"; then
+	AC_DEFINE_UNQUOTED(
+		[LDAP_ENABLED], [1],
+		[Define if you want to enable LDAP queries])
+	LDAP_ON=''
+	LDAP_OFF='#'
+else
+	LDAP_ON='#'
+	LDAP_OFF=''
+fi
+AC_SUBST([LDAP_ON])
+AC_SUBST([LDAP_OFF])
+])
+
+
+# AC_LDAP_FUNCS(FUNCTION...)
+# --------------------------------
+AC_DEFUN([AC_LDAP_FUNCS],
+[
+dnl
+dnl Check ldap functions
+dnl
+AC_REQUIRE([AC_WITH_LDAP])
+if test "x$ac_ldap" = "xyes"; then
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  ac_save_LDFLAGS="$LDFLAGS"
+  ac_save_LIBS="$LIBS"
+  CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS"
+  LDFLAGS="$LDFLAGS $LDAP_LDFLAGS"
+  LIBS="$LDAP_LIBS $LIBS"
+  AC_CHECK_FUNCS([$1],[],[])
+  LIBS="$ac_save_LIBS"
+  LDFLAGS="$ac_save_LDFLAGS"
+  CPPFLAGS="$ac_save_CPPFLAGS"
+fi
+])
diff -ruN openssh-7.5p1/mac.c openssh-7.5p1+x509-10.2/mac.c
--- openssh-7.5p1/mac.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/mac.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,7 @@
 /* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011-2014 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +36,8 @@
 #include "umac.h"
 #include "mac.h"
 #include "misc.h"
+#include "xmalloc.h"
+#include "log.h"
 #include "ssherr.h"
 #include "sshbuf.h"
 
@@ -89,6 +92,19 @@
 	{ NULL,					0, 0, 0, 0, 0, 0 }
 };
 
+static inline int/*bool*/
+macalg_allowed(const struct macalg *m) {
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		if (m->type != SSH_DIGEST)
+			return(0);
+		if (ssh_digest_bytes(m->alg) == 0)
+			return(0);
+	}
+#endif
+	return(1);
+}
+
 /* Returns a list of supported MACs separated by the specified char. */
 char *
 mac_alg_list(char sep)
@@ -98,6 +114,8 @@
 	const struct macalg *m;
 
 	for (m = macs; m->name != NULL; m++) {
+		if (!macalg_allowed(m))
+			continue;
 		if (ret != NULL)
 			ret[rlen++] = sep;
 		nlen = strlen(m->name);
@@ -139,6 +157,8 @@
 	for (m = macs; m->name != NULL; m++) {
 		if (strcmp(name, m->name) != 0)
 			continue;
+		if (!macalg_allowed(m))
+			continue;
 		if (mac != NULL)
 			return mac_setup_by_alg(mac, m);
 		return 0;
@@ -270,3 +290,38 @@
 	free(maclist);
 	return 1;
 }
+
+#ifdef OPENSSL_FIPS
+char*
+only_fips_valid_macs(const char* names)
+{
+	Buffer b;
+	char *fips_names, *cp, *p;
+
+	if (names == NULL || *names == '\0')
+		return NULL;
+
+	buffer_init(&b);
+
+	/* default set in myproposals.h */
+	cp = xstrdup(names);
+	for (p = strsep(&cp, MAC_SEP);
+	     p && *p != '\0';
+	     p = strsep(&cp, MAC_SEP)
+	) {
+		if (mac_setup(NULL, p) < 0) continue;
+
+		if (buffer_len(&b) > 0)
+			buffer_append(&b, ",", 1);
+		buffer_append(&b, p, strlen(p));
+	}
+	buffer_append(&b, "\0", 1);
+
+	fips_names = xstrdup(buffer_ptr(&b));
+
+	buffer_free(&b);
+
+	debug3("%s: fips_macs: [%s]", __func__, fips_names);
+	return fips_names;
+}
+#endif /*def OPENSSL_FIPS*/
diff -ruN openssh-7.5p1/mac.h openssh-7.5p1+x509-10.2/mac.h
--- openssh-7.5p1/mac.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/mac.h	2017-05-20 21:07:00.000000000 +0300
@@ -1,6 +1,7 @@
 /* $OpenBSD: mac.h,v 1.10 2016/07/08 03:44:42 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,4 +51,8 @@
     const u_char *, size_t);
 void	 mac_clear(struct sshmac *);
 
+#ifdef OPENSSL_FIPS
+extern char*	only_fips_valid_macs(const char*);
+#endif
+
 #endif /* SSHMAC_H */
diff -ruN openssh-7.5p1/Makefile.in openssh-7.5p1+x509-10.2/Makefile.in
--- openssh-7.5p1/Makefile.in	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/Makefile.in	2017-05-20 21:07:01.000000000 +0300
@@ -15,6 +15,7 @@
 mandir=@mandir@
 mansubdir=@mansubdir@
 sysconfdir=@sysconfdir@
+sshcadir=@sshcadir@
 piddir=@piddir@
 srcdir=@srcdir@
 top_srcdir=@top_srcdir@
@@ -32,6 +33,7 @@
 TEST_SHELL=@TEST_SHELL@
 
 PATHS= -DSSHDIR=\"$(sysconfdir)\" \
+	-DSSHCADIR=\"$(sshcadir)\" \
 	-D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
 	-D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
 	-D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
@@ -40,16 +42,20 @@
 	-D_PATH_SSH_PIDDIR=\"$(piddir)\" \
 	-D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
 
+FIPSLD_CC=@FIPSLD_CC@
 CC=@CC@
 LD=@LD@
 CFLAGS=@CFLAGS@
-CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
+CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ @LDAP_CPPFLAGS@ $(PATHS) @DEFS@
 LIBS=@LIBS@
 K5LIBS=@K5LIBS@
 GSSLIBS=@GSSLIBS@
 SSHLIBS=@SSHLIBS@
 SSHDLIBS=@SSHDLIBS@
 LIBEDIT=@LIBEDIT@
+LIBOCSP=@LIBOCSP@
+LIBLDAP=@LDAP_LDFLAGS@ @LDAP_LIBS@
+FIPS_LIBS=@FIPS_LIBS@
 AR=@AR@
 AWK=@AWK@
 RANLIB=@RANLIB@
@@ -58,10 +64,19 @@
 SED=@SED@
 ENT=@ENT@
 XAUTH_PATH=@XAUTH_PATH@
-LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
+LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ @XLDFLAGS@
 EXEEXT=@EXEEXT@
 MANFMT=@MANFMT@
 
+@LDAP_ON@LDAP_OBJS=x509_by_ldap.o
+@LDAP_OFF@LDAP_OBJS=
+
+@OCSP_ON@OCSP_OBJS=ssh-ocsp.o
+@OCSP_OFF@OCSP_OBJS=
+
+SSHX509_OBJS=ssh-x509.o ssh-xkalg.o x509_nm_cmp.o key-eng.o a_utf8.o
+X509STORE_OBJS=x509store.o $(LDAP_OBJS)
+
 TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
 
 LIBOPENSSH_OBJS=\
@@ -84,6 +99,7 @@
 	readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
 	atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \
 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
+	$(SSHX509_OBJS) \
 	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
 	ssh-pkcs11.o smult_curve25519_ref.o \
 	poly1305.o chacha.o cipher-chachapoly.o \
@@ -95,25 +111,27 @@
 	platform-pledge.o platform-tracing.o
 
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
+	$(X509STORE_OBJS) $(OCSP_OBJS) \
 	sshconnect.o sshconnect1.o sshconnect2.o mux.o
 
-SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
+SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
 	audit.o audit-bsm.o audit-linux.o platform.o \
 	sshpty.o sshlogin.o servconf.o serverloop.o \
-	auth.o auth2.o auth-options.o session.o \
-	auth2-chall.o groupaccess.o \
+	$(X509STORE_OBJS) $(OCSP_OBJS) \
+	auth.o auth1.o auth2.o auth-options.o session.o \
+	auth-chall.o auth2-chall.o groupaccess.o \
 	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
 	auth2-none.o auth2-passwd.o auth2-pubkey.o \
 	monitor.o monitor_wrap.o auth-krb5.o \
 	auth2-gss.o gss-serv.o gss-serv-krb5.o \
-	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
+	loginrec.o auth-pam.o auth-shadow.o auth-sia.o \
 	sftp-server.o sftp-common.o \
 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
 	sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
 	sandbox-solaris.o
 
-MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
-MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
+MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out ssh_engine.5.out
+MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 ssh_engine.5
 MANTYPE		= @MANTYPE@
 
 CONFIGFILES=sshd_config.out ssh_config.out moduli.out
@@ -130,6 +148,10 @@
 	-e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
 	-e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
 	-e 's|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \
+	-e 's|/etc/ssh/ca/ca-bundle.crt|$(sshcadir)/ca-bundle.crt|g' \
+	-e 's|/etc/ssh/ca/crt|$(sshcadir)/crt|g' \
+	-e 's|/etc/ssh/ca/ca-bundle.crl|$(sshcadir)/ca-bundle.crl|g' \
+	-e 's|/etc/ssh/ca/crl|$(sshcadir)/crl|g' \
 	-e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
 	-e 's|/etc/moduli|$(sysconfdir)/moduli|g' \
 	-e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
@@ -161,10 +183,12 @@
 	$(RANLIB) $@
 
 ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
-	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
+	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBLDAP) $(LIBOCSP) $(SSHLIBS) $(FIPS_LIBS) $(LIBS) $(GSSLIBS)
+	@@FIPSHMAC@ $@
 
 sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
-	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
+	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBLDAP) $(LIBOCSP) $(SSHDLIBS) $(FIPS_LIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
+	@@FIPSHMAC@ $@
 
 scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
 	$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
@@ -172,14 +196,16 @@
 ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
 	$(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
-ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
-	$(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o x509store.o
+	$(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o x509store.o $(LDFLAGS) -lssh -lopenbsd-compat $(FIPS_LIBS) $(LIBS)
+	@@FIPSHMAC@ $@
 
 ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
-	$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+	$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(FIPS_LIBS) $(LIBS)
+	@@FIPSHMAC@ $@
 
-ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o
-	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o x509store.o
+	$(LD) -o $@ ssh-keysign.o readconf.o x509store.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
 	$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
@@ -276,6 +302,7 @@
 	rm -f regress/unittests/utf8/test_utf8
 	rm -f regress/unittests/misc/kexfuzz
 	(cd openbsd-compat && $(MAKE) distclean)
+	(cd tests/CA && $(MAKE) distclean)
 	if test -d pkg ; then \
 		rm -fr pkg ; \
 	fi
@@ -293,13 +320,15 @@
 	@for f in $(MANPAGES_IN) ; do \
 		base=`echo $$f | sed 's/\..*$$//'` ; \
 		echo "$$f -> $$base.0" ; \
+		LANG=C LANGUAGE=C LC_ALL=C \
 		$(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \
 			>$$base.0 ; \
 	done
 
-distprep: catman-do
+distprep:
 	$(AUTORECONF)
 	-rm -rf autom4te.cache
+	@test -n "$(MANFMT)" && echo "run 'make -f Makefile.in catman-do MANFMT=....' with appropriate for you host MANFMT macro"
 
 install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config
 install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf
@@ -316,6 +345,8 @@
 	$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)5
 	$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8
 	$(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir)
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(sshcadir)
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(piddir)
 	(umask 022 ; $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH))
 	$(INSTALL) -m 0755 $(STRIP_OPT) ssh$(EXEEXT) $(DESTDIR)$(bindir)/ssh$(EXEEXT)
 	$(INSTALL) -m 0755 $(STRIP_OPT) scp$(EXEEXT) $(DESTDIR)$(bindir)/scp$(EXEEXT)
@@ -328,6 +359,10 @@
 	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
+	@@FIPSHMAC@ $(DESTDIR)$(bindir)/ssh$(EXEEXT)
+	@@FIPSHMAC@ $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
+	@@FIPSHMAC@ $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
+	@@FIPSHMAC@ $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
 	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
 	$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
 	$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
@@ -337,6 +372,7 @@
 	$(INSTALL) -m 644 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5
 	$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
 	$(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
+	$(INSTALL) -m 644 ssh_engine.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_engine.5
 	$(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
 	$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
@@ -581,6 +617,10 @@
 	regress/unittests/utf8/test_utf8$(EXEEXT) \
 	regress/misc/kexfuzz/kexfuzz$(EXEEXT)
 
+
+# Target check is more common for the projects using autoXXXX tools
+check: tests
+
 tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS)
 	BUILDDIR=`pwd`; \
 	TEST_SSH_SCP="$${BUILDDIR}/scp"; \
@@ -626,15 +666,35 @@
 		TEST_SSH_ECC="$${TEST_SSH_ECC}" \
 		TEST_SHELL="${TEST_SHELL}" \
 		EXEEXT="$(EXEEXT)" \
-		$@ && echo all tests passed
+		$@ && echo all mainstream tests passed
+	$(MAKE) check-certs
+
+
+CHECKCERTSENV = \
+	TEST_SSH_SSH="$${TEST_SSH_SSH-$$BUILDDIR/ssh}" \
+	TEST_SSH_SSHD="$${TEST_SSH_SSHD-$$BUILDDIR/sshd}" \
+	TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT-$$BUILDDIR/ssh-agent}" \
+	TEST_SSH_SSHADD="$${TEST_SSH_SSHADD-$$BUILDDIR/ssh-add}" \
+	TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN-$$BUILDDIR/ssh-keygen}"
+
+check-certs: $(TARGETS)
+	@if test skip = "$$SSH_X509TESTS"; then echo 'skip X.509 certificate tests'; else \
+	BUILDDIR="`pwd`"; \
+	$(CHECKCERTSENV); \
+	cd tests/CA || exit $$?; \
+	$(MAKE) \
+		$(CHECKCERTSENV) \
+		$@; \
+	fi
 
 compat-tests: $(LIBCOMPAT)
 	(cd openbsd-compat/regress && $(MAKE))
 
 regressclean:
 	if [ -f regress/Makefile ] && [ -r regress/Makefile ]; then \
-		(cd regress && $(MAKE) clean) \
+		(cd regress && $(MAKE) clean TEST_SHELL="${TEST_SHELL}" ) \
 	fi
+	(cd tests/CA && $(MAKE) clean)
 
 survey: survey.sh ssh
 	@$(SHELL) ./survey.sh > survey
@@ -649,3 +709,9 @@
 	if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \
 		sh buildpkg.sh; \
 	fi
+
+# Usefull only if build is in source tree.
+# Outside source tree (VPATH build) result is not correct.
+depend:
+	(cd openbsd-compat && $(MAKE) $@)
+	makedepend -- $(CPPFLAGS) $(CFLAGS) -- $(srcdir)/*.c
diff -ruN openssh-7.5p1/md5crypt.c openssh-7.5p1+x509-10.2/md5crypt.c
--- openssh-7.5p1/md5crypt.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/md5crypt.c	2017-05-20 21:07:01.000000000 +0300
@@ -9,6 +9,7 @@
  */
 
 #include "includes.h"
+#include "md5crypt.h"
 
 #if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
 #include <sys/types.h>
@@ -67,7 +68,7 @@
 	/* It stops at the first '$', max 8 chars */
 	for (ep = sp; *ep != '$'; ep++) {
 		if (*ep == '\0' || ep >= (sp + 8))
-			return (NULL);
+			break;
 	}
 
 	/* get the length of the true salt */
diff -ruN openssh-7.5p1/misc.c openssh-7.5p1+x509-10.2/misc.c
--- openssh-7.5p1/misc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/misc.c	2017-05-20 21:07:01.000000000 +0300
@@ -29,7 +29,6 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
-#include <sys/time.h>
 #include <sys/un.h>
 
 #include <limits.h>
@@ -208,7 +207,14 @@
 	struct passwd *copy = xcalloc(1, sizeof(*copy));
 
 	copy->pw_name = xstrdup(pw->pw_name);
+#if defined(__ANDROID__)
+	/* FIXME: password is NULL on Android */
+	copy->pw_passwd = xstrdup(pw->pw_passwd ? pw->pw_passwd :
+	/* fake password from auth.c */
+	"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK");
+#else
 	copy->pw_passwd = xstrdup(pw->pw_passwd);
+#endif
 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
 	copy->pw_gecos = xstrdup(pw->pw_gecos);
 #endif
@@ -1257,6 +1263,21 @@
 	return 1;
 }
 
+#ifdef __ANDROID__
+/* NOTE getsid syscall wrapper is not included in
+ * some versions of bionic C-library!
+ */
+#include <sys/syscall.h>
+
+static inline pid_t
+android_getsid(pid_t pid) {
+	return syscall(__NR_getsid, pid);
+}
+
+# define getsid android_getsid
+
+#endif /*def __ANDROID__*/
+
 /* returns 1 if process is already daemonized, 0 otherwise */
 int
 daemonized(void)
diff -ruN openssh-7.5p1/misc.h openssh-7.5p1+x509-10.2/misc.h
--- openssh-7.5p1/misc.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/misc.h	2017-05-20 21:07:00.000000000 +0300
@@ -15,7 +15,11 @@
 #ifndef _MISC_H
 #define _MISC_H
 
-#include <sys/time.h>
+#include "config.h"
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
 
 /* Data structure for representing a forwarding request. */
 struct Forward {
diff -ruN openssh-7.5p1/moduli.0 openssh-7.5p1+x509-10.2/moduli.0
--- openssh-7.5p1/moduli.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/moduli.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-MODULI(5)                     File Formats Manual                    MODULI(5)
+MODULI(5)                   BSD File Formats Manual                  MODULI(5)
 
 NAME
-     moduli M-bM-^@M-^S Diffie-Hellman moduli
+     moduli -- Diffie-Hellman moduli
 
 DESCRIPTION
      The /etc/moduli file contains prime numbers and generators for use by
@@ -14,11 +14,11 @@
      are prime and are safe for use in Diffie-Hellman operations by sshd(8).
      This moduli format is used as the output from each pass.
 
-     The file consists of newline-separated records, one per modulus,
-     containing seven space-separated fields.  These fields are as follows:
+     The file consists of newline-separated records, one per modulus, contain-
+     ing seven space-separated fields.  These fields are as follows:
 
-           timestamp    The time that the modulus was last processed as
-                        YYYYMMDDHHMMSS.
+           timestamp    The time that the modulus was last processed as YYYYM-
+                        MDDHHMMSS.
 
            type         Decimal number specifying the internal structure of
                         the prime modulus.  Supported types are:
@@ -38,7 +38,7 @@
                         bitmask of the following values:
 
                         0x00  Not tested.
-                        0x01  Composite number M-bM-^@M-^S not prime.
+                        0x01  Composite number - not prime.
                         0x02  Sieve of Eratosthenes.
                         0x04  Probabilistic Miller-Rabin primality tests.
 
@@ -47,8 +47,8 @@
                         ssh-keygen(1) primality tests are Miller-Rabin tests
                         (flag 0x04).
 
-           trials       Decimal number indicating the number of primality
-                        trials that have been performed on the modulus.
+           trials       Decimal number indicating the number of primality tri-
+                        als that have been performed on the modulus.
 
            size         Decimal number indicating the size of the prime in
                         bits.
@@ -66,9 +66,9 @@
 SEE ALSO
      ssh-keygen(1), sshd(8)
 
-STANDARDS
+CONFORMING TO
      M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for
-     the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
+     the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006
      2006.
 
-OpenBSD 6.0                   September 26, 2012                   OpenBSD 6.0
+BSD                           September 26, 2012                           BSD
diff -ruN openssh-7.5p1/moduli.5 openssh-7.5p1+x509-10.2/moduli.5
--- openssh-7.5p1/moduli.5	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/moduli.5	2017-05-20 21:07:00.000000000 +0300
@@ -1,4 +1,11 @@
-.\"	$OpenBSD: moduli.5,v 1.17 2012/09/26 17:34:38 jmc Exp $
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" Copyright (c) 2008 Damien Miller <djm@mindrot.org>
 .\"
@@ -115,7 +122,7 @@
 .Sh SEE ALSO
 .Xr ssh-keygen 1 ,
 .Xr sshd 8
-.Sh STANDARDS
+.Sh CONFORMING TO
 .Rs
 .%A M. Friedl
 .%A N. Provos
diff -ruN openssh-7.5p1/monitor.c openssh-7.5p1+x509-10.2/monitor.c
--- openssh-7.5p1/monitor.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/monitor.c	2017-05-20 21:07:01.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
  * All rights reserved.
  *
+ * X509 certificate support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -62,14 +65,14 @@
 
 #ifdef WITH_OPENSSL
 #include <openssl/dh.h>
+#include "evp-compat.h"
 #endif
 
 #include "openbsd-compat/sys-queue.h"
 #include "atomicio.h"
 #include "xmalloc.h"
 #include "ssh.h"
-#include "key.h"
-#include "buffer.h"
+#include "ssh-x509.h"
 #include "hostfile.h"
 #include "auth.h"
 #include "cipher.h"
@@ -168,6 +171,10 @@
 
 static Authctxt *authctxt;
 
+#ifdef WITH_SSH1
+static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth */
+#endif
+
 /* local state for key verify */
 static u_char *key_blob = NULL;
 static u_int key_bloblen = 0;
@@ -249,6 +256,52 @@
     {0, 0, NULL}
 };
 
+struct mon_table mon_dispatch_proto15[] = {
+#ifdef WITH_SSH1
+    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
+    {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
+    {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
+    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
+    {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed},
+    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed},
+    {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
+    {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
+#ifdef BSD_AUTH
+    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
+    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
+#endif
+#ifdef SKEY
+    {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
+    {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
+#endif
+#ifdef USE_PAM
+    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
+    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
+    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
+    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
+    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
+    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
+#endif
+#ifdef SSH_AUDIT_EVENTS
+    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+#endif
+#endif /* WITH_SSH1 */
+    {0, 0, NULL}
+};
+
+struct mon_table mon_dispatch_postauth15[] = {
+#ifdef WITH_SSH1
+    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
+    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
+    {MONITOR_REQ_TERM, 0, mm_answer_term},
+#ifdef SSH_AUDIT_EVENTS
+    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
+#endif
+#endif /* WITH_SSH1 */
+    {0, 0, NULL}
+};
+
 struct mon_table *mon_dispatch;
 
 /* Specifies if a certain message is allowed at the moment */
@@ -298,10 +351,17 @@
 
 	authctxt->loginmsg = &loginmsg;
 
-	mon_dispatch = mon_dispatch_proto20;
-	/* Permit requests for moduli and signatures */
-	monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
-	monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
+	if (compat20) {
+		mon_dispatch = mon_dispatch_proto20;
+
+		/* Permit requests for moduli and signatures */
+		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
+		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
+	} else {
+		mon_dispatch = mon_dispatch_proto15;
+
+		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
+	}
 
 	/* The first few requests do not require asynchronous access */
 	while (!authenticated) {
@@ -312,6 +372,9 @@
 
 		/* Special handling for multiple required authentications */
 		if (options.num_auth_methods != 0) {
+			if (!compat20)
+				fatal("AuthenticationMethods is not supported"
+				    "with SSH protocol 1");
 			if (authenticated &&
 			    !auth2_update_methods_lists(authctxt,
 			    auth_method, auth_submethod)) {
@@ -396,13 +459,17 @@
 	signal(SIGXFSZ, SIG_IGN);
 #endif
 
-	mon_dispatch = mon_dispatch_postauth20;
-
-	/* Permit requests for moduli and signatures */
-	monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
-	monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
-	monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
+	if (compat20) {
+		mon_dispatch = mon_dispatch_postauth20;
 
+		/* Permit requests for moduli and signatures */
+		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
+		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
+		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
+	} else {
+		mon_dispatch = mon_dispatch_postauth15;
+		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
+	}
 	if (!no_pty_flag) {
 		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
 		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
@@ -580,10 +647,13 @@
 		buffer_put_char(m, 0);
 		return (0);
 	} else {
+		const BIGNUM *p = NULL, *g = NULL;
+
+		DH_get0_pqg(dh, &p, NULL, &g);
 		/* Send first bignum */
 		buffer_put_char(m, 1);
-		buffer_put_bignum2(m, dh->p);
-		buffer_put_bignum2(m, dh->g);
+		buffer_put_bignum2(m, p);
+		buffer_put_bignum2(m, g);
 
 		DH_free(dh);
 	}
@@ -608,13 +678,19 @@
 
 	debug3("%s", __func__);
 
-	if ((r = sshbuf_get_u32(m, &keyid)) != 0 ||
+{
+	u_int32_t keyid32;
+
+	if ((r = sshbuf_get_u32(m, &keyid32)) != 0 ||
 	    (r = sshbuf_get_string(m, &p, &datlen)) != 0 ||
 	    (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-	if (keyid > INT_MAX)
+	if (keyid32 > INT_MAX)
 		fatal("%s: invalid key ID", __func__);
 
+	keyid = keyid32; /*save cast*/
+}
+
 	/*
 	 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
 	 * SHA384 (48 bytes) and SHA512 (64 bytes).
@@ -640,7 +716,7 @@
 		if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
 		    (r = sshbuf_put_string(sigbuf, session_id2,
 		    session_id2_len)) != 0 ||
-		    (r = sshkey_puts(key, sigbuf)) != 0)
+		    (r = Xkey_puts(alg, key, sigbuf)) != 0)
 			fatal("%s: couldn't prepare private key "
 			    "proof buffer: %s", __func__, ssh_err(r));
 		if (datlen != sshbuf_len(sigbuf) ||
@@ -658,20 +734,24 @@
 		memcpy(session_id2, p, session_id2_len);
 	}
 
+{	ssh_compat compat = { datafellows, xcompat };
+
 	if ((key = get_hostkey_by_index(keyid)) != NULL) {
-		if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
-		    datafellows)) != 0)
-			fatal("%s: sshkey_sign failed: %s",
+		ssh_sign_ctx ctx = { alg, key, &compat };
+		if ((r = Xkey_sign(&ctx, &signature, &siglen, p, datlen)) != 0)
+			fatal("%s: Xkey_sign failed: %s",
 			    __func__, ssh_err(r));
 	} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
 	    auth_sock > 0) {
-		if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
-		    p, datlen, alg, datafellows)) != 0) {
+		ssh_sign_ctx ctx = { alg, key, &compat };
+		if ((r = Xssh_agent_sign(auth_sock, &ctx, &signature, &siglen,
+		    p, datlen)) != 0) {
 			fatal("%s: ssh_agent_sign failed: %s",
 			    __func__, ssh_err(r));
 		}
 	} else
 		fatal("%s: no hostkey from index %d", __func__, keyid);
+}
 
 	debug3("%s: %s signature %p(%zu)", __func__,
 	    is_proof ? "KEX" : "hostkey proof", signature, siglen);
@@ -746,6 +826,10 @@
 	    authctxt->valid ? "authenticating" : "invalid ", authctxt->user);
 	buffer_put_string(m, &options, sizeof(options));
 
+	/* for string options that are not set we must send emtpy string! */
+	buffer_put_cstring(m, (options.hostbased_algorithms ? options.hostbased_algorithms : ""));
+	buffer_put_cstring(m, (options.pubkey_algorithms    ? options.pubkey_algorithms    : ""));
+
 #define M_CP_STROPT(x) do { \
 		if (options.x != NULL) \
 			buffer_put_cstring(m, options.x); \
@@ -760,7 +844,7 @@
 #undef M_CP_STRARRAYOPT
 
 	/* Create valid auth method lists */
-	if (auth2_setup_methods_lists(authctxt) != 0) {
+	if (compat20 && auth2_setup_methods_lists(authctxt) != 0) {
 		/*
 		 * The monitor will continue long enough to let the child
 		 * run to it's packet_disconnect(), but it must not allow any
@@ -772,10 +856,14 @@
 	debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
 	mm_request_send(sock, MONITOR_ANS_PWNAM, m);
 
-	/* Allow service/style information on the auth context */
-	monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
-	monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
-
+	/* For SSHv1 allow authentication now */
+	if (!compat20)
+		monitor_permit_authentications(1);
+	else {
+		/* Allow service/style information on the auth context */
+		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
+		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
+	}
 #ifdef USE_PAM
 	if (options.use_pam)
 		monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
@@ -908,8 +996,11 @@
 	debug3("%s: sending authenticated: %d", __func__, authok);
 	mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
 
-	auth_method = "keyboard-interactive";
-	auth_submethod = "bsdauth";
+	if (compat20) {
+		auth_method = "keyboard-interactive";
+		auth_submethod = "bsdauth";
+	} else
+		auth_method = "bsdauth";
 
 	return (authok != 0);
 }
@@ -1119,6 +1210,7 @@
 int
 mm_answer_keyallowed(int sock, Buffer *m)
 {
+	char *pkalg;
 	Key *key;
 	char *cuser, *chost;
 	u_char *blob;
@@ -1131,12 +1223,20 @@
 	type = buffer_get_int(m);
 	cuser = buffer_get_string(m, NULL);
 	chost = buffer_get_string(m, NULL);
+	pkalg = buffer_get_string(m, NULL);
 	blob = buffer_get_string(m, &bloblen);
 	pubkey_auth_attempt = buffer_get_int(m);
 
-	key = key_from_blob(blob, bloblen);
+	key = xkey_from_blob(pkalg, blob, bloblen);
+
+	if ((compat20 && type == MM_RSAHOSTKEY) ||
+	    (!compat20 && type != MM_RSAHOSTKEY))
+		fatal("%s: key type and protocol mismatch", __func__);
 
-	debug3("%s: key_from_blob: %p", __func__, key);
+	debug3("%s: xkey_from_blob: %s %p", __func__, pkalg, (void*)key);
+
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, key, &ctx_compat };
 
 	if (key != NULL && authctxt->valid) {
 		/* These should not make it past the privsep child */
@@ -1148,9 +1248,11 @@
 		case MM_USERKEY:
 			allowed = options.pubkey_authentication &&
 			    !auth2_userkey_already_used(authctxt, key) &&
+			    /* ignore as algorithm is already allowed
+			       in user authentication request.
 			    match_pattern_list(sshkey_ssh_name(key),
-			    options.pubkey_key_types, 0) == 1 &&
-			    user_key_allowed(authctxt->pw, key,
+			    options.pubkey_key_types, 0) == 1 &&*/
+			    user_xkey_allowed(authctxt->pw, &ctx,
 			    pubkey_auth_attempt);
 			pubkey_auth_info(authctxt, key, NULL);
 			auth_method = "publickey";
@@ -1160,20 +1262,34 @@
 			break;
 		case MM_HOSTKEY:
 			allowed = options.hostbased_authentication &&
+			    /* ignore as algorithm is already allowed
+			       in user authentication request.
 			    match_pattern_list(sshkey_ssh_name(key),
-			    options.hostbased_key_types, 0) == 1 &&
-			    hostbased_key_allowed(authctxt->pw,
-			    cuser, chost, key);
+			    options.hostbased_key_types, 0) == 1 &&*/
+			    hostbased_xkey_allowed(authctxt->pw, &ctx,
+			    cuser, chost);
 			pubkey_auth_info(authctxt, key,
 			    "client user \"%.100s\", client host \"%.100s\"",
 			    cuser, chost);
 			auth_method = "hostbased";
 			break;
+#ifdef WITH_SSH1
+		case MM_RSAHOSTKEY:
+			key->type = KEY_RSA1; /* XXX */
+			allowed = options.rhosts_rsa_authentication &&
+			    auth_rhosts_rsa_xkey_allowed(authctxt->pw, &ctx,
+			    cuser, chost);
+			if (options.rhosts_rsa_authentication && allowed != 1)
+				auth_clear_options();
+			auth_method = "rsa";
+			break;
+#endif
 		default:
 			fatal("%s: unknown key type %d", __func__, type);
 			break;
 		}
 	}
+}
 
 	debug3("%s: key %p is %s",
 	    __func__, key, allowed ? "allowed" : "not allowed");
@@ -1205,6 +1321,9 @@
 
 	mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m);
 
+	if (type == MM_RSAHOSTKEY)
+		monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
+
 	return (0);
 }
 
@@ -1332,12 +1451,14 @@
 int
 mm_answer_keyverify(int sock, Buffer *m)
 {
+	char *pkalg;
 	Key *key;
 	u_char *signature, *data, *blob;
 	u_int signaturelen, datalen, bloblen;
 	int verified = 0;
 	int valid_data = 0;
 
+	pkalg = buffer_get_string(m, NULL);
 	blob = buffer_get_string(m, &bloblen);
 	signature = buffer_get_string(m, &signaturelen);
 	data = buffer_get_string(m, &datalen);
@@ -1346,7 +1467,7 @@
 	  !monitor_allowed_key(blob, bloblen))
 		fatal("%s: bad key, not previously allowed", __func__);
 
-	key = key_from_blob(blob, bloblen);
+	key = xkey_from_blob(pkalg, blob, bloblen);
 	if (key == NULL)
 		fatal("%s: bad public key blob", __func__);
 
@@ -1365,7 +1486,11 @@
 	if (!valid_data)
 		fatal("%s: bad signature data blob", __func__);
 
-	verified = key_verify(key, signature, signaturelen, data, datalen);
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, key, &ctx_compat };
+
+	verified = xkey_verify(&ctx, signature, signaturelen, data, datalen);
+}
 	debug3("%s: key %p signature %s",
 	    __func__, key, (verified == 1) ? "verified" : "unverified");
 
@@ -1510,6 +1635,186 @@
 	return (0);
 }
 
+#ifdef WITH_SSH1
+int
+mm_answer_sesskey(int sock, Buffer *m)
+{
+	BIGNUM *p;
+	int rsafail;
+
+	/* Turn off permissions */
+	monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0);
+
+	if ((p = BN_new()) == NULL)
+		fatal("%s: BN_new", __func__);
+
+	buffer_get_bignum2(m, p);
+
+	rsafail = ssh1_session_key(p);
+
+	buffer_clear(m);
+	buffer_put_int(m, rsafail);
+	buffer_put_bignum2(m, p);
+
+	BN_clear_free(p);
+
+	mm_request_send(sock, MONITOR_ANS_SESSKEY, m);
+
+	/* Turn on permissions for sessid passing */
+	monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);
+
+	return (0);
+}
+
+int
+mm_answer_sessid(int sock, Buffer *m)
+{
+	int i;
+
+	debug3("%s entering", __func__);
+
+	if (buffer_len(m) != 16)
+		fatal("%s: bad ssh1 session id", __func__);
+	for (i = 0; i < 16; i++)
+		session_id[i] = buffer_get_char(m);
+
+	/* Turn on permissions for getpwnam */
+	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
+
+	return (0);
+}
+
+int
+mm_answer_rsa_keyallowed(int sock, Buffer *m)
+{
+	BIGNUM *client_n;
+	Key *key = NULL;
+	u_char *blob = NULL;
+	u_int blen = 0;
+	int allowed = 0;
+
+	debug3("%s entering", __func__);
+
+	auth_method = "rsa";
+	if (options.rsa_authentication && authctxt->valid) {
+		if ((client_n = BN_new()) == NULL)
+			fatal("%s: BN_new", __func__);
+		buffer_get_bignum2(m, client_n);
+		allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);
+		BN_clear_free(client_n);
+	}
+	buffer_clear(m);
+	buffer_put_int(m, allowed);
+	buffer_put_int(m, forced_command != NULL);
+
+	/* clear temporarily storage (used by generate challenge) */
+	monitor_reset_key_state();
+
+	if (allowed && key != NULL) {
+		key->type = KEY_RSA;	/* cheat for key_to_blob */
+		if (key_to_blob(key, &blob, &blen) == 0)
+			fatal("%s: key_to_blob failed", __func__);
+		buffer_put_string(m, blob, blen);
+
+		/* Save temporarily for comparison in verify */
+		key_blob = blob;
+		key_bloblen = blen;
+		key_blobtype = MM_RSAUSERKEY;
+	}
+	if (key != NULL)
+		key_free(key);
+
+	mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m);
+
+	monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
+	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0);
+	return (0);
+}
+
+int
+mm_answer_rsa_challenge(int sock, Buffer *m)
+{
+	Key *key = NULL;
+	u_char *blob;
+	u_int blen;
+
+	debug3("%s entering", __func__);
+
+	if (!authctxt->valid)
+		fatal("%s: authctxt not valid", __func__);
+	blob = buffer_get_string(m, &blen);
+	if (!monitor_allowed_key(blob, blen))
+		fatal("%s: bad key, not previously allowed", __func__);
+	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
+		fatal("%s: key type mismatch", __func__);
+	if ((key = key_from_blob(blob, blen)) == NULL)
+		fatal("%s: received bad key", __func__);
+	if (key->type != KEY_RSA)
+		fatal("%s: received bad key type %d", __func__, key->type);
+	key->type = KEY_RSA1;
+	if (ssh1_challenge)
+		BN_clear_free(ssh1_challenge);
+	ssh1_challenge = auth_rsa_generate_challenge(key);
+
+	buffer_clear(m);
+	buffer_put_bignum2(m, ssh1_challenge);
+
+	debug3("%s sending reply", __func__);
+	mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m);
+
+	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
+
+	free(blob);
+	key_free(key);
+	return (0);
+}
+
+int
+mm_answer_rsa_response(int sock, Buffer *m)
+{
+	Key *key = NULL;
+	u_char *blob, *response;
+	u_int blen, len;
+	int success;
+
+	debug3("%s entering", __func__);
+
+	if (!authctxt->valid)
+		fatal("%s: authctxt not valid", __func__);
+	if (ssh1_challenge == NULL)
+		fatal("%s: no ssh1_challenge", __func__);
+
+	blob = buffer_get_string(m, &blen);
+	if (!monitor_allowed_key(blob, blen))
+		fatal("%s: bad key, not previously allowed", __func__);
+	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
+		fatal("%s: key type mismatch: %d", __func__, key_blobtype);
+	if ((key = key_from_blob(blob, blen)) == NULL)
+		fatal("%s: received bad key", __func__);
+	response = buffer_get_string(m, &len);
+	if (len != 16)
+		fatal("%s: received bad response to challenge", __func__);
+	success = auth_rsa_verify_response(key, ssh1_challenge, response);
+
+	free(blob);
+	key_free(key);
+	free(response);
+
+	auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";
+
+	/* reset state */
+	BN_clear_free(ssh1_challenge);
+	ssh1_challenge = NULL;
+	monitor_reset_key_state();
+
+	buffer_clear(m);
+	buffer_put_int(m, success);
+	mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m);
+
+	return (success);
+}
+#endif
+
 int
 mm_answer_term(int sock, Buffer *req)
 {
@@ -1606,10 +1911,10 @@
 # endif
 #endif /* WITH_OPENSSL */
 		kex->kex[KEX_C25519_SHA256] = kexc25519_server;
-		kex->load_host_public_key=&get_hostkey_public_by_type;
-		kex->load_host_private_key=&get_hostkey_private_by_type;
+		kex->find_host_public_key=&get_hostkey_public_by_alg;
+		kex->find_host_private_key=&get_hostkey_private_by_alg;
 		kex->host_key_index=&get_hostkey_index;
-		kex->sign = sshd_hostkey_sign;
+		kex->xsign = Xsshd_hostkey_sign;
 	}
 }
 
diff -ruN openssh-7.5p1/monitor_wrap.c openssh-7.5p1+x509-10.2/monitor_wrap.c
--- openssh-7.5p1/monitor_wrap.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/monitor_wrap.c	2017-05-20 21:07:01.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
  * All rights reserved.
  *
+ * X509 certificate support,
+ * Copyright (c) 2007-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -50,8 +53,7 @@
 #ifdef WITH_OPENSSL
 #include "dh.h"
 #endif
-#include "buffer.h"
-#include "key.h"
+#include "ssh-x509.h"
 #include "cipher.h"
 #include "kex.h"
 #include "hostfile.h"
@@ -85,6 +87,7 @@
 #include "ssherr.h"
 
 /* Imports */
+extern int compat20;
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern struct monitor *pmonitor;
@@ -216,9 +219,10 @@
 #endif
 
 int
-mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
-    const u_char *data, u_int datalen, const char *hostkey_alg)
+mm_xkey_sign(ssh_sign_ctx *ctx, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen)
 {
+	const char *hostkey_alg = ctx->alg;
+	Key *key = ctx->key;
 	struct kex *kex = *pmonitor->m_pkex;
 	Buffer m;
 
@@ -281,6 +285,18 @@
 	if (len != sizeof(*newopts))
 		fatal("%s: option block size mismatch", __func__);
 
+	newopts->hostbased_algorithms = buffer_get_string(&m, NULL);
+	if (*newopts->hostbased_algorithms == '\0') {
+		free(newopts->hostbased_algorithms);
+		newopts->hostbased_algorithms = xstrdup("*");
+	}
+
+	newopts->pubkey_algorithms = buffer_get_string(&m, NULL);
+	if (*newopts->pubkey_algorithms == '\0') {
+		free(newopts->pubkey_algorithms);
+		newopts->pubkey_algorithms = xstrdup("*");
+	}
+
 #define M_CP_STROPT(x) do { \
 		if (newopts->x != NULL) \
 			newopts->x = buffer_get_string(&m, NULL); \
@@ -291,6 +307,7 @@
 	} while (0)
 	/* See comment in servconf.h */
 	COPY_MATCH_STRING_OPTS();
+
 #undef M_CP_STROPT
 #undef M_CP_STRARRAYOPT
 
@@ -373,24 +390,11 @@
 	return (authenticated);
 }
 
-int
-mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
-{
-	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
-	    pubkey_auth_attempt));
-}
-
-int
-mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
-    Key *key)
-{
-	return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
-}
-
-int
-mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
-    Key *key, int pubkey_auth_attempt)
+static int
+mm_xkey_allowed(enum mm_keytype type, const char *user, const char *host,
+    ssh_sign_ctx *ctx, int pubkey_auth_attempt)
 {
+	const char *pkalg = ctx->alg;
 	Buffer m;
 	u_char *blob;
 	u_int len;
@@ -399,13 +403,15 @@
 	debug3("%s entering", __func__);
 
 	/* Convert the key to a blob and the pass it over */
-	if (!key_to_blob(key, &blob, &len))
+	if (pkalg == NULL) pkalg = sshkey_ssh_name(ctx->key);
+	if (!xkey_to_blob(pkalg, ctx->key, &blob, &len))
 		return (0);
 
 	buffer_init(&m);
 	buffer_put_int(&m, type);
 	buffer_put_cstring(&m, user ? user : "");
 	buffer_put_cstring(&m, host ? host : "");
+	buffer_put_cstring(&m, pkalg);
 	buffer_put_string(&m, blob, len);
 	buffer_put_int(&m, pubkey_auth_attempt);
 	free(blob);
@@ -427,6 +433,38 @@
 	return (allowed);
 }
 
+int
+mm_user_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx,
+    int pubkey_auth_attempt)
+{
+	(void)pw;
+	return (mm_xkey_allowed(MM_USERKEY, NULL, NULL, ctx,
+	    pubkey_auth_attempt));
+}
+
+int
+mm_hostbased_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx,
+    const char *user, const char *host)
+{
+	(void)pw;
+	return (mm_xkey_allowed(MM_HOSTKEY, user, host, ctx, 0));
+}
+
+#ifdef WITH_SSH1
+int
+mm_auth_rhosts_rsa_xkey_allowed(struct passwd *pw, ssh_sign_ctx *ctx,
+    const char *user, const char *host)
+{
+	int ret;
+
+	(void)pw;
+	ctx->key->type = KEY_RSA; /* XXX hack for xkey_to_blob */
+	ret = mm_xkey_allowed(MM_RSAHOSTKEY, user, host, ctx, 0);
+	ctx->key->type = KEY_RSA1;
+	return (ret);
+}
+#endif
+
 /*
  * This key verify needs to send the key type along, because the
  * privileged parent makes the decision if the key is allowed
@@ -434,8 +472,9 @@
  */
 
 int
-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
+mm_xkey_verify(ssh_sign_ctx *ctx, u_char *sig, u_int siglen, u_char *data, u_int datalen)
 {
+	const char *pkalg = ctx->alg;
 	Buffer m;
 	u_char *blob;
 	u_int len;
@@ -444,10 +483,12 @@
 	debug3("%s entering", __func__);
 
 	/* Convert the key to a blob and the pass it over */
-	if (!key_to_blob(key, &blob, &len))
+	if (pkalg == NULL) pkalg = sshkey_ssh_name(ctx->key);
+	if (!xkey_to_blob(pkalg, ctx->key, &blob, &len))
 		return (0);
 
 	buffer_init(&m);
+	buffer_put_cstring(&m, pkalg);
 	buffer_put_string(&m, blob, len);
 	buffer_put_string(&m, sig, siglen);
 	buffer_put_string(&m, data, datalen);
@@ -697,6 +738,28 @@
 	buffer_free(&m);
 }
 
+#ifdef WITH_SSH1
+int
+mm_ssh1_session_key(BIGNUM *num)
+{
+	int rsafail;
+	Buffer m;
+
+	buffer_init(&m);
+	buffer_put_bignum2(&m, num);
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
+
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
+
+	rsafail = buffer_get_int(&m);
+	buffer_get_bignum2(&m, num);
+
+	buffer_free(&m);
+
+	return (rsafail);
+}
+#endif
+
 static void
 mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
     char ***prompts, u_int **echo_on)
@@ -827,6 +890,120 @@
 }
 #endif /* SKEY */
 
+void
+mm_ssh1_session_id(u_char session_id[16])
+{
+	Buffer m;
+	int i;
+
+	debug3("%s entering", __func__);
+
+	buffer_init(&m);
+	for (i = 0; i < 16; i++)
+		buffer_put_char(&m, session_id[i]);
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
+	buffer_free(&m);
+}
+
+#ifdef WITH_SSH1
+int
+mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+	Buffer m;
+	Key *key;
+	u_char *blob;
+	u_int blen;
+	int allowed = 0, have_forced = 0;
+
+	debug3("%s entering", __func__);
+
+	buffer_init(&m);
+	buffer_put_bignum2(&m, client_n);
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
+
+	allowed = buffer_get_int(&m);
+
+	/* fake forced command */
+	auth_clear_options();
+	have_forced = buffer_get_int(&m);
+	forced_command = have_forced ? xstrdup("true") : NULL;
+
+	if (allowed && rkey != NULL) {
+		blob = buffer_get_string(&m, &blen);
+		if ((key = key_from_blob(blob, blen)) == NULL)
+			fatal("%s: key_from_blob failed", __func__);
+		*rkey = key;
+		free(blob);
+	}
+	buffer_free(&m);
+
+	return (allowed);
+}
+
+BIGNUM *
+mm_auth_rsa_generate_challenge(Key *key)
+{
+	Buffer m;
+	BIGNUM *challenge;
+	u_char *blob;
+	u_int blen;
+
+	debug3("%s entering", __func__);
+
+	if ((challenge = BN_new()) == NULL)
+		fatal("%s: BN_new failed", __func__);
+
+	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
+	if (key_to_blob(key, &blob, &blen) == 0)
+		fatal("%s: key_to_blob failed", __func__);
+	key->type = KEY_RSA1;
+
+	buffer_init(&m);
+	buffer_put_string(&m, blob, blen);
+	free(blob);
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
+
+	buffer_get_bignum2(&m, challenge);
+	buffer_free(&m);
+
+	return (challenge);
+}
+
+int
+mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
+{
+	Buffer m;
+	u_char *blob;
+	u_int blen;
+	int success = 0;
+
+	debug3("%s entering", __func__);
+
+	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
+	if (key_to_blob(key, &blob, &blen) == 0)
+		fatal("%s: key_to_blob failed", __func__);
+	key->type = KEY_RSA1;
+
+	buffer_init(&m);
+	buffer_put_string(&m, blob, blen);
+	buffer_put_string(&m, response, 16);
+	free(blob);
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
+
+	success = buffer_get_int(&m);
+	buffer_free(&m);
+
+	return (success);
+}
+#endif
+
 #ifdef SSH_AUDIT_EVENTS
 void
 mm_audit_event(ssh_audit_event_t event)
diff -ruN openssh-7.5p1/monitor_wrap.h openssh-7.5p1+x509-10.2/monitor_wrap.h
--- openssh-7.5p1/monitor_wrap.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/monitor_wrap.h	2017-05-20 21:07:00.000000000 +0300
@@ -4,6 +4,9 @@
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -31,7 +34,7 @@
 extern int use_privsep;
 #define PRIVSEP(x)	(use_privsep ? mm_##x : x)
 
-enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY };
+enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY};
 
 struct monitor;
 struct mm_master;
@@ -40,16 +43,22 @@
 void mm_log_handler(LogLevel, const char *, void *);
 int mm_is_monitor(void);
 DH *mm_choose_dh(int, int, int);
-int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *);
+int mm_xkey_sign(ssh_sign_ctx *ctx, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen);
 void mm_inform_authserv(char *, char *);
 struct passwd *mm_getpwnamallow(const char *);
 char *mm_auth2_read_banner(void);
 int mm_auth_password(struct Authctxt *, char *);
-int mm_key_allowed(enum mm_keytype, const char *, const char *, Key *, int);
-int mm_user_key_allowed(struct passwd *, Key *, int);
-int mm_hostbased_key_allowed(struct passwd *, const char *,
-    const char *, Key *);
-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
+int mm_user_xkey_allowed(struct passwd *, ssh_sign_ctx *, int);
+int mm_hostbased_xkey_allowed(struct passwd *, ssh_sign_ctx *,
+	const char *, const char *);
+#ifdef WITH_SSH1
+int mm_auth_rhosts_rsa_xkey_allowed(struct passwd *, ssh_sign_ctx *,
+	const char *, const char *);
+#endif
+int mm_xkey_verify(ssh_sign_ctx *ctx, u_char *sig, u_int siglen, u_char *data, u_int datalen);
+int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
+BIGNUM *mm_auth_rsa_generate_challenge(Key *);
 
 #ifdef GSSAPI
 OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
@@ -79,6 +88,10 @@
 int mm_pty_allocate(int *, int *, char *, size_t);
 void mm_session_pty_cleanup2(struct Session *);
 
+/* SSHv1 interfaces */
+void mm_ssh1_session_id(u_char *);
+int mm_ssh1_session_key(BIGNUM *);
+
 /* Key export functions */
 struct newkeys *mm_newkeys_from_blob(u_char *, int);
 int mm_newkeys_to_blob(int, u_char **, u_int *);
diff -ruN openssh-7.5p1/mux.c openssh-7.5p1+x509-10.2/mux.c
--- openssh-7.5p1/mux.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/mux.c	2017-05-20 21:07:01.000000000 +0300
@@ -691,7 +691,6 @@
 		connect_addr = NULL;
 	}
 
-	memset(&fwd, 0, sizeof(fwd));
 	fwd.listen_port = lport;
 	if (fwd.listen_port == PORT_STREAMLOCAL)
 		fwd.listen_path = listen_addr;
@@ -860,7 +859,6 @@
 		connect_addr = NULL;
 	}
 
-	memset(&fwd, 0, sizeof(fwd));
 	fwd.listen_port = lport;
 	if (fwd.listen_port == PORT_STREAMLOCAL)
 		fwd.listen_path = listen_addr;
diff -ruN openssh-7.5p1/myproposal.h openssh-7.5p1+x509-10.2/myproposal.h
--- openssh-7.5p1/myproposal.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/myproposal.h	2017-05-20 21:07:00.000000000 +0300
@@ -73,13 +73,21 @@
 	"diffie-hellman-group18-sha512,"
 # define KEX_SHA2_GROUP14 \
 	"diffie-hellman-group14-sha256,"
-#define	SHA2_HMAC_MODES \
+# define SHA2_HMAC_ETM_MODES \
+	"hmac-sha2-256-etm@openssh.com," \
+	"hmac-sha2-512-etm@openssh.com,"
+# define SHA2_HMAC_MODES \
 	"hmac-sha2-256," \
 	"hmac-sha2-512,"
+# define RSA_SHA2_PK_ALG \
+	"rsa-sha2-256," \
+	"rsa-sha2-512,"
 #else
 # define KEX_SHA2_METHODS
 # define KEX_SHA2_GROUP14
+# define SHA2_HMAC_ETM_MODES
 # define SHA2_HMAC_MODES
+# define RSA_SHA2_PK_ALG
 #endif
 
 #ifdef WITH_OPENSSL
@@ -110,8 +118,7 @@
 	"ssh-rsa-cert-v01@openssh.com," \
 	HOSTKEY_ECDSA_METHODS \
 	"ssh-ed25519," \
-	"rsa-sha2-512," \
-	"rsa-sha2-256," \
+	RSA_SHA2_PK_ALG \
 	"ssh-rsa"
 
 /* the actual algorithms */
@@ -127,13 +134,11 @@
 #define KEX_SERVER_MAC \
 	"umac-64-etm@openssh.com," \
 	"umac-128-etm@openssh.com," \
-	"hmac-sha2-256-etm@openssh.com," \
-	"hmac-sha2-512-etm@openssh.com," \
+	SHA2_HMAC_ETM_MODES \
 	"hmac-sha1-etm@openssh.com," \
 	"umac-64@openssh.com," \
 	"umac-128@openssh.com," \
-	"hmac-sha2-256," \
-	"hmac-sha2-512," \
+	SHA2_HMAC_MODES \
 	"hmac-sha1"
 
 #define KEX_CLIENT_MAC KEX_SERVER_MAC
@@ -152,13 +157,11 @@
 #define	KEX_SERVER_MAC \
 	"umac-64-etm@openssh.com," \
 	"umac-128-etm@openssh.com," \
-	"hmac-sha2-256-etm@openssh.com," \
-	"hmac-sha2-512-etm@openssh.com," \
+	SHA2_HMAC_ETM_MODES \
 	"hmac-sha1-etm@openssh.com," \
 	"umac-64@openssh.com," \
 	"umac-128@openssh.com," \
-	"hmac-sha2-256," \
-	"hmac-sha2-512," \
+	SHA2_HMAC_MODES \
 	"hmac-sha1"
 
 #define KEX_CLIENT_KEX KEX_SERVER_KEX
diff -ruN openssh-7.5p1/opacket.c openssh-7.5p1+x509-10.2/opacket.c
--- openssh-7.5p1/opacket.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/opacket.c	2017-05-20 21:07:01.000000000 +0300
@@ -6,7 +6,7 @@
 #include "packet.h"
 #include "log.h"
 
-struct ssh *active_state, *backup_state;
+struct ssh *active_state = NULL;
 
 /* Map old to new API */
 
@@ -76,7 +76,7 @@
 
 #ifdef WITH_SSH1
 void
-ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)
+ssh_packet_put_bignum(struct ssh *ssh, const BIGNUM * value)
 {
 	int r;
 
@@ -87,7 +87,7 @@
 
 #ifdef WITH_OPENSSL
 void
-ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value)
+ssh_packet_put_bignum2(struct ssh *ssh, const BIGNUM * value)
 {
 	int r;
 
@@ -273,6 +273,7 @@
 packet_close(void)
 {
 	ssh_packet_close(active_state);
+	free(active_state);
 	active_state = NULL;
 }
 
diff -ruN openssh-7.5p1/opacket.h openssh-7.5p1+x509-10.2/opacket.h
--- openssh-7.5p1/opacket.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/opacket.h	2017-05-20 21:07:00.000000000 +0300
@@ -6,8 +6,8 @@
 void     ssh_packet_put_char(struct ssh *, int ch);
 void     ssh_packet_put_int(struct ssh *, u_int value);
 void     ssh_packet_put_int64(struct ssh *, u_int64_t value);
-void     ssh_packet_put_bignum(struct ssh *, BIGNUM * value);
-void     ssh_packet_put_bignum2(struct ssh *, BIGNUM * value);
+void     ssh_packet_put_bignum(struct ssh *, const BIGNUM * value);
+void     ssh_packet_put_bignum2(struct ssh *, const BIGNUM * value);
 void     ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *);
 void     ssh_packet_put_string(struct ssh *, const void *buf, u_int len);
 void     ssh_packet_put_cstring(struct ssh *, const char *str);
diff -ruN openssh-7.5p1/openbsd-compat/arc4random.c openssh-7.5p1+x509-10.2/openbsd-compat/arc4random.c
--- openssh-7.5p1/openbsd-compat/arc4random.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/arc4random.c	2017-05-20 21:07:01.000000000 +0300
@@ -6,6 +6,7 @@
  * Copyright (c) 1996, David Mazieres <dm@uun.org>
  * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
  * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Roumen Petrov
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -32,9 +33,71 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#ifdef OPENSSL_FIPS
+#include <log.h>
+#include <openssl/err.h>
+#endif
+
 
 #ifndef HAVE_ARC4RANDOM
 
+#ifdef OPENSSL_FIPS
+  /* synchronize HAVE_ARC4RANDOM_<...> with defined.h */
+# define HAVE_ARC4RANDOM_BUF
+
+/* Size of key to use */
+#define SEED_SIZE 20
+static int rc4_ready = 0;
+
+void      fips_arc4random_stir(void);
+u_int32_t fips_arc4random(void);
+void      save_arc4random_stir(void);
+u_int32_t save_arc4random(void);
+
+/* FIXME: based on readhat/fedora fips patch */
+void
+fips_arc4random_stir(void) {
+	unsigned char rand_buf[SEED_SIZE];
+
+	if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0)
+		fatal("Couldn't obtain random bytes (error %ld)",
+		    ERR_get_error());
+	rc4_ready = 1;
+}
+u_int32_t
+fips_arc4random(void) {
+	unsigned int r = 0;
+	void *rp = &r;
+
+	if (!rc4_ready) {
+		fips_arc4random_stir();
+	}
+	RAND_bytes(rp, sizeof(r));
+
+	return(r);
+}
+
+void
+arc4random_stir(void) {
+	if (FIPS_mode())
+		fips_arc4random_stir();
+	else
+		save_arc4random_stir();
+}
+
+u_int32_t
+arc4random(void) {
+	if (FIPS_mode())
+		fips_arc4random();
+	else
+		save_arc4random();
+}
+
+# define arc4random_stir	save_arc4random_stir
+# define arc4random		save_arc4random
+#endif
+
+
 #ifdef WITH_OPENSSL
 #include <openssl/rand.h>
 #include <openssl/err.h>
@@ -45,12 +108,6 @@
 #define KEYSTREAM_ONLY
 #include "chacha_private.h"
 
-#ifdef __GNUC__
-#define inline __inline
-#else				/* !__GNUC__ */
-#define inline
-#endif				/* !__GNUC__ */
-
 /* OpenSSH isn't multithreaded */
 #define _ARC4_LOCK()
 #define _ARC4_UNLOCK()
@@ -246,6 +303,11 @@
 	_ARC4_UNLOCK();
 }
 # endif /* !HAVE_ARC4RANDOM_BUF */
+#ifdef OPENSSL_FIPS
+ /* to use arc4random_buf based on arc4random */
+# define HAVE_ARC4RANDOM
+# undef HAVE_ARC4RANDOM_BUF
+#endif
 #endif /* !HAVE_ARC4RANDOM */
 
 /* arc4random_buf() that uses platform arc4random() */
diff -ruN openssh-7.5p1/openbsd-compat/bsd-closefrom.c openssh-7.5p1+x509-10.2/openbsd-compat/bsd-closefrom.c
--- openssh-7.5p1/openbsd-compat/bsd-closefrom.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/bsd-closefrom.c	2017-05-20 21:07:01.000000000 +0300
@@ -74,13 +74,36 @@
     struct dirent *dent;
     DIR *dirp;
     int len;
+#ifdef __ANDROID__
+    int pws_fd = -1;
+#endif
 
+#ifdef __ANDROID__
+{
+    /* keep android property workspace open */
+    char *pws_env = getenv("ANDROID_PROPERTY_WORKSPACE");
+    if (pws_env) {
+	char *s, *q;
+	s = strdup(pws_env);
+	/* format "int,int" */
+	q = strchr(s, ',');
+	if (q) {
+	    q = '\0';
+	    pws_fd = atoi(s);
+	}
+	free(s);
+    }
+}
+#endif
     /* Check for a /proc/$$/fd directory. */
     len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid());
     if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) {
 	while ((dent = readdir(dirp)) != NULL) {
 	    fd = strtol(dent->d_name, &endp, 10);
 	    if (dent->d_name != endp && *endp == '\0' &&
+	    #ifdef __ANDROID__
+		(fd != pws_fd) &&
+	    #endif
 		fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
 		(void) close((int) fd);
 	}
diff -ruN openssh-7.5p1/openbsd-compat/bsd-misc.c openssh-7.5p1+x509-10.2/openbsd-compat/bsd-misc.c
--- openssh-7.5p1/openbsd-compat/bsd-misc.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/bsd-misc.c	2017-05-20 21:07:01.000000000 +0300
@@ -35,6 +35,8 @@
 char *__progname;
 #endif
 
+char *ssh_progpath = NULL;
+
 /*
  * NB. duplicate __progname in case it is an alias for argv[0]
  * Otherwise it may get clobbered by setproctitle()
@@ -59,6 +61,16 @@
 		perror("strdup");
 		exit(1);
 	}
+
+{
+	ssh_progpath = strdup(argv0);
+	p = strrchr(ssh_progpath, '/');
+	if (p != NULL) *p = '\0';
+	p = ssh_progpath;
+	ssh_progpath = realpath(p, NULL);
+	free(p);
+}
+
 	return q;
 }
 
@@ -301,11 +313,3 @@
 	return 1;
 }
 #endif
-
-#ifndef HAVE_LLABS
-long long
-llabs(long long j)
-{
-	return (j < 0 ? -j : j);
-}
-#endif
diff -ruN openssh-7.5p1/openbsd-compat/bsd-misc.h openssh-7.5p1+x509-10.2/openbsd-compat/bsd-misc.h
--- openssh-7.5p1/openbsd-compat/bsd-misc.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/bsd-misc.h	2017-05-20 21:07:00.000000000 +0300
@@ -109,9 +109,14 @@
 #endif
 
 #ifndef HAVE_ENDGRENT
+#ifdef __ANDROID__
+/* endgrent is declared but not defined, see port-android.c */
+#else
 # define endgrent() do { } while(0)
 #endif
+#endif
 
+#ifdef KRB5
 #ifndef HAVE_KRB5_GET_ERROR_MESSAGE
 # define krb5_get_error_message krb5_get_err_text
 #endif
@@ -119,6 +124,7 @@
 #ifndef HAVE_KRB5_FREE_ERROR_MESSAGE
 # define krb5_free_error_message(a,b) do { } while(0)
 #endif
+#endif /*def KRB5*/
 
 #ifndef HAVE_PLEDGE
 int pledge(const char *promises, const char *paths[]);
@@ -135,8 +141,4 @@
 void warn(const char *, ...) __attribute__((format(printf, 1, 2)));
 #endif
 
-#ifndef HAVE_LLABS
-long long llabs(long long);
-#endif
-
 #endif /* _BSD_MISC_H */
diff -ruN openssh-7.5p1/openbsd-compat/bsd-openpty.c openssh-7.5p1+x509-10.2/openbsd-compat/bsd-openpty.c
--- openssh-7.5p1/openbsd-compat/bsd-openpty.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/bsd-openpty.c	2017-05-20 21:07:01.000000000 +0300
@@ -125,11 +125,13 @@
 	 * Try to push the appropriate streams modules, as described
 	 * in Solaris pts(7).
 	 */
+# ifndef __ANDROID__
 	ioctl(*aslave, I_PUSH, "ptem");
 	ioctl(*aslave, I_PUSH, "ldterm");
 # ifndef __hpux
 	ioctl(*aslave, I_PUSH, "ttcompat");
 # endif /* __hpux */
+# endif /*ndef __ANDROID__*/
 
 	return (0);
 
diff -ruN openssh-7.5p1/openbsd-compat/bsd-statvfs.c openssh-7.5p1+x509-10.2/openbsd-compat/bsd-statvfs.c
--- openssh-7.5p1/openbsd-compat/bsd-statvfs.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/bsd-statvfs.c	2017-05-20 21:07:01.000000000 +0300
@@ -19,12 +19,19 @@
 #if !defined(HAVE_STATVFS) || !defined(HAVE_FSTATVFS)
 
 #include <sys/param.h>
+#ifdef HAVE_SYS_STATFS_H
+# include <sys/statfs.h>
+#endif
 #ifdef HAVE_SYS_MOUNT_H
 # include <sys/mount.h>
 #endif
 
 #include <errno.h>
 
+#ifndef MNAMELEN
+# define MNAMELEN 90
+#endif
+
 static void
 copy_statfs_to_statvfs(struct statvfs *to, struct statfs *from)
 {
diff -ruN openssh-7.5p1/openbsd-compat/explicit_bzero.c openssh-7.5p1+x509-10.2/openbsd-compat/explicit_bzero.c
--- openssh-7.5p1/openbsd-compat/explicit_bzero.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/explicit_bzero.c	2017-05-20 21:07:01.000000000 +0300
@@ -25,6 +25,7 @@
 
 #else /* HAVE_MEMSET_S */
 
+#if 0
 /*
  * Indirect bzero through a volatile pointer to hopefully avoid
  * dead-store optimisation eliminating the call.
@@ -47,6 +48,22 @@
 
 	ssh_bzero(p, n);
 }
+#else
+/*
+ * Android does not define bzero and declare a macro that
+ * use builtin.
+ * Note that SSH build disable builtin functions!
+ * Function memset is more portable!
+ */
+typedef void *(*memset_t)(void *,int,size_t);
+static volatile memset_t ssh_memset = memset;
+
+void
+explicit_bzero(void *p, size_t n)
+{
+	ssh_memset(p, 0, n);
+}
+#endif
 
 #endif /* HAVE_MEMSET_S */
 
diff -ruN openssh-7.5p1/openbsd-compat/fmt_scaled.c openssh-7.5p1+x509-10.2/openbsd-compat/fmt_scaled.c
--- openssh-7.5p1/openbsd-compat/fmt_scaled.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/fmt_scaled.c	2017-05-20 21:07:01.000000000 +0300
@@ -49,6 +49,17 @@
 #include <ctype.h>
 #include <limits.h>
 
+/* mixed declaration => force local_llabs
+ * For insnace on Android
+ * platform-9 -> static __inline__ long long => not found by configure
+ * platform-21 -> extern long long
+ * So to be ABI compatible lest use local
+*/
+static inline long long local_llabs(long long ll) {
+    return (ll < 0LL) ? -ll : ll;
+}
+#define llabs local_llabs
+
 typedef enum {
 	NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
 } unit_type;
diff -ruN openssh-7.5p1/openbsd-compat/Makefile.in openssh-7.5p1+x509-10.2/openbsd-compat/Makefile.in
--- openssh-7.5p1/openbsd-compat/Makefile.in	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/Makefile.in	2017-05-20 21:07:01.000000000 +0300
@@ -1,15 +1,15 @@
 # $Id: Makefile.in,v 1.56 2014/09/30 23:43:08 djm Exp $
 
-sysconfdir=@sysconfdir@
-piddir=@piddir@
+prefix=@prefix@
 srcdir=@srcdir@
 top_srcdir=@top_srcdir@
 
 VPATH=@srcdir@
+FIPSLD_CC=@FIPSLD_CC@
 CC=@CC@
 LD=@LD@
 CFLAGS=@CFLAGS@
-CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
+CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ -D_PATH_PREFIX=\"$(prefix)\"
 LIBS=@LIBS@
 AR=@AR@
 RANLIB=@RANLIB@
@@ -18,9 +18,9 @@
 
 OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
 
-COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
+COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o xmd5crypt.o kludge-fd_set.o
 
-PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
+PORTS=port-aix.o port-android.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
 
 .c.o:
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
@@ -40,3 +40,8 @@
 
 distclean: clean
 	rm -f Makefile *~
+
+# Usefull only if build is in source tree.
+# Outside source tree (VPATH build) result is not correct.
+depend:
+	makedepend -- $(CPPFLAGS) $(CFLAGS) -- $(srcdir)/*.c
diff -ruN openssh-7.5p1/openbsd-compat/openbsd-compat.h openssh-7.5p1+x509-10.2/openbsd-compat/openbsd-compat.h
--- openssh-7.5p1/openbsd-compat/openbsd-compat.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/openbsd-compat.h	2017-05-20 21:07:00.000000000 +0300
@@ -2,6 +2,7 @@
  * Copyright (c) 1999-2003 Damien Miller.  All rights reserved.
  * Copyright (c) 2003 Ben Lindstrom. All rights reserved.
  * Copyright (c) 2002 Tim Rice.  All rights reserved.
+ * Copyright (c) 2013-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -179,20 +180,22 @@
 int getpeereid(int , uid_t *, gid_t *);
 #endif
 
-#ifdef HAVE_ARC4RANDOM
-# ifndef HAVE_ARC4RANDOM_STIR
-#  define arc4random_stir()
-# endif
-#else
+#if !HAVE_DECL_ARC4RANDOM
 unsigned int arc4random(void);
 void arc4random_stir(void);
-#endif /* !HAVE_ARC4RANDOM */
+#endif
 
-#ifndef HAVE_ARC4RANDOM_BUF
+#if !HAVE_DECL_ARC4RANDOM_BUF
 void arc4random_buf(void *, size_t);
 #endif
 
-#ifndef HAVE_ARC4RANDOM_UNIFORM
+#if !HAVE_DECL_ARC4RANDOM_UNIFORM
+u_int32_t arc4random_uniform(u_int32_t);
+#endif
+
+#ifdef __ANDROID__
+/* defined but not declared */
+void arc4random_buf(void *, size_t);
 u_int32_t arc4random_uniform(u_int32_t);
 #endif
 
@@ -225,10 +228,13 @@
 long long strtonum(const char *, long long, long long, const char **);
 #endif
 
+#if 0
+/* on Android function mblen is declared but not defined ! */
 /* multibyte character support */
 #ifndef HAVE_MBLEN
 # define mblen(x, y)	(1)
 #endif
+#endif
 
 #ifndef HAVE_WCWIDTH
 # define wcwidth(x)	(((x) >= 0x20 && (x) <= 0x7e) ? 1 : -1)
@@ -307,6 +313,7 @@
 #include "bsd-cygwin_util.h"
 
 #include "port-aix.h"
+#include "port-android.h"
 #include "port-irix.h"
 #include "port-linux.h"
 #include "port-solaris.h"
diff -ruN openssh-7.5p1/openbsd-compat/openssl-compat.c openssh-7.5p1+x509-10.2/openbsd-compat/openssl-compat.c
--- openssh-7.5p1/openbsd-compat/openssl-compat.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/openssl-compat.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
+ * Copyright (c) 2011-2017 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,6 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS
 #include "includes.h"
 
 #ifdef WITH_OPENSSL
@@ -26,11 +26,68 @@
 # include <openssl/engine.h>
 # include <openssl/conf.h>
 #endif
+#include <openssl/rand.h>
 
 #include "log.h"
 
 #include "openssl-compat.h"
 
+#ifndef HAVE_BN_IS_PRIME_EX
+int
+BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
+{
+	if (cb != NULL)
+		fatal("%s: callback args not supported", __func__);
+	return BN_is_prime(p, nchecks, NULL, ctx, NULL);
+}
+#endif
+
+#ifndef HAVE_RSA_GENERATE_KEY_EX
+int
+RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *bn_e, void *cb)
+{
+	RSA *new_rsa, tmp_rsa;
+	unsigned long e;
+
+	if (cb != NULL)
+		fatal("%s: callback args not supported", __func__);
+	e = BN_get_word(bn_e);
+	if (e == 0xffffffffL)
+		fatal("%s: value of e too large", __func__);
+	new_rsa = RSA_generate_key(bits, e, NULL, NULL);
+	if (new_rsa == NULL)
+		return 0;
+	/* swap rsa/new_rsa then free new_rsa */
+	tmp_rsa = *rsa;
+	*rsa = *new_rsa;
+	*new_rsa = tmp_rsa;
+	RSA_free(new_rsa);
+	return 1;
+}
+#endif
+
+#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
+int
+DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed,
+    int seed_len, int *counter_ret, unsigned long *h_ret, void *cb)
+{
+	DSA *new_dsa, tmp_dsa;
+
+	if (cb != NULL)
+		fatal("%s: callback args not supported", __func__);
+	new_dsa = DSA_generate_parameters(bits, (unsigned char *)seed, seed_len,
+	    counter_ret, h_ret, NULL, NULL);
+	if (new_dsa == NULL)
+		return 0;
+	/* swap dsa/new_dsa then free new_dsa */
+	tmp_dsa = *dsa;
+	*dsa = *new_dsa;
+	*new_dsa = tmp_dsa;
+	DSA_free(new_dsa);
+	return 1;
+}
+#endif
+
 /*
  * OpenSSL version numbers: MNNFFPPS: major minor fix patch status
  * We match major, minor, fix and status (not patch) for <1.0.0.
@@ -66,17 +123,128 @@
 	return 0;
 }
 
-#ifdef	USE_OPENSSL_ENGINE
+
+int
+ssh_FIPS_mode(int onoff)
+{
+#ifdef OPENSSL_FIPS
+	int mode = FIPS_mode();
+
+	if (onoff && mode)
+		return(1);
+
+	if (!onoff && !mode)
+		return(1);
+
+	if (!FIPS_mode_set(onoff)) {
+		char ebuf[512];
+
+		ERR_load_crypto_strings();
+		fatal("FIPS_mode_set(%s) failed: %s",
+		      (onoff ? "on" : "off"),
+		      openssl_errormsg(ebuf, sizeof(ebuf)));
+	}
+
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+	if(!onoff)
+		RAND_set_rand_method(NULL);
+#endif
+
+	return(1);
+
+#else	/* ndef OPENSSL_FIPS */
+	(void) onoff;
+	return(0);
+#endif
+}
+
+
 void
-ssh_OpenSSL_add_all_algorithms(void)
+ssh_OpenSSL_startup()
 {
+#ifdef HAVE_OPENSSL_INIT_CRYPTO
+	/* NOTE FIPS is not available for OpenSSL 1.1 */
+	OPENSSL_init_crypto(
+	#ifdef USE_OPENSSL_ENGINE
+	    OPENSSL_INIT_ENGINE_ALL_BUILTIN |
+	#endif
+	    OPENSSL_INIT_ADD_ALL_CIPHERS |
+	    OPENSSL_INIT_ADD_ALL_DIGESTS |
+	    OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 	OpenSSL_add_all_algorithms();
 
+#ifdef OPENSSL_FIPS
+	if (getenv("OPENSSL_FIPS")) {
+		(void) ssh_FIPS_mode(1);
+	}
+#endif
+
+#ifdef	USE_OPENSSL_ENGINE
+#if 0
+/* Next two calls are useless if link is with dynamic engine. Also
+ * they will initialize static engines and later OPENSSL_config load
+ * engines again. This double initialization could crash application,
+ * usually in application shutdown code (engine cleanup) even without
+ * use of engines.
+ */
 	/* Enable use of crypto hardware */
 	ENGINE_load_builtin_engines();
 	ENGINE_register_all_complete();
+#endif
+
+	/* OPENSSL_config will load buildin engines and engines
+	 * specified in configuration file, i.e. method call
+	 * ENGINE_load_builtin_engines. Latter is only for
+	 * dynamic engines.
+	 */
 	OPENSSL_config(NULL);
+
+	/* Starting from openssl 1.0.1 ENGINE_load_builtin_engines
+	 * call ENGINE_register_all_complete internally.
+	 * Application should request registration for compatibility
+	 * with all previous versions and it is save to request again.
+	 * Note that dynamic_path in openssl engine configuration
+	 * may register engine as default. If engine methods are not
+	 * usable as default methods use of non-engine keys may trigger
+	 * error in sign/verify operation.
+	 */
+	ENGINE_register_all_complete();
+#endif /*def USE_OPENSSL_ENGINE*/
+#endif /*def HAVE_OPENSSL_INIT_CRYPTO*/
 }
+
+
+void
+ssh_OpenSSL_shuthdown() {
+#ifdef HAVE_OPENSSL_INIT_CRYPTO
+	OPENSSL_cleanup();
+#else
+	/* clean configuraton before engine:
+	 * - it should clean internaly initialized engines */
+	CONF_modules_unload(1);
+	/* engine may provide rand implementation:
+	 * - lets clean rand before engines */
+	RAND_cleanup();
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	/* engine may use extra data so clean it after engines */
+	CRYPTO_cleanup_all_ex_data();
+	EVP_cleanup();
+	OBJ_cleanup();
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
+	ERR_remove_thread_state(NULL);
+#else
+	ERR_remove_state(0);
 #endif
+	ERR_free_strings();
+#endif /*def HAVE_OPENSSL_INIT_CRYPTO*/
+}
+
+#else
+
+void ssh_OpenSSL_startup()   {}
+void ssh_OpenSSL_shuthdown() {}
 
 #endif /* WITH_OPENSSL */
diff -ruN openssh-7.5p1/openbsd-compat/openssl-compat.h openssh-7.5p1+x509-10.2/openbsd-compat/openssl-compat.h
--- openssh-7.5p1/openbsd-compat/openssl-compat.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/openssl-compat.h	2017-05-20 21:07:00.000000000 +0300
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
+ * Copyright (c) 2011-2016 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -22,13 +23,31 @@
 
 #include <openssl/opensslv.h>
 #include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
 
 int ssh_compatible_openssl(long, long);
 
-#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL)
-# error OpenSSL 0.9.8f or greater is required
+#if OPENSSL_VERSION_NUMBER <= 0x00906fffL
+# error "OpenSSL 0.9.7 or greater is required"
+#endif
+
+#if OPENSSL_VERSION_NUMBER <= 0x00907fffL
+/* Workaround for bug in some openssl versions before 0.9.8f
+ * We will not use configure check as 0.9.7x define correct
+ * macro or some verdors patch their versions.
+ */
+#undef EVP_CIPHER_CTX_key_length
+#define EVP_CIPHER_CTX_key_length ssh_EVP_CIPHER_CTX_key_length
+
+static inline int
+ssh_EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) {
+	return ctx->key_len;
+}
 #endif
 
 #if OPENSSL_VERSION_NUMBER < 0x10000001L
@@ -75,26 +94,31 @@
 # endif
 #endif
 
-/*
- * We overload some of the OpenSSL crypto functions with ssh_* equivalents
- * to automatically handle OpenSSL engine initialisation.
- *
- * In order for the compat library to call the real functions, it must
- * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and
- * implement the ssh_* equivalents.
- */
-#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS
 
-# ifdef USE_OPENSSL_ENGINE
-#  ifdef OpenSSL_add_all_algorithms
-#   undef OpenSSL_add_all_algorithms
-#  endif
-#  define OpenSSL_add_all_algorithms()  ssh_OpenSSL_add_all_algorithms()
+#ifndef HAVE_BN_IS_NEGATIVE
+# ifndef BN_is_negative
+    /* before OpenSSL 0.9.8 */
+#   define BN_is_negative(a) ((a)->neg != 0)
+#endif
+#endif
+
+# ifndef HAVE_BN_IS_PRIME_EX
+int BN_is_prime_ex(const BIGNUM *, int, BN_CTX *, void *);
 # endif
 
-void ssh_OpenSSL_add_all_algorithms(void);
+#ifndef HAVE_RSA_GENERATE_KEY_EX
+int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *);
+#endif
+
+#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
+int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *,
+    unsigned long *, void *);
+#endif
+
+extern int  ssh_FIPS_mode(int onoff);
 
-#endif	/* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */
+extern void ssh_OpenSSL_startup(void);
+extern void ssh_OpenSSL_shuthdown(void);
 
 #endif /* WITH_OPENSSL */
 #endif /* _OPENSSL_COMPAT_H */
diff -ruN openssh-7.5p1/openbsd-compat/port-android.c openssh-7.5p1+x509-10.2/openbsd-compat/port-android.c
--- openssh-7.5p1/openbsd-compat/port-android.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/port-android.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1,349 @@
+#ifdef __ANDROID__
+/*
+ * Copyright (c) 2016-2017, Roumen Petrov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include <unistd.h>
+
+extern char *ssh_progpath;
+
+
+/* bionic stub replacement
+ *
+ * The  function ttyname() returns a pointer to a pathname on success.
+ * On error, NULL is returned, and errno is set appropriately.
+ */
+char*
+android_ttyname(int fd) {
+	static char buf[PATH_MAX];
+
+	return (android_ttyname_r(fd, buf, sizeof(buf)) == 0)
+		? buf
+		: NULL;
+}
+
+
+/* bionic stub replacement
+ *
+ * The function ttyname_r() returns 0 on success, and an error number
+ * upon error.
+ */
+int
+android_ttyname_r(int fd, char *buf, size_t buflen) {
+	ssize_t k;
+
+	if (buf == NULL) {
+		errno = EINVAL;
+		return errno;
+	}
+	if (buflen < 6) { /* "/dev/" + NUL */
+		errno = ERANGE;
+		return errno;
+	}
+
+	if (!isatty(fd)) {
+		return errno;
+	}
+
+{
+	char proc_fd[PATH_MAX];
+	snprintf(proc_fd, sizeof(proc_fd), "/proc/self/fd/%d", fd);
+	/*NOTE on error content of buf is undefined*/
+	k = readlink(proc_fd, buf, buflen);
+}
+
+	if (k == -1)
+		return errno;
+
+	if ((size_t)k == buflen) {
+		errno = ERANGE;
+		return errno;
+	}
+	buf[k] = '\0';
+	return 0;
+}
+
+
+/* bionic missing
+ *
+ * Function endgrent is declared in grp.h but not defined.
+ */
+void
+endgrent(void) {
+}
+
+/* bionic missing
+ *
+ * Function endpwent is declared in pwd.h but not defined.
+ */
+void
+endpwent(void) {
+}
+
+
+const char*
+relocate_path(const char *pathname, char *pathbuf, size_t pathlen) {
+	size_t len = strlen(_PATH_PREFIX);
+
+	if (pathlen <= len) return pathname;
+
+	if (strncmp(pathname, _PATH_PREFIX, len) == 0) {
+		len = snprintf(pathbuf, pathlen, "%s/..%s", ssh_progpath, pathname + len);
+		if (len <= pathlen)
+			return pathbuf;
+	}
+	return pathname;
+}
+
+
+extern int __real_open(const char *path, int flags, mode_t mode);
+
+int
+__wrap_open(const char *path, int flags, mode_t mode) {
+	int ret;
+
+{	char newpath[PATH_MAX];
+	path = relocate_path(path, newpath, sizeof(newpath));
+	ret = __real_open(path, flags, mode);
+}
+	return ret;
+}
+
+
+extern FILE* __real_fopen(const char *path, const char *mode);
+
+FILE*
+__wrap_fopen(const char *path, const char *mode) {
+	FILE *ret;
+
+{	char newpath[PATH_MAX];
+	path = relocate_path(path, newpath, sizeof(newpath));
+	ret = __real_fopen(path, mode);
+}
+	return ret;
+}
+
+
+/* Fake user for android */
+#include "xmalloc.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <openssl/des.h>
+#undef getpwnam
+#undef getpwuid
+
+
+static struct passwd *fake_passwd = NULL;
+static char *ssh_home = NULL;
+static char *ssh_shell = NULL;
+
+
+static void
+parse_fake_passwd() {
+	char *pw_name;
+	char *pw_passwd;
+	char *pw_uid;
+	char *pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell = NULL;
+
+	int   fd = -1;
+
+{	const char *path = _PATH_PREFIX _PATH_PASSWD;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return;
+}
+
+{	/* parse password line */
+	char buf[1024], *s;
+
+	if (read(fd, buf, sizeof(buf)) <= 0) {
+		close(fd);
+		return;
+	}
+
+	if ((s = strchr(buf, '\r')) != NULL) *s = '\0';
+	if ((s = strchr(buf, '\n')) != NULL) *s = '\0';
+	if ((s = strchr(buf, '\t')) != NULL) *s = '\0';
+	if ((s = strchr(buf, ' ' )) != NULL) *s = '\0';
+
+	s = buf;
+
+	pw_name = s;
+	if (*pw_name == '\0') goto parse_err;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_passwd = ++s;
+	if (*pw_passwd == '\0') goto parse_err;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_uid = ++s;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_gid = ++s;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_gecos= ++s;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_dir = ++s;
+	if (*pw_dir == '\0') goto parse_err;
+	s = strchr(s, ':'); if (s == NULL) goto parse_err;
+	*s = '\0';
+
+	pw_shell = ++s;
+
+parse_err:
+	close(fd);
+}
+
+	if (pw_shell == NULL) return;
+
+{	/* preset password data */
+	char *s;
+
+	s = strdup(pw_name);
+	if (s != NULL)
+		fake_passwd->pw_name = s;
+
+	s = strdup(pw_passwd);
+	if (s != NULL)
+		fake_passwd->pw_passwd = s;
+
+	(void) pw_uid;
+	(void) pw_gid;
+#ifdef __LP64__
+	fake_passwd->pw_gecos = strdup(pw_gecos);
+#else
+	(void) pw_gecos;
+#endif
+
+	if (strcmp(pw_dir, "$HOME") == 0)
+		pw_dir = getenv("HOME");
+	if ((pw_dir != NULL) && (*pw_dir != '\0'))
+		ssh_home = strdup(pw_dir);
+	if (ssh_home != NULL)
+		fake_passwd->pw_dir = ssh_home;
+
+	if (strcmp(pw_shell, "$SHELL") == 0)
+		pw_shell = getenv("SHELL");
+	if ((pw_shell != NULL) && (*pw_shell != '\0'))
+		ssh_shell = strdup(pw_shell);
+	if (ssh_shell != NULL)
+		fake_passwd->pw_shell = ssh_shell;
+}
+}
+
+
+static void
+init_fake_passwd() {
+
+	if (fake_passwd != NULL) return;
+
+{
+	struct passwd* pw;
+	size_t n;
+
+	pw = getpwuid(getuid());
+	if (pw == NULL) return;
+
+	n = sizeof(*fake_passwd);
+	fake_passwd = calloc(1, n);
+	if (fake_passwd == NULL) return;
+
+	memcpy(fake_passwd, pw, n);
+}
+
+	parse_fake_passwd();
+}
+
+
+static struct passwd*
+preset_passwd(struct passwd *pw) {
+	if (pw == NULL) return NULL;
+
+#ifdef __LP64__
+	/* usually not initialized but code expect string value */
+	if (pw->pw_gecos == NULL)
+		pw->pw_gecos = fake_passwd->pw_gecos;
+#endif
+
+	if (ssh_home != NULL)
+		pw->pw_dir = ssh_home;
+
+	if (ssh_shell != NULL)
+		pw->pw_shell = ssh_shell;
+
+	return pw;
+}
+
+
+/* bionic replacement */
+struct passwd*
+android_getpwnam(const char* name) {
+	struct passwd* pw;
+
+	init_fake_passwd();
+
+	if ((fake_passwd != NULL) && (strcmp(name, fake_passwd->pw_name) == 0))
+		return fake_passwd;
+
+	pw = getpwnam(name);
+
+	return preset_passwd(pw);
+}
+
+
+/* bionic replacement */
+struct passwd*
+android_getpwuid(uid_t uid) {
+	struct passwd* pw;
+
+	init_fake_passwd();
+
+	if ((fake_passwd != NULL) && (uid == fake_passwd->pw_uid))
+		return fake_passwd;
+
+	pw = getpwuid(uid);
+
+	return preset_passwd(pw);
+}
+
+
+#else
+
+static void *empty_translation_unit = &empty_translation_unit;
+
+#endif /*def __ANDROID__*/
diff -ruN openssh-7.5p1/openbsd-compat/port-android.h openssh-7.5p1+x509-10.2/openbsd-compat/port-android.h
--- openssh-7.5p1/openbsd-compat/port-android.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/port-android.h	2017-05-20 21:07:00.000000000 +0300
@@ -0,0 +1,45 @@
+#ifdef __ANDROID__
+/*
+ * Copyright (c) 2016, Roumen Petrov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PORT_ANDROID_H
+
+#define ttyname android_ttyname
+char *android_ttyname(int fd);
+#define ttyname_r android_ttyname_r
+int android_ttyname_r(int fd, char *buf, size_t buflen);
+
+
+#include <pwd.h>
+
+#define getpwnam android_getpwnam
+struct passwd* android_getpwnam(const char*);
+#define getpwuid android_getpwuid
+struct passwd* android_getpwuid(uid_t);
+
+#endif /*ndef PORT_ANDROID_H*/
+#endif /*def __ANDROID__*/
diff -ruN openssh-7.5p1/openbsd-compat/port-tun.c openssh-7.5p1+x509-10.2/openbsd-compat/port-tun.c
--- openssh-7.5p1/openbsd-compat/port-tun.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/port-tun.c	2017-05-20 21:07:01.000000000 +0300
@@ -43,6 +43,7 @@
  *
  * SSH_TUN_LINUX	Use the (newer) Linux tun/tap device
  * SSH_TUN_FREEBSD	Use the FreeBSD tun/tap device
+ * SSH_TUN_DARWIN	Use the Darwin utun device
  * SSH_TUN_COMPAT_AF	Translate the OpenBSD address family
  * SSH_TUN_PREPEND_AF	Prepend/remove the address family
  */
@@ -194,6 +195,65 @@
 }
 #endif /* SSH_TUN_FREEBSD */
 
+#ifdef SSH_TUN_DARWIN
+#include <sys/sys_domain.h>
+#include <sys/kern_control.h>
+#include <net/if_utun.h>
+
+int
+sys_tun_open(int tun, int mode)
+{
+	struct ctl_info info;
+	struct sockaddr_ctl addr;
+	int fd;
+
+	if (tun != SSH_TUNID_ANY && tun > SSH_TUNID_MAX) {
+		debug("%s: invalid tunnel %u", __func__, tun);
+		return (-1);
+	}
+
+	if (mode == SSH_TUNMODE_ETHERNET) {
+		debug("%s: no layer 2 tunnelling support", __func__);
+		return (-1);
+	}
+
+	fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
+	if (fd == -1) {
+		debug("%s: failed to create control socket: %s",
+		    __func__, strerror(errno));
+		return (-1);
+	}
+
+	bzero(&info, sizeof(info));
+	strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
+	if (ioctl(fd, CTLIOCGINFO, &info) == -1) {
+		debug("%s: failed to lookup utun control id: %s",
+		    __func__, strerror(errno));
+		goto failed;
+	}
+
+	bzero(&addr, sizeof(addr));
+	addr.sc_id = info.ctl_id;
+	addr.sc_len = sizeof(addr);
+	addr.sc_family = AF_SYSTEM;
+	addr.ss_sysaddr = AF_SYS_CONTROL;
+	if (tun != SSH_TUNID_ANY)
+		addr.sc_unit = tun + 1;
+
+	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+		debug("%s: failed to connect to utun device: %s",
+		    __func__, strerror(errno));
+		goto failed;
+	}
+
+	return (fd);
+
+ failed:
+	close(fd);
+	return (-1);
+}
+#endif /* SSH_TUN_DARWIN */
+
 /*
  * System-specific channel filters
  */
diff -ruN openssh-7.5p1/openbsd-compat/port-tun.h openssh-7.5p1+x509-10.2/openbsd-compat/port-tun.h
--- openssh-7.5p1/openbsd-compat/port-tun.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/port-tun.h	2017-05-20 21:07:00.000000000 +0300
@@ -19,7 +19,8 @@
 
 struct Channel;
 
-#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
+#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) || \
+    defined(SSH_TUN_DARWIN)
 # define CUSTOM_SYS_TUN_OPEN
 int	  sys_tun_open(int, int);
 #endif
diff -ruN openssh-7.5p1/openbsd-compat/xcrypt.c openssh-7.5p1+x509-10.2/openbsd-compat/xcrypt.c
--- openssh-7.5p1/openbsd-compat/xcrypt.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/xcrypt.c	2017-05-20 21:07:01.000000000 +0300
@@ -63,6 +63,13 @@
 #  define crypt DES_crypt
 # endif
 
+#ifndef HAVE_SETPWENT
+/*FIXME: detect by configure */
+#  define HAVE_SETPWENT 1
+#endif
+#ifdef __ANDROID__
+# undef HAVE_SETPWENT
+#endif
 /*
  * Pick an appropriate password encryption type and salt for the running
  * system by searching through accounts until we find one that has a valid
@@ -80,6 +87,7 @@
 	if (salt[0] != '\0')
 		return salt;
 	strlcpy(salt, "xx", sizeof(salt));
+#ifdef HAVE_SETPWENT
 	setpwent();
 	while ((pw = getpwent()) != NULL) {
 		passwd = shadow_pw(pw);
@@ -92,6 +100,7 @@
 	}
  out:
 	endpwent();
+#endif /*def HAVE_SETPWENT*/
 	return salt;
 }
 
@@ -120,6 +129,8 @@
 # elif defined(HAVE_SECUREWARE)
 	crypted = bigcrypt(password, salt);
 # else
+	/* if password is NULL (on Android ...) */
+	if (password == NULL) return NULL;
 	crypted = crypt(password, salt);
 # endif
 
diff -ruN openssh-7.5p1/openbsd-compat/xmd5crypt.c openssh-7.5p1+x509-10.2/openbsd-compat/xmd5crypt.c
--- openssh-7.5p1/openbsd-compat/xmd5crypt.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/openbsd-compat/xmd5crypt.c	2017-05-20 21:07:01.000000000 +0300
@@ -0,0 +1 @@
+#include "../md5crypt.c"
diff -ruN openssh-7.5p1/packet.c openssh-7.5p1+x509-10.2/packet.c
--- openssh-7.5p1/packet.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/packet.c	2017-05-20 21:07:01.000000000 +0300
@@ -624,6 +624,11 @@
 	ssh->remote_ipaddr = NULL;
 	free(ssh->state);
 	ssh->state = NULL;
+
+	if (ssh->kex != NULL) {
+		kex_free(ssh->kex);
+		ssh->kex = NULL;
+	}
 }
 
 /* Sets remote side protocol flags. */
@@ -2490,11 +2495,13 @@
 kex_to_blob(struct sshbuf *m, struct kex *kex)
 {
 	int r;
+	const char *s = kex->hostkey_alg;
 
 	if ((r = sshbuf_put_string(m, kex->session_id,
 	    kex->session_id_len)) != 0 ||
 	    (r = sshbuf_put_u32(m, kex->we_need)) != 0 ||
-	    (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||
+	    /* TODO why to send hostkey_foo as is not set? */
+	    (r = sshbuf_put_cstring(m, (s ? s : ""))) != 0 ||
 	    (r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
 	    (r = sshbuf_put_stringb(m, kex->my)) != 0 ||
 	    (r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
@@ -2694,7 +2701,7 @@
 	}
 	if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 ||
 	    (r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||
-	    (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||
+	    (r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 ||
 	    (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
 	    (r = sshbuf_get_stringb(m, kex->my)) != 0 ||
 	    (r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
diff -ruN openssh-7.5p1/pathnames.h openssh-7.5p1+x509-10.2/pathnames.h
--- openssh-7.5p1/pathnames.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/pathnames.h	2017-05-20 21:07:00.000000000 +0300
@@ -10,6 +10,29 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X.509 certificates support,
+ * Copyright (c) 2002 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #define ETCDIR				"/etc"
@@ -86,6 +109,14 @@
  */
 #define _PATH_SSH_USER_CONFFILE		_PATH_SSH_USER_DIR "/config"
 
+#ifdef USE_OPENSSL_ENGINE
+/*
+ * Engine configuration file in user's home directory. Same rules as
+ * for user config file.
+ */
+#define _PATH_SSH_ENGINE_CONFFILE	".ssh/engine"
+#endif
+
 /*
  * File containing a list of those rsa keys that permit logging in as this
  * user.  This file need not be readable by anyone but the user him/herself,
@@ -170,3 +201,20 @@
 #ifndef ASKPASS_PROGRAM
 #define ASKPASS_PROGRAM         "/usr/lib/ssh/ssh-askpass"
 #endif /* ASKPASS_PROGRAM */
+
+
+#ifndef SSHCADIR
+#define SSHCADIR			SSHDIR "/ca"
+#endif
+
+/* x509 user store */
+#define _PATH_USERCA_CERTIFICATE_FILE	"~/" _PATH_SSH_USER_DIR "/ca-bundle.crt"
+#define _PATH_USERCA_CERTIFICATE_PATH	"~/" _PATH_SSH_USER_DIR "/crt"
+#define _PATH_USERCA_REVOCATION_FILE	"~/" _PATH_SSH_USER_DIR "/ca-bundle.crl"
+#define _PATH_USERCA_REVOCATION_PATH	"~/" _PATH_SSH_USER_DIR "/crl"
+
+/* x509 system store */
+#define _PATH_CA_CERTIFICATE_FILE	SSHCADIR "/ca-bundle.crt"
+#define _PATH_CA_CERTIFICATE_PATH	SSHCADIR "/crt"
+#define _PATH_CA_REVOCATION_FILE	SSHCADIR "/ca-bundle.crl"
+#define _PATH_CA_REVOCATION_PATH	SSHCADIR "/crl"
diff -ruN openssh-7.5p1/readconf.c openssh-7.5p1+x509-10.2/readconf.c
--- openssh-7.5p1/readconf.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/readconf.c	2017-05-20 21:07:01.000000000 +0300
@@ -10,6 +10,29 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
@@ -62,6 +85,7 @@
 #include "readconf.h"
 #include "match.h"
 #include "kex.h"
+#include "ssh-xkalg.h"
 #include "mac.h"
 #include "uidswap.h"
 #include "myproposal.h"
@@ -141,6 +165,21 @@
 
 typedef enum {
 	oBadOption,
+	/* X.509 Standard Options */
+	oHostbasedAlgorithms,
+	oPubkeyAlgorithms,
+	oX509KeyAlgorithm,
+	oAllowedServerCertPurpose,
+	oMandatoryCRL,
+	oCACertificateFile, oCACertificatePath,
+	oCARevocationFile, oCARevocationPath,
+	oCAldapVersion, oCAldapURL,
+	oUserCACertificateFile, oUserCACertificatePath,
+	oUserCARevocationFile, oUserCARevocationPath,
+	oUserCAldapVersion, oUserCAldapURL,
+	oVAType, oVACertificateFile,
+	oVAOCSPResponderURL,
+	/* Standard Options */
 	oHost, oMatch, oInclude,
 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
 	oGatewayPorts, oExitOnForwardFailure,
@@ -218,6 +257,28 @@
 	{ "compressionlevel", oUnsupported },
 #endif
 
+	/* X.509 Standard Options */
+	{ "hostbasedalgorithms", oHostbasedAlgorithms },
+	{ "pubkeyalgorithms", oPubkeyAlgorithms },
+	{ "x509keyalgorithm", oX509KeyAlgorithm },
+	{ "allowedcertpurpose", oAllowedServerCertPurpose },
+	{ "mandatorycrl", oMandatoryCRL },
+	{ "cacertificatefile", oCACertificateFile },
+	{ "cacertificatepath", oCACertificatePath },
+	{ "carevocationfile", oCARevocationFile },
+	{ "carevocationpath", oCARevocationPath },
+	{ "caldapversion", oCAldapVersion },
+	{ "caldapurl", oCAldapURL },
+	{ "usercacertificatefile", oUserCACertificateFile },
+	{ "usercacertificatepath", oUserCACertificatePath },
+	{ "usercarevocationfile", oUserCARevocationFile },
+	{ "usercarevocationpath", oUserCARevocationPath },
+	{ "usercaldapversion", oCAldapVersion },
+	{ "usercaldapurl", oCAldapURL },
+	{ "vatype", oVAType },
+	{ "vacertificatefile", oVACertificateFile },
+	{ "vaocspresponderurl", oVAOCSPResponderURL },
+	/* Standard Options */
 	{ "forwardagent", oForwardAgent },
 	{ "forwardx11", oForwardX11 },
 	{ "forwardx11trusted", oForwardX11Trusted },
@@ -874,6 +935,160 @@
 		debug("%s line %d: Ignored unknown option \"%s\"",
 		    filename, linenum, keyword);
 		return 0;
+	/* X.509 Standard Options */
+	case oHostbasedKeyTypes:	/* for compatibility */
+	case oHostbasedAlgorithms:
+		charptr = (char**)&options->hostbased_algorithms;
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+		/* cannot validate here - depend from X509KeyAlgorithm */
+		if (*activep && *charptr == NULL)
+			*charptr = xstrdup(arg);
+		break;
+
+	case oPubkeyAcceptedKeyTypes:	/* for compatibility */
+	case oPubkeyAlgorithms:
+		charptr = (char**)&options->pubkey_algorithms;
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+		/* cannot validate here - depend from X509KeyAlgorithm */
+		if (*activep && *charptr == NULL)
+			*charptr = xstrdup(arg);
+		break;
+
+	case oX509KeyAlgorithm:
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+
+		if (*activep) {
+			if (ssh_add_x509key_alg(arg) < 0) {
+				fatal("%.200s line %d: Bad X.509 key algorithm '%.200s'.",
+				    filename, linenum, arg);
+			}
+		}
+		break;
+
+	case oAllowedServerCertPurpose:
+		intptr = &options->x509flags->allowedcertpurpose;
+		arg = strdelim(&s);
+		if (arg && *arg) {
+			if (strcasecmp(arg, "skip") == 0) goto skip_purpose;
+
+			/* convert string to OpenSSL index */
+			value = ssh_get_x509purpose_s (0, arg);
+			if (value < 0)
+				fatal("%.200s line %d: Bad certificate purpose '%.30s'.",
+				    filename, linenum, arg);
+
+			if (*activep && *intptr == -1)
+				*intptr = value;
+		} else {
+skip_purpose:
+			if (*activep && *intptr == -1) {
+				*intptr = -2;
+				verbose("%.200s line %d: option is set to don`t check certificate purpose.",
+				    filename, linenum);
+			}
+		}
+		break;
+
+	case oMandatoryCRL:
+		intptr = &options->x509flags->mandatory_crl;
+		goto parse_flag;
+
+	case oCACertificateFile:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.certificate_file;
+		goto parse_string;
+
+	case oCACertificatePath:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.certificate_path;
+		goto parse_string;
+
+	case oCARevocationFile:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.revocation_file;
+		goto parse_string;
+
+	case oCARevocationPath:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.revocation_path;
+		goto parse_string;
+
+	case oUserCACertificateFile:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.certificate_file;
+		goto parse_string;
+
+	case oUserCACertificatePath:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.certificate_path;
+		goto parse_string;
+
+	case oUserCARevocationFile:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.revocation_file;
+		goto parse_string;
+
+	case oUserCARevocationPath:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.revocation_path;
+		goto parse_string;
+
+#ifdef LDAP_ENABLED
+	case oCAldapVersion:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.ldap_ver;
+		goto parse_string;
+
+	case oCAldapURL:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.ldap_url;
+		goto parse_string;
+
+	case oUserCAldapVersion:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.ldap_ver;
+		goto parse_string;
+
+	case oUserCAldapURL:
+		/*X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->userca.ldap_url;
+		goto parse_string;
+#endif /*def LDAP_ENABLED*/
+
+#ifdef SSH_OCSP_ENABLED
+	case oVAType:
+		intptr = &options->va.type;
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+
+		value = ssh_get_vatype_s(arg);
+		if (value < 0) {
+			fatal("%.200s line %d: Bad OCSP responder type '%.30s'.",
+			    filename, linenum, arg);
+		}
+
+		if (*activep && *intptr == -1)
+			*intptr = value;
+		break;
+
+	case oVACertificateFile:
+		/* VAOptions prefered type is 'const char*' */
+		charptr = (char**)&options->va.certificate_file;
+		goto parse_string;
+
+	case oVAOCSPResponderURL:
+		/* VAOptions prefered type is 'const char*' */
+		charptr = (char**)&options->va.responder_url;
+		goto parse_string;
+#endif /*def SSH_OCSP_ENABLED*/
+	/* Other Standard Options */
 	case oConnectTimeout:
 		intptr = &options->connection_timeout;
 parse_time:
@@ -1232,10 +1447,12 @@
 		if (!arg || *arg == '\0')
 			fatal("%.200s line %d: Missing argument.",
 			    filename, linenum);
+#if 0		/* cannot validate here - depend from X509KeyAlgorithm */
 		if (*arg != '-' &&
 		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
 			fatal("%s line %d: Bad key types '%s'.",
 				filename, linenum, arg ? arg : "<NONE>");
+#endif
 		if (*activep && *charptr == NULL)
 			*charptr = xstrdup(arg);
 		break;
@@ -1297,6 +1514,15 @@
 				add_local_forward(options, &fwd);
 			else if (opcode == oRemoteForward)
 				add_remote_forward(options, &fwd);
+		} else {
+			free(fwd.connect_host);
+			fwd.connect_host = NULL;
+			free(fwd.connect_path);
+			fwd.connect_path = NULL;
+			free(fwd.listen_host);
+			fwd.listen_host = NULL;
+			free(fwd.listen_path);
+			fwd.listen_path = NULL;
 		}
 		break;
 
@@ -1659,13 +1885,17 @@
 		multistate_ptr = multistate_yesnoask;
 		goto parse_multistate;
 
+#if 0 /* already defined as oHostbasedAlgorithms */
 	case oHostbasedKeyTypes:
 		charptr = &options->hostbased_key_types;
 		goto parse_keytypes;
+#endif
 
+#if 0 /* already defined as oPubkeyAlgorithms */
 	case oPubkeyAcceptedKeyTypes:
 		charptr = &options->pubkey_key_types;
 		goto parse_keytypes;
+#endif
 
 	case oAddKeysToAgent:
 		intptr = &options->add_keys_to_agent;
@@ -1681,6 +1911,17 @@
 		    filename, linenum, keyword);
 		return 0;
 
+#ifndef LDAP_ENABLED
+	case oCAldapVersion:
+	case oCAldapURL:
+	case oUserCAldapVersion:
+	case oUserCAldapURL:
+#endif /*ndef LDAP_ENABLED*/
+#ifndef SSH_OCSP_ENABLED
+	case oVAType:
+	case oVACertificateFile:
+	case oVAOCSPResponderURL:
+#endif /*ndef SSH_OCSP_ENABLED*/
 	case oUnsupported:
 		error("%s line %d: Unsupported option \"%s\"",
 		    filename, linenum, keyword);
@@ -1781,6 +2022,21 @@
 initialize_options(Options * options)
 {
 	memset(options, 'X', sizeof(*options));
+	/* X.509 Standard Options */
+	options->hostbased_algorithms = NULL;
+	options->pubkey_algorithms = NULL;
+	/* Supported X.509 key algorithms and signatures
+	   are defined is external source. */
+	options->x509flags = &ssh_x509flags;
+	ssh_x509flags_initialize(options->x509flags, 0);
+	X509StoreOptions_init(&options->ca);
+	X509StoreOptions_init(&options->userca);
+#ifdef SSH_OCSP_ENABLED
+	options->va.type = -1;
+	options->va.certificate_file = NULL;
+	options->va.responder_url = NULL;
+#endif /*def SSH_OCSP_ENABLED*/
+	/* Standard Options */
 	options->forward_agent = -1;
 	options->forward_x11 = -1;
 	options->forward_x11_trusted = -1;
@@ -1976,6 +2232,15 @@
 	if (options->cipher == -1)
 		options->cipher = SSH_CIPHER_NOT_SET;
 	/* options->hostkeyalgorithms, default set in myproposals.h */
+	/* HostKeyAlgorithms depend from X509KeyAlgorithm options */
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		if (options->ciphers == NULL)
+			options->ciphers = only_fips_valid_ciphers(KEX_CLIENT_ENCRYPT);
+		if (options->macs == NULL)
+			options->macs = only_fips_valid_macs(KEX_CLIENT_MAC);
+	}
+#endif
 	if (options->protocol == SSH_PROTO_UNKNOWN)
 		options->protocol = SSH_PROTO_2;
 	if (options->add_keys_to_agent == -1)
@@ -2068,11 +2333,7 @@
 		options->update_hostkeys = 0;
 	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
 	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
-	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
-	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
-	    &options->hostbased_key_types) != 0 ||
-	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
-	    &options->pubkey_key_types) != 0)
+	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0)
 		fatal("%s: kex_assemble_names failed", __func__);
 
 #define CLEAR_ON_NONE(v) \
@@ -2091,6 +2352,57 @@
 	/* options->hostname will be set in the main program if appropriate */
 	/* options->host_key_alias should not be set by default */
 	/* options->preferred_authentications will be set in ssh */
+
+	/* options->hostbased_algorithms */
+	/* options->pubkey_algorithms */
+	fill_default_xkalg();
+	ssh_x509flags_defaults(options->x509flags);
+	X509StoreOptions_system_defaults(&options->ca);
+
+	{
+		extern uid_t original_real_uid;
+		X509StoreOptions_user_defaults(&options->userca, original_real_uid);
+	}
+
+	(void)ssh_x509store_addlocations(&options->userca);
+	(void)ssh_x509store_addlocations(&options->ca);
+#ifdef SSH_OCSP_ENABLED
+	if (options->va.type == -1)
+		options->va.type = ssh_get_default_vatype();
+	ssh_set_validator(&options->va);
+#endif /*def SSH_OCSP_ENABLED*/
+
+	if (options->hostkeyalgorithms != NULL) {
+		char *alg = options->hostkeyalgorithms;
+		if (*alg == '+') alg++;
+		if (!sshkey_names_valid2(alg, 1))
+			fatal("Bad protocol 2 hostkey algorithms '%s'.",
+			    options->hostkeyalgorithms);
+	}
+{	/* see use of hostkeyalgorithms in sshconnect2.c */
+	char *p = default_publickey_algorithms();
+
+	if (kex_assemble_names(p, &options->hostkeyalgorithms) != 0)
+		fatal("%s: kex_assemble_names failed", __func__);
+
+	free(p);
+}
+
+	if (options->hostbased_algorithms != NULL) {
+		if (!sshkey_names_valid2(options->hostbased_algorithms, 1))
+			fatal("Bad protocol 2 hostbased key algorithms '%s'.",
+			    options->hostbased_algorithms);
+	} else
+		options->hostbased_algorithms = xstrdup("*");
+	options->hostbased_key_types = xstrdup(options->hostbased_algorithms); /* for compatibility */
+
+	if (options->pubkey_algorithms != NULL) {
+		if (!sshkey_names_valid2(options->pubkey_algorithms, 1))
+			fatal("Bad protocol 2 public key algorithms '%s'.",
+			    options->pubkey_algorithms);
+	} else
+		options->pubkey_algorithms = xstrdup("*");
+	options->pubkey_key_types = xstrdup(options->pubkey_algorithms); /* for compatibility */
 }
 
 struct fwdarg {
@@ -2302,6 +2614,50 @@
 	return (0);
 }
 
+#ifdef USE_OPENSSL_ENGINE
+/*
+ * Reads the endgine config file and execute commands accordingly.
+ * If the file does not exist, this returns 0.
+ */
+int/*bool*/
+process_engconfig_file(const char *filename) {
+	FILE *f;
+	char line[1024];
+	int linenum;
+	int flag = 1;
+
+	f = fopen(filename, "r");
+	if (f == NULL)
+		return(0);
+
+	{/*always check permitions of user engine file*/
+		struct stat sb;
+
+		if (fstat(fileno(f), &sb) == -1)
+			fatal("fstat %s: %s", filename, strerror(errno));
+		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
+		    (sb.st_mode & 022) != 0))
+			fatal("Bad owner or permissions on %s", filename);
+	}
+
+	debug("Reading engines configuration options %.200s", filename);
+
+	linenum = 0;
+	while (fgets(line, sizeof(line), f)) {
+		linenum++;
+		flag = process_engconfig_line(line, filename, linenum);
+		if (!flag)
+			break;
+	}
+
+	fclose(f);
+	if (!flag)
+		fatal("%s: terminating, bad engine option on line %d",
+		    filename, linenum);
+	return(flag);
+}
+#endif /*def USE_OPENSSL_ENGINE*/
+
 int
 parse_jump(const char *s, Options *o, int active)
 {
@@ -2369,6 +2725,10 @@
 	if (val == -1)
 		return "unset";
 	switch (code) {
+#ifdef SSH_OCSP_ENABLED
+	case oVAType:
+		return ssh_get_vatype_i(val);
+#endif
 	case oAddressFamily:
 		return fmt_multistate_int(val, multistate_addressfamily);
 	case oVerifyHostKeyDNS:
@@ -2503,15 +2863,33 @@
 	int i;
 	char buf[8];
 
-	/* This is normally prepared in ssh_kex2 */
-	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
-		fatal("%s: kex_assemble_names failed", __func__);
-
 	/* Most interesting options first: user, host, port */
 	dump_cfg_string(oUser, o->user);
 	dump_cfg_string(oHostName, host);
 	dump_cfg_int(oPort, o->port);
 
+	/* X.509 options */
+	dump_cfg_string(oHostbasedAlgorithms, o->hostbased_algorithms);
+	dump_cfg_string(oPubkeyAlgorithms, o->pubkey_algorithms);
+	/* TODO to implement dump of sX509KeyAlgorithm */
+	/* sshd PKI(X509) flags */
+	/* sshd PKI(X509) system store */
+	dump_cfg_string(oCACertificateFile, o->ca.certificate_file);
+	dump_cfg_string(oCACertificatePath, o->ca.certificate_path);
+	dump_cfg_string(oCARevocationFile , o->ca.revocation_file );
+	dump_cfg_string(oCARevocationPath , o->ca.revocation_path );
+	/* sshd PKI(X509) user store */
+	dump_cfg_string(oUserCACertificateFile, o->userca.certificate_file);
+	dump_cfg_string(oUserCACertificatePath, o->userca.certificate_path);
+	dump_cfg_string(oUserCARevocationFile , o->userca.revocation_file );
+	dump_cfg_string(oUserCARevocationPath , o->userca.revocation_path );
+#ifdef SSH_OCSP_ENABLED
+	/* ssh X.509 extra validation */
+	dump_cfg_fmtint(oVAType		   , o->va.type		   );
+	dump_cfg_string(oVACertificateFile , o->va.certificate_file);
+	dump_cfg_string(oVAOCSPResponderURL, o->va.responder_url   );
+#endif /*def SSH_OCSP_ENABLED*/
+
 	/* Flag options */
 	dump_cfg_fmtint(oAddressFamily, o->address_family);
 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
@@ -2574,7 +2952,6 @@
 	dump_cfg_string(oControlPath, o->control_path);
 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
-	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
 	dump_cfg_string(oIdentityAgent, o->identity_agent);
 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
@@ -2585,7 +2962,6 @@
 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
 #endif
 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
-	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
 	dump_cfg_string(oXAuthLocation, o->xauth_location);
 
diff -ruN openssh-7.5p1/readconf.h openssh-7.5p1+x509-10.2/readconf.h
--- openssh-7.5p1/readconf.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/readconf.h	2017-05-20 21:07:00.000000000 +0300
@@ -11,11 +11,35 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef READCONF_H
 #define READCONF_H
 
+#include "x509store.h"
 /* Data structure for representing option data. */
 
 #define MAX_SEND_ENV		256
@@ -134,6 +158,23 @@
 
 	int	hash_known_hosts;
 
+	char*   hostbased_algorithms;	/* Allowed hostbased algorithms. */
+	char*   pubkey_algorithms;	/* Allowed pubkey algorithms. */
+
+	/* Supported X.509 key algorithms and signatures
+	   are defined is external source. */
+
+	/* ssh PKI(X509) flags */
+	SSH_X509Flags    *x509flags;
+	/* sshd PKI(X509) system store */
+	X509StoreOptions ca;
+	/* sshd PKI(X509) user store */
+	X509StoreOptions userca;
+#ifdef SSH_OCSP_ENABLED
+	/* ssh X.509 extra validation */
+	VAOptions va;
+#endif /*def SSH_OCSP_ENABLED*/
+
 	int	tun_open;	/* tun(4) */
 	int     tun_local;	/* force tun device (optional) */
 	int     tun_remote;	/* force tun device (optional) */
@@ -213,4 +254,9 @@
 void	 add_identity_file(Options *, const char *, const char *, int);
 void	 add_certificate_file(Options *, const char *, int);
 
+#ifdef USE_OPENSSL_ENGINE
+int/*bool*/ process_engconfig_file(const char *filename);
+int/*bool*/ process_engconfig_line(char *line, const char *filename, int linenum);
+#endif
+
 #endif				/* READCONF_H */
diff -ruN openssh-7.5p1/README.dns openssh-7.5p1+x509-10.2/README.dns
--- openssh-7.5p1/README.dns	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/README.dns	2017-05-20 21:07:00.000000000 +0300
@@ -5,6 +5,8 @@
 draft-ietf-secsh-dns-05.txt. The document contains very brief instructions
 on how to use this feature. Configuring DNS is out of the scope of this
 document.
+Note that public host key file may contain X.509 certificate. In this case
+is used CERT RR as is descibed in rfc2538 obsoleted by rfc4398.
 
 
 (1) Server: Generate and publish the DNS RR
@@ -26,6 +28,17 @@
 To publish the fingerprint using the DNS you must add the generated RR
 to your DNS zone file and sign your zone.
 
+To create a DNS CERT resource record containing X.509 host key, use the
+following command:
+
+	ssh-keygen -r hostname -f keyfile
+
+In the example above, ssh-keygen will print a standard CERT RR. Key
+algorithms are described in rfc2535 obsoleted by rfc4034. If algorithm
+is not parsable by name server you should use -g flag and ssh-keygen
+will print the CERT RR in a generic format parsable by most modern
+name server.
+
 
 (2) Client: Enable ssh to verify host keys using DNS
 
@@ -35,13 +48,14 @@
 
     VerifyHostKeyDNS yes
 
-Upon connection the client will try to look up the fingerprint RR
-using DNS. If the fingerprint received from the DNS server matches
+Upon connection the client will try to look up the CERT or SSHFP RR
+using DNS. If the CERT or SSHFP received from the DNS server matches
 the remote host key, the user will be notified.
 
 
 	Jakob Schlyter
 	Wesley Griffin
+	Roumen Petrov
 
 
 $OpenBSD: README.dns,v 1.2 2003/10/14 19:43:23 jakob Exp $
diff -ruN openssh-7.5p1/README.x509v3 openssh-7.5p1+x509-10.2/README.x509v3
--- openssh-7.5p1/README.x509v3	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/README.x509v3	2017-03-23 20:27:54.000000000 +0200
@@ -0,0 +1,639 @@
+                                                          Roumen Petrov
+                                                        Sofia, Bulgaria
+                                                        Tru Mar 23 2017
+
+How to use X.509 certificates with SSH?
+
+
+Identity or hostkey file for protocol version 2 can contain private key
+plus X.509 certificate in PEM format. Note that protocol version 2 keys
+are in PEM format. To use X.509 certificate as identity or hostkey user
+should convert certificate in PEM format and append to file. After this
+with "ssh-keygen -y ..." user must update "pub" file.
+File (identity or hostkey) with X.509 certificate (RSA key):
+-----BEGIN RSA PRIVATE KEY-----
+.....
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+.....
+-----END CERTIFICATE-----
+Note that X.509 certificate has to match private key!
+Also for x509v3-ecdsa-sha2-*, x509v3-ssh-dss and x509v3-ssh-rsa, i.e.
+public key algorithms defined in RFC6187 file may contain extra
+certificates used to build chain of certificates leading to a trusted
+certificate authority.
+
+
+1.) server configuration:
+
+1.1.) .../sshd_config
+
+1.1.1.) AllowedCertPurpose sslclient
+  The intended use of the X.509 client certificate.
+
+1.1.2.) "X509 store".
+  Server use "X509 store" to verify and validate client keys.
+
+1.1.2.1.) CACertificateFile /etc/ssh/ca/ca-bundle.crt
+  This file contain multiple certificates of certificate signers in PEM
+format concatenated together. You can get a copy from openssl, apache,
+KDE, mutt, etc. packages. Original file might is exported from Mozilla
+certificate database.
+
+1.1.2.2.) CACertificatePath /etc/ssh/ca/crt
+  "Hash dir" with certificates of certificate signers. Each certificate
+should be stored in separate file with name [HASH].[NUMBER], where
+[HASH] is certificate hash value and [NUMBER] is an integer starting
+from zero. Hash is result from command like this:
+$ openssl x509 -in certificate_file_name -noout -hash
+
+1.1.2.3.) CARevocationFile /etc/ssh/ca/ca-bundle.crl
+  This file contain multiple "Certificate Revocation List" (CRL) of
+certificate signers in PEM format concatenated together.
+
+1.1.2.4.) CARevocationPath /etc/ssh/ca/crl
+  "Hash dir" with "Certificate Revocation List" (CRL) of certificate
+signers. Each CRL should be stored in separate file with name
+[HASH].r[NUMBER], where [HASH] is CRL hash value and [NUMBER] is an
+integer starting from zero. Hash is result from command like this:
+$ openssl crl -in crl_file_name -noout -hash
+
+1.1.2.5.) CAldapVersion
+  LDAP protocol version. Default depend from LDAP library.
+
+1.1.2.6.) CAldapURL
+  Hostport and dn of LDAP URL. No default value.
+
+1.1.3.) HostKey files...
+  Host key for protocol version 2 may contain private key and X.509
+certificate in PEM format.
+
+1.1.4.) X509KeyAlgorithm
+  The option list multiple "X509 Key Algorithms Formats"
+  supported by server.
+  The format is described in sshd_config(5).
+  The default for certificates with ECDSA keys is:
+    X509KeyAlgorithm x509v3-ecdsa-sha2-nistp256,ssh-sha256,ecdsa-sha2-nistp256
+    X509KeyAlgorithm x509v3-ecdsa-sha2-nistp384,ssh-sha384,ecdsa-sha2-nistp384
+    X509KeyAlgorithm x509v3-ecdsa-sha2-nistp521,ssh-sha512,ecdsa-sha2-nistp521
+  The default for certificates with RSA key is:
+    X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1
+    X509KeyAlgorithm x509v3-sign-rsa,rsa-md5
+    X509KeyAlgorithm x509v3-ssh-rsa,rsa-sha1,ssh-rsa
+  The default for certificates with DSA key is:
+    X509KeyAlgorithm x509v3-sign-dss,dss-asn1
+    X509KeyAlgorithm x509v3-sign-dss,dss-raw
+    X509KeyAlgorithm x509v3-ssh-dss,dss-raw,ssh-dss
+  The first listed format for RSA or DSA key-type is used as default in
+  signing. The server will accept all listed formats.
+
+NOTES:
+- versions before 7.1 use rsa-md5 first. Starting from 7.1 rsa-sha1 is
+  prefered and client and server identify itself as PKIX in comment
+  section of ssh identification string.
+- ECDSA support was added in version 8.0. In version implemenation is
+  corrected to strictly match RFC 6187 description.
+- x509v3-ssh-* support was added in version 10.0.
+
+1.1.5.) VAType none
+  Specifies whether 'Online Certificate Status Protocol' (OCSP) is used
+  to validate client X.509 certificates. Specified value is used only
+  when SSH is build with OCSP support. See sshd_config(5) man page
+  for allowed values and other VA* options.
+
+1.1.6.) KeyAllowSelfIssued no
+  Specifies whether self-issued(self-signed) X.509 certificate can be
+  allowed only by entry in AutorizedKeysFile that contain matching
+  public key or certificate blob.
+
+1.2.) user files on the server
+  Append in USER_HOME/.ssh/authorized_keys a record with following
+format:
+<KEY_TYPE><SPACE><WORDDN><SPACE>{<Distinguished_Name>|CertBlob}
+where:
+KEY_TYPE:=x509v3-sign-rsa|x509v3-sign-dss (case sensitive !)
+WORDDN:={Distinguished Name|
+        Distinguished-Name|
+        Distinguished_Name|
+        DistinguishedName|
+        DN|
+        Subject}<WORDDNSUFF>
+WORDDNSUFF:='='|':'|''
+NOTES:
+- WORDDN is case insensitive !
+
+- <Distinguished Name> is like output from command:
+$ openssl x509 -noout -subject -in A_CERTIFICATE_FILE -nameopt oneline
+
+- <Distinguished Name> can be in RFC2253 format like output from command:
+$ openssl x509 -noout -subject -in A_CERTIFICATE_FILE -nameopt RFC2253
+
+IMPORTANT NOTE (if a distinguished name contain non-ascii characters):
+- for versions 6.+:
+  ALWAIS use "openssl x509" command option -nameopt !
+  The parser don't and won't support output without -nameopt
+- for versions prior 6.0:
+  The program couldn't parse non-latin subject. Use "blob" format (see below).
+
+- Order of items in <Distinguished Name> is not important and separator
+can be symbol "/", "," or mixed. All following subjects are equal:
+a)CN=dsa test certificate,OU=SSH Testers,O=Test Team,ST=World,C=XX
+b)/C=XX/ST=World/O=Test Team/OU=SSH Testers/CN=dsa test certificate
+c)/O=Test Team/OU=SSH Testers/C=XX/ST=World/CN=dsa test certificate
+d)O=Test Team,OU=SSH Testers/C=XX,ST=World/CN=dsa test certificate
+
+- CertBlob is base64 encoded sequence of bytes in only one line.
+
+Shell sample:
+- "Distinguished Name" format (rsa key):
+$ ( printf 'x509v3-sign-rsa ';
+  openssl x509 -noout -subject \
+  -in A_SSH_IDENTITY_FILE \
+  -nameopt oneline \
+  ) >> $HOME/.ssh/authorized_keys
+
+- "blob" format:
+$ cat A_SSH_IDENTITY_FILE.pub \
+  >> $HOME/.ssh/authorized_keys
+
+NOTES:
+- adjust user authorized_keys file ownership - user must have at least
+read access.
+- SecSH X.509 key algorithms
+  for ECDSA keys:
+    "x509v3-ecdsa-sha2-nistp256",
+    "x509v3-ecdsa-sha2-nistp384" or
+    "x509v3-ecdsa-sha2-nistp521"
+  for RSA keys:
+    "x509v3-sign-rsa" or
+    "x509v3-ssh-rsa"
+  for DSA keys:
+  "x509v3-sign-dss" or
+  "x509v3-ssh-dss".
+
+- When SSH is build with "--disable-x509store" YOU CANNOT USE
+"Distinguished Name" format. You shold use ONLY "blob" format.
+  Option "--disable-x509store" was removed in PKIX-SSH verion 9.0.
+
+
+2.) client settings:
+
+2.1.) IdentityFile
+  Depends from client. To use X.509 certificate "SSH id-file" must
+contain both sections - private key and certificate in PEM format:
+Note: Don't forget to update public key file with command:
+$ ssh-keygen -y -f IDENTITY_FILE > IDENTITY_FILE.pub
+Command ssh-add use public key file!
+
+2.2.) global ssh_config, $HOME/.ssh/config or command line
+
+2.2.1.) AllowedCertPurpose sslserver
+  The intended use of the X.509 server certificate.
+
+2.2.2.) "X509 store".
+  Client use "X509 store" to verify and validate server hostkey.
+  See p. 1.1.2.) and check the options:
+- [User]CACertificatePath;
+- [User]CACertificateFile;
+- [User]CARevocationFile;
+- [User]CARevocationPath;
+- [User]CAldapVersion;
+- [User]CAldapURL.
+
+Note: When we use own CA we must import CA certificate[s] to
+"X509 store". More info on:
+  http://roumenpetrov.info/domino_CA/#dca2bundle
+
+2.2.3.) X509KeyAlgorithm
+  The meaning of options is same as in server.
+  See p. 1.1.4.)
+
+2.2.4.) VAType none
+  Specifies whether `Online Certificate Status Protocol' (OCSP) is used
+  to validate server X.509 certificates. Specified value is used only
+  when SSH is build with OCSP support. See ssh_config(5) man page
+  for allowed values and other VA* options.
+
+
+3.) test X.509 certificates.
+
+3.1.) In SSH build dir run "make check" or "make tests".
+  Both commands are equivalent and run regression tests.
+  If you want to test only X.509 certificates you can run
+$ make check-certs
+
+  If certificate test scripts fail might you should setup test
+configuration in the file SSH_SOURCE_PATH/tests/CA/config or
+use some environment variables. Used variables are described
+later in the document.
+
+  Output from "make check-certs" is in color and when is redirected to
+file later we can see content best with command "less -r ...".
+  When script run a test command print star '*' followed by simple
+information about command. When command succeed script print at right
+"done" in GREEN(!) otherwise "failed" in RED(!). After failed command
+script show on next lines in RED(!) response, skip execution of next
+command/script, print message like this:
+....
+Testing client and server with X.509 certificates finished.
+  status:                                                        failed
+....
+  Note that failed is in RED(!) and exit code is NONZERO(!).
+  Some command in a test script must fail. Part of "simple information"
+about command expected to fail is in RED(!). When command fail script
+print "done" (THIS IS CORRECT - COMMAND MUST FAIL) and on next lines
+print in GREEN(!) response. Usually this occur when server reject logon.
+WHEN ALL TESTS SUCCEED output is:
+....
+Testing client and server with X.509 certificates finished.
+  status:                                                        done
+....
+  Note that "done" is in GREEN(!) and exit code is ZERO(!).
+
+3.1.1.) Description of variables in Makefile file:
+  - SHELL
+    Used shell to run tests. Supported shell are bash, ksh, zsh and ash.
+    Test scripts runs on standard unix sh.
+    Example:
+    $ make check-certs SHELL=/bin/zsh
+
+    See below how to specify shell at configure time. This is preffered
+    setup instead to override shell.
+
+3.1.2.) Description of variables in config file:
+
+3.1.2.1.) main variables:
+  - SUDO
+    (environment or config) by default is not set.
+    on some system sshd must be started as root.
+    If necessary configure sudo'ers first and then set variable to sudo
+    for test pusposed.
+  - TMPDIR
+    (environment or config)
+    directory for temporary files. If not set its value is selected
+    from /tmp, /var/tmp or /usr/tmp.
+  - SSH_X509TESTS
+    (environment or config)
+    list with test scripts. A test script is in file with following
+    name: test-<LISTITEM>.sh.inc.
+  - OPENSSL_FIPS
+    (environment)
+    applicable for build with FIPS capable OpenSSL
+    see notes below
+  - SSH_DN_FORCE_UTF8=yes
+    (environment)
+    force UTF8String for distinguished name items from type
+    DirectoryString. Default no
+
+3.1.2.2.) openssl:
+  - OPENSSL
+    (environment or config)
+    path to openssl binary. The default is result from command:
+    `which openssl`.
+  - RSA_DIGEST_LIST
+    (environment or config)
+    list with RSA digests in support of openssl. The default value is
+    build at run time from following digest list "sha1 md5 mdc2 md4
+    rmd160" and contain only supported by openssl.
+
+3.1.2.3.) server section:
+  Read sshd_config.5 manual page for valid values.
+  - SSHD_PORT
+    (environment or config)
+    Specifies the port number that server listens on and client connect
+    to on SSHD_LISTENADDRESS. The default is 20022.
+  - SSHD_LISTENADDRESS
+    (only in config)
+    Same as sshd option "ListenAddress" but without(!) port number.
+    The default is "127.0.0.1".
+  - SSHSERVER_USEPRIVILEGESEPARATION="yes":
+    (only in config)
+    sshd "UsePrivilegeSeparation" option.
+    if necessary set to "no", to disable privilege separation.
+  - SSHSERVER_SYSLOGFACILITY=AUTH
+    (only in config)
+    sshd "SyslogFacility" option.
+  - SSHSERVER_LOGLEVEL=INFO
+    (only in config)
+    sshd 'LogLevel' option.
+
+3.1.2.4.) certificates:
+  - Variables related to test certificates and CA.
+    (only in config)
+
+3.1.2.5.) OCSP responder:
+  Used only when SSH is build with OCSP support!
+  Variables related to OCSP tests.
+  - SSH_VA_BASEPORT
+    (environment or config)
+    Test script run one or more OCSP responders at same once. First
+    responder listen on specified port, second on port plus one and
+    etc. The default is 20080.
+  - SSH_OPENSSL_OCSP_TMOUT=60
+    (config)
+    Wait specified number of seconds sockets opened by OCSP responders
+    to close. After this test script continue with next step.
+    This is work around for missing SO_REUSEADDR socket option in
+    OpenSSL OCSP responder.
+
+3.1.2.5.) LDAP:
+  In use only when SSH is build with LDAP support!
+  - SSH_LDAP_DB
+    (config)
+    Specifies LDAP database type. The default is ldbm.
+  - SSH_LDAP_DC
+    (config)
+    Specifies domain name component in LDAP distinguished name.
+    The default is "dc=example,dc=com".
+  - LDAPD_PORT
+    (environment or config)
+    LDAP daemon run by test script run listens on SSHD_LISTENADDRESS
+    and this port. The default is 20389.
+
+3.1.2.6.) Key&Certificate from "devices":
+  Starting from version 7.0 of X.509 certificate support in ssh client
+  you could use X.509 certificates and respective key stored in
+  external devices. Access is based on OpenSSL engine.
+
+3.1.2.6.1.) OpenSSL NSS engine (cryptographic module)
+  Next sample show how to use client with "OpenSSL NSS engine"
+  ( http://roumenpetrov.info/e_nss/ ).
+
+  First lets list certificates:
+$ openssl engine e_nss -t -post LIST_CERTS:1
+....E_NSS:CMD_LIST_CERT:DB is not initialized:e_nss_cmd.c:77:
+
+  Above failure show that engine is not properly configured.
+
+  You should find NSS db directory and to configure. For instance:
+    $HOME/.mozilla/firefox/<PROFILEHASH>.default
+    $HOME/.mozilla/seamonkey/<PROFILEHASH>.default
+  , where <PROFILEHASH> is created when you create profile
+  for Mozillas application.
+  In case of doubt where is located NSS database just run
+$ find $HOME/.mozilla -name cert8.db
+
+   Next samples will use "test/nssdb" as path to NSS database.
+
+$ openssl engine e_nss -t \
+  -post CONFIG_DIR:test/nssdb \
+  -post LIST_CERTS:1
+(e_nss) NSS engine support (0.2.1)
+     [ available ]
+[Success]: CONFIG_DIR:test/nssdb
+nickname='SSH DSA test certificate(rsa_sha1) - SSH Te.........
+  subject_name='E=email@not.set,CN=SSH DSA test certific..........
+  email_addr  ='email@not.set'
+nickname='SSH RSA test certificate(rsa_sha1) - SSH Te.........
+  subject_name='E=email@not.set,CN=SSH RSA test certific..........
+  email_addr  ='email@not.set'
+[Success]: LIST_CERTS:1
+
+  Next setup ssh_engine:
+$ cat ssh_engine
+Engine e_nss
+          CONFIG_DIR test/nssdb
+  The SSH configuration match above openssl test command.
+  Ref. to manual page ssh_engine(5) for details.
+
+  Lets assume that ssh server is setup to accept you certificate.
+$ ssh -E ssh_engine \
+  -i engine:e_nss:"\"SSH RSA test certificate(rsa_sha1) -....\"" \
+  ....
+  where dots replease part of actual nickname, -E specify engine
+  configuration file instead default one, -i specify IdentityFile in
+  format engine:[ENGNAME]:[KEY_SEARCH_CRITERIA]
+  Note quote of nickname is it contain space characters
+
+3.1.2.7.) FIPS capable openssl:
+  Starting from version 7.1 of X.509 certificate support all programs
+  initialise openssl in FIPS mode if enviroment variable OPENSSL_FIPS
+  is set.
+  Note that you could run X.509 certificate tests in FIPS mode but
+  you must ensure that test certificates are created in fips mode.
+  So first go to $(top_builddir)/tests/CA and run "make clean".
+  Then return to top build directory and run the tests again.
+  OPENSSL_FIPS=1 make check-certs ....
+
+
+3.1.3.) Sample commands to run tests:
+$ OPENSSL=/usr/local/ssl/bin/openssl make check-certs
+$ SSHD_PORT=1122 SSH_X509TESTS="agent blob_auth" make check-certs
+$ RSA_DIGEST_LIST="sha1 md5" make check-certs
+$ make check-certs SHELL=/bin/ksh
+
+When check fail see "Troubleshooting" later in document.
+
+Note: starting from version 7.0 of X.509 certificate support test use
+shell specified during configuration by CONFIG_SHELL=..., i.e.
+$ CONFIG_SHELL=/bin/ksh .../configure ...
+$ ...
+$ make check-certs
+
+3.2.) Current test scripts uses only rsa as server hostkey.
+  To test sshd with X.509 certificate please find in file
+ssh_tests.sh variable TEST_SSHD_HOSTKEY and change it. Sample:
+TEST_SSH_HOSTKEY="$CWD/testhostkey_rsa-rsa_sha1"
+
+
+3.3.) Test SecSH from "Microsoft Windows OS-es".
+  This is not part of document.
+Tips: use created after "make check-certs" files:
+- convert SSH_BUILD_PATH/tests/CA/ca-test/crt/*crt.pem CA
+  certificates from PEM to DER format and import in
+  "Windows keystore";
+- import SSH_BUILD_PATH/tests/CA/testid_*.p12 files in
+  "Windows keystore";
+- setup your client to use certificate[s](see SecSH client manuals).
+DON'T FORGET TO REMOVE entries from "Windows keystore" after test!
+
+
+3.4.) Go to SSH_BUILD_PATH/tests/CA and run command "make clean" to
+remove all client/server and CA files.
+
+
+3.5.) files in SSH_SOURCE_PATH/tests/CA directory:
+config:
+  Configuration file.
+
+env.in:
+  Template file.
+  Currently contain variables related to LDAP directories.
+
+shell.rc:
+  Shell settings.
+
+1-cre_cadb.sh:
+  Create "Test CA" directories and files.
+
+2-cre_key.sh
+  Create ssh keys. Use test configuration, i.e.
+  run ssh-keygen in FIPS mode if requested.
+
+2-cre_cakeys.sh:
+  Create "Test CA" private keys and certificates.
+
+3-cre_certs.sh:
+  Create client/server certificates.
+  This command create files with mask
+  "PATH_TO_KEYFILEn-<SIGNATURE_ALGORITHM>[.<EXTENTION>]"
+  , where <SIGNATURE_ALGORITHM> is in format "rsa_<DIGEST>" or "dsa".
+  DIGEST are form variable "RSA_DIGEST_LIST" specified in "config"
+  file. Files without extention are SSH identity or hostkey files.
+  File with .pub extention contain SSH public key (BLOB format).
+  File with .crt extention contain OpenSSL "text output" for identity
+  files. Files with .p12 extention are for "Microsoft Windows keystore".
+  Note: .p12 = .pfx for Windows.
+
+4-cre_crls.sh:
+  Revoke part of client certificates.
+
+5-cre_ldap.sh
+  Create LDAP ldif files and slapd config.
+
+verify.sh:
+  To check certificates against "Test CA". Note: check only
+  testid_*.crt and testhostkey_*.crt files in current directory.
+
+functions:
+  Common usefull functions.
+
+ssh_tests.sh:
+  Main test script - call other testscripts.
+
+test-blob_auth.sh.inc,
+test-dn_auth_file.sh.inc,
+test-dn_auth_path.sh.inc,
+test-agent.sh.inc,
+test-crl.sh.inc,
+test-self.sh.inc,
+test-alg.sh.inc,
+test-hostalg.sh.inc,
+test-algfmt.sh.inc,
+test-ocsp.sh.inc,
+test-by_ldap.sh.inc:
+  Test shell scripts listed in test execution order.
+  See DESCRIPTION in each file.
+
+Note that hostbased authentication we cannot test without to install.
+Generated testhostkey_* certificates are with sslserver and sslclient
+purposes and you can use them to test manually hostbased authentication.
+
+
+4.) Troubleshooting
+"make check-certs" fails on:
+
+4.1.) "generating a new ... private key for the TEST CA ..."
+Usually this happen on system without /dev/{u}random.
+In file [BUILDDIR]/tests/CA/ca-2.log we can see a message:
+"... PRNG not seeded ...".
+Read again WARNING.RNG from SSH sourcedir and/or
+http://www.openssl.org/support/faq.html
+
+4.1.1.) reconfigure your system and/or openssl
+4.1.2.) or do next
+4.1.2.1.) install SSH :-( otherwise later "make check-certs"
+(ssh-keygen) fail with message:
+"couldn't exec '.../libexec/ssh-rand-helper': ..."
+and second ./ssh-rand-helper fail with message:
+"couldn't read entropy commands file ../ssh_prng_cmds: ..."
+Tip: configure SSH with prefix for example $HOME/test
+
+4.1.2.2.) run:
+ssh-rand-helper
+rm -f $HOME/.rnd
+ln -s .ssh/prng_seed $HOME/.rnd
+Note: ssh-rand-helper was removed in OpenSSH 5.9.
+
+4.1.2.3.) test openssl with command:
+/usr/local/ssl/bin/openssl genrsa -des3 -passout pass:change_it
+Tip: before to create every key with OpenSSL run ssh-rand-helper !
+
+4.1.2.4.) run again "... make check-certs ..."
+
+4.2.) fail on first check: "* rsa_sha1 valid blob              failed"
+- Usually SUDO command is not set. See p. 3.1.2.1.
+- When you build with tcpwrappers your hosts.allow must permit
+connections from localhost, otherwise you can see in failed message
+text like this: "... connection closed by remote host ..."
+
+4.3.) fail on "starting OCSP responder(XXX) on YYY:NNNNN       failed"
+- Ensure sequence of about six free ports and use SSH_VA_BASEPORT
+  to specify first of them.
+- Ensure enough timeout previous running OCSP responders to free
+  ports. Increase value of SSH_OPENSSL_OCSP_TMOUT in test config file.
+
+
+5.) FAQ
+
+Q.) How to convert a certificate from DER to PEM format?
+A.) Run command "openssl x509 ..." with command line options
+-inform/-outform  - you can select one of formats: DER, NET or PEM.
+The default is PEM.
+
+Q.) How to convert pfx to p12 file?
+A.) Just change file extension ;-).
+
+Q.) How to use my p12 file in SSH as identity?
+A.) Run commands:
+$ openssl pkcs12 -in FILE.p12 -clcerts > id_x509
+$ ssh-keygen -f id_x509 -y > id_x509.pub
+  Don't forget to set properly permition on file id_x509, as
+example "chmod 600 id_x509".
+  Note name of identity file can be one of defaults:
+  'id_rsa', 'id_dsa' or 'id_ecdsa'.
+  Configure client.
+
+Q.) How to use p12 file in SSH as hostkey?
+A.) Note that host keys are password less!
+  It is similar to client identity.
+  Remember umask settings.
+  Run as root commands:
+# umask 0077
+# openssl pkcs12 -in FILE.p12 -clcerts > ssh_host_x509
+  Note: you must enter export password!
+# ssh-keygen -p -f ssh_host_x509 -N ''
+  Now hostkey file is password less !
+# ssh-keygen -f ssh_host_x509 -y > ssh_host_x509.pub
+  Restore umask settings.
+  Note name of hostkey file can be one of defaults:
+  'ssh_host_rsa_key', 'ssh_host_dsa_key' or  'ssh_host_ecdsa_key'.
+  Configure server, test configuration with command
+# sshd -t ..../sshd_config
+  and start/restart the server. Don't forget to inform users
+  that hostkey is changed!
+
+Q.) How to import CA certificates and/or CRLs in LDAP?
+A.) You should create a ldif file with LDAP entries that contains
+  binary atributes "cACertificate" and/or "certificateRevocationList"
+  and to specify path to file with certificate or CRL in DER format.
+  Entry should contain objectClass "pkiCA". See definition in core
+  LDAP schema. After this to use command ldapadd or ldapmodify to
+  add/modify LDAP data. See command manual pages.
+
+  As example when you build SSH with ldap queries after
+  regression test see content of file
+    $(top_builddir)/tests/CA/ldap/ca.ldif .
+  This file is created by the script
+    $(srcdir)/tests/CA/5-cre_ldap.sh
+  and entries are added to LDAP with command:
+$ ldapadd -x -w secret -D cn=... -H ldap://... \
+    -f .../ca.ldif .
+  See ldapadd manual page for options meaning.
+
+Q.) How to build with FIPS capable OpenSSL ?
+A.) At configure time you must set environment variables:
+  CC : openssl fips compiler - fipsld
+  FIPSLD_CC : actual compiler to be used by openssl fips compiler
+
+  Sample command:
+$ CC=gcc FIPSLD_CC=fipsld .../configure ...
+
+  Next verify configure script output:
+....
+   Actual compiler: gcc
+          Compiler: FIPSLD_CC=$(FIPSLD_CC) fipsld
+....
+
+
+Enjoy ;-)
diff -ruN openssh-7.5p1/regress/cert-hostkey.sh openssh-7.5p1+x509-10.2/regress/cert-hostkey.sh
--- openssh-7.5p1/regress/cert-hostkey.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/cert-hostkey.sh	2017-05-20 21:07:00.000000000 +0300
@@ -59,10 +59,12 @@
 touch $OBJ/host_revoked_cert
 cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca
 
-PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
+PLAIN_TYPES=`$SSH -Q key-plain | grep -v "^x509v3-" | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
 
 if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then
+    if config_defined HAVE_EVP_SHA256 ; then
 	PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512"
+    fi
 fi
 
 # Prepare certificate, plain key and CA KRLs
diff -ruN openssh-7.5p1/regress/cert-userkey.sh openssh-7.5p1+x509-10.2/regress/cert-userkey.sh
--- openssh-7.5p1/regress/cert-userkey.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/cert-userkey.sh	2017-05-20 21:07:00.000000000 +0300
@@ -7,10 +7,12 @@
 cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
 cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
 
-PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
+PLAIN_TYPES=`$SSH -Q key-plain | grep -v "^x509v3-" | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
 
 if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then
+    if config_defined HAVE_EVP_SHA256 ; then
 	PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512"
+    fi
 fi
 
 kname() {
diff -ruN openssh-7.5p1/regress/cfginclude.sh openssh-7.5p1+x509-10.2/regress/cfginclude.sh
--- openssh-7.5p1/regress/cfginclude.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/cfginclude.sh	2017-05-20 21:07:00.000000000 +0300
@@ -86,7 +86,7 @@
 trial() {
 	_host="$1"
 	_exp="$2"
-	${REAL_SSH} -F $OBJ/ssh_config.i -G "$_host" > $OBJ/ssh_config.out ||
+	${REAL_SSH} -F $OBJ/ssh_config.i -d "$_host" > $OBJ/ssh_config.out ||
 		fatal "ssh config parse failed"
 	_got=`grep -i '^hostname ' $OBJ/ssh_config.out | awk '{print $2}'`
 	if test "x$_exp" != "x$_got" ; then
@@ -111,10 +111,10 @@
 	Junk
 _EOF
 
-${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \
+${REAL_SSH} -F $OBJ/ssh_config.i -d a 2>/dev/null && \
 	fail "ssh include allowed invalid config"
 
-${REAL_SSH} -F $OBJ/ssh_config.i -G x 2>/dev/null && \
+${REAL_SSH} -F $OBJ/ssh_config.i -d x 2>/dev/null && \
 	fail "ssh include allowed invalid config"
 
 rm -f $OBJ/ssh_config.i.*
@@ -227,7 +227,7 @@
 trial() {
 	_host="$1"
 	_exp="$2"
-	${REAL_SSH} -F $OBJ/ssh_config.i -G "$_host" > $OBJ/ssh_config.out ||
+	${REAL_SSH} -F $OBJ/ssh_config.i -d "$_host" > $OBJ/ssh_config.out ||
 		fatal "ssh config parse failed"
 	_got=`grep -i '^hostname ' $OBJ/ssh_config.out | awk '{print $2}'`
 	if test "x$_exp" != "x$_got" ; then
@@ -252,10 +252,10 @@
 	Junk
 _EOF
 
-${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \
+${REAL_SSH} -F $OBJ/ssh_config.i -d a 2>/dev/null && \
 	fail "ssh include allowed invalid config"
 
-${REAL_SSH} -F $OBJ/ssh_config.i -G x 2>/dev/null && \
+${REAL_SSH} -F $OBJ/ssh_config.i -d x 2>/dev/null && \
 	fail "ssh include allowed invalid config"
 
 rm -f $OBJ/ssh_config.i.*
@@ -286,7 +286,7 @@
 Include $OBJ/ssh_config.i
 _EOF
 
-${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \
+${REAL_SSH} -F $OBJ/ssh_config.i -d a 2>/dev/null && \
 	fail "ssh include allowed infinite recursion?" # or hang...
 
 # cleanup
diff -ruN openssh-7.5p1/regress/connect-privsep.sh openssh-7.5p1+x509-10.2/regress/connect-privsep.sh
--- openssh-7.5p1/regress/connect-privsep.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/connect-privsep.sh	2017-05-20 21:07:00.000000000 +0300
@@ -7,6 +7,7 @@
 echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy
 
 for p in ${SSH_PROTOCOLS}; do
+	echo "= UsePrivilegeSeparation yes, protocol $p" >> $TEST_SSH_LOGFILE
 	${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
 	if [ $? -ne 0 ]; then
 		fail "ssh privsep+proxyconnect protocol $p failed"
@@ -17,6 +18,7 @@
 echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
 
 for p in ${SSH_PROTOCOLS}; do
+	echo "= UsePrivilegeSeparation sandbox, protocol $p" >> $TEST_SSH_LOGFILE
 	${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
 	if [ $? -ne 0 ]; then
 		# XXX replace this with fail once sandbox has stabilised
@@ -31,6 +33,9 @@
 else
 	mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'`
 fi
+# Skip tests as sandbox is not stabilized yet and the tested malloc
+# options are OpenBSD specific.
+: || \
 for m in '' $mopts ; do
     for p in ${SSH_PROTOCOLS}; do
 	env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
diff -ruN openssh-7.5p1/regress/fips-connect-privsep.sh openssh-7.5p1+x509-10.2/regress/fips-connect-privsep.sh
--- openssh-7.5p1/regress/fips-connect-privsep.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/fips-connect-privsep.sh	2012-09-30 14:28:33.674089235 +0300
@@ -0,0 +1,42 @@
+#	Placed in the Public Domain.
+
+# NOTE: sandbox is not stabilised yet so just warn bellow
+tid="proxy connect with privsep in FIPS mode"
+
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy
+
+for p in 2 1; do
+  echo "= UsePrivilegeSeparation yes, protocol $p" >> $TEST_SSH_LOGFILE
+
+  $SSH -$p -F $OBJ/ssh_proxy 999.999.999.999 :
+  if test 0 -ne $?; then
+    if test 2 -eq $p ; then
+      warn "ssh privsep+proxyconnect protocol $p failed"
+    fi
+  else
+    if test 1 -eq $p ; then
+      warn "ssh privsep+proxyconnect protocol $p failed"
+    fi
+  fi
+done
+
+
+cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
+echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
+
+for p in 2 1; do
+  echo "= UsePrivilegeSeparation sandbox, protocol $p" >> $TEST_SSH_LOGFILE
+
+  $SSH -$p -F $OBJ/ssh_proxy 999.999.999.999 :
+  if test 0 -ne $?; then
+    if test 2 -eq $p ; then
+      warn "ssh privsep/sandbox+proxyconnect protocol $p failed"
+    fi
+  else
+    if test 1 -eq $p ; then
+      warn "ssh privsep/sandbox+proxyconnect protocol $p failed"
+    fi
+  fi
+done
diff -ruN openssh-7.5p1/regress/fips-try-ciphers.sh openssh-7.5p1+x509-10.2/regress/fips-try-ciphers.sh
--- openssh-7.5p1/regress/fips-try-ciphers.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/fips-try-ciphers.sh	2016-09-18 19:53:59.428681661 +0300
@@ -0,0 +1,89 @@
+#	Placed in the Public Domain.
+
+tid="try ciphers in FIPS mode"
+
+fips_ciphers="
+  aes128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
+  3des-cbc
+"
+config_defined OPENSSL_HAVE_EVPCTR &&
+  fips_ciphers="$fips_ciphers
+  aes128-ctr aes192-ctr aes256-ctr
+"
+ciphers="
+  blowfish-cbc cast128-cbc
+  arcfour128 arcfour256 arcfour
+"
+
+
+fips_macs="hmac-sha1 hmac-sha1-96"
+config_defined HAVE_EVP_SHA256 &&
+  fips_macs="$fips_macs
+  hmac-sha2-256 hmac-sha2-512
+"
+macs="
+  hmac-md5 umac-64@openssh.com hmac-md5-96
+"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+update_sshd_proxy() {
+  cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+  echo "Ciphers=$1" >> $OBJ/sshd_proxy
+  echo "MACs=$2"    >> $OBJ/sshd_proxy
+}
+
+
+for c in $fips_ciphers; do
+  for m in $fips_macs; do
+    msg="proto 2 fips-cipher $c fips-mac $m"
+    trace "$msg"
+    verbose "test $tid: $msg"
+    update_sshd_proxy $c $m
+    $SSH -F $OBJ/ssh_proxy -2 -m $m -c $c somehost :
+    if test 0 -ne $?; then
+      fail "ssh -2 failed with mac $m cipher $c"
+    fi
+  done
+done
+
+# non-fips mac should fail
+for c in $fips_ciphers; do
+  for m in $macs; do
+    msg="proto 2 fips-cipher $c mac $m"
+    trace "$msg"
+    verbose "negative test $tid: $msg"
+    update_sshd_proxy $c $m
+    $SSH -F $OBJ/ssh_proxy -2 -m $m -c $c somehost : >>$TEST_SSH_LOGFILE 2>&1
+    if test 0 -eq $?; then
+      fail "ssh -2 succeeded with mac $m cipher $c - nok"
+    fi
+  done
+done
+
+# non-fips cipher should fail
+for c in $ciphers; do
+  for m in $fips_macs $macs; do
+    msg="proto 2 cipher $c mac $m"
+    trace "$msg"
+    verbose "negative test $tid: $msg"
+    update_sshd_proxy $c $m
+    $SSH -F $OBJ/ssh_proxy -2 -m $m -c $c somehost : >>$TEST_SSH_LOGFILE 2>&1
+    if test 0 -eq $?; then
+      fail "ssh -2 succeeded with mac $m cipher $c - nok"
+    fi
+  done
+done
+
+# protocol 1 should fail
+ciphers="3des blowfish"
+for c in $ciphers; do
+  msg="proto 1 cipher $c"
+  trace "$msg"
+  verbose "negative test $tid: $msg"
+  update_sshd_proxy $c $m
+  $SSH -F $OBJ/ssh_proxy -1 -c $c somehost : >>$TEST_SSH_LOGFILE 2>&1
+  if test 0 -eq $?; then
+    fail "ssh -1 succeeded with cipher $c - nok"
+  fi
+done
diff -ruN openssh-7.5p1/regress/hostkey-agent.sh openssh-7.5p1+x509-10.2/regress/hostkey-agent.sh
--- openssh-7.5p1/regress/hostkey-agent.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/hostkey-agent.sh	2017-05-20 21:07:00.000000000 +0300
@@ -14,7 +14,7 @@
 echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig
 
 trace "load hostkeys"
-for k in `${SSH} -Q key-plain` ; do
+for k in `${SSH} -Q key-plain | grep -v "^x509v3-"` ; do
 	${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
 	(
 		printf 'localhost-with-alias,127.0.0.1,::1 '
@@ -31,7 +31,7 @@
 unset SSH_AUTH_SOCK
 
 for ps in no yes; do
-	for k in `${SSH} -Q key-plain` ; do
+	for k in `${SSH} -Q key-plain | grep -v "^x509v3-"` ; do
 		verbose "key type $k privsep=$ps"
 		cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
 		echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
diff -ruN openssh-7.5p1/regress/hostkey-rotate.sh openssh-7.5p1+x509-10.2/regress/hostkey-rotate.sh
--- openssh-7.5p1/regress/hostkey-rotate.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/hostkey-rotate.sh	2017-05-20 21:07:00.000000000 +0300
@@ -15,7 +15,7 @@
 trace "prepare hostkeys"
 nkeys=0
 all_algs=""
-for k in `${SSH} -Q key-plain` ; do
+for k in `${SSH} -Q key-plain | grep -v "^x509v3-"` ; do
 	${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"
 	echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig
 	nkeys=`expr $nkeys + 1`
@@ -62,7 +62,7 @@
 check_key_present ssh-rsa || fail "didn't learn keys"
 
 # Check each key type
-for k in `${SSH} -Q key-plain` ; do
+for k in `${SSH} -Q key-plain | grep -v "^x509v3-"` ; do
 	verbose "learn additional hostkeys, type=$k"
 	dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs
 	expect_nkeys $nkeys "learn hostkeys $k"
diff -ruN openssh-7.5p1/regress/integrity.sh openssh-7.5p1+x509-10.2/regress/integrity.sh
--- openssh-7.5p1/regress/integrity.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/integrity.sh	2017-05-20 21:07:00.000000000 +0300
@@ -17,8 +17,10 @@
 echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \
 	>> $OBJ/ssh_proxy
 
+SH=${TEST_SHELL-sh}
+
 # sshd-command for proxy (see test-exec.sh)
-cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy"
+cmd="$SUDO $SH ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy"
 
 for m in $macs; do
 	trace "test $tid: mac $m"
diff -ruN openssh-7.5p1/regress/keygen-change.sh openssh-7.5p1+x509-10.2/regress/keygen-change.sh
--- openssh-7.5p1/regress/keygen-change.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/keygen-change.sh	2017-05-20 21:07:00.000000000 +0300
@@ -6,7 +6,7 @@
 S1="secret1"
 S2="2secret"
 
-KEYTYPES=`${SSH} -Q key-plain`
+KEYTYPES=`${SSH} -Q key-plain | grep -v "^x509v3-"`
 if ssh_version 1; then
 	KEYTYPES="${KEYTYPES} rsa1"
 fi
diff -ruN openssh-7.5p1/regress/keytype.sh openssh-7.5p1+x509-10.2/regress/keytype.sh
--- openssh-7.5p1/regress/keytype.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/keytype.sh	2017-05-20 21:07:00.000000000 +0300
@@ -1,20 +1,15 @@
-#	$OpenBSD: keytype.sh,v 1.4 2015/07/10 06:23:25 markus Exp $
+#	$OpenBSD: keytype.sh,v 1.5 2017/03/20 22:08:06 djm Exp $
 #	Placed in the Public Domain.
 
 tid="login with different key types"
 
-TIME=`which time 2>/dev/null`
-if test ! -x "$TIME"; then
-	TIME=""
-fi
-
 cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
 cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
 
 # Traditional and builtin key types.
 ktypes="dsa-1024 rsa-2048 rsa-3072 ed25519-512"
 # Types not present in all OpenSSL versions.
-for i in `$SSH -Q key`; do
+for i in `$SSH -Q key | grep -v "^x509v3-" `; do
 	case "$i" in
 		ecdsa-sha2-nistp256)	ktypes="$ktypes ecdsa-256" ;;
 		ecdsa-sha2-nistp384)	ktypes="$ktypes ecdsa-384" ;;
@@ -26,8 +21,8 @@
 	rm -f $OBJ/key.$kt
 	bits=`echo ${kt} | awk -F- '{print $2}'`
 	type=`echo ${kt}  | awk -F- '{print $1}'`
-	printf "keygen $type, $bits bits:\t"
-	${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type  -f $OBJ/key.$kt ||\
+	verbose "keygen $type, $bits bits"
+	${SSHKEYGEN} -b $bits -q -N '' -t $type  -f $OBJ/key.$kt ||\
 		fail "ssh-keygen for type $type, $bits bits failed"
 done
 
@@ -63,8 +58,8 @@
 		) > $OBJ/known_hosts
 		cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER
 		for i in $tries; do
-			printf "userkey $ut, hostkey ${ht}:\t"
-			${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
+			verbose "userkey $ut, hostkey ${ht}"
+			${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
 			if [ $? -ne 0 ]; then
 				fail "ssh userkey $ut, hostkey $ht failed"
 			fi
diff -ruN openssh-7.5p1/regress/limit-keytype.sh openssh-7.5p1+x509-10.2/regress/limit-keytype.sh
--- openssh-7.5p1/regress/limit-keytype.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/limit-keytype.sh	2017-05-20 21:07:00.000000000 +0300
@@ -34,6 +34,8 @@
 opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
 certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub"
 
+config_defined HAVE_EVP_SHA256 && extra_algs=",rsa-sha2-*"
+
 echo mekmitasdigoat > $OBJ/authorized_principals_$USER
 cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER
 cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER
@@ -60,7 +62,7 @@
 
 # Allow plain Ed25519 and RSA. The certificate should fail.
 verbose "allow rsa,ed25519"
-prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519"
+prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519$extra_algs"
 ${SSH} $certopts proxy true && fatal "cert succeeded"
 ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
 ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
@@ -81,8 +83,8 @@
 
 # Allow RSA in main config, Ed25519 for non-existent user.
 verbose "match w/ no match"
-prepare_config "PubkeyAcceptedKeyTypes ssh-rsa" \
-	"Match user x$USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
+prepare_config "PubkeyAcceptedKeyTypes ssh-rsa$extra_algs" \
+	"Match user x$USER" "PubkeyAcceptedKeyTypes ssh-ed25519"
 ${SSH} $certopts proxy true && fatal "cert succeeded"
 ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded"
 ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed"
@@ -90,7 +92,7 @@
 # Allow only DSA in main config, Ed25519 for user.
 verbose "match w/ matching"
 prepare_config "PubkeyAcceptedKeyTypes ssh-dss" \
-	"Match user $USER" "PubkeyAcceptedKeyTypes +ssh-ed25519"
+	"Match user $USER" "PubkeyAcceptedKeyTypes ssh-rsa-cert-v01@openssh.com,ssh-ed25519"
 ${SSH} $certopts proxy true || fatal "cert failed"
 ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed"
 ${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded"
diff -ruN openssh-7.5p1/regress/Makefile openssh-7.5p1+x509-10.2/regress/Makefile
--- openssh-7.5p1/regress/Makefile	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/Makefile	2017-05-20 21:07:00.000000000 +0300
@@ -84,6 +84,10 @@
 
 #		dhgex \
 
+FIPS_TESTS=\
+	fips-connect-privsep \
+	fips-try-ciphers
+
 INTEROP_TESTS=	putty-transfer putty-ciphers putty-kex conch-ciphers
 #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
 
@@ -120,6 +124,8 @@
 TEST_ENV=      "MALLOC_OPTIONS=CFGJRSUX"
 
 TEST_SSH_SSHKEYGEN?=ssh-keygen
+TEST_SHELL?=sh
+SHELL=$(TEST_SHELL)
 
 CPPFLAGS=-I..
 
@@ -140,6 +146,7 @@
 	${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub
 
 t4:
+	OPENSSL_FIPS=; unset OPENSSL_FIPS || :; \
 	${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\
 		awk '{print $$2}' | diff - ${.CURDIR}/t4.ok
 
@@ -186,8 +193,10 @@
 	${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null
 
 t11:
+	if egrep "^#define.*HAVE_EVP_SHA256" ${BUILDDIR}/config.h >/dev/null 2>&1 ; then \
 	${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\
-		awk '{print $$2}' | diff - ${.CURDIR}/t11.ok
+		awk '{print $$2}' | diff - ${.CURDIR}/t11.ok \
+	; fi
 
 $(OBJ)/t12.out:
 	${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $@
@@ -198,14 +207,21 @@
 t-exec:	${LTESTS:=.sh}
 	@if [ "x$?" = "x" ]; then exit 0; fi; \
 	for TEST in ""$?; do \
-		echo "run test $${TEST}" ... 1>&2; \
+		echo "=== run test $$TEST" ... >&2; \
+		(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+	done
+
+f-exec:	${FIPS_LTESTS:=.sh}
+	@if [ "x$?" = "x" ]; then exit 0; fi; \
+	for TEST in ""$?; do \
+		echo "=== run test $$TEST" ... >&2; \
 		(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
 	done
 
 t-exec-interop:	${INTEROP_TESTS:=.sh}
 	@if [ "x$?" = "x" ]; then exit 0; fi; \
 	for TEST in ""$?; do \
-		echo "run test $${TEST}" ... 1>&2; \
+		echo "=== run test $$TEST" ... >&2; \
 		(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
 	done
 
diff -ruN openssh-7.5p1/regress/misc/kexfuzz/kexfuzz.c openssh-7.5p1+x509-10.2/regress/misc/kexfuzz/kexfuzz.c
--- openssh-7.5p1/regress/misc/kexfuzz/kexfuzz.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/misc/kexfuzz/kexfuzz.c	2017-05-20 21:07:01.000000000 +0300
@@ -287,9 +287,9 @@
 # endif
 #endif
 	server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
-	server2->kex->load_host_public_key = server->kex->load_host_public_key;
-	server2->kex->load_host_private_key = server->kex->load_host_private_key;
-	server2->kex->sign = server->kex->sign;
+	server2->kex->find_host_public_key = server->kex->find_host_public_key;
+	server2->kex->find_host_private_key = server->kex->find_host_private_key;
+	server2->kex->xsign = server->kex->xsign;
 	TEST_DONE();
 
 	TEST_START("rekeying server2");
diff -ruN openssh-7.5p1/regress/sshcfgparse.sh openssh-7.5p1+x509-10.2/regress/sshcfgparse.sh
--- openssh-7.5p1/regress/sshcfgparse.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/sshcfgparse.sh	2017-05-20 21:07:00.000000000 +0300
@@ -4,24 +4,24 @@
 tid="ssh config parse"
 
 verbose "reparse minimal config"
-(${SSH} -G -F $OBJ/ssh_config somehost >$OBJ/ssh_config.1 &&
- ${SSH} -G -F $OBJ/ssh_config.1 somehost >$OBJ/ssh_config.2 &&
+(${SSH} -d -F $OBJ/ssh_config somehost >$OBJ/ssh_config.1 &&
+ ${SSH} -d -F $OBJ/ssh_config.1 somehost >$OBJ/ssh_config.2 &&
  diff $OBJ/ssh_config.1 $OBJ/ssh_config.2) || fail "reparse minimal config"
 
 verbose "ssh -W opts"
-f=`${SSH} -GF $OBJ/ssh_config host | awk '/exitonforwardfailure/{print $2}'`
+f=`${SSH} -dF $OBJ/ssh_config host | awk '/exitonforwardfailure/{print $2}'`
 test "$f" = "no" || fail "exitonforwardfailure default"
-f=`${SSH} -GF $OBJ/ssh_config -W a:1 h | awk '/exitonforwardfailure/{print $2}'`
+f=`${SSH} -dF $OBJ/ssh_config -W a:1 h | awk '/exitonforwardfailure/{print $2}'`
 test "$f" = "yes" || fail "exitonforwardfailure enable"
-f=`${SSH} -GF $OBJ/ssh_config -W a:1 -o exitonforwardfailure=no h | \
+f=`${SSH} -dF $OBJ/ssh_config -W a:1 -o exitonforwardfailure=no h | \
     awk '/exitonforwardfailure/{print $2}'`
 test "$f" = "no" || fail "exitonforwardfailure override"
 
-f=`${SSH} -GF $OBJ/ssh_config host | awk '/clearallforwardings/{print $2}'`
+f=`${SSH} -dF $OBJ/ssh_config host | awk '/clearallforwardings/{print $2}'`
 test "$f" = "no" || fail "clearallforwardings default"
-f=`${SSH} -GF $OBJ/ssh_config -W a:1 h | awk '/clearallforwardings/{print $2}'`
+f=`${SSH} -dF $OBJ/ssh_config -W a:1 h | awk '/clearallforwardings/{print $2}'`
 test "$f" = "yes" || fail "clearallforwardings enable"
-f=`${SSH} -GF $OBJ/ssh_config -W a:1 -o clearallforwardings=no h | \
+f=`${SSH} -dF $OBJ/ssh_config -W a:1 -o clearallforwardings=no h | \
     awk '/clearallforwardings/{print $2}'`
 test "$f" = "no" || fail "clearallforwardings override"
 
diff -ruN openssh-7.5p1/regress/test-exec.sh openssh-7.5p1+x509-10.2/regress/test-exec.sh
--- openssh-7.5p1/regress/test-exec.sh	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/test-exec.sh	2017-05-20 21:07:00.000000000 +0300
@@ -6,6 +6,9 @@
 # Unbreak GNU head(1)
 _POSIX2_VERSION=199209
 export _POSIX2_VERSION
+TEST_SHELL=${TEST_SHELL-sh}
+
+. ../tests/CA/shell.rc
 
 case `uname -s 2>/dev/null` in
 OSF1*)
@@ -55,13 +58,20 @@
 	echo "not a file: $SCRIPT"
 	exit 2
 fi
-if $TEST_SHELL -n $SCRIPT; then
-	true
+case $TEST_SHELL in
+	*zsh*)	# turn on NULL_GLOB
+		$TEST_SHELL -G -n $SCRIPT;;
+	*)
+		$TEST_SHELL -n $SCRIPT;;
+esac
+ret=$?
+if test 0 -eq $ret; then
+	:
 else
 	echo "syntax error in $SCRIPT"
 	exit 2
 fi
-unset SSH_AUTH_SOCK
+unset SSH_AUTH_SOCK || :
 
 SRC=`dirname ${SCRIPT}`
 
@@ -209,6 +219,7 @@
 if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then
 	TEST_REGRESS_LOGFILE=$OBJ/regress.log
 fi
+echo "=== $SCRIPT ..." >> $TEST_SSH_LOGFILE
 
 # truncate logfiles
 >$TEST_SSH_LOGFILE
@@ -247,6 +258,11 @@
 export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
 #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
 
+# NOTE: always unset OPENSSL_FIPS even for build with FIPS
+# capable OpenSSL library. It will be set latter only if
+# fips test is requested.
+unset OPENSSL_FIPS || :
+
 # Portable specific functions
 have_prog()
 {
@@ -548,6 +564,13 @@
 	echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
 ) > $OBJ/ssh_proxy
 
+case $SCRIPT in
+  */fips-*)
+    OPENSSL_FIPS=1
+    export OPENSSL_FIPS
+    ;;
+esac
+
 # check proxy config
 ${SSHD} -t -f $OBJ/sshd_proxy	|| fatal "sshd_proxy broken"
 
diff -ruN openssh-7.5p1/regress/unittests/kex/test_kex.c openssh-7.5p1+x509-10.2/regress/unittests/kex/test_kex.c
--- openssh-7.5p1/regress/unittests/kex/test_kex.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/unittests/kex/test_kex.c	2017-05-20 21:07:01.000000000 +0300
@@ -148,14 +148,16 @@
 	server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
 	server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
 	server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
+#ifdef HAVE_EVP_SHA256
 	server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
 #ifdef OPENSSL_HAS_ECC
 	server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
 #endif
 	server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
-	server2->kex->load_host_public_key = server->kex->load_host_public_key;
-	server2->kex->load_host_private_key = server->kex->load_host_private_key;
-	server2->kex->sign = server->kex->sign;
+#endif /*def HAVE_EVP_SHA256*/
+	server2->kex->find_host_public_key = server->kex->find_host_public_key;
+	server2->kex->find_host_private_key = server->kex->find_host_private_key;
+	server2->kex->xsign = server->kex->xsign;
 	TEST_DONE();
 
 	TEST_START("rekeying server2");
@@ -180,15 +182,18 @@
 {
 	do_kex_with_key(kex, KEY_RSA, 2048);
 	do_kex_with_key(kex, KEY_DSA, 1024);
+#ifdef HAVE_EVP_SHA256
 #ifdef OPENSSL_HAS_ECC
 	do_kex_with_key(kex, KEY_ECDSA, 256);
 #endif
 	do_kex_with_key(kex, KEY_ED25519, 256);
+#endif /*def HAVE_EVP_SHA256*/
 }
 
 void
 kex_tests(void)
 {
+#ifdef HAVE_EVP_SHA256
 	do_kex("curve25519-sha256@libssh.org");
 #ifdef OPENSSL_HAS_ECC
 	do_kex("ecdh-sha2-nistp256");
@@ -196,6 +201,7 @@
 	do_kex("ecdh-sha2-nistp521");
 #endif
 	do_kex("diffie-hellman-group-exchange-sha256");
+#endif /*def HAVE_EVP_SHA256*/
 	do_kex("diffie-hellman-group-exchange-sha1");
 	do_kex("diffie-hellman-group14-sha1");
 	do_kex("diffie-hellman-group1-sha1");
diff -ruN openssh-7.5p1/regress/unittests/sshkey/test_file.c openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_file.c
--- openssh-7.5p1/regress/unittests/sshkey/test_file.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_file.c	2017-05-20 21:07:01.000000000 +0300
@@ -26,6 +26,7 @@
 #ifdef OPENSSL_HAS_NISTP256
 # include <openssl/ec.h>
 #endif
+#include "evp-compat.h"
 
 #include "../test_helper/test_helper.h"
 
@@ -58,7 +59,11 @@
 	sshbuf_free(buf);
 	ASSERT_PTR_NE(k1, NULL);
 	a = load_bignum("rsa1_1.param.n");
-	ASSERT_BIGNUM_EQ(k1->rsa->n, a);
+{
+	const BIGNUM *n = NULL;
+	RSA_get0_key(k1->rsa, &n, NULL, NULL);
+	ASSERT_BIGNUM_EQ(n, a);
+}
 	BN_free(a);
 	TEST_DONE();
 
@@ -80,6 +85,7 @@
 	sshkey_free(k2);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("RSA1 key hex fingerprint");
 	buf = load_text_file("rsa1_1.fp");
 	cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -88,6 +94,7 @@
 	sshbuf_free(buf);
 	free(cp);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("RSA1 key bubblebabble fingerprint");
 	buf = load_text_file("rsa1_1.fp.bb");
@@ -109,9 +116,16 @@
 	a = load_bignum("rsa_1.param.n");
 	b = load_bignum("rsa_1.param.p");
 	c = load_bignum("rsa_1.param.q");
-	ASSERT_BIGNUM_EQ(k1->rsa->n, a);
-	ASSERT_BIGNUM_EQ(k1->rsa->p, b);
-	ASSERT_BIGNUM_EQ(k1->rsa->q, c);
+{
+	const BIGNUM *n = NULL, *p = NULL, *q = NULL;
+
+	RSA_get0_key(k1->rsa, &n, NULL, NULL);
+	RSA_get0_factors(k1->rsa, &p, &q);
+
+	ASSERT_BIGNUM_EQ(n, a);
+	ASSERT_BIGNUM_EQ(p, b);
+	ASSERT_BIGNUM_EQ(q, c);
+}
 	BN_free(a);
 	BN_free(b);
 	BN_free(c);
@@ -162,6 +176,7 @@
 	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("RSA key hex fingerprint");
 	buf = load_text_file("rsa_1.fp");
 	cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -170,7 +185,9 @@
 	sshbuf_free(buf);
 	free(cp);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("RSA cert hex fingerprint");
 	buf = load_text_file("rsa_1-cert.fp");
 	cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -180,6 +197,7 @@
 	free(cp);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("RSA key bubblebabble fingerprint");
 	buf = load_text_file("rsa_1.fp.bb");
@@ -200,9 +218,16 @@
 	a = load_bignum("dsa_1.param.g");
 	b = load_bignum("dsa_1.param.priv");
 	c = load_bignum("dsa_1.param.pub");
-	ASSERT_BIGNUM_EQ(k1->dsa->g, a);
-	ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
-	ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
+{
+	const BIGNUM *g = NULL, *pub_key = NULL, *priv_key = NULL;
+
+	DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
+	DSA_get0_key(k1->dsa, &pub_key, &priv_key);
+
+	ASSERT_BIGNUM_EQ(g, a);
+	ASSERT_BIGNUM_EQ(priv_key, b);
+	ASSERT_BIGNUM_EQ(pub_key, c);
+}
 	BN_free(a);
 	BN_free(b);
 	BN_free(c);
@@ -253,6 +278,7 @@
 	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("DSA key hex fingerprint");
 	buf = load_text_file("dsa_1.fp");
 	cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -261,7 +287,9 @@
 	sshbuf_free(buf);
 	free(cp);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("DSA cert hex fingerprint");
 	buf = load_text_file("dsa_1-cert.fp");
 	cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -271,6 +299,7 @@
 	free(cp);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("DSA key bubblebabble fingerprint");
 	buf = load_text_file("dsa_1.fp.bb");
@@ -351,6 +380,7 @@
 	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("ECDSA key hex fingerprint");
 	buf = load_text_file("ecdsa_1.fp");
 	cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -359,7 +389,9 @@
 	sshbuf_free(buf);
 	free(cp);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("ECDSA cert hex fingerprint");
 	buf = load_text_file("ecdsa_1-cert.fp");
 	cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -369,6 +401,7 @@
 	free(cp);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("ECDSA key bubblebabble fingerprint");
 	buf = load_text_file("ecdsa_1.fp.bb");
@@ -417,6 +450,7 @@
 	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("Ed25519 key hex fingerprint");
 	buf = load_text_file("ed25519_1.fp");
 	cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -425,7 +459,9 @@
 	sshbuf_free(buf);
 	free(cp);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("Ed25519 cert hex fingerprint");
 	buf = load_text_file("ed25519_1-cert.fp");
 	cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64);
@@ -435,6 +471,7 @@
 	free(cp);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("Ed25519 key bubblebabble fingerprint");
 	buf = load_text_file("ed25519_1.fp.bb");
diff -ruN openssh-7.5p1/regress/unittests/sshkey/test_fuzz.c openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_fuzz.c
--- openssh-7.5p1/regress/unittests/sshkey/test_fuzz.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_fuzz.c	2017-05-20 21:07:01.000000000 +0300
@@ -356,6 +356,7 @@
 	sshkey_free(k1);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("fuzz RSA SHA256 sig");
 	buf = load_file("rsa_1");
 	ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -363,7 +364,9 @@
 	sig_fuzz(k1, "rsa-sha2-256");
 	sshkey_free(k1);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("fuzz RSA SHA512 sig");
 	buf = load_file("rsa_1");
 	ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -371,6 +374,7 @@
 	sig_fuzz(k1, "rsa-sha2-512");
 	sshkey_free(k1);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("fuzz DSA sig");
 	buf = load_file("dsa_1");
diff -ruN openssh-7.5p1/regress/unittests/sshkey/test_sshkey.c openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_sshkey.c
--- openssh-7.5p1/regress/unittests/sshkey/test_sshkey.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/regress/unittests/sshkey/test_sshkey.c	2017-05-20 21:07:01.000000000 +0300
@@ -22,6 +22,7 @@
 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
 # include <openssl/ec.h>
 #endif
+#include "evp-compat.h"
 
 #include "../test_helper/test_helper.h"
 
@@ -197,9 +198,16 @@
 	k1 = sshkey_new(KEY_RSA1);
 	ASSERT_PTR_NE(k1, NULL);
 	ASSERT_PTR_NE(k1->rsa, NULL);
-	ASSERT_PTR_NE(k1->rsa->n, NULL);
-	ASSERT_PTR_NE(k1->rsa->e, NULL);
-	ASSERT_PTR_EQ(k1->rsa->p, NULL);
+{
+	const BIGNUM *n = NULL, *e = NULL, *p = NULL;
+
+	RSA_get0_key(k1->rsa, &n, &e, NULL);
+	RSA_get0_factors(k1->rsa, &p, NULL);
+
+	ASSERT_PTR_NE(n, NULL);
+	ASSERT_PTR_NE(e, NULL);
+	ASSERT_PTR_EQ(p, NULL);
+}
 	sshkey_free(k1);
 	TEST_DONE();
 
@@ -207,9 +215,16 @@
 	k1 = sshkey_new(KEY_RSA);
 	ASSERT_PTR_NE(k1, NULL);
 	ASSERT_PTR_NE(k1->rsa, NULL);
-	ASSERT_PTR_NE(k1->rsa->n, NULL);
-	ASSERT_PTR_NE(k1->rsa->e, NULL);
-	ASSERT_PTR_EQ(k1->rsa->p, NULL);
+{
+	const BIGNUM *n = NULL, *e = NULL, *p = NULL;
+
+	RSA_get0_key(k1->rsa, &n, &e, NULL);
+	RSA_get0_factors(k1->rsa, &p, NULL);
+
+	ASSERT_PTR_NE(n, NULL);
+	ASSERT_PTR_NE(e, NULL);
+	ASSERT_PTR_EQ(p, NULL);
+}
 	sshkey_free(k1);
 	TEST_DONE();
 
@@ -217,8 +232,15 @@
 	k1 = sshkey_new(KEY_DSA);
 	ASSERT_PTR_NE(k1, NULL);
 	ASSERT_PTR_NE(k1->dsa, NULL);
-	ASSERT_PTR_NE(k1->dsa->g, NULL);
-	ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+{
+	const BIGNUM *g = NULL, *priv_key = NULL;
+
+	DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
+	DSA_get0_key(k1->dsa, NULL, &priv_key);
+
+	ASSERT_PTR_NE(g, NULL);
+	ASSERT_PTR_EQ(priv_key, NULL);
+}
 	sshkey_free(k1);
 	TEST_DONE();
 
@@ -244,9 +266,16 @@
 	k1 = sshkey_new_private(KEY_RSA);
 	ASSERT_PTR_NE(k1, NULL);
 	ASSERT_PTR_NE(k1->rsa, NULL);
-	ASSERT_PTR_NE(k1->rsa->n, NULL);
-	ASSERT_PTR_NE(k1->rsa->e, NULL);
-	ASSERT_PTR_NE(k1->rsa->p, NULL);
+{
+	const BIGNUM *n = NULL, *e = NULL, *p = NULL;
+
+	RSA_get0_key(k1->rsa, &n, &e, NULL);
+	RSA_get0_factors(k1->rsa, &p, NULL);
+
+	ASSERT_PTR_NE(n, NULL);
+	ASSERT_PTR_NE(e, NULL);
+	ASSERT_PTR_NE(p, NULL);
+}
 	ASSERT_INT_EQ(sshkey_add_private(k1), 0);
 	sshkey_free(k1);
 	TEST_DONE();
@@ -255,8 +284,15 @@
 	k1 = sshkey_new_private(KEY_DSA);
 	ASSERT_PTR_NE(k1, NULL);
 	ASSERT_PTR_NE(k1->dsa, NULL);
-	ASSERT_PTR_NE(k1->dsa->g, NULL);
-	ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
+{
+	const BIGNUM *g = NULL, *priv_key = NULL;
+
+	DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
+	DSA_get0_key(k1->dsa, NULL, &priv_key);
+
+	ASSERT_PTR_NE(g, NULL);
+	ASSERT_PTR_NE(priv_key, NULL);
+}
 	ASSERT_INT_EQ(sshkey_add_private(k1), 0);
 	sshkey_free(k1);
 	TEST_DONE();
@@ -295,18 +331,32 @@
 	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
 	ASSERT_PTR_NE(kr, NULL);
 	ASSERT_PTR_NE(kr->rsa, NULL);
-	ASSERT_PTR_NE(kr->rsa->n, NULL);
-	ASSERT_PTR_NE(kr->rsa->e, NULL);
-	ASSERT_PTR_NE(kr->rsa->p, NULL);
-	ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
+{
+	const BIGNUM *n = NULL, *e = NULL, *p = NULL;
+
+	RSA_get0_key(kr->rsa, &n, &e, NULL);
+	RSA_get0_factors(kr->rsa, &p, NULL);
+
+	ASSERT_PTR_NE(n, NULL);
+	ASSERT_PTR_NE(e, NULL);
+	ASSERT_PTR_NE(p, NULL);
+	ASSERT_INT_EQ(BN_num_bits(n), 1024);
+}
 	TEST_DONE();
 
 	TEST_START("generate KEY_DSA");
 	ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
 	ASSERT_PTR_NE(kd, NULL);
 	ASSERT_PTR_NE(kd->dsa, NULL);
-	ASSERT_PTR_NE(kd->dsa->g, NULL);
-	ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
+{
+	const BIGNUM *g = NULL, *priv_key = NULL;
+
+	DSA_get0_pqg(kd->dsa, NULL, NULL, &g);
+	DSA_get0_key(kd->dsa, NULL, &priv_key);
+
+	ASSERT_PTR_NE(g, NULL);
+	ASSERT_PTR_NE(priv_key, NULL);
+}
 	TEST_DONE();
 
 #ifdef OPENSSL_HAS_ECC
@@ -333,9 +383,16 @@
 	ASSERT_PTR_NE(kr, k1);
 	ASSERT_INT_EQ(k1->type, KEY_RSA);
 	ASSERT_PTR_NE(k1->rsa, NULL);
-	ASSERT_PTR_NE(k1->rsa->n, NULL);
-	ASSERT_PTR_NE(k1->rsa->e, NULL);
-	ASSERT_PTR_EQ(k1->rsa->p, NULL);
+{
+	const BIGNUM *n = NULL, *e = NULL, *p = NULL;
+
+	RSA_get0_key(k1->rsa, &n, &e, NULL);
+	RSA_get0_factors(k1->rsa, &p, NULL);
+
+	ASSERT_PTR_NE(n, NULL);
+	ASSERT_PTR_NE(e, NULL);
+	ASSERT_PTR_EQ(p, NULL);
+}
 	TEST_DONE();
 
 	TEST_START("equal KEY_RSA/demoted KEY_RSA");
@@ -349,8 +406,15 @@
 	ASSERT_PTR_NE(kd, k1);
 	ASSERT_INT_EQ(k1->type, KEY_DSA);
 	ASSERT_PTR_NE(k1->dsa, NULL);
-	ASSERT_PTR_NE(k1->dsa->g, NULL);
-	ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+{
+	const BIGNUM *g = NULL, *priv_key = NULL;
+
+	DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
+	DSA_get0_key(k1->dsa, NULL, &priv_key);
+
+	ASSERT_PTR_NE(g, NULL);
+	ASSERT_PTR_EQ(priv_key, NULL);
+}
 	TEST_DONE();
 
 	TEST_START("equal KEY_DSA/demoted KEY_DSA");
@@ -476,6 +540,7 @@
 	sshkey_free(k2);
 	TEST_DONE();
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("sign and verify RSA-SHA256");
 	k1 = get_private("rsa_1");
 	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
@@ -484,7 +549,9 @@
 	sshkey_free(k1);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
+#ifdef HAVE_EVP_SHA256
 	TEST_START("sign and verify RSA-SHA512");
 	k1 = get_private("rsa_1");
 	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
@@ -493,6 +560,7 @@
 	sshkey_free(k1);
 	sshkey_free(k2);
 	TEST_DONE();
+#endif /*def HAVE_EVP_SHA256*/
 
 	TEST_START("sign and verify DSA");
 	k1 = get_private("dsa_1");
diff -ruN openssh-7.5p1/rsa.c openssh-7.5p1+x509-10.2/rsa.c
--- openssh-7.5p1/rsa.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/rsa.c	2017-05-20 21:07:01.000000000 +0300
@@ -67,6 +67,7 @@
 #include <stdarg.h>
 #include <string.h>
 
+#include "evp-compat.h"
 #include "rsa.h"
 #include "log.h"
 #include "ssherr.h"
@@ -74,13 +75,16 @@
 int
 rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
 {
+	const BIGNUM *n = NULL, *e = NULL;
 	u_char *inbuf = NULL, *outbuf = NULL;
 	int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
 
-	if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
+	RSA_get0_key(key, &n, &e, NULL);
+
+	if (BN_num_bits(e) < 2 || !BN_is_odd(e))
 		return SSH_ERR_INVALID_ARGUMENT;
 
-	olen = BN_num_bytes(key->n);
+	olen = BN_num_bytes(n);
 	if ((outbuf = malloc(olen)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
@@ -120,10 +124,13 @@
 int
 rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
 {
+	const BIGNUM *n = NULL;
 	u_char *inbuf = NULL, *outbuf = NULL;
 	int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
 
-	olen = BN_num_bytes(key->n);
+	RSA_get0_key(key, &n, NULL, NULL);
+
+	olen = BN_num_bytes(n);
 	if ((outbuf = malloc(olen)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
@@ -162,6 +169,8 @@
 rsa_generate_additional_parameters(RSA *rsa)
 {
 	BIGNUM *aux = NULL;
+	const BIGNUM *p = NULL, *q = NULL;
+	BIGNUM *d = NULL, *dmp1 = NULL, *dmq1 = NULL;
 	BN_CTX *ctx = NULL;
 	int r;
 
@@ -172,10 +181,14 @@
 		goto out;
 	}
 
-	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
-	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
-	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
-	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
+	RSA_get0_key(rsa, NULL, NULL, (const BIGNUM**)&d);
+	RSA_get0_factors(rsa, &p, &q);
+	RSA_get0_crt_params(rsa, (const BIGNUM**)&dmp1, (const BIGNUM**)&dmq1, NULL);
+
+	if ((BN_sub(aux, q, BN_value_one()) == 0) ||
+	    (BN_mod(dmq1, d, aux, ctx) == 0) ||
+	    (BN_sub(aux, p, BN_value_one()) == 0) ||
+	    (BN_mod(dmp1, d, aux, ctx) == 0)) {
 		r = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
diff -ruN openssh-7.5p1/sandbox-seccomp-filter.c openssh-7.5p1+x509-10.2/sandbox-seccomp-filter.c
--- openssh-7.5p1/sandbox-seccomp-filter.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sandbox-seccomp-filter.c	2017-05-20 21:07:01.000000000 +0300
@@ -50,6 +50,9 @@
 #include <elf.h>
 
 #include <asm/unistd.h>
+#ifdef __s390__
+#include <asm/zcrypt.h>
+#endif
 
 #include <errno.h>
 #include <signal.h>
@@ -222,6 +225,7 @@
 #endif
 #ifdef __NR_socketcall
 	SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN),
+	SC_DENY(__NR_socketcall, EACCES),
 #endif
 #if defined(__NR_ioctl) && defined(__s390__)
 	/* Allow ioctls for ICA crypto card on s390 */
@@ -235,7 +239,7 @@
 	 * x86-64 syscall under some circumstances, e.g.
 	 * https://bugs.debian.org/849923
 	 */
-	SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT);
+	SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT),
 #endif
 
 	/* Default deny */
diff -ruN openssh-7.5p1/scp.0 openssh-7.5p1+x509-10.2/scp.0
--- openssh-7.5p1/scp.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/scp.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SCP(1)                      General Commands Manual                     SCP(1)
+SCP(1)                    BSD General Commands Manual                   SCP(1)
 
 NAME
-     scp M-bM-^@M-^S secure copy (remote file copy program)
+     scp -- Secure copy (remote file copy program)
 
 SYNOPSIS
      scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
@@ -17,7 +17,7 @@
      File names may contain a user and host specification to indicate that the
      file is to be copied to/from that host.  Local file names can be made
      explicit using absolute or relative pathnames to avoid scp treating file
-     names containing M-bM-^@M-^X:M-bM-^@M-^Y as host specifiers.  Copies between two remote hosts
+     names containing ':' as host specifiers.  Copies between two remote hosts
      are also permitted.
 
      The options are as follows:
@@ -38,8 +38,8 @@
      -B      Selects batch mode (prevents asking for passwords or
              passphrases).
 
-     -C      Compression enable.  Passes the -C flag to ssh(1) to enable
-             compression.
+     -C      Compression enable.  Passes the -C flag to ssh(1) to enable com-
+             pression.
 
      -c cipher
              Selects the cipher to use for encrypting the data transfer.  This
@@ -61,76 +61,11 @@
              Can be used to pass options to ssh in the format used in
              ssh_config(5).  This is useful for specifying options for which
              there is no separate scp command-line flag.  For full details of
-             the options listed below, and their possible values, see
-             ssh_config(5).
-
-                   AddressFamily
-                   BatchMode
-                   BindAddress
-                   CanonicalDomains
-                   CanonicalizeFallbackLocal
-                   CanonicalizeHostname
-                   CanonicalizeMaxDots
-                   CanonicalizePermittedCNAMEs
-                   CertificateFile
-                   ChallengeResponseAuthentication
-                   CheckHostIP
-                   Cipher
-                   Ciphers
-                   Compression
-                   CompressionLevel
-                   ConnectionAttempts
-                   ConnectTimeout
-                   ControlMaster
-                   ControlPath
-                   ControlPersist
-                   GlobalKnownHostsFile
-                   GSSAPIAuthentication
-                   GSSAPIDelegateCredentials
-                   HashKnownHosts
-                   Host
-                   HostbasedAuthentication
-                   HostbasedKeyTypes
-                   HostKeyAlgorithms
-                   HostKeyAlias
-                   HostName
-                   IdentitiesOnly
-                   IdentityAgent
-                   IdentityFile
-                   IPQoS
-                   KbdInteractiveAuthentication
-                   KbdInteractiveDevices
-                   KexAlgorithms
-                   LogLevel
-                   MACs
-                   NoHostAuthenticationForLocalhost
-                   NumberOfPasswordPrompts
-                   PasswordAuthentication
-                   PKCS11Provider
-                   Port
-                   PreferredAuthentications
-                   Protocol
-                   ProxyCommand
-                   ProxyJump
-                   PubkeyAcceptedKeyTypes
-                   PubkeyAuthentication
-                   RekeyLimit
-                   RhostsRSAAuthentication
-                   RSAAuthentication
-                   SendEnv
-                   ServerAliveInterval
-                   ServerAliveCountMax
-                   StrictHostKeyChecking
-                   TCPKeepAlive
-                   UpdateHostKeys
-                   UsePrivilegedPort
-                   User
-                   UserKnownHostsFile
-                   VerifyHostKeyDNS
+             the options and their possible values, see ssh_config(5).
 
      -P port
              Specifies the port to connect to on the remote host.  Note that
-             this option is written with a capital M-bM-^@M-^XPM-bM-^@M-^Y, because -p is already
+             this option is written with a capital 'P', because -p is already
              reserved for preserving the times and modes of the file.
 
      -p      Preserves modification times, access times, and modes from the
@@ -139,8 +74,8 @@
      -q      Quiet mode: disables the progress meter as well as warning and
              diagnostic messages from ssh(1).
 
-     -r      Recursively copy entire directories.  Note that scp follows
-             symbolic links encountered in the tree traversal.
+     -r      Recursively copy entire directories.  Note that scp follows sym-
+             bolic links encountered in the tree traversal.
 
      -S program
              Name of program to use for the encrypted connection.  The program
@@ -151,7 +86,7 @@
              authentication, and configuration problems.
 
 EXIT STATUS
-     The scp utility exitsM-BM- 0 on success, andM-BM- >0 if an error occurs.
+     The scp utility exits 0 on success, and >0 if an error occurs.
 
 SEE ALSO
      sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh_config(5),
@@ -165,4 +100,4 @@
      Timo Rinne <tri@iki.fi>
      Tatu Ylonen <ylo@cs.hut.fi>
 
-OpenBSD 6.0                      July 16, 2016                     OpenBSD 6.0
+BSD                              July 16, 2016                             BSD
diff -ruN openssh-7.5p1/scp.1 openssh-7.5p1+x509-10.2/scp.1
--- openssh-7.5p1/scp.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/scp.1	2017-05-20 21:07:00.000000000 +0300
@@ -1,3 +1,11 @@
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" scp.1
 .\"
@@ -15,7 +23,7 @@
 .Os
 .Sh NAME
 .Nm scp
-.Nd secure copy (remote file copy program)
+.Nd Secure copy (remote file copy program)
 .Sh SYNOPSIS
 .Nm scp
 .Bk -words
@@ -121,74 +129,8 @@
 for which there is no separate
 .Nm scp
 command-line flag.
-For full details of the options listed below, and their possible values, see
+For full details of the options and their possible values, see
 .Xr ssh_config 5 .
-.Pp
-.Bl -tag -width Ds -offset indent -compact
-.It AddressFamily
-.It BatchMode
-.It BindAddress
-.It CanonicalDomains
-.It CanonicalizeFallbackLocal
-.It CanonicalizeHostname
-.It CanonicalizeMaxDots
-.It CanonicalizePermittedCNAMEs
-.It CertificateFile
-.It ChallengeResponseAuthentication
-.It CheckHostIP
-.It Cipher
-.It Ciphers
-.It Compression
-.It CompressionLevel
-.It ConnectionAttempts
-.It ConnectTimeout
-.It ControlMaster
-.It ControlPath
-.It ControlPersist
-.It GlobalKnownHostsFile
-.It GSSAPIAuthentication
-.It GSSAPIDelegateCredentials
-.It HashKnownHosts
-.It Host
-.It HostbasedAuthentication
-.It HostbasedKeyTypes
-.It HostKeyAlgorithms
-.It HostKeyAlias
-.It HostName
-.It IdentitiesOnly
-.It IdentityAgent
-.It IdentityFile
-.It IPQoS
-.It KbdInteractiveAuthentication
-.It KbdInteractiveDevices
-.It KexAlgorithms
-.It LogLevel
-.It MACs
-.It NoHostAuthenticationForLocalhost
-.It NumberOfPasswordPrompts
-.It PasswordAuthentication
-.It PKCS11Provider
-.It Port
-.It PreferredAuthentications
-.It Protocol
-.It ProxyCommand
-.It ProxyJump
-.It PubkeyAcceptedKeyTypes
-.It PubkeyAuthentication
-.It RekeyLimit
-.It RhostsRSAAuthentication
-.It RSAAuthentication
-.It SendEnv
-.It ServerAliveInterval
-.It ServerAliveCountMax
-.It StrictHostKeyChecking
-.It TCPKeepAlive
-.It UpdateHostKeys
-.It UsePrivilegedPort
-.It User
-.It UserKnownHostsFile
-.It VerifyHostKeyDNS
-.El
 .It Fl P Ar port
 Specifies the port to connect to on the remote host.
 Note that this option is written with a capital
diff -ruN openssh-7.5p1/servconf.c openssh-7.5p1+x509-10.2/servconf.c
--- openssh-7.5p1/servconf.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/servconf.c	2017-05-20 21:07:01.000000000 +0300
@@ -9,6 +9,29 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
@@ -42,6 +65,7 @@
 #include "buffer.h"
 #include "misc.h"
 #include "servconf.h"
+#include "ssh-xkalg.h"
 #include "compat.h"
 #include "pathnames.h"
 #include "cipher.h"
@@ -61,6 +85,10 @@
 static void add_listen_addr(ServerOptions *, char *, int);
 static void add_one_listen_addr(ServerOptions *, char *, int);
 
+/* used in kex.c */
+extern char *server_pkalgs;
+extern char *server_sigalgs;
+
 /* Use of privilege separation or not */
 extern int use_privsep;
 extern Buffer cfg;
@@ -75,6 +103,18 @@
 	/* Portable-specific options */
 	options->use_pam = -1;
 
+	/* X.509 Standard Options */
+	options->hostbased_algorithms = NULL;
+	options->pubkey_algorithms = NULL;
+	options->accepted_algorithms = NULL;
+	ssh_x509flags_initialize(&options->x509flags, 1);
+	X509StoreOptions_init(&options->ca);
+#ifdef SSH_OCSP_ENABLED
+	options->va.type = -1;
+	options->va.certificate_file = NULL;
+	options->va.responder_url = NULL;
+#endif /*def SSH_OCSP_ENABLED*/
+
 	/* Standard Options */
 	options->num_ports = 0;
 	options->ports_from_cmdline = 0;
@@ -86,7 +126,9 @@
 	options->num_host_cert_files = 0;
 	options->host_key_agent = NULL;
 	options->pid_file = NULL;
+	options->server_key_bits = -1;
 	options->login_grace_time = -1;
+	options->key_regeneration_time = -1;
 	options->permit_root_login = PERMIT_NOT_SET;
 	options->ignore_rhosts = -1;
 	options->ignore_user_known_hosts = -1;
@@ -102,10 +144,12 @@
 	options->tcp_keep_alive = -1;
 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
 	options->log_level = SYSLOG_LEVEL_NOT_SET;
+	options->rhosts_rsa_authentication = -1;
 	options->hostbased_authentication = -1;
 	options->hostbased_uses_name_from_packet_only = -1;
 	options->hostbased_key_types = NULL;
 	options->hostkeyalgorithms = NULL;
+	options->rsa_authentication = -1;
 	options->pubkey_authentication = -1;
 	options->pubkey_key_types = NULL;
 	options->kerberos_authentication = -1;
@@ -133,6 +177,7 @@
 	options->ciphers = NULL;
 	options->macs = NULL;
 	options->kex_algorithms = NULL;
+	options->protocol = SSH_PROTO_UNKNOWN;
 	options->fwd_opts.gateway_ports = -1;
 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
 	options->fwd_opts.streamlocal_bind_unlink = -1;
@@ -173,20 +218,6 @@
 	return o == NULL || strcasecmp(o, "none") == 0;
 }
 
-static void
-assemble_algorithms(ServerOptions *o)
-{
-	if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 ||
-	    kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 ||
-	    kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 ||
-	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
-	    &o->hostkeyalgorithms) != 0 ||
-	    kex_assemble_names(KEX_DEFAULT_PK_ALG,
-	    &o->hostbased_key_types) != 0 ||
-	    kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0)
-		fatal("kex_assemble_names failed");
-}
-
 void
 fill_default_server_options(ServerOptions *options)
 {
@@ -196,19 +227,49 @@
 	if (options->use_pam == -1)
 		options->use_pam = 0;
 
+	/* X.509 Standard Options */
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		if (options->ciphers == NULL)
+			options->ciphers = only_fips_valid_ciphers(KEX_SERVER_ENCRYPT);
+		if (options->macs == NULL)
+			options->macs = only_fips_valid_macs(KEX_SERVER_MAC);
+	}
+#endif
+	/* options->hostbased_algorithms */
+	/* options->pubkey_algorithms */
+	/* options->accepted_algorithms */
+	fill_default_xkalg();
+	ssh_x509flags_defaults(&options->x509flags);
+	memcpy(&ssh_x509flags, &options->x509flags, sizeof(ssh_x509flags));
+	X509StoreOptions_system_defaults(&options->ca);
+	ssh_x509store_addlocations(&options->ca);
+#ifdef SSH_OCSP_ENABLED
+	if (options->va.type == -1)
+		options->va.type = ssh_get_default_vatype();
+	ssh_set_validator(&options->va);
+#endif /*def SSH_OCSP_ENABLED*/
+
 	/* Standard Options */
+	if (options->protocol == SSH_PROTO_UNKNOWN)
+		options->protocol = SSH_PROTO_2;
 	if (options->num_host_key_files == 0) {
 		/* fill default hostkeys for protocols */
-		options->host_key_files[options->num_host_key_files++] =
-		    _PATH_HOST_RSA_KEY_FILE;
-		options->host_key_files[options->num_host_key_files++] =
-		    _PATH_HOST_DSA_KEY_FILE;
+		if (options->protocol & SSH_PROTO_1)
+			options->host_key_files[options->num_host_key_files++] =
+			    _PATH_HOST_KEY_FILE;
+		if (options->protocol & SSH_PROTO_2) {
+			options->host_key_files[options->num_host_key_files++] =
+			    _PATH_HOST_RSA_KEY_FILE;
+			options->host_key_files[options->num_host_key_files++] =
+			    _PATH_HOST_DSA_KEY_FILE;
 #ifdef OPENSSL_HAS_ECC
-		options->host_key_files[options->num_host_key_files++] =
-		    _PATH_HOST_ECDSA_KEY_FILE;
+			options->host_key_files[options->num_host_key_files++] =
+			    _PATH_HOST_ECDSA_KEY_FILE;
 #endif
-		options->host_key_files[options->num_host_key_files++] =
-		    _PATH_HOST_ED25519_KEY_FILE;
+			options->host_key_files[options->num_host_key_files++] =
+			    _PATH_HOST_ED25519_KEY_FILE;
+		}
 	}
 	/* No certificates by default */
 	if (options->num_ports == 0)
@@ -219,8 +280,12 @@
 		add_listen_addr(options, NULL, 0);
 	if (options->pid_file == NULL)
 		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
+	if (options->server_key_bits == -1)
+		options->server_key_bits = 1024;
 	if (options->login_grace_time == -1)
 		options->login_grace_time = 120;
+	if (options->key_regeneration_time == -1)
+		options->key_regeneration_time = 3600;
 	if (options->permit_root_login == PERMIT_NOT_SET)
 		options->permit_root_login = PERMIT_NO_PASSWD;
 	if (options->ignore_rhosts == -1)
@@ -251,10 +316,14 @@
 		options->log_facility = SYSLOG_FACILITY_AUTH;
 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
 		options->log_level = SYSLOG_LEVEL_INFO;
+	if (options->rhosts_rsa_authentication == -1)
+		options->rhosts_rsa_authentication = 0;
 	if (options->hostbased_authentication == -1)
 		options->hostbased_authentication = 0;
 	if (options->hostbased_uses_name_from_packet_only == -1)
 		options->hostbased_uses_name_from_packet_only = 0;
+	if (options->rsa_authentication == -1)
+		options->rsa_authentication = 1;
 	if (options->pubkey_authentication == -1)
 		options->pubkey_authentication = 1;
 	if (options->kerberos_authentication == -1)
@@ -334,7 +403,10 @@
 	if (options->disable_forwarding == -1)
 		options->disable_forwarding = 0;
 
-	assemble_algorithms(options);
+	if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 ||
+	    kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 ||
+	    kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0)
+		fatal("%s: kex_assemble_names failed", __func__);
 
 	/* Turn privilege separation and sandboxing on by default */
 	if (use_privsep == -1)
@@ -378,6 +450,40 @@
 	}
 #endif
 
+	if (options->hostbased_algorithms != NULL) {
+		if (!sshkey_names_valid2(options->hostbased_algorithms, 1))
+			fatal("Bad protocol 2 hostbased algorithms '%s'.",
+			    options->hostbased_algorithms);
+	} else
+		options->hostbased_algorithms = xstrdup("*");
+	options->hostbased_key_types = xstrdup(options->hostbased_algorithms); /* for compatibility */
+
+	if (options->pubkey_algorithms != NULL) {
+		if (!sshkey_names_valid2(options->pubkey_algorithms, 1))
+			fatal("Bad protocol 2 public key algorithms '%s'.",
+			    options->pubkey_algorithms);
+	} else
+		options->pubkey_algorithms = xstrdup("*");
+	options->pubkey_key_types = xstrdup(options->pubkey_algorithms); /* for compatibility */
+
+	if (options->hostkeyalgorithms != NULL) {
+		if (!sshkey_names_valid2(options->hostkeyalgorithms, 1))
+			fatal("Bad protocol 2 host key algorithms '%s'.",
+			    options->hostkeyalgorithms);
+	} else
+		options->hostkeyalgorithms = xstrdup("*");
+
+	if (options->accepted_algorithms != NULL) {
+		if (!sshkey_names_valid2(options->accepted_algorithms, 1))
+			fatal("Bad protocol 2 key algorithms '%s'.",
+			    options->accepted_algorithms);
+	} else
+		options->accepted_algorithms = xstrdup("*");
+
+	server_pkalgs = ssh_get_allnames(',', 0, options->accepted_algorithms);
+	debug("annonced algorithms: %s", server_pkalgs);
+	server_sigalgs = ssh_get_allnames(',', 1, options->accepted_algorithms);
+	debug("annonced signatures: %s", server_sigalgs);
 }
 
 /* Keyword tokens. */
@@ -385,9 +491,21 @@
 	sBadOption,		/* == unknown option */
 	/* Portable-specific options */
 	sUsePAM,
+	/* X.509 Standard Options */
+	sHostbasedAlgorithms,
+	sPubkeyAlgorithms,
+	sAcceptedAlgorithms,
+	sX509KeyAlgorithm,
+	sAllowedClientCertPurpose,
+	sKeyAllowSelfIssued, sMandatoryCRL,
+	sCACertificateFile, sCACertificatePath,
+	sCARevocationFile, sCARevocationPath,
+	sCAldapVersion, sCAldapURL,
+	sVAType, sVACertificateFile,
+	sVAOCSPResponderURL,
 	/* Standard Options */
-	sPort, sHostKeyFile, sLoginGraceTime,
-	sPermitRootLogin, sLogFacility, sLogLevel,
+	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime,
+	sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel,
 	sRhostsRSAAuthentication, sRSAAuthentication,
 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
 	sKerberosGetAFSToken,
@@ -399,7 +517,7 @@
 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
 	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
-	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
+	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
 	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
 	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
 	sBanner, sUseDNS, sHostbasedAuthentication,
@@ -438,25 +556,42 @@
 	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
 #endif
 	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
+	/* X.509 Standard Options */
+	{ "hostbasedalgorithms", sHostbasedAlgorithms, SSHCFG_ALL },
+	{ "pubkeyalgorithms", sPubkeyAlgorithms, SSHCFG_ALL },
+	{ "acceptedalgorithms", sAcceptedAlgorithms, SSHCFG_ALL },
+	{ "x509keyalgorithm", sX509KeyAlgorithm, SSHCFG_GLOBAL },
+	{ "allowedcertpurpose", sAllowedClientCertPurpose, SSHCFG_GLOBAL },
+	{ "keyallowselfissued", sKeyAllowSelfIssued, SSHCFG_GLOBAL } ,
+	{ "mandatorycrl", sMandatoryCRL, SSHCFG_GLOBAL } ,
+	{ "cacertificatefile", sCACertificateFile, SSHCFG_GLOBAL },
+	{ "cacertificatepath", sCACertificatePath, SSHCFG_GLOBAL },
+	{ "carevocationfile", sCARevocationFile, SSHCFG_GLOBAL },
+	{ "carevocationpath", sCARevocationPath, SSHCFG_GLOBAL },
+	{ "caldapversion", sCAldapVersion, SSHCFG_GLOBAL },
+	{ "caldapurl", sCAldapURL, SSHCFG_GLOBAL },
+	{ "vatype", sVAType, SSHCFG_GLOBAL },
+	{ "vacertificatefile", sVACertificateFile, SSHCFG_GLOBAL },
+	{ "vaocspresponderurl", sVAOCSPResponderURL, SSHCFG_GLOBAL },
 	/* Standard Options */
 	{ "port", sPort, SSHCFG_GLOBAL },
 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
 	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
-	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
+	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
-	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
+	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
-	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
+	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
 	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
 	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
-	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
+	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
 	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
@@ -521,7 +656,7 @@
 	{ "denygroups", sDenyGroups, SSHCFG_ALL },
 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
 	{ "macs", sMacs, SSHCFG_GLOBAL },
-	{ "protocol", sIgnore, SSHCFG_GLOBAL },
+	{ "protocol", sProtocol, SSHCFG_GLOBAL },
 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
@@ -535,7 +670,7 @@
 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
 	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
-	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
+	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
 	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
 	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
 	{ "permittty", sPermitTTY, SSHCFG_ALL },
@@ -1010,6 +1145,144 @@
 		intptr = &options->use_pam;
 		goto parse_flag;
 
+	/* X.509 Standard Options */
+	case sHostbasedAcceptedKeyTypes:	/* for compatibility */
+	case sHostbasedAlgorithms:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing argument.", filename, linenum);
+		/* cannot validate here - depend from X509KeyAlgorithm */
+		if (*activep && options->hostbased_algorithms == NULL)
+			options->hostbased_algorithms = xstrdup(arg);
+		break;
+
+	case sPubkeyAcceptedKeyTypes:		/* for compatibility */
+	case sPubkeyAlgorithms:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing argument.", filename, linenum);
+		/* cannot validate here - depend from X509KeyAlgorithm */
+		if (*activep && options->pubkey_algorithms == NULL)
+			options->pubkey_algorithms = xstrdup(arg);
+		break;
+
+	case sAcceptedAlgorithms:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing argument.", filename, linenum);
+		/* cannot validate here - depend from X509KeyAlgorithm */
+		if (*activep && options->accepted_algorithms == NULL)
+			options->accepted_algorithms = xstrdup(arg);
+		break;
+
+	case sX509KeyAlgorithm:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing argument.", filename, linenum);
+		if (ssh_add_x509key_alg(arg) < 0) {
+			fatal("%.200s line %d: Bad X.509 key algorithm '%.200s'.",
+			    filename, linenum, arg);
+		}
+		break;
+
+	case sAllowedClientCertPurpose:
+		intptr = &options->x509flags.allowedcertpurpose;
+		arg = strdelim(&cp);
+		if (arg && *arg) {
+			if (strcasecmp(arg, "skip") == 0) goto skip_purpose;
+
+			/* convert string to OpenSSL index */
+			value = ssh_get_x509purpose_s (1, arg);
+			if (value < 0)
+				fatal("%.200s line %d: Bad certificate purpose '%.30s'.",
+				    filename, linenum, arg);
+
+			if (*intptr == -1)
+				*intptr = value;
+		} else {
+skip_purpose:
+			if (*intptr == -1) {
+				*intptr = -2;
+				verbose("%.200s line %d: option is set to don`t check certificate purpose.",
+				    filename, linenum);
+			}
+		}
+		break;
+
+	case sKeyAllowSelfIssued:
+		intptr = &options->x509flags.key_allow_selfissued;
+		goto parse_flag;
+
+	case sMandatoryCRL:
+		intptr = &options->x509flags.mandatory_crl;
+		goto parse_flag;
+
+	case sCACertificateFile:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.certificate_file;
+parse_string:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+		if (*charptr == NULL)
+			*charptr = xstrdup(arg);
+		break;
+
+	case sCACertificatePath:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.certificate_path;
+		goto parse_string;
+
+	case sCARevocationFile:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.revocation_file;
+		goto parse_string;
+
+	case sCARevocationPath:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.revocation_path;
+		goto parse_string;
+
+#ifdef LDAP_ENABLED
+	case sCAldapVersion:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.ldap_ver;
+		goto parse_string;
+
+	case sCAldapURL:
+		/* X509StoreOptions prefered type is 'const char*' */
+		charptr = (char**)&options->ca.ldap_url;
+		goto parse_string;
+#endif /*def LDAP_ENABLED*/
+
+#ifdef SSH_OCSP_ENABLED
+	case sVAType:
+		intptr = &options->va.type;
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+
+		value = ssh_get_vatype_s(arg);
+		if (value < 0) {
+			fatal("%.200s line %d: Bad OCSP responder type '%.30s'.",
+			    filename, linenum, arg);
+		}
+
+		if (*intptr == -1)
+			*intptr = value;
+		break;
+
+	case sVACertificateFile:
+		/* VAOptions prefered type is 'const char*' */
+		charptr = (char**)&options->va.certificate_file;
+		goto parse_string;
+
+	case sVAOCSPResponderURL:
+		/* VAOptions prefered type is 'const char*' */
+		charptr = (char**)&options->va.responder_url;
+		goto parse_string;
+#endif /*def SSH_OCSP_ENABLED*/
+
 	/* Standard Options */
 	case sBadOption:
 		return -1;
@@ -1030,6 +1303,10 @@
 			    filename, linenum);
 		break;
 
+	case sServerKeyBits:
+		intptr = &options->server_key_bits;
+		goto parse_int;
+
 	case sLoginGraceTime:
 		intptr = &options->login_grace_time;
  parse_time:
@@ -1044,6 +1321,10 @@
 			*intptr = value;
 		break;
 
+	case sKeyRegenerationTime:
+		intptr = &options->key_regeneration_time;
+		goto parse_time;
+
 	case sListenAddress:
 		arg = strdelim(&cp);
 		if (arg == NULL || *arg == '\0')
@@ -1162,6 +1443,10 @@
 		intptr = &options->ignore_user_known_hosts;
 		goto parse_flag;
 
+	case sRhostsRSAAuthentication:
+		intptr = &options->rhosts_rsa_authentication;
+		goto parse_flag;
+
 	case sHostbasedAuthentication:
 		intptr = &options->hostbased_authentication;
 		goto parse_flag;
@@ -1170,32 +1455,42 @@
 		intptr = &options->hostbased_uses_name_from_packet_only;
 		goto parse_flag;
 
+#if 0	/* already defined as sHostbasedAlgorithms */
 	case sHostbasedAcceptedKeyTypes:
 		charptr = &options->hostbased_key_types;
+		goto parse_keytypes;
+#endif
+
+	case sHostKeyAlgorithms:
+		charptr = &options->hostkeyalgorithms;
  parse_keytypes:
 		arg = strdelim(&cp);
 		if (!arg || *arg == '\0')
 			fatal("%s line %d: Missing argument.",
 			    filename, linenum);
+#if 0		/* cannot validate here - depend from X509KeyAlgorithm */
 		if (*arg != '-' &&
 		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
 			fatal("%s line %d: Bad key types '%s'.",
 			    filename, linenum, arg ? arg : "<NONE>");
+#endif
 		if (*activep && *charptr == NULL)
 			*charptr = xstrdup(arg);
 		break;
 
-	case sHostKeyAlgorithms:
-		charptr = &options->hostkeyalgorithms;
-		goto parse_keytypes;
+	case sRSAAuthentication:
+		intptr = &options->rsa_authentication;
+		goto parse_flag;
 
 	case sPubkeyAuthentication:
 		intptr = &options->pubkey_authentication;
 		goto parse_flag;
 
+#if 0	/* already defined as sPubkeyAlgorithms */
 	case sPubkeyAcceptedKeyTypes:
 		charptr = &options->pubkey_key_types;
 		goto parse_keytypes;
+#endif
 
 	case sKerberosAuthentication:
 		intptr = &options->kerberos_authentication;
@@ -1374,6 +1669,11 @@
 		intptr = &options->disable_forwarding;
 		goto parse_flag;
 
+	case sUsePrivilegeSeparation:
+		intptr = &use_privsep;
+		multistate_ptr = multistate_privsep;
+		goto parse_multistate;
+
 	case sAllowUsers:
 		while ((arg = strdelim(&cp)) && *arg != '\0') {
 			if (options->num_allow_users >= MAX_ALLOW_USERS)
@@ -1463,6 +1763,19 @@
 			options->kex_algorithms = xstrdup(arg);
 		break;
 
+	case sProtocol:
+		intptr = &options->protocol;
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing argument.", filename, linenum);
+		value = proto_spec(arg);
+		if (value == SSH_PROTO_UNKNOWN)
+			fatal("%s line %d: Bad protocol spec '%s'.",
+			    filename, linenum, arg ? arg : "<NONE>");
+		if (*intptr == SSH_PROTO_UNKNOWN)
+			*intptr = value;
+		break;
+
 	case sSubsystem:
 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
 			fatal("%s line %d: too many subsystems defined.",
@@ -1844,11 +2157,20 @@
 
 	case sDeprecated:
 	case sIgnore:
+#ifndef LDAP_ENABLED
+	case sCAldapVersion:
+	case sCAldapURL:
+#endif /*ndef LDAP_ENABLED*/
+#ifndef SSH_OCSP_ENABLED
+	case sVAType:
+	case sVACertificateFile:
+	case sVAOCSPResponderURL:
+#endif /*ndef SSH_OCSP_ENABLED*/
 	case sUnsupported:
 		do_log2(opcode == sIgnore ?
 		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
 		    "%s line %d: %s option %s", filename, linenum,
-		    opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
+		    opcode == sDeprecated || opcode == sIgnore ? "Deprecated" : "Unsupported", arg);
 		while (arg)
 		    arg = strdelim(&cp);
 		break;
@@ -1968,6 +2290,7 @@
 
 	M_CP_INTOPT(password_authentication);
 	M_CP_INTOPT(gss_authentication);
+	M_CP_INTOPT(rsa_authentication);
 	M_CP_INTOPT(pubkey_authentication);
 	M_CP_INTOPT(kerberos_authentication);
 	M_CP_INTOPT(hostbased_authentication);
@@ -2021,11 +2344,17 @@
 	} \
 } while(0)
 
+	M_CP_STROPT(hostbased_algorithms);
+	M_CP_STROPT(pubkey_algorithms);
+
 	/* See comment in servconf.h */
 	COPY_MATCH_STRING_OPTS();
 
-	/* Arguments that accept '+...' need to be expanded */
-	assemble_algorithms(dst);
+	/* for compatibility */
+	free(dst->hostbased_key_types);
+	dst->hostbased_key_types = xstrdup(dst->hostbased_algorithms);
+	free(dst->pubkey_key_types);
+	dst->pubkey_key_types = xstrdup(dst->pubkey_algorithms);
 
 	/*
 	 * The only things that should be below this point are string options
@@ -2102,12 +2431,32 @@
 		return fmt_multistate_int(val, multistate_gatewayports);
 	case sCompression:
 		return fmt_multistate_int(val, multistate_compression);
+	case sUsePrivilegeSeparation:
+		return fmt_multistate_int(val, multistate_privsep);
 	case sAllowTcpForwarding:
 		return fmt_multistate_int(val, multistate_tcpfwd);
 	case sAllowStreamLocalForwarding:
 		return fmt_multistate_int(val, multistate_tcpfwd);
 	case sFingerprintHash:
 		return ssh_digest_alg_name(val);
+	case sProtocol:
+		switch (val) {
+		case SSH_PROTO_1:
+			return "1";
+		case SSH_PROTO_2:
+			return "2";
+		case (SSH_PROTO_1|SSH_PROTO_2):
+			return "2,1";
+		default:
+			return "UNKNOWN";
+		}
+	case sAllowedClientCertPurpose:
+		return format_x509_purpose(val);
+#ifdef SSH_OCSP_ENABLED
+	case sVAType: {
+		return ssh_get_vatype_i(val);
+		} break;
+#endif
 	default:
 		switch (val) {
 		case 0:
@@ -2152,6 +2501,8 @@
 static void
 dump_cfg_string(ServerOpCodes code, const char *val)
 {
+	if (val == NULL)
+		return;
 	printf("%s %s\n", lookup_opcode_name(code),
 	    val == NULL ? "none" : val);
 }
@@ -2192,6 +2543,7 @@
 	/* these are usually at the top of the config */
 	for (i = 0; i < o->num_ports; i++)
 		printf("port %d\n", o->ports[i]);
+	dump_cfg_fmtint(sProtocol, o->protocol);
 	dump_cfg_fmtint(sAddressFamily, o->address_family);
 
 	/*
@@ -2224,7 +2576,35 @@
 #ifdef USE_PAM
 	dump_cfg_fmtint(sUsePAM, o->use_pam);
 #endif
+	/* X.509 Standard Options */
+	dump_cfg_string(sHostbasedAlgorithms, o->hostbased_algorithms);
+	dump_cfg_string(sPubkeyAlgorithms, o->pubkey_algorithms);
+	dump_cfg_string(sAcceptedAlgorithms, o->accepted_algorithms);
+	/* TODO to implement dump of sX509KeyAlgorithm */
+	/* sshd PKI(X509) flags */
+	dump_cfg_fmtint(sAllowedClientCertPurpose, o->x509flags.allowedcertpurpose);
+	dump_cfg_fmtint(sKeyAllowSelfIssued, o->x509flags.key_allow_selfissued);
+	dump_cfg_fmtint(sMandatoryCRL	   , o->x509flags.mandatory_crl	      );
+	/* sshd PKI(X509) system store */
+	dump_cfg_string(sCACertificateFile, o->ca.certificate_file);
+	dump_cfg_string(sCACertificatePath, o->ca.certificate_path);
+	dump_cfg_string(sCARevocationFile , o->ca.revocation_file );
+	dump_cfg_string(sCARevocationPath , o->ca.revocation_path );
+#ifdef LDAP_ENABLED
+	dump_cfg_string(sCAldapVersion    , o->ca.ldap_ver	  );
+	dump_cfg_string(sCAldapURL	  , o->ca.ldap_url	  );
+#endif
+#ifdef SSH_OCSP_ENABLED
+	/* ssh X.509 extra validation */
+	dump_cfg_fmtint(sVAType		   , o->va.type		   );
+	dump_cfg_string(sVACertificateFile , o->va.certificate_file);
+	dump_cfg_string(sVAOCSPResponderURL, o->va.responder_url   );
+#endif /*def SSH_OCSP_ENABLED*/
+
+	/* Standard Options */
+	dump_cfg_int(sServerKeyBits, o->server_key_bits);
 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
+	dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
 	dump_cfg_int(sMaxSessions, o->max_sessions);
@@ -2236,9 +2616,11 @@
 	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
 	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
 	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
+	dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
 	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
 	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
 	    o->hostbased_uses_name_from_packet_only);
+	dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
 	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
 #ifdef KRB5
 	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
@@ -2277,6 +2659,7 @@
 	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
 	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
 	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
+	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
 	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
 
 	/* string arguments */
@@ -2300,12 +2683,7 @@
 	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
 	dump_cfg_string(sKexAlgorithms,
 	    o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
-	dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
-	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
-	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
-	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
-	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
-	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
+	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
 
 	/* string arguments requiring a lookup */
 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
diff -ruN openssh-7.5p1/servconf.h openssh-7.5p1+x509-10.2/servconf.h
--- openssh-7.5p1/servconf.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/servconf.h	2017-05-20 21:07:00.000000000 +0300
@@ -11,11 +11,36 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SERVCONF_H
 #define SERVCONF_H
 
+#include "x509store.h"
+
 #define MAX_PORTS		256	/* Max # ports. */
 
 #define MAX_ALLOW_USERS		256	/* Max # users on allow list. */
@@ -69,8 +94,10 @@
 	int     num_host_cert_files;     /* Number of files for host certs. */
 	char   *host_key_agent;		 /* ssh-agent socket for host keys. */
 	char   *pid_file;	/* Where to put our pid */
+	int     server_key_bits;/* Size of the server key. */
 	int     login_grace_time;	/* Disconnect if no auth in this time
 					 * (sec). */
+	int     key_regeneration_time;	/* Server key lifetime (seconds). */
 	int     permit_root_login;	/* PERMIT_*, see above */
 	int     ignore_rhosts;	/* Ignore .rhosts and .shosts. */
 	int     ignore_user_known_hosts;	/* Ignore ~/.ssh/known_hosts
@@ -91,13 +118,17 @@
 	char   *ciphers;	/* Supported SSH2 ciphers. */
 	char   *macs;		/* Supported SSH2 macs. */
 	char   *kex_algorithms;	/* SSH2 kex methods in order of preference. */
+	int	protocol;	/* Supported protocol versions. */
 	struct ForwardOptions fwd_opts;	/* forwarding options */
 	SyslogFacility log_facility;	/* Facility for system logging. */
 	LogLevel log_level;	/* Level for system logging. */
+	int     rhosts_rsa_authentication;	/* If true, permit rhosts RSA
+						 * authentication. */
 	int     hostbased_authentication;	/* If true, permit ssh2 hostbased auth */
 	int     hostbased_uses_name_from_packet_only; /* experimental */
 	char   *hostbased_key_types;	/* Key types allowed for hostbased */
 	char   *hostkeyalgorithms;	/* SSH2 server key types */
+	int     rsa_authentication;	/* If true, permit RSA authentication. */
 	int     pubkey_authentication;	/* If true, permit ssh2 pubkey authentication. */
 	char   *pubkey_key_types;	/* Key types allowed for public key */
 	int     kerberos_authentication;	/* If true, permit Kerberos
@@ -167,6 +198,22 @@
 
 	int	use_pam;		/* Enable auth via PAM */
 
+	char*   hostbased_algorithms;	/* Allowed hostbased algorithms. */
+	char*   pubkey_algorithms;	/* Allowed pubkey algorithms. */
+	char*   accepted_algorithms;	/* Announced to client algorithms. */
+
+	/* Supported X.509 key algorithms and signatures
+	   are defined is external source. */
+
+	/* sshd PKI(X509) flags */
+	SSH_X509Flags    x509flags;
+	/* sshd PKI(X509) system store */
+	X509StoreOptions ca;
+#ifdef SSH_OCSP_ENABLED
+	/* ssh X.509 extra validation */
+	VAOptions va;
+#endif /*def SSH_OCSP_ENABLED*/
+
 	int	permit_tun;
 
 	int	num_permitted_opens;
@@ -219,8 +266,6 @@
 		M_CP_STROPT(authorized_principals_file); \
 		M_CP_STROPT(authorized_principals_command); \
 		M_CP_STROPT(authorized_principals_command_user); \
-		M_CP_STROPT(hostbased_key_types); \
-		M_CP_STROPT(pubkey_key_types); \
 		M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
 		M_CP_STRARRAYOPT(allow_users, num_allow_users); \
 		M_CP_STRARRAYOPT(deny_users, num_deny_users); \
diff -ruN openssh-7.5p1/serverloop.c openssh-7.5p1+x509-10.2/serverloop.c
--- openssh-7.5p1/serverloop.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/serverloop.c	2017-05-20 21:07:01.000000000 +0300
@@ -14,6 +14,9 @@
  * SSH2 support by Markus Friedl.
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -58,7 +61,7 @@
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
 #include "packet.h"
-#include "buffer.h"
+#include "ssh-x509.h"
 #include "log.h"
 #include "misc.h"
 #include "servconf.h"
@@ -66,8 +69,8 @@
 #include "sshpty.h"
 #include "channels.h"
 #include "compat.h"
+#include "ssh1.h"
 #include "ssh2.h"
-#include "key.h"
 #include "cipher.h"
 #include "kex.h"
 #include "hostfile.h"
@@ -84,6 +87,25 @@
 extern Authctxt *the_authctxt;
 extern int use_privsep;
 
+static Buffer stdin_buffer;	/* Buffer for stdin data. */
+static Buffer stdout_buffer;	/* Buffer for stdout data. */
+static Buffer stderr_buffer;	/* Buffer for stderr data. */
+static int fdin;		/* Descriptor for stdin (for writing) */
+static int fdout;		/* Descriptor for stdout (for reading);
+				   May be same number as fdin. */
+static int fderr;		/* Descriptor for stderr.  May be -1. */
+static long stdin_bytes = 0;	/* Number of bytes written to stdin. */
+static long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
+static long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
+static long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
+static int stdin_eof = 0;	/* EOF message received from client. */
+static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
+static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
+static int fdin_is_tty = 0;	/* fdin points to a tty. */
+static int connection_in;	/* Connection to client (input). */
+static int connection_out;	/* Connection to client (output). */
+static int connection_closed = 0;	/* Connection to client closed. */
+static u_int buffer_high;	/* "Soft" max buffer size. */
 static int no_more_sessions = 0; /* Disallow further sessions. */
 
 /*
@@ -164,6 +186,64 @@
 	received_sigterm = sig;
 }
 
+/*
+ * Make packets from buffered stderr data, and buffer it for sending
+ * to the client.
+ */
+static void
+make_packets_from_stderr_data(void)
+{
+	u_int len;
+
+	/* Send buffered stderr data to the client. */
+	while (buffer_len(&stderr_buffer) > 0 &&
+	    packet_not_very_much_data_to_write()) {
+		len = buffer_len(&stderr_buffer);
+		if (packet_is_interactive()) {
+			if (len > 512)
+				len = 512;
+		} else {
+			/* Keep the packets at reasonable size. */
+			if (len > packet_get_maxsize())
+				len = packet_get_maxsize();
+		}
+		packet_start(SSH_SMSG_STDERR_DATA);
+		packet_put_string(buffer_ptr(&stderr_buffer), len);
+		packet_send();
+		buffer_consume(&stderr_buffer, len);
+		stderr_bytes += len;
+	}
+}
+
+/*
+ * Make packets from buffered stdout data, and buffer it for sending to the
+ * client.
+ */
+static void
+make_packets_from_stdout_data(void)
+{
+	u_int len;
+
+	/* Send buffered stdout data to the client. */
+	while (buffer_len(&stdout_buffer) > 0 &&
+	    packet_not_very_much_data_to_write()) {
+		len = buffer_len(&stdout_buffer);
+		if (packet_is_interactive()) {
+			if (len > 512)
+				len = 512;
+		} else {
+			/* Keep the packets at reasonable size. */
+			if (len > packet_get_maxsize())
+				len = packet_get_maxsize();
+		}
+		packet_start(SSH_SMSG_STDOUT_DATA);
+		packet_put_string(buffer_ptr(&stdout_buffer), len);
+		packet_send();
+		buffer_consume(&stdout_buffer, len);
+		stdout_bytes += len;
+	}
+}
+
 static void
 client_alive_check(void)
 {
@@ -196,14 +276,14 @@
  * for the duration of the wait (0 = infinite).
  */
 static void
-wait_until_can_do_something(int connection_in, int connection_out,
-    fd_set **readsetp, fd_set **writesetp, int *maxfdp,
+wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
     u_int *nallocp, u_int64_t max_time_ms)
 {
 	struct timeval tv, *tvp;
 	int ret;
 	time_t minwait_secs = 0;
 	int client_alive_scheduled = 0;
+	int program_alive_scheduled = 0;
 
 	/* Allocate and update select() masks for channel descriptors. */
 	channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
@@ -221,7 +301,7 @@
 	 * this could be randomized somewhat to make traffic
 	 * analysis more difficult, but we're not doing it yet.
 	 */
-	if (options.client_alive_interval) {
+	if (compat20 && options.client_alive_interval) {
 		uint64_t keepalive_ms =
 		    (uint64_t)options.client_alive_interval * 1000;
 
@@ -230,11 +310,38 @@
 			max_time_ms = keepalive_ms;
 	}
 
+	if (compat20) {
 #if 0
-	/* wrong: bad condition XXX */
-	if (channel_not_very_much_buffered_data())
+		/* wrong: bad condition XXX */
+		if (channel_not_very_much_buffered_data())
 #endif
-	FD_SET(connection_in, *readsetp);
+		FD_SET(connection_in, *readsetp);
+	} else {
+		/*
+		 * Read packets from the client unless we have too much
+		 * buffered stdin or channel data.
+		 */
+		if (buffer_len(&stdin_buffer) < buffer_high &&
+		    channel_not_very_much_buffered_data())
+			FD_SET(connection_in, *readsetp);
+		/*
+		 * If there is not too much data already buffered going to
+		 * the client, try to get some more data from the program.
+		 */
+		if (packet_not_very_much_data_to_write()) {
+			program_alive_scheduled = child_terminated;
+			if (!fdout_eof)
+				FD_SET(fdout, *readsetp);
+			if (!fderr_eof)
+				FD_SET(fderr, *readsetp);
+		}
+		/*
+		 * If we have buffered data, try to write some of that data
+		 * to the program.
+		 */
+		if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
+			FD_SET(fdin, *writesetp);
+	}
 	notify_prepare(*readsetp);
 
 	/*
@@ -268,8 +375,16 @@
 		memset(*writesetp, 0, *nallocp);
 		if (errno != EINTR)
 			error("select: %.100s", strerror(errno));
-	} else if (ret == 0 && client_alive_scheduled)
-		client_alive_check();
+	} else {
+		if (ret == 0 && client_alive_scheduled)
+			client_alive_check();
+		if (!compat20 && program_alive_scheduled && fdin_is_tty) {
+			if (!fdout_eof)
+				FD_SET(fdout, *readsetp);
+			if (!fderr_eof)
+				FD_SET(fderr, *readsetp);
+		}
+	}
 
 	notify_done(*readsetp);
 }
@@ -278,8 +393,8 @@
  * Processes input from the client and the program.  Input data is stored
  * in buffers and processed later.
  */
-static int
-process_input(fd_set *readset, int connection_in)
+static void
+process_input(fd_set *readset)
 {
 	struct ssh *ssh = active_state; /* XXX */
 	int len;
@@ -291,7 +406,10 @@
 		if (len == 0) {
 			verbose("Connection closed by %.100s port %d",
 			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
-			return -1;
+			connection_closed = 1;
+			if (compat20)
+				return;
+			cleanup_exit(255);
 		} else if (len < 0) {
 			if (errno != EINTR && errno != EAGAIN &&
 			    errno != EWOULDBLOCK) {
@@ -306,26 +424,381 @@
 			packet_process_incoming(buf, len);
 		}
 	}
-	return 0;
+	if (compat20)
+		return;
+
+	/* Read and buffer any available stdout data from the program. */
+	if (!fdout_eof && FD_ISSET(fdout, readset)) {
+		errno = 0;
+		len = read(fdout, buf, sizeof(buf));
+		if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
+		    errno == EWOULDBLOCK) && !child_terminated))) {
+			/* do nothing */
+#ifndef PTY_ZEROREAD
+		} else if (len <= 0) {
+#else
+		} else if ((!isatty(fdout) && len <= 0) ||
+		    (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
+			fdout_eof = 1;
+		} else {
+			buffer_append(&stdout_buffer, buf, len);
+			fdout_bytes += len;
+		}
+	}
+	/* Read and buffer any available stderr data from the program. */
+	if (!fderr_eof && FD_ISSET(fderr, readset)) {
+		errno = 0;
+		len = read(fderr, buf, sizeof(buf));
+		if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
+		    errno == EWOULDBLOCK) && !child_terminated))) {
+			/* do nothing */
+#ifndef PTY_ZEROREAD
+		} else if (len <= 0) {
+#else
+		} else if ((!isatty(fderr) && len <= 0) ||
+		    (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
+			fderr_eof = 1;
+		} else {
+			buffer_append(&stderr_buffer, buf, len);
+		}
+	}
 }
 
 /*
  * Sends data from internal buffers to client program stdin.
  */
 static void
-process_output(fd_set *writeset, int connection_out)
+process_output(fd_set *writeset)
 {
+	struct termios tio;
+	u_char *data;
+	u_int dlen;
+	int len;
+
+	/* Write buffered data to program stdin. */
+	if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
+		data = buffer_ptr(&stdin_buffer);
+		dlen = buffer_len(&stdin_buffer);
+		len = write(fdin, data, dlen);
+		if (len < 0 &&
+		    (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) {
+			/* do nothing */
+		} else if (len <= 0) {
+			if (fdin != fdout)
+				close(fdin);
+			else
+				shutdown(fdin, SHUT_WR); /* We will no longer send. */
+			fdin = -1;
+		} else {
+			/* Successful write. */
+			if (fdin_is_tty && dlen >= 1 && data[0] != '\r' &&
+			    tcgetattr(fdin, &tio) == 0 &&
+			    !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
+				/*
+				 * Simulate echo to reduce the impact of
+				 * traffic analysis
+				 */
+				packet_send_ignore(len);
+				packet_send();
+			}
+			/* Consume the data from the buffer. */
+			buffer_consume(&stdin_buffer, len);
+			/* Update the count of bytes written to the program. */
+			stdin_bytes += len;
+		}
+	}
 	/* Send any buffered packet data to the client. */
 	if (FD_ISSET(connection_out, writeset))
 		packet_write_poll();
 }
 
+/*
+ * Wait until all buffered output has been sent to the client.
+ * This is used when the program terminates.
+ */
+static void
+drain_output(void)
+{
+	/* Send any buffered stdout data to the client. */
+	if (buffer_len(&stdout_buffer) > 0) {
+		packet_start(SSH_SMSG_STDOUT_DATA);
+		packet_put_string(buffer_ptr(&stdout_buffer),
+				  buffer_len(&stdout_buffer));
+		packet_send();
+		/* Update the count of sent bytes. */
+		stdout_bytes += buffer_len(&stdout_buffer);
+	}
+	/* Send any buffered stderr data to the client. */
+	if (buffer_len(&stderr_buffer) > 0) {
+		packet_start(SSH_SMSG_STDERR_DATA);
+		packet_put_string(buffer_ptr(&stderr_buffer),
+				  buffer_len(&stderr_buffer));
+		packet_send();
+		/* Update the count of sent bytes. */
+		stderr_bytes += buffer_len(&stderr_buffer);
+	}
+	/* Wait until all buffered data has been written to the client. */
+	packet_write_wait();
+}
+
 static void
 process_buffered_input_packets(void)
 {
 	dispatch_run(DISPATCH_NONBLOCK, NULL, active_state);
 }
 
+/*
+ * Performs the interactive session.  This handles data transmission between
+ * the client and the program.  Note that the notion of stdin, stdout, and
+ * stderr in this function is sort of reversed: this function writes to
+ * stdin (of the child program), and reads from stdout and stderr (of the
+ * child program).
+ */
+void
+server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
+{
+	fd_set *readset = NULL, *writeset = NULL;
+	int max_fd = 0;
+	u_int nalloc = 0;
+	int wait_status;	/* Status returned by wait(). */
+	pid_t wait_pid;		/* pid returned by wait(). */
+	int waiting_termination = 0;	/* Have displayed waiting close message. */
+	u_int64_t max_time_milliseconds;
+	u_int previous_stdout_buffer_bytes;
+	u_int stdout_buffer_bytes;
+	int type;
+
+	debug("Entering interactive session.");
+
+	/* Initialize the SIGCHLD kludge. */
+	child_terminated = 0;
+	mysignal(SIGCHLD, sigchld_handler);
+
+	if (!use_privsep) {
+		signal(SIGTERM, sigterm_handler);
+		signal(SIGINT, sigterm_handler);
+		signal(SIGQUIT, sigterm_handler);
+	}
+
+	/* Initialize our global variables. */
+	fdin = fdin_arg;
+	fdout = fdout_arg;
+	fderr = fderr_arg;
+
+	/* nonblocking IO */
+	set_nonblock(fdin);
+	set_nonblock(fdout);
+	/* we don't have stderr for interactive terminal sessions, see below */
+	if (fderr != -1)
+		set_nonblock(fderr);
+
+	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
+		fdin_is_tty = 1;
+
+	connection_in = packet_get_connection_in();
+	connection_out = packet_get_connection_out();
+
+	notify_setup();
+
+	previous_stdout_buffer_bytes = 0;
+
+	/* Set approximate I/O buffer size. */
+	if (packet_is_interactive())
+		buffer_high = 4096;
+	else
+		buffer_high = 64 * 1024;
+
+#if 0
+	/* Initialize max_fd to the maximum of the known file descriptors. */
+	max_fd = MAX(connection_in, connection_out);
+	max_fd = MAX(max_fd, fdin);
+	max_fd = MAX(max_fd, fdout);
+	if (fderr != -1)
+		max_fd = MAX(max_fd, fderr);
+#endif
+
+	/* Initialize Initialize buffers. */
+	buffer_init(&stdin_buffer);
+	buffer_init(&stdout_buffer);
+	buffer_init(&stderr_buffer);
+
+	/*
+	 * If we have no separate fderr (which is the case when we have a pty
+	 * - there we cannot make difference between data sent to stdout and
+	 * stderr), indicate that we have seen an EOF from stderr.  This way
+	 * we don't need to check the descriptor everywhere.
+	 */
+	if (fderr == -1)
+		fderr_eof = 1;
+
+	server_init_dispatch();
+
+	/* Main loop of the server for the interactive session mode. */
+	for (;;) {
+
+		/* Process buffered packets from the client. */
+		process_buffered_input_packets();
+
+		/*
+		 * If we have received eof, and there is no more pending
+		 * input data, cause a real eof by closing fdin.
+		 */
+		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
+			if (fdin != fdout)
+				close(fdin);
+			else
+				shutdown(fdin, SHUT_WR); /* We will no longer send. */
+			fdin = -1;
+		}
+		/* Make packets from buffered stderr data to send to the client. */
+		make_packets_from_stderr_data();
+
+		/*
+		 * Make packets from buffered stdout data to send to the
+		 * client. If there is very little to send, this arranges to
+		 * not send them now, but to wait a short while to see if we
+		 * are getting more data. This is necessary, as some systems
+		 * wake up readers from a pty after each separate character.
+		 */
+		max_time_milliseconds = 0;
+		stdout_buffer_bytes = buffer_len(&stdout_buffer);
+		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
+		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
+			/* try again after a while */
+			max_time_milliseconds = 10;
+		} else {
+			/* Send it now. */
+			make_packets_from_stdout_data();
+		}
+		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
+
+		/* Send channel data to the client. */
+		if (packet_not_very_much_data_to_write())
+			channel_output_poll();
+
+		/*
+		 * Bail out of the loop if the program has closed its output
+		 * descriptors, and we have no more data to send to the
+		 * client, and there is no pending buffered data.
+		 */
+		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
+		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
+			if (!channel_still_open())
+				break;
+			if (!waiting_termination) {
+				const char *s = "Waiting for forwarded connections to terminate...\r\n";
+				char *cp;
+				waiting_termination = 1;
+				buffer_append(&stderr_buffer, s, strlen(s));
+
+				/* Display list of open channels. */
+				cp = channel_open_message();
+				buffer_append(&stderr_buffer, cp, strlen(cp));
+				free(cp);
+			}
+		}
+		max_fd = MAX(connection_in, connection_out);
+		max_fd = MAX(max_fd, fdin);
+		max_fd = MAX(max_fd, fdout);
+		max_fd = MAX(max_fd, fderr);
+		max_fd = MAX(max_fd, notify_pipe[0]);
+
+		/* Sleep in select() until we can do something. */
+		wait_until_can_do_something(&readset, &writeset, &max_fd,
+		    &nalloc, max_time_milliseconds);
+
+		if (received_sigterm) {
+			logit("Exiting on signal %d", (int)received_sigterm);
+			/* Clean up sessions, utmp, etc. */
+			cleanup_exit(255);
+		}
+
+		/* Process any channel events. */
+		channel_after_select(readset, writeset);
+
+		/* Process input from the client and from program stdout/stderr. */
+		process_input(readset);
+
+		/* Process output to the client and to program stdin. */
+		process_output(writeset);
+	}
+	free(readset);
+	free(writeset);
+
+	/* Cleanup and termination code. */
+
+	/* Wait until all output has been sent to the client. */
+	drain_output();
+
+	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
+	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
+
+	/* Free and clear the buffers. */
+	buffer_free(&stdin_buffer);
+	buffer_free(&stdout_buffer);
+	buffer_free(&stderr_buffer);
+
+	/* Close the file descriptors. */
+	if (fdout != -1)
+		close(fdout);
+	fdout = -1;
+	fdout_eof = 1;
+	if (fderr != -1)
+		close(fderr);
+	fderr = -1;
+	fderr_eof = 1;
+	if (fdin != -1)
+		close(fdin);
+	fdin = -1;
+
+	channel_free_all();
+
+	/* We no longer want our SIGCHLD handler to be called. */
+	mysignal(SIGCHLD, SIG_DFL);
+
+	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
+		if (errno != EINTR)
+			packet_disconnect("wait: %.100s", strerror(errno));
+	if (wait_pid != pid)
+		error("Strange, wait returned pid %ld, expected %ld",
+		    (long)wait_pid, (long)pid);
+
+	/* Check if it exited normally. */
+	if (WIFEXITED(wait_status)) {
+		/* Yes, normal exit.  Get exit status and send it to the client. */
+		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
+		packet_start(SSH_SMSG_EXITSTATUS);
+		packet_put_int(WEXITSTATUS(wait_status));
+		packet_send();
+		packet_write_wait();
+
+		/*
+		 * Wait for exit confirmation.  Note that there might be
+		 * other packets coming before it; however, the program has
+		 * already died so we just ignore them.  The client is
+		 * supposed to respond with the confirmation when it receives
+		 * the exit status.
+		 */
+		do {
+			type = packet_read();
+		}
+		while (type != SSH_CMSG_EXIT_CONFIRMATION);
+
+		debug("Received exit confirmation.");
+		return;
+	}
+	/* Check if the program terminated due to a signal. */
+	if (WIFSIGNALED(wait_status))
+		packet_disconnect("Command terminated on signal %d.",
+				  WTERMSIG(wait_status));
+
+	/* Some weird exit cause.  Just exit. */
+	packet_disconnect("wait returned status %04x.", wait_status);
+	/* NOTREACHED */
+}
+
 static void
 collect_children(void)
 {
@@ -353,7 +826,7 @@
 {
 	fd_set *readset = NULL, *writeset = NULL;
 	int max_fd;
-	u_int nalloc = 0, connection_in, connection_out;
+	u_int nalloc = 0;
 	u_int64_t rekey_timeout_ms = 0;
 
 	debug("Entering interactive session for SSH2.");
@@ -382,14 +855,14 @@
 		if (!ssh_packet_is_rekeying(active_state) &&
 		    packet_not_very_much_data_to_write())
 			channel_output_poll();
-		if (options.rekey_interval > 0 &&
+		if (options.rekey_interval > 0 && compat20 &&
 		    !ssh_packet_is_rekeying(active_state))
 			rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
 		else
 			rekey_timeout_ms = 0;
 
-		wait_until_can_do_something(connection_in, connection_out,
-		    &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
+		wait_until_can_do_something(&readset, &writeset, &max_fd,
+		    &nalloc, rekey_timeout_ms);
 
 		if (received_sigterm) {
 			logit("Exiting on signal %d", (int)received_sigterm);
@@ -400,9 +873,10 @@
 		collect_children();
 		if (!ssh_packet_is_rekeying(active_state))
 			channel_after_select(readset, writeset);
-		if (process_input(readset, connection_in) < 0)
+		process_input(readset);
+		if (connection_closed)
 			break;
-		process_output(writeset, connection_out);
+		process_output(writeset);
 	}
 	collect_children();
 
@@ -429,6 +903,53 @@
 	return 0;
 }
 
+static int
+server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
+{
+	char *data;
+	u_int data_len;
+
+	/* Stdin data from the client.  Append it to the buffer. */
+	/* Ignore any data if the client has closed stdin. */
+	if (fdin == -1)
+		return 0;
+	data = packet_get_string(&data_len);
+	packet_check_eom();
+	buffer_append(&stdin_buffer, data, data_len);
+	explicit_bzero(data, data_len);
+	free(data);
+	return 0;
+}
+
+static int
+server_input_eof(int type, u_int32_t seq, void *ctxt)
+{
+	/*
+	 * Eof from the client.  The stdin descriptor to the
+	 * program will be closed when all buffered data has
+	 * drained.
+	 */
+	debug("EOF received for stdin.");
+	packet_check_eom();
+	stdin_eof = 1;
+	return 0;
+}
+
+static int
+server_input_window_size(int type, u_int32_t seq, void *ctxt)
+{
+	u_int row = packet_get_int();
+	u_int col = packet_get_int();
+	u_int xpixel = packet_get_int();
+	u_int ypixel = packet_get_int();
+
+	debug("Window change received.");
+	packet_check_eom();
+	if (fdin != -1)
+		pty_change_window_size(fdin, row, col, xpixel, ypixel);
+	return 0;
+}
+
 static Channel *
 server_request_direct_tcpip(int *reason, const char **errmsg)
 {
@@ -639,6 +1160,7 @@
 	struct sshbuf *resp = NULL;
 	struct sshbuf *sigbuf = NULL;
 	struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
+	char *pkalg = NULL;
 	int r, ndx, success = 0;
 	const u_char *blob;
 	u_char *sig = 0;
@@ -650,12 +1172,15 @@
 	while (ssh_packet_remaining(ssh) > 0) {
 		sshkey_free(key);
 		key = NULL;
+		free(pkalg);
+		pkalg = NULL;
 		if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 ||
-		    (r = sshkey_from_blob(blob, blen, &key)) != 0) {
+		    (r = parse_key_from_blob(blob, blen, &key, &pkalg)) != 0) {
 			error("%s: couldn't parse key: %s",
 			    __func__, ssh_err(r));
 			goto out;
 		}
+		debug3("%s: pkalg %s", __func__, pkalg);
 		/*
 		 * Better check that this is actually one of our hostkeys
 		 * before attempting to sign anything with it.
@@ -665,6 +1190,7 @@
 			    __func__, sshkey_type(key));
 			goto out;
 		}
+		debug3("%s: ndx %d", __func__, ndx);
 		/*
 		 * XXX refactor: make kex->sign just use an index rather
 		 * than passing in public and private keys
@@ -677,19 +1203,23 @@
 		sshbuf_reset(sigbuf);
 		free(sig);
 		sig = NULL;
+	{	ssh_compat ctx_compat = { ssh->compat, xcompat }; /* TODO-Xkey_sign compat */
+		ssh_sign_ctx ctx = { pkalg, key_prv, &ctx_compat };
+
 		if ((r = sshbuf_put_cstring(sigbuf,
 		    "hostkeys-prove-00@openssh.com")) != 0 ||
 		    (r = sshbuf_put_string(sigbuf,
 		    ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
-		    (r = sshkey_puts(key, sigbuf)) != 0 ||
-		    (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
-		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 ||
+		    (r = Xkey_puts(pkalg, key, sigbuf)) != 0 ||
+		    (r = ssh->kex->xsign(&ctx, key_pub, &sig, &slen,
+		        sshbuf_ptr(sigbuf), sshbuf_len(sigbuf))) != 0 ||
 		    (r = sshbuf_put_string(resp, sig, slen)) != 0) {
 			error("%s: couldn't prepare signature: %s",
 			    __func__, ssh_err(r));
 			goto out;
 		}
 	}
+	}
 	/* Success */
 	*respp = resp;
 	resp = NULL; /* don't free it */
@@ -699,6 +1229,7 @@
 	sshbuf_free(resp);
 	sshbuf_free(sigbuf);
 	sshkey_free(key);
+	free(pkalg);
 	return success;
 }
 
@@ -843,9 +1374,9 @@
 }
 
 static void
-server_init_dispatch(void)
+server_init_dispatch_20(void)
 {
-	debug("server_init_dispatch");
+	debug("server_init_dispatch_20");
 	dispatch_init(&dispatch_protocol_error);
 	dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
 	dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
@@ -865,3 +1396,36 @@
 	/* rekeying */
 	dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
 }
+static void
+server_init_dispatch_13(void)
+{
+	debug("server_init_dispatch_13");
+	dispatch_init(NULL);
+	dispatch_set(SSH_CMSG_EOF, &server_input_eof);
+	dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data);
+	dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size);
+	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
+	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
+	dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
+	dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
+	dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
+	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
+}
+static void
+server_init_dispatch_15(void)
+{
+	server_init_dispatch_13();
+	debug("server_init_dispatch_15");
+	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
+	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);
+}
+static void
+server_init_dispatch(void)
+{
+	if (compat20)
+		server_init_dispatch_20();
+	else if (compat13)
+		server_init_dispatch_13();
+	else
+		server_init_dispatch_15();
+}
diff -ruN openssh-7.5p1/serverloop.h openssh-7.5p1+x509-10.2/serverloop.h
--- openssh-7.5p1/serverloop.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/serverloop.h	2017-05-20 21:07:00.000000000 +0300
@@ -21,6 +21,7 @@
 #ifndef SERVERLOOP_H
 #define SERVERLOOP_H
 
+void    server_loop(pid_t, int, int, int);
 void    server_loop2(Authctxt *);
 
 #endif
diff -ruN openssh-7.5p1/session.c openssh-7.5p1+x509-10.2/session.c
--- openssh-7.5p1/session.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/session.c	2017-05-20 21:07:01.000000000 +0300
@@ -66,6 +66,7 @@
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
 #include "ssh.h"
+#include "ssh1.h"
 #include "ssh2.h"
 #include "sshpty.h"
 #include "packet.h"
@@ -127,6 +128,7 @@
 void	do_motd(void);
 int	check_quietlogin(Session *, const char *);
 
+static void do_authenticated1(Authctxt *);
 static void do_authenticated2(Authctxt *);
 
 static int session_pty_req(Session *);
@@ -265,7 +267,11 @@
 
 	auth_debug_send();
 
-	do_authenticated2(authctxt);
+	if (compat20)
+		do_authenticated2(authctxt);
+	else
+		do_authenticated1(authctxt);
+
 	do_cleanup(authctxt);
 }
 
@@ -284,6 +290,164 @@
 	return 1;
 }
 
+/*
+ * Prepares for an interactive session.  This is called after the user has
+ * been successfully authenticated.  During this message exchange, pseudo
+ * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
+ * are requested, etc.
+ */
+static void
+do_authenticated1(Authctxt *authctxt)
+{
+	Session *s;
+	char *command;
+	int success, type, screen_flag;
+	int enable_compression_after_reply = 0;
+	u_int proto_len, data_len, dlen, compression_level = 0;
+
+	s = session_new();
+	if (s == NULL) {
+		error("no more sessions");
+		return;
+	}
+	s->authctxt = authctxt;
+	s->pw = authctxt->pw;
+
+	/*
+	 * We stay in this loop until the client requests to execute a shell
+	 * or a command.
+	 */
+	for (;;) {
+		success = 0;
+
+		/* Get a packet from the client. */
+		type = packet_read();
+
+		/* Process the packet. */
+		switch (type) {
+		case SSH_CMSG_REQUEST_COMPRESSION:
+			compression_level = packet_get_int();
+			packet_check_eom();
+			if (compression_level < 1 || compression_level > 9) {
+				packet_send_debug("Received invalid compression level %d.",
+				    compression_level);
+				break;
+			}
+			if (options.compression == COMP_NONE) {
+				debug2("compression disabled");
+				break;
+			}
+			/* Enable compression after we have responded with SUCCESS. */
+			enable_compression_after_reply = 1;
+			success = 1;
+			break;
+
+		case SSH_CMSG_REQUEST_PTY:
+			success = session_pty_req(s);
+			break;
+
+		case SSH_CMSG_X11_REQUEST_FORWARDING:
+			s->auth_proto = packet_get_string(&proto_len);
+			s->auth_data = packet_get_string(&data_len);
+
+			screen_flag = packet_get_protocol_flags() &
+			    SSH_PROTOFLAG_SCREEN_NUMBER;
+			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
+
+			if (packet_remaining() == 4) {
+				if (!screen_flag)
+					debug2("Buggy client: "
+					    "X11 screen flag missing");
+				s->screen = packet_get_int();
+			} else {
+				s->screen = 0;
+			}
+			packet_check_eom();
+			if (xauth_valid_string(s->auth_proto) &&
+			    xauth_valid_string(s->auth_data))
+				success = session_setup_x11fwd(s);
+			else {
+				success = 0;
+				error("Invalid X11 forwarding data");
+			}
+			if (!success) {
+				free(s->auth_proto);
+				free(s->auth_data);
+				s->auth_proto = NULL;
+				s->auth_data = NULL;
+			}
+			break;
+
+		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
+			if (!options.allow_agent_forwarding ||
+			    no_agent_forwarding_flag || compat13) {
+				debug("Authentication agent forwarding not permitted for this authentication.");
+				break;
+			}
+			debug("Received authentication agent forwarding request.");
+			success = auth_input_request_forwarding(s->pw);
+			break;
+
+		case SSH_CMSG_PORT_FORWARD_REQUEST:
+			if (no_port_forwarding_flag) {
+				debug("Port forwarding not permitted for this authentication.");
+				break;
+			}
+			if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) {
+				debug("Port forwarding not permitted.");
+				break;
+			}
+			debug("Received TCP/IP port forwarding request.");
+			if (channel_input_port_forward_request(s->pw->pw_uid == 0,
+			    &options.fwd_opts) < 0) {
+				debug("Port forwarding failed.");
+				break;
+			}
+			success = 1;
+			break;
+
+		case SSH_CMSG_MAX_PACKET_SIZE:
+			if (packet_set_maxsize(packet_get_int()) > 0)
+				success = 1;
+			break;
+
+		case SSH_CMSG_EXEC_SHELL:
+		case SSH_CMSG_EXEC_CMD:
+			if (type == SSH_CMSG_EXEC_CMD) {
+				command = packet_get_string(&dlen);
+				debug("Exec command '%.500s'", command);
+				if (do_exec(s, command) != 0)
+					packet_disconnect(
+					    "command execution failed");
+				free(command);
+			} else {
+				if (do_exec(s, NULL) != 0)
+					packet_disconnect(
+					    "shell execution failed");
+			}
+			packet_check_eom();
+			session_close(s);
+			return;
+
+		default:
+			/*
+			 * Any unknown messages in this phase are ignored,
+			 * and a failure message is returned.
+			 */
+			logit("Unknown packet type received after authentication: %d", type);
+		}
+		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
+		packet_send();
+		packet_write_wait();
+
+		/* Enable compression now that we have replied if appropriate. */
+		if (enable_compression_after_reply) {
+			enable_compression_after_reply = 0;
+			packet_start_compression(compression_level);
+		}
+	}
+}
+
 #define USE_PIPES 1
 /*
  * This is called to fork and execute a command when we have no tty.  This
@@ -451,8 +615,14 @@
 	close(pout[1]);
 	close(perr[1]);
 
-	session_set_fds(s, pin[1], pout[0], perr[0],
-	    s->is_subsystem, 0);
+	if (compat20) {
+		session_set_fds(s, pin[1], pout[0], perr[0],
+		    s->is_subsystem, 0);
+	} else {
+		/* Enter the interactive session. */
+		server_loop(pid, pin[1], pout[0], perr[0]);
+		/* server_loop has closed pin[1], pout[0], and perr[0]. */
+	}
 #else
 	/* We are the parent.  Close the child sides of the socket pairs. */
 	close(inout[0]);
@@ -462,8 +632,13 @@
 	 * Enter the interactive session.  Note: server_loop must be able to
 	 * handle the case that fdin and fdout are the same.
 	 */
-	session_set_fds(s, inout[1], inout[1], err[1],
-	    s->is_subsystem, 0);
+	if (compat20) {
+		session_set_fds(s, inout[1], inout[1], err[1],
+		    s->is_subsystem, 0);
+	} else {
+		server_loop(pid, inout[1], inout[1], err[1]);
+		/* server_loop has closed inout[1] and err[1]. */
+	}
 #endif
 	return 0;
 }
@@ -575,7 +750,12 @@
 	s->ptymaster = ptymaster;
 	packet_set_interactive(1, 
 	    options.ip_qos_interactive, options.ip_qos_bulk);
-	session_set_fds(s, ptyfd, fdout, -1, 1, 1);
+	if (compat20) {
+		session_set_fds(s, ptyfd, fdout, -1, 1, 1);
+	} else {
+		server_loop(pid, ptyfd, fdout, -1);
+		/* server_loop _has_ closed ptyfd and fdout. */
+	}
 	return 0;
 }
 
@@ -1056,6 +1236,36 @@
 	if (getenv("TZ"))
 		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
 
+#ifdef __ANDROID__
+{
+#define COPY_ANDROID_ENV(name)	{			\
+	char *s = getenv(name);				\
+	if (s)	child_set_env(&env, &envsize, name, s); }
+
+	/* from /init.rc */
+	COPY_ANDROID_ENV("ANDROID_BOOTLOGO");
+	COPY_ANDROID_ENV("ANDROID_ROOT");
+	COPY_ANDROID_ENV("ANDROID_ASSETS");
+	COPY_ANDROID_ENV("ANDROID_DATA");
+	COPY_ANDROID_ENV("ASEC_MOUNTPOINT");
+	COPY_ANDROID_ENV("LOOP_MOUNTPOINT");
+	COPY_ANDROID_ENV("BOOTCLASSPATH");
+
+	/* FIXME: keep android property workspace open
+	 * (see openbsd-compat/bsd-closefrom.c)
+	 */
+	COPY_ANDROID_ENV("ANDROID_PROPERTY_WORKSPACE");
+
+	COPY_ANDROID_ENV("EXTERNAL_STORAGE");		/* ??? */
+	COPY_ANDROID_ENV("SECONDARY_STORAGE");		/* ??? */
+	COPY_ANDROID_ENV("SD_EXT_DIRECTORY");		/* ??? */
+
+	/* may contain path to custom libraries */
+	COPY_ANDROID_ENV("LD_LIBRARY_PATH");
+#undef COPY_ANDROID_ENV
+}
+#endif
+
 	/* Set custom environment options from RSA authentication. */
 	while (custom_environment) {
 		struct envstring *ce = custom_environment;
@@ -1876,8 +2086,14 @@
 	}
 
 	s->term = packet_get_string(&len);
-	s->col = packet_get_int();
-	s->row = packet_get_int();
+
+	if (compat20) {
+		s->col = packet_get_int();
+		s->row = packet_get_int();
+	} else {
+		s->row = packet_get_int();
+		s->col = packet_get_int();
+	}
 	s->xpixel = packet_get_int();
 	s->ypixel = packet_get_int();
 
@@ -1899,7 +2115,9 @@
 	}
 	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
 
-	n_bytes = packet_remaining();
+	/* for SSH1 the tty modes length is not given */
+	if (!compat20)
+		n_bytes = packet_remaining();
 	tty_parse_modes(s->ttyfd, &n_bytes);
 
 	if (!use_privsep)
@@ -2115,6 +2333,8 @@
 session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
     int is_tty)
 {
+	if (!compat20)
+		fatal("session_set_fds: called for proto != 2.0");
 	/*
 	 * now that have a child and a pipe to the child,
 	 * we can activate our channel and register the fd's
@@ -2549,7 +2769,7 @@
 #endif
 
 #ifdef GSSAPI
-	if (options.gss_cleanup_creds)
+	if (compat20 && options.gss_cleanup_creds)
 		ssh_gssapi_cleanup_creds();
 #endif
 
diff -ruN openssh-7.5p1/session.h openssh-7.5p1+x509-10.2/session.h
--- openssh-7.5p1/session.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/session.h	2017-05-20 21:07:00.000000000 +0300
@@ -51,6 +51,7 @@
 	char	*auth_data;
 	int	single_connection;
 
+	/* proto 2 */
 	int	chanid;
 	int	*x11_chanids;
 	int	is_subsystem;
diff -ruN openssh-7.5p1/sftp.0 openssh-7.5p1+x509-10.2/sftp.0
--- openssh-7.5p1/sftp.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sftp.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SFTP(1)                     General Commands Manual                    SFTP(1)
+SFTP(1)                   BSD General Commands Manual                  SFTP(1)
 
 NAME
-     sftp M-bM-^@M-^S secure file transfer program
+     sftp -- Secure file transfer program
 
 SYNOPSIS
      sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
@@ -15,20 +15,20 @@
 DESCRIPTION
      sftp is an interactive file transfer program, similar to ftp(1), which
      performs all operations over an encrypted ssh(1) transport.  It may also
-     use many features of ssh, such as public key authentication and
-     compression.  sftp connects and logs into the specified host, then enters
-     an interactive command mode.
-
-     The second usage format will retrieve files automatically if a non-
-     interactive authentication method is used; otherwise it will do so after
-     successful interactive authentication.
+     use many features of ssh, such as public key authentication and compres-
+     sion.  sftp connects and logs into the specified host, then enters an
+     interactive command mode.
+
+     The second usage format will retrieve files automatically if a non-inter-
+     active authentication method is used; otherwise it will do so after suc-
+     cessful interactive authentication.
 
      The third usage format allows sftp to start in a remote directory.
 
      The final usage format allows for automated sessions using the -b option.
-     In such cases, it is necessary to configure non-interactive
-     authentication to obviate the need to enter a password at connection time
-     (see sshd(8) and ssh-keygen(1) for details).
+     In such cases, it is necessary to configure non-interactive authentica-
+     tion to obviate the need to enter a password at connection time (see
+     sshd(8) and ssh-keygen(1) for details).
 
      Since some usage formats use colon characters to delimit host names from
      path names, IPv6 addresses must be enclosed in square brackets to avoid
@@ -58,12 +58,12 @@
              Batch mode reads a series of commands from an input batchfile
              instead of stdin.  Since it lacks user interaction it should be
              used in conjunction with non-interactive authentication.  A
-             batchfile of M-bM-^@M-^X-M-bM-^@M-^Y may be used to indicate standard input.  sftp
+             batchfile of '-' may be used to indicate standard input.  sftp
              will abort if any of the following commands fail: get, put,
              reget, reput, rename, ln, rm, mkdir, chdir, ls, lchdir, chmod,
              chown, chgrp, lpwd, df, symlink, and lmkdir.  Termination on
-             error can be suppressed on a command by command basis by
-             prefixing the command with a M-bM-^@M-^X-M-bM-^@M-^Y character (for example, -rm
+             error can be suppressed on a command by command basis by prefix-
+             ing the command with a '-' character (for example, -rm
              /tmp/blah*).
 
      -C      Enables compression (via ssh's -C flag).
@@ -80,9 +80,9 @@
              Specifies an alternative per-user configuration file for ssh(1).
              This option is directly passed to ssh(1).
 
-     -f      Requests that files be flushed to disk immediately after
-             transfer.  When uploading files, this feature is only enabled if
-             the server implements the "fsync@openssh.com" extension.
+     -f      Requests that files be flushed to disk immediately after trans-
+             fer.  When uploading files, this feature is only enabled if the
+             server implements the "fsync@openssh.com" extension.
 
      -i identity_file
              Selects the file from which the identity (private key) for public
@@ -97,71 +97,7 @@
              ssh_config(5).  This is useful for specifying options for which
              there is no separate sftp command-line flag.  For example, to
              specify an alternate port use: sftp -oPort=24.  For full details
-             of the options listed below, and their possible values, see
-             ssh_config(5).
-
-                   AddressFamily
-                   BatchMode
-                   BindAddress
-                   CanonicalDomains
-                   CanonicalizeFallbackLocal
-                   CanonicalizeHostname
-                   CanonicalizeMaxDots
-                   CanonicalizePermittedCNAMEs
-                   CertificateFile
-                   ChallengeResponseAuthentication
-                   CheckHostIP
-                   Cipher
-                   Ciphers
-                   Compression
-                   CompressionLevel
-                   ConnectionAttempts
-                   ConnectTimeout
-                   ControlMaster
-                   ControlPath
-                   ControlPersist
-                   GlobalKnownHostsFile
-                   GSSAPIAuthentication
-                   GSSAPIDelegateCredentials
-                   HashKnownHosts
-                   Host
-                   HostbasedAuthentication
-                   HostbasedKeyTypes
-                   HostKeyAlgorithms
-                   HostKeyAlias
-                   HostName
-                   IdentitiesOnly
-                   IdentityAgent
-                   IdentityFile
-                   IPQoS
-                   KbdInteractiveAuthentication
-                   KbdInteractiveDevices
-                   KexAlgorithms
-                   LogLevel
-                   MACs
-                   NoHostAuthenticationForLocalhost
-                   NumberOfPasswordPrompts
-                   PasswordAuthentication
-                   PKCS11Provider
-                   Port
-                   PreferredAuthentications
-                   Protocol
-                   ProxyCommand
-                   ProxyJump
-                   PubkeyAuthentication
-                   RekeyLimit
-                   RhostsRSAAuthentication
-                   RSAAuthentication
-                   SendEnv
-                   ServerAliveInterval
-                   ServerAliveCountMax
-                   StrictHostKeyChecking
-                   TCPKeepAlive
-                   UpdateHostKeys
-                   UsePrivilegedPort
-                   User
-                   UserKnownHostsFile
-                   VerifyHostKeyDNS
+             of the options and their possible values, see ssh_config(5).
 
      -P port
              Specifies the port to connect to on the remote host.
@@ -177,9 +113,9 @@
              Increasing this may slightly improve file transfer speed but will
              increase memory usage.  The default is 64 outstanding requests.
 
-     -r      Recursively copy entire directories when uploading and
-             downloading.  Note that sftp does not follow symbolic links
-             encountered in the tree traversal.
+     -r      Recursively copy entire directories when uploading and download-
+             ing.  Note that sftp does not follow symbolic links encountered
+             in the tree traversal.
 
      -S program
              Name of the program to use for the encrypted connection.  The
@@ -188,8 +124,8 @@
      -s subsystem | sftp_server
              Specifies the SSH2 subsystem or the path for an sftp server on
              the remote host.  A path is useful for using sftp over protocol
-             version 1, or when the remote sshd(8) does not have an sftp
-             subsystem configured.
+             version 1, or when the remote sshd(8) does not have an sftp sub-
+             system configured.
 
      -v      Raise logging level.  This option is also passed to ssh.
 
@@ -198,7 +134,7 @@
      those of ftp(1).  Commands are case insensitive.  Pathnames that contain
      spaces must be enclosed in quotes.  Any special characters contained
      within pathnames that are recognized by glob(3) must be escaped with
-     backslashes (M-bM-^@M-^X\M-bM-^@M-^Y).
+     backslashes ('\').
 
      bye     Quit sftp.
 
@@ -206,18 +142,16 @@
              Change remote directory to path.
 
      chgrp grp path
-             Change group of file path to grp.  path may contain glob(3)
-             characters and may match multiple files.  grp must be a numeric
-             GID.
+             Change group of file path to grp.  path may contain glob(3) char-
+             acters and may match multiple files.  grp must be a numeric GID.
 
      chmod mode path
              Change permissions of file path to mode.  path may contain
              glob(3) characters and may match multiple files.
 
      chown own path
-             Change owner of file path to own.  path may contain glob(3)
-             characters and may match multiple files.  own must be a numeric
-             UID.
+             Change owner of file path to own.  path may contain glob(3) char-
+             acters and may match multiple files.  own must be a numeric UID.
 
      df [-hi] [path]
              Display usage information for the filesystem holding the current
@@ -225,7 +159,7 @@
              the capacity information will be displayed using "human-readable"
              suffixes.  The -i flag requests display of inode information in
              addition to capacity information.  This command is only supported
-             on servers that implement the M-bM-^@M-^\statvfs@openssh.comM-bM-^@M-^] extension.
+             on servers that implement the ``statvfs@openssh.com'' extension.
 
      exit    Quit sftp.
 
@@ -234,8 +168,8 @@
              the local path name is not specified, it is given the same name
              it has on the remote machine.  remote-path may contain glob(3)
              characters and may match multiple files.  If it does and
-             local-path is specified, then local-path must specify a
-             directory.
+             local-path is specified, then local-path must specify a direc-
+             tory.
 
              If the -a flag is specified, then attempt to resume partial
              transfers of existing files.  Note that resumption assumes that
@@ -246,8 +180,8 @@
              If the -f flag is specified, then fsync(2) will be called after
              the file transfer has completed to flush the file to disk.
 
-             If either the -P or -p flag is specified, then full file
-             permissions and access times are copied too.
+             If either the -P or -p flag is specified, then full file permis-
+             sions and access times are copied too.
 
              If the -r flag is specified then directories will be copied
              recursively.  Note that sftp does not follow symbolic links when
@@ -259,18 +193,18 @@
              Change local directory to path.
 
      lls [ls-options [path]]
-             Display local directory listing of either path or current
-             directory if path is not specified.  ls-options may contain any
-             flags supported by the local system's ls(1) command.  path may
-             contain glob(3) characters and may match multiple files.
+             Display local directory listing of either path or current direc-
+             tory if path is not specified.  ls-options may contain any flags
+             supported by the local system's ls(1) command.  path may contain
+             glob(3) characters and may match multiple files.
 
      lmkdir path
              Create local directory specified by path.
 
      ln [-s] oldpath newpath
-             Create a link from oldpath to newpath.  If the -s flag is
-             specified the created link is a symbolic link, otherwise it is a
-             hard link.
+             Create a link from oldpath to newpath.  If the -s flag is speci-
+             fied the created link is a symbolic link, otherwise it is a hard
+             link.
 
      lpwd    Print local working directory.
 
@@ -284,10 +218,10 @@
 
              -1      Produce single columnar output.
 
-             -a      List files beginning with a dot (M-bM-^@M-^X.M-bM-^@M-^Y).
+             -a      List files beginning with a dot ('.').
 
-             -f      Do not sort the listing.  The default sort order is
-                     lexicographical.
+             -f      Do not sort the listing.  The default sort order is lexi-
+                     cographical.
 
              -h      When used with a long format option, use unit suffixes:
                      Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte,
@@ -295,8 +229,8 @@
                      four or fewer using powers of 2 for sizes (K=1024,
                      M=1048576, etc.).
 
-             -l      Display additional details including permissions and
-                     ownership information.
+             -l      Display additional details including permissions and own-
+                     ership information.
 
              -n      Produce a long listing with user and group information
                      presented numerically.
@@ -319,10 +253,9 @@
      put [-afPpr] local-path [remote-path]
              Upload local-path and store it on the remote machine.  If the
              remote path name is not specified, it is given the same name it
-             has on the local machine.  local-path may contain glob(3)
-             characters and may match multiple files.  If it does and
-             remote-path is specified, then remote-path must specify a
-             directory.
+             has on the local machine.  local-path may contain glob(3) charac-
+             ters and may match multiple files.  If it does and remote-path is
+             specified, then remote-path must specify a directory.
 
              If the -a flag is specified, then attempt to resume partial
              transfers of existing files.  Note that resumption assumes that
@@ -335,8 +268,8 @@
              Note that this is only supported by servers that implement the
              "fsync@openssh.com" extension.
 
-             If either the -P or -p flag is specified, then full file
-             permissions and access times are copied too.
+             If either the -P or -p flag is specified, then full file permis-
+             sions and access times are copied too.
 
              If the -r flag is specified then directories will be copied
              recursively.  Note that sftp does not follow symbolic links when
@@ -383,4 +316,4 @@
      T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
      filexfer-00.txt, January 2001, work in progress material.
 
-OpenBSD 6.0                      July 16, 2016                     OpenBSD 6.0
+BSD                              July 16, 2016                             BSD
diff -ruN openssh-7.5p1/sftp.1 openssh-7.5p1+x509-10.2/sftp.1
--- openssh-7.5p1/sftp.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sftp.1	2017-05-20 21:07:00.000000000 +0300
@@ -22,12 +22,20 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .Dd $Mdocdate: July 16 2016 $
 .Dt SFTP 1
 .Os
 .Sh NAME
 .Nm sftp
-.Nd secure file transfer program
+.Nd Secure file transfer program
 .Sh SYNOPSIS
 .Nm sftp
 .Bk -words
@@ -186,73 +194,8 @@
 command-line flag.
 For example, to specify an alternate port use:
 .Ic sftp -oPort=24 .
-For full details of the options listed below, and their possible values, see
+For full details of the options and their possible values, see
 .Xr ssh_config 5 .
-.Pp
-.Bl -tag -width Ds -offset indent -compact
-.It AddressFamily
-.It BatchMode
-.It BindAddress
-.It CanonicalDomains
-.It CanonicalizeFallbackLocal
-.It CanonicalizeHostname
-.It CanonicalizeMaxDots
-.It CanonicalizePermittedCNAMEs
-.It CertificateFile
-.It ChallengeResponseAuthentication
-.It CheckHostIP
-.It Cipher
-.It Ciphers
-.It Compression
-.It CompressionLevel
-.It ConnectionAttempts
-.It ConnectTimeout
-.It ControlMaster
-.It ControlPath
-.It ControlPersist
-.It GlobalKnownHostsFile
-.It GSSAPIAuthentication
-.It GSSAPIDelegateCredentials
-.It HashKnownHosts
-.It Host
-.It HostbasedAuthentication
-.It HostbasedKeyTypes
-.It HostKeyAlgorithms
-.It HostKeyAlias
-.It HostName
-.It IdentitiesOnly
-.It IdentityAgent
-.It IdentityFile
-.It IPQoS
-.It KbdInteractiveAuthentication
-.It KbdInteractiveDevices
-.It KexAlgorithms
-.It LogLevel
-.It MACs
-.It NoHostAuthenticationForLocalhost
-.It NumberOfPasswordPrompts
-.It PasswordAuthentication
-.It PKCS11Provider
-.It Port
-.It PreferredAuthentications
-.It Protocol
-.It ProxyCommand
-.It ProxyJump
-.It PubkeyAuthentication
-.It RekeyLimit
-.It RhostsRSAAuthentication
-.It RSAAuthentication
-.It SendEnv
-.It ServerAliveInterval
-.It ServerAliveCountMax
-.It StrictHostKeyChecking
-.It TCPKeepAlive
-.It UpdateHostKeys
-.It UsePrivilegedPort
-.It User
-.It UserKnownHostsFile
-.It VerifyHostKeyDNS
-.El
 .It Fl P Ar port
 Specifies the port to connect to on the remote host.
 .It Fl p
diff -ruN openssh-7.5p1/sftp.c openssh-7.5p1+x509-10.2/sftp.c
--- openssh-7.5p1/sftp.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sftp.c	2017-05-20 21:07:01.000000000 +0300
@@ -71,6 +71,19 @@
 #include "sftp-common.h"
 #include "sftp-client.h"
 
+#ifndef HAVE_MBLEN
+/* on Android function mblen is declared but not defined ! */
+/* multibyte character support */
+extern int mblen(const char *, size_t);
+
+inline int
+mblen(const char *s, size_t n) {
+	(void)s;
+	(void)n;
+	return 1;
+}
+#endif
+
 #define DEFAULT_COPY_BUFLEN	32768	/* Size of buffer for up/download */
 #define DEFAULT_NUM_REQUESTS	64	/* # concurrent outstanding requests */
 
diff -ruN openssh-7.5p1/sftp-server.0 openssh-7.5p1+x509-10.2/sftp-server.0
--- openssh-7.5p1/sftp-server.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sftp-server.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SFTP-SERVER(8)              System Manager's Manual             SFTP-SERVER(8)
+SFTP-SERVER(8)            BSD System Manager's Manual           SFTP-SERVER(8)
 
 NAME
-     sftp-server M-bM-^@M-^S SFTP server subsystem
+     sftp-server -- Secure FTP server subsystem
 
 SYNOPSIS
      sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level]
@@ -21,13 +21,13 @@
      Valid options are:
 
      -d start_directory
-             specifies an alternate starting directory for users.  The
-             pathname may contain the following tokens that are expanded at
-             runtime: %% is replaced by a literal '%', %d is replaced by the
-             home directory of the user being authenticated, and %u is
-             replaced by the username of that user.  The default is to use the
-             user's home directory.  This option is useful in conjunction with
-             the sshd_config(5) ChrootDirectory option.
+             specifies an alternate starting directory for users.  The path-
+             name may contain the following tokens that are expanded at run-
+             time: %% is replaced by a literal '%', %d is replaced by the home
+             directory of the user being authenticated, and %u is replaced by
+             the username of that user.  The default is to use the user's home
+             directory.  This option is useful in conjunction with the
+             sshd_config(5) ChrootDirectory option.
 
      -e      Causes sftp-server to print logging information to stderr instead
              of syslog for debugging.
@@ -41,8 +41,8 @@
      -h      Displays sftp-server usage information.
 
      -l log_level
-             Specifies which messages will be logged by sftp-server.  The
-             possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG,
+             Specifies which messages will be logged by sftp-server.  The pos-
+             sible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG,
              DEBUG1, DEBUG2, and DEBUG3.  INFO and VERBOSE log transactions
              that sftp-server performs on behalf of the client.  DEBUG and
              DEBUG1 are equivalent.  DEBUG2 and DEBUG3 each specify higher
@@ -65,8 +65,8 @@
 
      -Q protocol_feature
              Query protocol features supported by sftp-server.  At present the
-             only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be used
-             for black or whitelisting (flags -P and -p respectively).
+             only feature that may be queried is ``requests'', which may be
+             used for black or whitelisting (flags -P and -p respectively).
 
      -R      Places this instance of sftp-server into a read-only mode.
              Attempts to open files for writing, as well as other operations
@@ -93,4 +93,4 @@
 AUTHORS
      Markus Friedl <markus@openbsd.org>
 
-OpenBSD 6.0                    December 11, 2014                   OpenBSD 6.0
+BSD                            December 11, 2014                           BSD
diff -ruN openssh-7.5p1/sftp-server.8 openssh-7.5p1+x509-10.2/sftp-server.8
--- openssh-7.5p1/sftp-server.8	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sftp-server.8	2017-05-20 21:07:00.000000000 +0300
@@ -22,12 +22,20 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .Dd $Mdocdate: December 11 2014 $
 .Dt SFTP-SERVER 8
 .Os
 .Sh NAME
 .Nm sftp-server
-.Nd SFTP server subsystem
+.Nd Secure FTP server subsystem
 .Sh SYNOPSIS
 .Nm sftp-server
 .Bk -words
diff -ruN openssh-7.5p1/ssh.0 openssh-7.5p1+x509-10.2/ssh.0
--- openssh-7.5p1/ssh.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,12 +1,12 @@
-SSH(1)                      General Commands Manual                     SSH(1)
+SSH(1)                    BSD General Commands Manual                   SSH(1)
 
 NAME
-     ssh M-bM-^@M-^S OpenSSH SSH client (remote login program)
+     ssh -- Secure shell client (remote login program)
 
 SYNOPSIS
-     ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
+     ssh [-1246AaCdfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
          [-D [bind_address:]port] [-E log_file] [-e escape_char]
-         [-F configfile] [-I pkcs11] [-i identity_file]
+         [-F configfile] [-G engine_configfile] [-I pkcs11] [-i identity_file]
          [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
          [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
          [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
@@ -46,7 +46,8 @@
              the forwarded connection.  An attacker cannot obtain key material
              from the agent, however they can perform operations on the keys
              that enable them to authenticate using the identities loaded into
-             the agent.
+             the agent.  Using the -c flag of ssh-add(1) can reduce (but not
+             eliminate) the risk.
 
      -a      Disables forwarding of the authentication agent connection.
 
@@ -56,26 +57,25 @@
              address.
 
      -C      Requests compression of all data (including stdin, stdout,
-             stderr, and data for forwarded X11, TCP and UNIX-domain
-             connections).  The compression algorithm is the same used by
-             gzip(1), and the M-bM-^@M-^\levelM-bM-^@M-^] can be controlled by the
-             CompressionLevel option for protocol version 1.  Compression is
-             desirable on modem lines and other slow connections, but will
-             only slow down things on fast networks.  The default value can be
-             set on a host-by-host basis in the configuration files; see the
-             Compression option.
+             stderr, and data for forwarded X11, TCP and UNIX-domain connec-
+             tions).  The compression algorithm is the same used by gzip(1),
+             and the ``level'' can be controlled by the CompressionLevel
+             option for protocol version 1.  Compression is desirable on modem
+             lines and other slow connections, but will only slow down things
+             on fast networks.  The default value can be set on a host-by-host
+             basis in the configuration files; see the Compression option.
 
      -c cipher_spec
              Selects the cipher specification for encrypting the session.
 
              Protocol version 1 allows specification of a single cipher.  The
-             supported values are M-bM-^@M-^\3desM-bM-^@M-^], M-bM-^@M-^\blowfishM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^].  For protocol
-             version 2, cipher_spec is a comma-separated list of ciphers
-             listed in order of preference.  See the Ciphers keyword in
-             ssh_config(5) for more information.
+             supported values are ``3des'', ``blowfish'', and ``des''.  For
+             protocol version 2, cipher_spec is a comma-separated list of
+             ciphers listed in order of preference.  See the Ciphers keyword
+             in ssh_config(5) for more information.
 
      -D [bind_address:]port
-             Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding.
+             Specifies a local ``dynamic'' application-level port forwarding.
              This works by allocating a socket to listen to port on the local
              side, optionally bound to the specified bind_address.  Whenever a
              connection is made to this port, the connection is forwarded over
@@ -83,33 +83,35 @@
              determine where to connect to from the remote machine.  Currently
              the SOCKS4 and SOCKS5 protocols are supported, and ssh will act
              as a SOCKS server.  Only root can forward privileged ports.
-             Dynamic port forwardings can also be specified in the
-             configuration file.
+             Dynamic port forwardings can also be specified in the configura-
+             tion file.
 
              IPv6 addresses can be specified by enclosing the address in
              square brackets.  Only the superuser can forward privileged
              ports.  By default, the local port is bound in accordance with
              the GatewayPorts setting.  However, an explicit bind_address may
              be used to bind the connection to a specific address.  The
-             bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be
-             bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates
-             that the port should be available from all interfaces.
+             bind_address of ``localhost'' indicates that the listening port
+             be bound for local use only, while an empty address or '*' indi-
+             cates that the port should be available from all interfaces.
 
+     -d      Causes ssh to print its configuration after evaluating Host and
+             Match blocks and exit.
      -E log_file
              Append debug logs to log_file instead of standard error.
 
      -e escape_char
-             Sets the escape character for sessions with a pty (default: M-bM-^@M-^X~M-bM-^@M-^Y).
+             Sets the escape character for sessions with a pty (default: '~').
              The escape character is only recognized at the beginning of a
-             line.  The escape character followed by a dot (M-bM-^@M-^X.M-bM-^@M-^Y) closes the
+             line.  The escape character followed by a dot ('.') closes the
              connection; followed by control-Z suspends the connection; and
              followed by itself sends the escape character once.  Setting the
-             character to M-bM-^@M-^\noneM-bM-^@M-^] disables any escapes and makes the session
+             character to ``none'' disables any escapes and makes the session
              fully transparent.
 
      -F configfile
-             Specifies an alternative per-user configuration file.  If a
-             configuration file is given on the command line, the system-wide
+             Specifies an alternative per-user configuration file.  If a con-
+             figuration file is given on the command line, the system-wide
              configuration file (/etc/ssh/ssh_config) will be ignored.  The
              default for the per-user configuration file is ~/.ssh/config.
 
@@ -119,41 +121,44 @@
              implies -n.  The recommended way to start X11 programs at a
              remote site is with something like ssh -f host xterm.
 
-             If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^],
-             then a client started with -f will wait for all remote port
-             forwards to be successfully established before placing itself in
-             the background.
-
-     -G      Causes ssh to print its configuration after evaluating Host and
-             Match blocks and exit.
-
+             If the ExitOnForwardFailure configuration option is set to
+             ``yes'', then a client started with -f will wait for all remote
+             port forwards to be successfully established before placing
+             itself in the background.
+
+     -G engine_configfile
+             Specifies an alternative per-user file for post initialization of
+             openssl(1) engines.  The default per-user configuration file is
+             ~/.ssh/engine.
      -g      Allows remote hosts to connect to local forwarded ports.  If used
              on a multiplexed connection, then this option must be specified
              on the master process.
 
      -I pkcs11
              Specify the PKCS#11 shared library ssh should use to communicate
-             with a PKCS#11 token providing the user's private RSA key.
+             with a PKCS#11 token providing the user's private EC or RSA key
+             and X.509 certificate.
 
      -i identity_file
              Selects a file from which the identity (private key) for public
              key authentication is read.  The default is ~/.ssh/identity for
              protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa,
-             ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2.
-             Identity files may also be specified on a per-host basis in the
-             configuration file.  It is possible to have multiple -i options
-             (and multiple identities specified in configuration files).  If
-             no certificates have been explicitly specified by the
-             CertificateFile directive, ssh will also try to load certificate
-             information from the filename obtained by appending -cert.pub to
-             identity filenames.
+             ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2.  In
+             addition for protocol version 2, identity may contain X.509 cer-
+             tificate that match private key.  Identity files may also be
+             specified on a per-host basis in the configuration file.  It is
+             possible to have multiple -i options (and multiple identities
+             specified in configuration files).  If no certificates have been
+             explicitly specified by the CertificateFile directive, ssh will
+             also try to load certificate information from the filename
+             obtained by appending -cert.pub to identity filenames.
 
      -J [user@]host[:port]
              Connect to the target host by first making a ssh connection to
-             the jump host and then establishing a TCP forwarding to the
-             ultimate destination from there.  Multiple jump hops may be
-             specified separated by comma characters.  This is a shortcut to
-             specify a ProxyJump configuration directive.
+             the jump host and then establishing a TCP forwarding to the ulti-
+             mate destination from there.  Multiple jump hops may be specified
+             separated by comma characters.  This is a shortcut to specify a
+             ProxyJump configuration directive.
 
      -K      Enables GSSAPI-based authentication and forwarding (delegation)
              of GSSAPI credentials to the server.
@@ -182,27 +187,27 @@
              By default, the local port is bound in accordance with the
              GatewayPorts setting.  However, an explicit bind_address may be
              used to bind the connection to a specific address.  The
-             bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be
-             bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates
-             that the port should be available from all interfaces.
+             bind_address of ``localhost'' indicates that the listening port
+             be bound for local use only, while an empty address or '*' indi-
+             cates that the port should be available from all interfaces.
 
      -l login_name
              Specifies the user to log in as on the remote machine.  This also
              may be specified on a per-host basis in the configuration file.
 
-     -M      Places the ssh client into M-bM-^@M-^\masterM-bM-^@M-^] mode for connection sharing.
-             Multiple -M options places ssh into M-bM-^@M-^\masterM-bM-^@M-^] mode with
+     -M      Places the ssh client into ``master'' mode for connection shar-
+             ing.  Multiple -M options places ssh into ``master'' mode with
              confirmation required before slave connections are accepted.
              Refer to the description of ControlMaster in ssh_config(5) for
              details.
 
      -m mac_spec
-             A comma-separated list of MAC (message authentication code)
-             algorithms, specified in order of preference.  See the MACs
-             keyword for more information.
+             A comma-separated list of MAC (message authentication code) algo-
+             rithms, specified in order of preference.  See the MACs keyword
+             for more information.
 
-     -N      Do not execute a remote command.  This is useful for just
-             forwarding ports.
+     -N      Do not execute a remote command.  This is useful for just for-
+             warding ports.
 
      -n      Redirects stdin from /dev/null (actually, prevents reading from
              stdin).  This must be used when ssh is run in the background.  A
@@ -217,121 +222,33 @@
      -O ctl_cmd
              Control an active connection multiplexing master process.  When
              the -O option is specified, the ctl_cmd argument is interpreted
-             and passed to the master process.  Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^]
-             (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request
-             forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel
-             forwardings), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^]
+             and passed to the master process.  Valid commands are: ``check''
+             (check that the master process is running), ``forward'' (request
+             forwardings without command execution), ``cancel'' (cancel for-
+             wardings), ``exit'' (request the master to exit), and ``stop''
              (request the master to stop accepting further multiplexing
              requests).
 
      -o option
-             Can be used to give options in the format used in the
-             configuration file.  This is useful for specifying options for
-             which there is no separate command-line flag.  For full details
-             of the options listed below, and their possible values, see
-             ssh_config(5).
-
-                   AddKeysToAgent
-                   AddressFamily
-                   BatchMode
-                   BindAddress
-                   CanonicalDomains
-                   CanonicalizeFallbackLocal
-                   CanonicalizeHostname
-                   CanonicalizeMaxDots
-                   CanonicalizePermittedCNAMEs
-                   CertificateFile
-                   ChallengeResponseAuthentication
-                   CheckHostIP
-                   Cipher
-                   Ciphers
-                   ClearAllForwardings
-                   Compression
-                   CompressionLevel
-                   ConnectionAttempts
-                   ConnectTimeout
-                   ControlMaster
-                   ControlPath
-                   ControlPersist
-                   DynamicForward
-                   EscapeChar
-                   ExitOnForwardFailure
-                   FingerprintHash
-                   ForwardAgent
-                   ForwardX11
-                   ForwardX11Timeout
-                   ForwardX11Trusted
-                   GatewayPorts
-                   GlobalKnownHostsFile
-                   GSSAPIAuthentication
-                   GSSAPIDelegateCredentials
-                   HashKnownHosts
-                   Host
-                   HostbasedAuthentication
-                   HostbasedKeyTypes
-                   HostKeyAlgorithms
-                   HostKeyAlias
-                   HostName
-                   IdentitiesOnly
-                   IdentityAgent
-                   IdentityFile
-                   Include
-                   IPQoS
-                   KbdInteractiveAuthentication
-                   KbdInteractiveDevices
-                   KexAlgorithms
-                   LocalCommand
-                   LocalForward
-                   LogLevel
-                   MACs
-                   Match
-                   NoHostAuthenticationForLocalhost
-                   NumberOfPasswordPrompts
-                   PasswordAuthentication
-                   PermitLocalCommand
-                   PKCS11Provider
-                   Port
-                   PreferredAuthentications
-                   Protocol
-                   ProxyCommand
-                   ProxyJump
-                   ProxyUseFdpass
-                   PubkeyAcceptedKeyTypes
-                   PubkeyAuthentication
-                   RekeyLimit
-                   RemoteForward
-                   RequestTTY
-                   RhostsRSAAuthentication
-                   RSAAuthentication
-                   SendEnv
-                   ServerAliveInterval
-                   ServerAliveCountMax
-                   StreamLocalBindMask
-                   StreamLocalBindUnlink
-                   StrictHostKeyChecking
-                   TCPKeepAlive
-                   Tunnel
-                   TunnelDevice
-                   UpdateHostKeys
-                   UsePrivilegedPort
-                   User
-                   UserKnownHostsFile
-                   VerifyHostKeyDNS
-                   VisualHostKey
-                   XAuthLocation
+             Can be used to give options in the format used in the configura-
+             tion file.  This is useful for specifying options for which there
+             is no separate command-line flag.  For full details of the
+             options and their possible values, see ssh_config(5).
 
      -p port
              Port to connect to on the remote host.  This can be specified on
              a per-host basis in the configuration file.
 
      -Q query_option
-             Queries ssh for the algorithms supported for the specified
-             version 2.  The available features are: cipher (supported
-             symmetric ciphers), cipher-auth (supported symmetric ciphers that
-             support authenticated encryption), mac (supported message
-             integrity codes), kex (key exchange algorithms), key (key types),
-             key-cert (certificate key types), key-plain (non-certificate key
-             types), and protocol-version (supported SSH protocol versions).
+             Queries ssh for the algorithms supported for the specified ver-
+             sion 2.  The available features are: cipher (supported symmetric
+             ciphers), cipher-auth (supported symmetric ciphers that support
+             authenticated encryption), mac (supported message integrity
+             codes), kex (key exchange algorithms), key (key types), key-cert
+             (certificate key types), key-plain (non-certificate key types),
+             and protocol-version (supported SSH protocol versions).  This
+             option must be specified last as other options may impact list of
+             supported algorithms.
 
      -q      Quiet mode.  Causes most warning and diagnostic messages to be
              suppressed.
@@ -342,8 +259,8 @@
      -R remote_socket:local_socket
              Specifies that connections to the given TCP port or Unix socket
              on the remote (server) host are to be forwarded to the given host
-             and port, or Unix socket, on the local side.  This works by
-             allocating a socket to listen to either a TCP port or to a Unix
+             and port, or Unix socket, on the local side.  This works by allo-
+             cating a socket to listen to either a TCP port or to a Unix
              socket on the remote side.  Whenever a connection is made to this
              port or Unix socket, the connection is forwarded over the secure
              channel, and a connection is made to either host port hostport,
@@ -355,28 +272,27 @@
              the address in square brackets.
 
              By default, TCP listening sockets on the server will be bound to
-             the loopback interface only.  This may be overridden by
-             specifying a bind_address.  An empty bind_address, or the address
-             M-bM-^@M-^X*M-bM-^@M-^Y, indicates that the remote socket should listen on all
-             interfaces.  Specifying a remote bind_address will only succeed
-             if the server's GatewayPorts option is enabled (see
-             sshd_config(5)).
+             the loopback interface only.  This may be overridden by specify-
+             ing a bind_address.  An empty bind_address, or the address '*',
+             indicates that the remote socket should listen on all interfaces.
+             Specifying a remote bind_address will only succeed if the
+             server's GatewayPorts option is enabled (see sshd_config(5)).
 
-             If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically
+             If the port argument is '0', the listen port will be dynamically
              allocated on the server and reported to the client at run time.
              When used together with -O forward the allocated port will be
              printed to the standard output.
 
      -S ctl_path
-             Specifies the location of a control socket for connection
-             sharing, or the string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing.
-             Refer to the description of ControlPath and ControlMaster in
+             Specifies the location of a control socket for connection shar-
+             ing, or the string ``none'' to disable connection sharing.  Refer
+             to the description of ControlPath and ControlMaster in
              ssh_config(5) for details.
 
      -s      May be used to request invocation of a subsystem on the remote
-             system.  Subsystems facilitate the use of SSH as a secure
-             transport for other applications (e.g. sftp(1)).  The subsystem
-             is specified as the remote command.
+             system.  Subsystems facilitate the use of SSH as a secure trans-
+             port for other applications (e.g. sftp(1)).  The subsystem is
+             specified as the remote command.
 
      -T      Disable pseudo-terminal allocation.
 
@@ -388,16 +304,16 @@
      -V      Display the version number and exit.
 
      -v      Verbose mode.  Causes ssh to print debugging messages about its
-             progress.  This is helpful in debugging connection,
-             authentication, and configuration problems.  Multiple -v options
-             increase the verbosity.  The maximum is 3.
+             progress.  This is helpful in debugging connection, authentica-
+             tion, and configuration problems.  Multiple -v options increase
+             the verbosity.  The maximum is 3.
 
      -W host:port
-             Requests that standard input and output on the client be
-             forwarded to host on port over the secure channel.  Implies -N,
-             -T, ExitOnForwardFailure and ClearAllForwardings, though these
-             can be overridden in the configuration file or using -o command
-             line options.
+             Requests that standard input and output on the client be for-
+             warded to host on port over the secure channel.  Implies -N, -T,
+             ExitOnForwardFailure and ClearAllForwardings, though these can be
+             overridden in the configuration file or using -o command line
+             options.
 
      -w local_tun[:remote_tun]
              Requests tunnel device forwarding with the specified tun(4)
@@ -405,11 +321,11 @@
              (remote_tun).
 
              The devices may be specified by numerical ID or the keyword
-             M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device.  If
-             remote_tun is not specified, it defaults to M-bM-^@M-^\anyM-bM-^@M-^].  See also the
-             Tunnel and TunnelDevice directives in ssh_config(5).  If the
+             ``any'', which uses the next available tunnel device.  If
+             remote_tun is not specified, it defaults to ``any''.  See also
+             the Tunnel and TunnelDevice directives in ssh_config(5).  If the
              Tunnel directive is unset, it is set to the default tunnel mode,
-             which is M-bM-^@M-^\point-to-pointM-bM-^@M-^].
+             which is ``point-to-point''.
 
      -X      Enables X11 forwarding.  This can also be specified on a per-host
              basis in a configuration file.
@@ -433,22 +349,22 @@
      -y      Send log information using the syslog(3) system module.  By
              default this information is sent to stderr.
 
-     ssh may additionally obtain configuration data from a per-user
-     configuration file and a system-wide configuration file.  The file format
-     and configuration options are described in ssh_config(5).
+     ssh may additionally obtain configuration data from a per-user configura-
+     tion file and a system-wide configuration file.  The file format and con-
+     figuration options are described in ssh_config(5).
 
 AUTHENTICATION
-     The OpenSSH SSH client supports SSH protocols 1 and 2.  The default is to
-     use protocol 2 only, though this can be changed via the Protocol option
-     in ssh_config(5) or the -1 and -2 options (see above).  Protocol 1 should
+     The SecSH client supports SSH protocols 1 and 2.  The default is to use
+     protocol 2 only, though this can be changed via the Protocol option in
+     ssh_config(5) or the -1 and -2 options (see above).  Protocol 1 should
      not be used and is only offered to support legacy devices.  It suffers
      from a number of cryptographic weaknesses and doesn't support many of the
      advanced features available for protocol 2.
 
-     The methods available for authentication are: GSSAPI-based
-     authentication, host-based authentication, public key authentication,
-     challenge-response authentication, and password authentication.
-     Authentication methods are tried in the order specified above, though
+     The methods available for authentication are: GSSAPI-based authentica-
+     tion, host-based authentication, public key authentication, challenge-
+     response authentication, and password authentication.  Authentication
+     methods are tried in the order specified above, though
      PreferredAuthentications can be used to change the default order.
 
      Host-based authentication works as follows: If the machine the user logs
@@ -457,29 +373,31 @@
      ~/.rhosts or ~/.shosts exist in the user's home directory on the remote
      machine and contain a line containing the name of the client machine and
      the name of the user on that machine, the user is considered for login.
-     Additionally, the server must be able to verify the client's host key
-     (see the description of /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts,
-     below) for login to be permitted.  This authentication method closes
-     security holes due to IP spoofing, DNS spoofing, and routing spoofing.
-     [Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the
-     rlogin/rsh protocol in general, are inherently insecure and should be
-     disabled if security is desired.]
-
-     Public key authentication works as follows: The scheme is based on
-     public-key cryptography, using cryptosystems where encryption and
-     decryption are done using separate keys, and it is unfeasible to derive
-     the decryption key from the encryption key.  The idea is that each user
-     creates a public/private key pair for authentication purposes.  The
-     server knows the public key, and only the user knows the private key.
-     ssh implements public key authentication protocol automatically, using
-     one of the DSA, ECDSA, Ed25519 or RSA algorithms.  The HISTORY section of
-     ssl(8) contains a brief discussion of the DSA and RSA algorithms.
-
-     The file ~/.ssh/authorized_keys lists the public keys that are permitted
-     for logging in.  When the user logs in, the ssh program tells the server
-     which key pair it would like to use for authentication.  The client
-     proves that it has access to the private key and the server checks that
-     the corresponding public key is authorized to accept the account.
+     Additionally, the server must be able to verify the client's host key or
+     X.509 certificate (see the description of /etc/ssh/ssh_known_hosts and
+     ~/.ssh/known_hosts, below) for login to be permitted.  This authentica-
+     tion method closes security holes due to IP spoofing, DNS spoofing, and
+     routing spoofing.  [Note to the administrator: /etc/hosts.equiv,
+     ~/.rhosts, and the rlogin/rsh protocol in general, are inherently inse-
+     cure and should be disabled if security is desired.]
+
+     Public key authentication works as follows: The scheme is based on pub-
+     lic-key cryptography or infrastructure (PKI), using cryptosystems where
+     encryption and decryption are done using separate keys, and it is unfea-
+     sible to derive the decryption key from the encryption key.  The idea is
+     that each user creates a public/private key pair for authentication pur-
+     poses.  The server knows the public key or X.509 certificate, and only
+     the user knows the private key.  ssh implements public key authentication
+     protocol automatically, using one of the DSA, ECDSA, Ed25519 or RSA algo-
+     rithms or X.509 certificates.  The HISTORY section of ssl(8) contains a
+     brief discussion of the DSA and RSA algorithms.
+
+     The file ~/.ssh/authorized_keys lists the public keys or X.509 certifi-
+     cates that are permitted for logging in.  When the user logs in, the ssh
+     program tells the server which key pair or X.509 certificate it would
+     like to use for authentication.  The client proves that it has access to
+     the private key and the server checks that the corresponding public key
+     or X.509 certificate is authorized to accept the account.
 
      The user creates his/her key pair by running ssh-keygen(1).  This stores
      the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (DSA),
@@ -487,18 +405,22 @@
      (RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1),
      ~/.ssh/id_dsa.pub (DSA), ~/.ssh/id_ecdsa.pub (ECDSA),
      ~/.ssh/id_ed25519.pub (Ed25519), or ~/.ssh/id_rsa.pub (RSA) in the user's
-     home directory.  The user should then copy the public key to
-     ~/.ssh/authorized_keys in his/her home directory on the remote machine.
+     home directory.  For protocol version 2 identity files may contain pri-
+     vate key and X.509 certificate that match it.  In this case *.pub file
+     must contain that certificate.  The user should then copy the public key
+     or X.509 certificate to ~/.ssh/authorized_keys in his/her home directory
+     on the remote machine.  In case with X.509 certificates user can use
+     ``new style'' : instead to add content of file to authorized_keys user
+     can write certificate ``Distinguished Name'' - see sshd(8) manual page.
      The authorized_keys file corresponds to the conventional ~/.rhosts file,
-     and has one key per line, though the lines can be very long.  After this,
-     the user can log in without giving the password.
+     and has one key or X.509 certificate per line, though the lines can be
+     very long.  After this, the user can log in without giving the password.
 
-     A variation on public key authentication is available in the form of
-     certificate authentication: instead of a set of public/private keys,
-     signed certificates are used.  This has the advantage that a single
-     trusted certification authority can be used in place of many
-     public/private keys.  See the CERTIFICATES section of ssh-keygen(1) for
-     more information.
+     A variation on public key authentication is available in the form of cer-
+     tificate authentication: instead of a set of public/private keys, signed
+     certificates are used.  This has the advantage that a single trusted cer-
+     tification authority can be used in place of many public/private keys.
+     See the CERTIFICATES section of ssh-keygen(1) for more information.
 
      The most convenient way to use public key or certificate authentication
      may be with an authentication agent.  See ssh-agent(1) and (optionally)
@@ -514,16 +436,19 @@
      since all communications are encrypted, the password cannot be seen by
      someone listening on the network.
 
-     ssh automatically maintains and checks a database containing
-     identification for all hosts it has ever been used with.  Host keys are
-     stored in ~/.ssh/known_hosts in the user's home directory.  Additionally,
-     the file /etc/ssh/ssh_known_hosts is automatically checked for known
-     hosts.  Any new hosts are automatically added to the user's file.  If a
-     host's identification ever changes, ssh warns about this and disables
-     password authentication to prevent server spoofing or man-in-the-middle
-     attacks, which could otherwise be used to circumvent the encryption.  The
-     StrictHostKeyChecking option can be used to control logins to machines
-     whose host key is not known or has changed.
+     ssh automatically maintains and checks a database containing identifica-
+     tion for all hosts it has ever been used with.  Host keys are stored in
+     ~/.ssh/known_hosts in the user's home directory.  Additionally, the file
+     /etc/ssh/ssh_known_hosts is automatically checked for known hosts.  If
+     host key is a X.509 certificate line may contain certificate
+     ``Distinguished Name'' instead base64 encoded representation.  This is
+     support only if ``X.509 store'' is enabled.  Any new hosts are automati-
+     cally added to the user's file.  If a host's identification ever changes,
+     ssh warns about this and disables password authentication to prevent
+     server spoofing or man-in-the-middle attacks, which could otherwise be
+     used to circumvent the encryption.  The StrictHostKeyChecking option can
+     be used to control logins to machines whose host key is not known or has
+     changed.
 
      When the user's identity has been accepted by the server, the server
      either executes the given command in a non-interactive session or, if no
@@ -535,28 +460,28 @@
      pseudo-terminal (pty) for interactive sessions when the client has one.
      The flags -T and -t can be used to override this behaviour.
 
-     If a pseudo-terminal has been allocated the user may use the escape
-     characters noted below.
+     If a pseudo-terminal has been allocated the user may use the escape char-
+     acters noted below.
 
      If no pseudo-terminal has been allocated, the session is transparent and
      can be used to reliably transfer binary data.  On most systems, setting
-     the escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent
+     the escape character to ``none'' will also make the session transparent
      even if a tty is used.
 
      The session terminates when the command or shell on the remote machine
      exits and all X11 and TCP connections have been closed.
 
 ESCAPE CHARACTERS
-     When a pseudo-terminal has been requested, ssh supports a number of
-     functions through the use of an escape character.
+     When a pseudo-terminal has been requested, ssh supports a number of func-
+     tions through the use of an escape character.
 
      A single tilde character can be sent as ~~ or by following the tilde by a
      character other than those described below.  The escape character must
-     always follow a newline to be interpreted as special.  The escape
-     character can be changed in configuration files using the EscapeChar
-     configuration directive or on the command line by the -e option.
+     always follow a newline to be interpreted as special.  The escape charac-
+     ter can be changed in configuration files using the EscapeChar configura-
+     tion directive or on the command line by the -e option.
 
-     The supported escapes (assuming the default M-bM-^@M-^X~M-bM-^@M-^Y) are:
+     The supported escapes (assuming the default '~') are:
 
      ~.      Disconnect.
 
@@ -569,8 +494,8 @@
 
      ~?      Display a list of escape characters.
 
-     ~B      Send a BREAK to the remote system (only useful if the peer
-             supports it).
+     ~B      Send a BREAK to the remote system (only useful if the peer sup-
+             ports it).
 
      ~C      Open command line.  Currently this allows the addition of port
              forwardings using the -L, -R and -D options (see above).  It also
@@ -581,8 +506,8 @@
              PermitLocalCommand option is enabled in ssh_config(5).  Basic
              help is available, using the -h option.
 
-     ~R      Request rekeying of the connection (only useful if the peer
-             supports it).
+     ~R      Request rekeying of the connection (only useful if the peer sup-
+             ports it).
 
      ~V      Decrease the verbosity (LogLevel) when errors are being written
              to stderr.
@@ -599,43 +524,43 @@
      In the example below, we look at encrypting communication between an IRC
      client and server, even though the IRC server does not directly support
      encrypted communications.  This works as follows: the user connects to
-     the remote host using ssh, specifying a port to be used to forward
-     connections to the remote server.  After that it is possible to start the
+     the remote host using ssh, specifying a port to be used to forward con-
+     nections to the remote server.  After that it is possible to start the
      service which is to be encrypted on the client machine, connecting to the
      same local port, and ssh will encrypt and forward the connection.
 
      The following example tunnels an IRC session from client machine
-     M-bM-^@M-^\127.0.0.1M-bM-^@M-^] (localhost) to remote server M-bM-^@M-^\server.example.comM-bM-^@M-^]:
+     ``127.0.0.1'' (localhost) to remote server ``server.example.com'':
 
          $ ssh -f -L 1234:localhost:6667 server.example.com sleep 10
          $ irc -c '#users' -p 1234 pinky 127.0.0.1
 
-     This tunnels a connection to IRC server M-bM-^@M-^\server.example.comM-bM-^@M-^], joining
-     channel M-bM-^@M-^\#usersM-bM-^@M-^], nickname M-bM-^@M-^\pinkyM-bM-^@M-^], using port 1234.  It doesn't matter
-     which port is used, as long as it's greater than 1023 (remember, only
+     This tunnels a connection to IRC server ``server.example.com'', joining
+     channel ``#users'', nickname ``pinky'', using port 1234.  It doesn't mat-
+     ter which port is used, as long as it's greater than 1023 (remember, only
      root can open sockets on privileged ports) and doesn't conflict with any
      ports already in use.  The connection is forwarded to port 6667 on the
      remote server, since that's the standard port for IRC services.
 
-     The -f option backgrounds ssh and the remote command M-bM-^@M-^\sleep 10M-bM-^@M-^] is
+     The -f option backgrounds ssh and the remote command ``sleep 10'' is
      specified to allow an amount of time (10 seconds, in the example) to
      start the service which is to be tunnelled.  If no connections are made
      within the time specified, ssh will exit.
 
 X11 FORWARDING
-     If the ForwardX11 variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the
-     -X, -x, and -Y options above) and the user is using X11 (the DISPLAY
-     environment variable is set), the connection to the X11 display is
-     automatically forwarded to the remote side in such a way that any X11
-     programs started from the shell (or command) will go through the
-     encrypted channel, and the connection to the real X server will be made
-     from the local machine.  The user should not manually set DISPLAY.
-     Forwarding of X11 connections can be configured on the command line or in
-     configuration files.
+     If the ForwardX11 variable is set to ``yes'' (or see the description of
+     the -X, -x, and -Y options above) and the user is using X11 (the DISPLAY
+     environment variable is set), the connection to the X11 display is auto-
+     matically forwarded to the remote side in such a way that any X11 pro-
+     grams started from the shell (or command) will go through the encrypted
+     channel, and the connection to the real X server will be made from the
+     local machine.  The user should not manually set DISPLAY.  Forwarding of
+     X11 connections can be configured on the command line or in configuration
+     files.
 
      The DISPLAY value set by ssh will point to the server machine, but with a
      display number greater than zero.  This is normal, and happens because
-     ssh creates a M-bM-^@M-^\proxyM-bM-^@M-^] X server on the server machine for forwarding the
+     ssh creates a ``proxy'' X server on the server machine for forwarding the
      connections over the encrypted channel.
 
      ssh will also automatically set up Xauthority data on the server machine.
@@ -645,7 +570,7 @@
      is opened.  The real authentication cookie is never sent to the server
      machine (and no cookies are sent in the plain).
 
-     If the ForwardAgent variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of
+     If the ForwardAgent variable is set to ``yes'' (or see the description of
      the -A and -a options above) and the user is using an authentication
      agent, the connection to the agent is automatically forwarded to the
      remote side.
@@ -663,16 +588,16 @@
      are available, the ssh-keygen(1) -E option may be used to downgrade the
      fingerprint algorithm to match.
 
-     Because of the difficulty of comparing host keys just by looking at
-     fingerprint strings, there is also support to compare host keys visually,
-     using random art.  By setting the VisualHostKey option to M-bM-^@M-^\yesM-bM-^@M-^], a small
-     ASCII graphic gets displayed on every login to a server, no matter if the
-     session itself is interactive or not.  By learning the pattern a known
-     server produces, a user can easily find out that the host key has changed
-     when a completely different pattern is displayed.  Because these patterns
-     are not unambiguous however, a pattern that looks similar to the pattern
-     remembered only gives a good probability that the host key is the same,
-     not guaranteed proof.
+     Because of the difficulty of comparing host keys just by looking at fin-
+     gerprint strings, there is also support to compare host keys visually,
+     using random art.  By setting the VisualHostKey option to ``yes'', a
+     small ASCII graphic gets displayed on every login to a server, no matter
+     if the session itself is interactive or not.  By learning the pattern a
+     known server produces, a user can easily find out that the host key has
+     changed when a completely different pattern is displayed.  Because these
+     patterns are not unambiguous however, a pattern that looks similar to the
+     pattern remembered only gives a good probability that the host key is the
+     same, not guaranteed proof.
 
      To get a listing of the fingerprints along with their random art for all
      known hosts, the following command line can be used:
@@ -680,13 +605,14 @@
            $ ssh-keygen -lv -f ~/.ssh/known_hosts
 
      If the fingerprint is unknown, an alternative method of verification is
-     available: SSH fingerprints verified by DNS.  An additional resource
-     record (RR), SSHFP, is added to a zonefile and the connecting client is
-     able to match the fingerprint with that of the key presented.
+     available: SSH fingerprints or X.509 certificates verified by DNS.  An
+     additional resource record (RR), SSHFP or CERT, is added to a zonefile
+     and the connecting client is able to match the fingerprint or X.509 cer-
+     tificate with that of the key presented.
 
      In this example, we are connecting a client to a server,
-     M-bM-^@M-^\host.example.comM-bM-^@M-^].  The SSHFP resource records should first be added to
-     the zonefile for host.example.com:
+     ``host.example.com''.  The SSHFP or CERT resource records should first be
+     added to the zonefile for host.example.com:
 
            $ ssh-keygen -r host.example.com.
 
@@ -695,6 +621,10 @@
 
            $ dig -t SSHFP host.example.com
 
+     To check that the zone is answering X.509 certificate queries:
+
+           $ dig -t CERT host.example.com
+
      Finally the client connects:
 
            $ ssh -o "VerifyHostKeyDNS ask" host.example.com
@@ -702,14 +632,18 @@
            Matching host key fingerprint found in DNS.
            Are you sure you want to continue connecting (yes/no)?
 
+     When host key is a X.509 certificate ``Distinguished Name'' is displayed
+     after fingerprint.  Note that host X.509 certificate always is verifified
+     and validated if ``X.509 store'' is enabled.
+
      See the VerifyHostKeyDNS option in ssh_config(5) for more information.
 
 SSH-BASED VIRTUAL PRIVATE NETWORKS
      ssh contains support for Virtual Private Network (VPN) tunnelling using
      the tun(4) network pseudo-device, allowing two networks to be joined
      securely.  The sshd_config(5) configuration option PermitTunnel controls
-     whether the server supports this, and at what level (layer 2 or 3
-     traffic).
+     whether the server supports this, and at what level (layer 2 or 3 traf-
+     fic).
 
      The following example would connect client network 10.0.50.0/24 with
      remote network 10.0.99.0/24 using a point-to-point connection from
@@ -729,16 +663,16 @@
 
      Client access may be more finely tuned via the /root/.ssh/authorized_keys
      file (see below) and the PermitRootLogin server option.  The following
-     entry would permit connections on tun(4) device 1 from user M-bM-^@M-^\janeM-bM-^@M-^] and on
-     tun device 2 from user M-bM-^@M-^\johnM-bM-^@M-^], if PermitRootLogin is set to
-     M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^]:
+     entry would permit connections on tun(4) device 1 from user ``jane'' and
+     on tun device 2 from user ``john'', if PermitRootLogin is set to
+     ``forced-commands-only'':
 
        tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
        tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
 
      Since an SSH-based setup entails a fair amount of overhead, it may be
-     more suited to temporary setups, such as for wireless VPNs.  More
-     permanent VPNs are better provided by tools such as ipsecctl(8) and
+     more suited to temporary setups, such as for wireless VPNs.  More perma-
+     nent VPNs are better provided by tools such as ipsecctl(8) and
      isakmpd(8).
 
 ENVIRONMENT
@@ -746,24 +680,24 @@
 
      DISPLAY               The DISPLAY variable indicates the location of the
                            X11 server.  It is automatically set by ssh to
-                           point to a value of the form M-bM-^@M-^\hostname:nM-bM-^@M-^], where
-                           M-bM-^@M-^\hostnameM-bM-^@M-^] indicates the host where the shell runs,
-                           and M-bM-^@M-^XnM-bM-^@M-^Y is an integer M-bM-^IM-% 1.  ssh uses this special
-                           value to forward X11 connections over the secure
-                           channel.  The user should normally not set DISPLAY
-                           explicitly, as that will render the X11 connection
-                           insecure (and will require the user to manually
-                           copy any required authorization cookies).
+                           point to a value of the form ``hostname:n'', where
+                           ``hostname'' indicates the host where the shell
+                           runs, and 'n' is an integer >= 1.  ssh uses this
+                           special value to forward X11 connections over the
+                           secure channel.  The user should normally not set
+                           DISPLAY explicitly, as that will render the X11
+                           connection insecure (and will require the user to
+                           manually copy any required authorization cookies).
 
      HOME                  Set to the path of the user's home directory.
 
-     LOGNAME               Synonym for USER; set for compatibility with
-                           systems that use this variable.
+     LOGNAME               Synonym for USER; set for compatibility with sys-
+                           tems that use this variable.
 
      MAIL                  Set to the path of the user's mailbox.
 
-     PATH                  Set to the default PATH, as specified when
-                           compiling ssh.
+     PATH                  Set to the default PATH, as specified when compil-
+                           ing ssh.
 
      SSH_ASKPASS           If ssh needs a passphrase, it will read the
                            passphrase from the current terminal if it was run
@@ -771,38 +705,37 @@
                            associated with it but DISPLAY and SSH_ASKPASS are
                            set, it will execute the program specified by
                            SSH_ASKPASS and open an X11 window to read the
-                           passphrase.  This is particularly useful when
-                           calling ssh from a .xsession or related script.
-                           (Note that on some machines it may be necessary to
-                           redirect the input from /dev/null to make this
-                           work.)
+                           passphrase.  This is particularly useful when call-
+                           ing ssh from a .xsession or related script.  (Note
+                           that on some machines it may be necessary to redi-
+                           rect the input from /dev/null to make this work.)
 
      SSH_AUTH_SOCK         Identifies the path of a UNIX-domain socket used to
                            communicate with the agent.
 
-     SSH_CONNECTION        Identifies the client and server ends of the
-                           connection.  The variable contains four space-
-                           separated values: client IP address, client port
-                           number, server IP address, and server port number.
+     SSH_CONNECTION        Identifies the client and server ends of the con-
+                           nection.  The variable contains four space-sepa-
+                           rated values: client IP address, client port num-
+                           ber, server IP address, and server port number.
 
      SSH_ORIGINAL_COMMAND  This variable contains the original command line if
                            a forced command is executed.  It can be used to
                            extract the original arguments.
 
      SSH_TTY               This is set to the name of the tty (path to the
-                           device) associated with the current shell or
-                           command.  If the current session has no tty, this
+                           device) associated with the current shell or com-
+                           mand.  If the current session has no tty, this
                            variable is not set.
 
      TZ                    This variable is set to indicate the present time
                            zone if it was set when the daemon was started
-                           (i.e. the daemon passes the value on to new
-                           connections).
+                           (i.e. the daemon passes the value on to new connec-
+                           tions).
 
      USER                  Set to the name of the user logging in.
 
      Additionally, ssh reads ~/.ssh/environment, and adds lines of the format
-     M-bM-^@M-^\VARNAME=valueM-bM-^@M-^] to the environment if the file exists and users are
+     ``VARNAME=value'' to the environment if the file exists and users are
      allowed to change their environment.  For more information, see the
      PermitUserEnvironment option in sshd_config(5).
 
@@ -822,18 +755,27 @@
              rlogin/rsh.
 
      ~/.ssh/
-             This directory is the default location for all user-specific
-             configuration and authentication information.  There is no
-             general requirement to keep the entire contents of this directory
-             secret, but the recommended permissions are read/write/execute
-             for the user, and not accessible by others.
+             This directory is the default location for all user-specific con-
+             figuration and authentication information.  There is no general
+             requirement to keep the entire contents of this directory secret,
+             but the recommended permissions are read/write/execute for the
+             user, and not accessible by others.
 
      ~/.ssh/authorized_keys
-             Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used
-             for logging in as this user.  The format of this file is
-             described in the sshd(8) manual page.  This file is not highly
-             sensitive, but the recommended permissions are read/write for the
-             user, and not accessible by others.
+             Lists the public keys (DSA, ECDSA, Ed25519, RSA) or X.509 cer-
+             tificates that can be used for logging in as this user.  The for-
+             mat of this file is described in the sshd(8) manual page.  This
+             file is not highly sensitive, but the recommended permissions are
+             read/write for the user, and not accessible by others.
+
+     ~/.ssh/ca/ca-bundle.crt
+     ~/.ssh/ca/ca-bundle.crl
+             Part of user ``X.509 store''.  Same as systemwide files below.
+
+     ~/.ssh/ca/crt
+     ~/.ssh/ca/crl
+             Part of user ``X.509 store''.  Same as systemwide directories
+             below.
 
      ~/.ssh/config
              This is the per-user configuration file.  The file format and
@@ -851,26 +793,34 @@
      ~/.ssh/id_ed25519
      ~/.ssh/id_rsa
              Contains the private key for authentication.  These files contain
-             sensitive data and should be readable by the user but not
-             accessible by others (read/write/execute).  ssh will simply
-             ignore a private key file if it is accessible by others.  It is
-             possible to specify a passphrase when generating the key which
-             will be used to encrypt the sensitive part of this file using
-             3DES.
+             sensitive data and should be readable by the user but not acces-
+             sible by others (read/write/execute).
+
+             Identity for protocol version 2 may contain X.509 certificate
+             that match private key.  For x509v3-ecdsa-sha2-* public key algo-
+             rithms, file with ECDSA key may contain extra X.509 certificates.
+             Extra certificates along with certificates from X.509 store are
+             used to build chain of certificates leading to a trusted certifi-
+             cate authority.  ssh will simply ignore a private key file if it
+             is accessible by others.  It is possible to specify a passphrase
+             when generating the key which will be used to encrypt the sensi-
+             tive part of this file using 3DES.
 
      ~/.ssh/identity.pub
      ~/.ssh/id_dsa.pub
      ~/.ssh/id_ecdsa.pub
      ~/.ssh/id_ed25519.pub
      ~/.ssh/id_rsa.pub
-             Contains the public key for authentication.  These files are not
+             Contains the public key for authentication.  Note for protocol
+             version 2 if an identity contain private key and X.509 certifi-
+             cate, file must contain that certificate.  These files are not
              sensitive and can (but need not) be readable by anyone.
 
      ~/.ssh/known_hosts
-             Contains a list of host keys for all hosts the user has logged
-             into that are not already in the systemwide list of known host
-             keys.  See sshd(8) for further details of the format of this
-             file.
+             Contains a list of host keys or X.509 certificates for all hosts
+             the user has logged into that are not already in the systemwide
+             list of known host keys.  See sshd(8) for further details of the
+             format of this file.
 
      ~/.ssh/rc
              Commands in this file are executed by ssh when the user logs in,
@@ -886,6 +836,24 @@
              allows host-based authentication without permitting login with
              rlogin/rsh.
 
+     /etc/ssh/ca/ca-bundle.crt
+     /etc/ssh/ca/ca-bundle.crl
+             Part of systemwide ``X.509 store''.  The first file contain mul-
+             tiple certificates and the second ``Certificate Revocation List''
+             (CRLs) of X.509 certificate signers in PEM format concatenated
+             together.  Used in verification and validation of server host
+             certificate.
+
+     /etc/ssh/ca/crt
+     /etc/ssh/ca/crl
+             Part of systemwide ``X.509 store''.  ``Hash dirs'' with certifi-
+             cates, the first directory or CLRs, the second of certificate
+             signers.  Each certificate should be stored in separate file with
+             name [HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where
+             [HASH] is certificate or CRL hash value and [NUMBER] is an inte-
+             ger starting from zero.  Used in verification and validation of
+             server host certificate.
+
      /etc/ssh/ssh_config
              Systemwide configuration file.  The file format and configuration
              options are described in ssh_config(5).
@@ -896,13 +864,19 @@
      /etc/ssh/ssh_host_ed25519_key
      /etc/ssh/ssh_host_rsa_key
              These files contain the private parts of the host keys and are
-             used for host-based authentication.
+             used for host-based authentication.  For protocol version 2 keys
+             files may contain private part and X.509 certificate that match
+             it.  If a X.509 certificate is used as host key for hostbased
+             authentication that certificate must have client purpose too or
+             server configuration must permit connection without client pur-
+             pose. For allowed client certificate purposes see ssh_config(5).
 
      /etc/ssh/ssh_known_hosts
-             Systemwide list of known host keys.  This file should be prepared
-             by the system administrator to contain the public host keys of
-             all machines in the organization.  It should be world-readable.
-             See sshd(8) for further details of the format of this file.
+             Systemwide list of known host keys or X.509 certificates.  This
+             file should be prepared by the system administrator to contain
+             the public host keys or X.509 certificates of all machines in the
+             organization.  It should be world-readable.  See sshd(8) for fur-
+             ther details of the format of this file.
 
      /etc/ssh/sshrc
              Commands in this file are executed by ssh when the user logs in,
@@ -917,7 +891,7 @@
      scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1),
      tun(4), ssh_config(5), ssh-keysign(8), sshd(8)
 
-STANDARDS
+CONFORMING TO
      S. Lehtinen and C. Lonvick, The Secure Shell (SSH) Protocol Assigned
      Numbers, RFC 4250, January 2006.
 
@@ -961,11 +935,19 @@
      Real-World Security, 1999, International Workshop on Cryptographic
      Techniques and E-Commerce (CrypTEC '99).
 
+     K. Igoe and D. Stebila, X.509v3 Certificates for Secure Shell
+     Authentication, RFC 6187, March 2011.
+
+     T. Ylonen, T. Kivinen, M. Saarinen, T. Rinne, and S. Lehtinen, SSH
+     Transport Layer Protocol, January 31, 2002, draft-ietf-secsh-
+     transport-12.txt.
+
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
-     versions 1.5 and 2.0.
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
 
-OpenBSD 6.0                      July 16, 2016                     OpenBSD 6.0
+BSD                           September 18, 2016                           BSD
diff -ruN openssh-7.5p1/ssh.1 openssh-7.5p1+x509-10.2/ssh.1
--- openssh-7.5p1/ssh.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh.1	2017-05-20 21:07:00.000000000 +0300
@@ -1,3 +1,11 @@
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,6 +20,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -34,22 +43,23 @@
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" $OpenBSD: ssh.1,v 1.376 2016/07/16 06:57:55 jmc Exp $
-.Dd $Mdocdate: July 16 2016 $
+.Dd $Mdocdate: September 18 2016 $
 .Dt SSH 1
 .Os
 .Sh NAME
 .Nm ssh
-.Nd OpenSSH SSH client (remote login program)
+.Nd Secure shell client (remote login program)
 .Sh SYNOPSIS
 .Nm ssh
 .Bk -words
-.Op Fl 1246AaCfGgKkMNnqsTtVvXxYy
+.Op Fl 1246AaCdfgKkMNnqsTtVvXxYy
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
 .Op Fl D Oo Ar bind_address : Oc Ns Ar port
 .Op Fl E Ar log_file
 .Op Fl e Ar escape_char
 .Op Fl F Ar configfile
+.Op Fl G Ar engine_configfile
 .Op Fl I Ar pkcs11
 .Op Fl i Ar identity_file
 .Op Fl J Oo Ar user Ns @ Oc Ns Ar host Ns Op : Ns Ar port
@@ -127,6 +137,11 @@
 An attacker cannot obtain key material from the agent,
 however they can perform operations on the keys that enable them to
 authenticate using the identities loaded into the agent.
+Using the
+.Fl c
+flag of
+.Xr ssh-add 1
+can reduce (but not eliminate) the risk.
 .Pp
 .It Fl a
 Disables forwarding of the authentication agent connection.
@@ -216,6 +231,14 @@
 .Sq *
 indicates that the port should be available from all interfaces.
 .Pp
+.It Fl d
+Causes
+.Nm
+to print its configuration after evaluating
+.Cm Host
+and
+.Cm Match
+blocks and exit.
 .It Fl E Ar log_file
 Append debug logs to
 .Ar log_file
@@ -266,15 +289,12 @@
 will wait for all remote port forwards to be successfully established
 before placing itself in the background.
 .Pp
-.It Fl G
-Causes
-.Nm
-to print its configuration after evaluating
-.Cm Host
-and
-.Cm Match
-blocks and exit.
-.Pp
+.It Fl G Ar engine_configfile
+Specifies an alternative per-user file for post initialization of
+.Xr openssl 1
+engines.
+The default per-user configuration file is
+.Pa ~/.ssh/engine .
 .It Fl g
 Allows remote hosts to connect to local forwarded ports.
 If used on a multiplexed connection, then this option must be specified
@@ -284,7 +304,7 @@
 Specify the PKCS#11 shared library
 .Nm
 should use to communicate with a PKCS#11 token providing the user's
-private RSA key.
+private EC or RSA key and X.509 certificate.
 .Pp
 .It Fl i Ar identity_file
 Selects a file from which the identity (private key) for
@@ -298,6 +318,8 @@
 and
 .Pa ~/.ssh/id_rsa
 for protocol version 2.
+In addition for protocol version 2, identity may contain
+X.509 certificate that match private key.
 Identity files may also be specified on
 a per-host basis in the configuration file.
 It is possible to have multiple
@@ -475,100 +497,9 @@
 Can be used to give options in the format used in the configuration file.
 This is useful for specifying options for which there is no separate
 command-line flag.
-For full details of the options listed below, and their possible values, see
+For full details of the options and their possible values, see
 .Xr ssh_config 5 .
 .Pp
-.Bl -tag -width Ds -offset indent -compact
-.It AddKeysToAgent
-.It AddressFamily
-.It BatchMode
-.It BindAddress
-.It CanonicalDomains
-.It CanonicalizeFallbackLocal
-.It CanonicalizeHostname
-.It CanonicalizeMaxDots
-.It CanonicalizePermittedCNAMEs
-.It CertificateFile
-.It ChallengeResponseAuthentication
-.It CheckHostIP
-.It Cipher
-.It Ciphers
-.It ClearAllForwardings
-.It Compression
-.It CompressionLevel
-.It ConnectionAttempts
-.It ConnectTimeout
-.It ControlMaster
-.It ControlPath
-.It ControlPersist
-.It DynamicForward
-.It EscapeChar
-.It ExitOnForwardFailure
-.It FingerprintHash
-.It ForwardAgent
-.It ForwardX11
-.It ForwardX11Timeout
-.It ForwardX11Trusted
-.It GatewayPorts
-.It GlobalKnownHostsFile
-.It GSSAPIAuthentication
-.It GSSAPIDelegateCredentials
-.It HashKnownHosts
-.It Host
-.It HostbasedAuthentication
-.It HostbasedKeyTypes
-.It HostKeyAlgorithms
-.It HostKeyAlias
-.It HostName
-.It IdentitiesOnly
-.It IdentityAgent
-.It IdentityFile
-.It Include
-.It IPQoS
-.It KbdInteractiveAuthentication
-.It KbdInteractiveDevices
-.It KexAlgorithms
-.It LocalCommand
-.It LocalForward
-.It LogLevel
-.It MACs
-.It Match
-.It NoHostAuthenticationForLocalhost
-.It NumberOfPasswordPrompts
-.It PasswordAuthentication
-.It PermitLocalCommand
-.It PKCS11Provider
-.It Port
-.It PreferredAuthentications
-.It Protocol
-.It ProxyCommand
-.It ProxyJump
-.It ProxyUseFdpass
-.It PubkeyAcceptedKeyTypes
-.It PubkeyAuthentication
-.It RekeyLimit
-.It RemoteForward
-.It RequestTTY
-.It RhostsRSAAuthentication
-.It RSAAuthentication
-.It SendEnv
-.It ServerAliveInterval
-.It ServerAliveCountMax
-.It StreamLocalBindMask
-.It StreamLocalBindUnlink
-.It StrictHostKeyChecking
-.It TCPKeepAlive
-.It Tunnel
-.It TunnelDevice
-.It UpdateHostKeys
-.It UsePrivilegedPort
-.It User
-.It UserKnownHostsFile
-.It VerifyHostKeyDNS
-.It VisualHostKey
-.It XAuthLocation
-.El
-.Pp
 .It Fl p Ar port
 Port to connect to on the remote host.
 This can be specified on a
@@ -595,6 +526,8 @@
 (non-certificate key types), and
 .Ar protocol-version
 (supported SSH protocol versions).
+This option must be specified last as other options may impact list
+of supported algorithms.
 .Pp
 .It Fl q
 Quiet mode.
@@ -806,7 +739,7 @@
 The file format and configuration options are described in
 .Xr ssh_config 5 .
 .Sh AUTHENTICATION
-The OpenSSH SSH client supports SSH protocols 1 and 2.
+The SecSH client supports SSH protocols 1 and 2.
 The default is to use protocol 2 only,
 though this can be changed via the
 .Cm Protocol
@@ -850,7 +783,7 @@
 Additionally, the server
 .Em must
 be able to verify the client's
-host key (see the description of
+host key or X.509 certificate (see the description of
 .Pa /etc/ssh/ssh_known_hosts
 and
 .Pa ~/.ssh/known_hosts ,
@@ -865,29 +798,29 @@
 disabled if security is desired.]
 .Pp
 Public key authentication works as follows:
-The scheme is based on public-key cryptography,
+The scheme is based on public-key cryptography or infrastructure (PKI),
 using cryptosystems
 where encryption and decryption are done using separate keys,
 and it is unfeasible to derive the decryption key from the encryption key.
 The idea is that each user creates a public/private
 key pair for authentication purposes.
-The server knows the public key, and only the user knows the private key.
+The server knows the public key or X.509 certificate, and only the user knows the private key.
 .Nm
 implements public key authentication protocol automatically,
-using one of the DSA, ECDSA, Ed25519 or RSA algorithms.
+using one of the DSA, ECDSA, Ed25519 or RSA algorithms or X.509 certificates.
 The HISTORY section of
 .Xr ssl 8
 contains a brief discussion of the DSA and RSA algorithms.
 .Pp
 The file
 .Pa ~/.ssh/authorized_keys
-lists the public keys that are permitted for logging in.
+lists the public keys or X.509 certificates that are permitted for logging in.
 When the user logs in, the
 .Nm
-program tells the server which key pair it would like to use for
+program tells the server which key pair or X.509 certificate it would like to use for
 authentication.
 The client proves that it has access to the private key
-and the server checks that the corresponding public key
+and the server checks that the corresponding public key or X.509 certificate
 is authorized to accept the account.
 .Pp
 The user creates his/her key pair by running
@@ -917,15 +850,26 @@
 .Pa ~/.ssh/id_rsa.pub
 (RSA)
 in the user's home directory.
-The user should then copy the public key
+For protocol version 2 identity files may contain
+private key and X.509 certificate that match it.
+In this case *.pub file must contain that certificate.
+The user should then copy the public key or X.509 certificate
 to
 .Pa ~/.ssh/authorized_keys
 in his/her home directory on the remote machine.
+In case with X.509 certificates user can use
+.Dq new style
+: instead to add content of file to authorized_keys user
+can write certificate
+.Dq Distinguished Name
+- see
+.Xr sshd 8
+manual page.
 The
 .Pa authorized_keys
 file corresponds to the conventional
 .Pa ~/.rhosts
-file, and has one key
+file, and has one key or X.509 certificate
 per line, though the lines can be very long.
 After this, the user can log in without giving the password.
 .Pp
@@ -977,6 +921,12 @@
 Additionally, the file
 .Pa /etc/ssh/ssh_known_hosts
 is automatically checked for known hosts.
+If host key is a X.509 certificate line may contain certificate
+.Dq Distinguished Name
+instead base64 encoded representation.
+This is support only if
+.Dq "X.509 store"
+is enabled.
 Any new hosts are automatically added to the user's file.
 If a host's identification ever changes,
 .Nm
@@ -1249,16 +1199,17 @@
 .Pp
 If the fingerprint is unknown,
 an alternative method of verification is available:
-SSH fingerprints verified by DNS.
+SSH fingerprints or X.509 certificates verified by DNS.
 An additional resource record (RR),
-SSHFP,
+SSHFP or CERT,
 is added to a zonefile
 and the connecting client is able to match the fingerprint
+or X.509 certificate
 with that of the key presented.
 .Pp
 In this example, we are connecting a client to a server,
 .Dq host.example.com .
-The SSHFP resource records should first be added to the zonefile for
+The SSHFP or CERT resource records should first be added to the zonefile for
 host.example.com:
 .Bd -literal -offset indent
 $ ssh-keygen -r host.example.com.
@@ -1269,6 +1220,10 @@
 .Pp
 .Dl $ dig -t SSHFP host.example.com
 .Pp
+To check that the zone is answering X.509 certificate queries:
+.Pp
+.Dl $ dig -t CERT host.example.com
+.Pp
 Finally the client connects:
 .Bd -literal -offset indent
 $ ssh -o "VerifyHostKeyDNS ask" host.example.com
@@ -1277,6 +1232,13 @@
 Are you sure you want to continue connecting (yes/no)?
 .Ed
 .Pp
+When host key is a X.509 certificate
+.Dq Distinguished Name
+is displayed after fingerprint.
+Note that host X.509 certificate always is verifified and validated if
+.Dq "X.509 store"
+is enabled.
+.Pp
 See the
 .Cm VerifyHostKeyDNS
 option in
@@ -1471,6 +1433,7 @@
 .Pp
 .It Pa ~/.ssh/authorized_keys
 Lists the public keys (DSA, ECDSA, Ed25519, RSA)
+or X.509 certificates
 that can be used for logging in as this user.
 The format of this file is described in the
 .Xr sshd 8
@@ -1478,6 +1441,18 @@
 This file is not highly sensitive, but the recommended
 permissions are read/write for the user, and not accessible by others.
 .Pp
+.It Pa ~/.ssh/ca/ca-bundle.crt
+.It Pa ~/.ssh/ca/ca-bundle.crl
+Part of user
+.Dq "X.509 store" .
+Same as systemwide files below.
+.Pp
+.It Pa ~/.ssh/ca/crt
+.It Pa ~/.ssh/ca/crl
+Part of user
+.Dq "X.509 store" .
+Same as systemwide directories below.
+.Pp
 .It Pa ~/.ssh/config
 This is the per-user configuration file.
 The file format and configuration options are described in
@@ -1499,6 +1474,14 @@
 These files
 contain sensitive data and should be readable by the user but not
 accessible by others (read/write/execute).
+.Pp
+Identity for protocol version 2 may contain
+X.509 certificate that match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, file
+with ECDSA key may contain extra X.509 certificates.
+Extra certificates along with certificates from X.509 store
+are used to build chain of certificates leading to
+a trusted certificate authority.
 .Nm
 will simply ignore a private key file if it is accessible by others.
 It is possible to specify a passphrase when
@@ -1511,11 +1494,13 @@
 .It Pa ~/.ssh/id_ed25519.pub
 .It Pa ~/.ssh/id_rsa.pub
 Contains the public key for authentication.
+Note for protocol version 2 if an identity contain private key
+and X.509 certificate, file must contain that certificate.
 These files are not
 sensitive and can (but need not) be readable by anyone.
 .Pp
 .It Pa ~/.ssh/known_hosts
-Contains a list of host keys for all hosts the user has logged into
+Contains a list of host keys or X.509 certificates for all hosts the user has logged into
 that are not already in the systemwide list of known host keys.
 See
 .Xr sshd 8
@@ -1540,6 +1525,28 @@
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
+.It /etc/ssh/ca/ca-bundle.crt
+.It /etc/ssh/ca/ca-bundle.crl
+Part of systemwide
+.Dq "X.509 store" .
+The first file contain multiple certificates and the second
+.Dq "Certificate Revocation List"
+(CRLs) of X.509 certificate signers in PEM format concatenated together.
+Used in verification and validation of server host certificate.
+.Pp
+.It /etc/ssh/ca/crt
+.It /etc/ssh/ca/crl
+Part of systemwide
+.Dq "X.509 store" .
+.Dq "Hash dirs"
+with certificates, the first directory or CLRs, the second of
+certificate signers.
+Each certificate should be stored in separate file with name
+[HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where [HASH] is
+certificate or CRL hash value and [NUMBER] is an integer starting
+from zero.
+Used in verification and validation of server host certificate.
+.Pp
 .It Pa /etc/ssh/ssh_config
 Systemwide configuration file.
 The file format and configuration options are described in
@@ -1552,12 +1559,19 @@
 .It Pa /etc/ssh/ssh_host_rsa_key
 These files contain the private parts of the host keys
 and are used for host-based authentication.
+For protocol version 2 keys files may contain private part
+and X.509 certificate that match it.
+If a X.509 certificate is used as host key for hostbased authentication
+that certificate must have client purpose too or server configuration
+must permit connection without client purpose. For allowed client
+certificate purposes see
+.Xr ssh_config 5 .
 .Pp
 .It Pa /etc/ssh/ssh_known_hosts
-Systemwide list of known host keys.
+Systemwide list of known host keys or X.509 certificates.
 This file should be prepared by the
-system administrator to contain the public host keys of all machines in the
-organization.
+system administrator to contain the public host keys or X.509 certificates
+of all machines in the organization.
 It should be world-readable.
 See
 .Xr sshd 8
@@ -1586,7 +1600,7 @@
 .Xr ssh_config 5 ,
 .Xr ssh-keysign 8 ,
 .Xr sshd 8
-.Sh STANDARDS
+.Sh CONFORMING TO
 .Rs
 .%A S. Lehtinen
 .%A C. Lonvick
@@ -1699,8 +1713,27 @@
 .%O International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)
 .%T Hash Visualization: a New Technique to improve Real-World Security
 .Re
+.Pp
+.Rs
+.%A K. Igoe
+.%A D. Stebila
+.%D March 2011
+.%R RFC 6187
+.%T X.509v3 Certificates for Secure Shell Authentication
+.Re
+.Pp
+.Rs
+.%A T. Ylonen
+.%A T. Kivinen
+.%A M. Saarinen
+.%A T. Rinne
+.%A S. Lehtinen
+.%D January 31, 2002
+.%O draft-ietf-secsh-transport-12.txt
+.%T SSH Transport Layer Protocol
+.Re
 .Sh AUTHORS
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
 Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
 Theo de Raadt and Dug Song
@@ -1708,3 +1741,4 @@
 created OpenSSH.
 Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
+Roumen Petrov contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/ssh-add.0 openssh-7.5p1+x509-10.2/ssh-add.0
--- openssh-7.5p1/ssh-add.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-add.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,29 +1,33 @@
-SSH-ADD(1)                  General Commands Manual                 SSH-ADD(1)
+SSH-ADD(1)                BSD General Commands Manual               SSH-ADD(1)
 
 NAME
-     ssh-add M-bM-^@M-^S adds private key identities to the authentication agent
+     ssh-add -- Adds private key identities to the authentication agent
 
 SYNOPSIS
      ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...]
-     ssh-add -s pkcs11
+     ssh-add -s pkcs11 [-S xstore]
      ssh-add -e pkcs11
 
 DESCRIPTION
      ssh-add adds private key identities to the authentication agent,
-     ssh-agent(1).  When run without arguments, it adds the files
-     ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and
-     ~/.ssh/identity.  After loading a private key, ssh-add will try to load
-     corresponding certificate information from the filename obtained by
-     appending -cert.pub to the name of the private key file.  Alternative
-     file names can be given on the command line.
+     ssh-agent(1).  In addition identity may contain X.509 certificate that
+     match private key.  For x509v3-ecdsa-sha2-* public key algorithms, iden-
+     tity with ECDSA key may contain extra X.509 certificates.  Agent uses
+     extra certificates along with certificates from system default X.509
+     store to build chain of certificates leading to a trusted certificate
+     authority.  When run without arguments, it adds the files ~/.ssh/id_rsa,
+     ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/identity.
+     After loading a private key, ssh-add will try to load corresponding cer-
+     tificate information from the filename obtained by appending -cert.pub to
+     the name of the private key file.  Alternative file names can be given on
+     the command line.
 
      If any file requires a passphrase, ssh-add asks for the passphrase from
      the user.  The passphrase is read from the user's tty.  ssh-add retries
      the last passphrase if multiple identity files are given.
 
-     The authentication agent must be running and the SSH_AUTH_SOCK
-     environment variable must contain the name of its socket for ssh-add to
-     work.
+     The authentication agent must be running and the SSH_AUTH_SOCK environ-
+     ment variable must contain the name of its socket for ssh-add to work.
 
      The options are as follows:
 
@@ -39,14 +43,14 @@
              If ssh-add has been run without arguments, the keys for the
              default identities and their corresponding certificates will be
              removed.  Otherwise, the argument list will be interpreted as a
-             list of paths to public key files to specify keys and
-             certificates to be removed from the agent.  If no public key is
-             found at a given path, ssh-add will append .pub and retry.
+             list of paths to public key files to specify keys and certifi-
+             cates to be removed from the agent.  If no public key is found at
+             a given path, ssh-add will append .pub and retry.
 
      -E fingerprint_hash
-             Specifies the hash algorithm used when displaying key
-             fingerprints.  Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^].  The
-             default is M-bM-^@M-^\sha256M-bM-^@M-^].
+             Specifies the hash algorithm used when displaying key finger-
+             prints.  Valid options are: ``md5'' and ``sha256''.  The default
+             is ``sha256''.
 
      -e pkcs11
              Remove keys provided by the PKCS#11 shared library pkcs11.
@@ -54,8 +58,9 @@
      -k      When loading keys into or deleting keys from the agent, process
              plain private keys only and skip certificates.
 
-     -L      Lists public key parameters of all identities currently
-             represented by the agent.
+     -L      Lists public key parameters of all identities currently repre-
+             sented by the agent.  X.509 certificates are displayed with their
+             ``Distinguished Name''.
 
      -l      Lists fingerprints of all identities currently represented by the
              agent.
@@ -63,10 +68,17 @@
      -s pkcs11
              Add keys provided by the PKCS#11 shared library pkcs11.
 
+     -S xstore
+             File with extra X.509 certificates in PEM format concatenated
+             together.  Certificates are added to X.509 store and together
+             with those from system default store are used in public key algo-
+             rithms in RFC 6187 format if applicable.  Note that currently
+             only EC keys support such format.
+
      -t life
              Set a maximum lifetime when adding identities to an agent.  The
-             lifetime may be specified in seconds or in a time format
-             specified in sshd_config(5).
+             lifetime may be specified in seconds or in a time format speci-
+             fied in sshd_config(5).
 
      -X      Unlock the agent.
 
@@ -78,8 +90,8 @@
              the current terminal if it was run from a terminal.  If ssh-add
              does not have a terminal associated with it but DISPLAY and
              SSH_ASKPASS are set, it will execute the program specified by
-             SSH_ASKPASS (by default M-bM-^@M-^\ssh-askpassM-bM-^@M-^]) and open an X11 window to
-             read the passphrase.  This is particularly useful when calling
+             SSH_ASKPASS (by default ``ssh-askpass'') and open an X11 window
+             to read the passphrase.  This is particularly useful when calling
              ssh-add from a .xsession or related script.  (Note that on some
              machines it may be necessary to redirect the input from /dev/null
              to make this work.)
@@ -95,11 +107,14 @@
 
      ~/.ssh/id_dsa
              Contains the protocol version 2 DSA authentication identity of
-             the user.
+             the user.  It may contain private key and X.509 certificate that
+             match it.
 
      ~/.ssh/id_ecdsa
              Contains the protocol version 2 ECDSA authentication identity of
-             the user.
+             the user.  It may contain private key, X.509 certificate that
+             match it and extra certificates used to build chain of certifi-
+             cates leading to a trusted certificate authority.
 
      ~/.ssh/id_ed25519
              Contains the protocol version 2 Ed25519 authentication identity
@@ -107,7 +122,8 @@
 
      ~/.ssh/id_rsa
              Contains the protocol version 2 RSA authentication identity of
-             the user.
+             the user.  It may contain private key and X.509 certificate that
+             match it.
 
      Identity files should not be readable by anyone but the user.  Note that
      ssh-add ignores identity files if they are accessible by others.
@@ -120,10 +136,11 @@
      ssh(1), ssh-agent(1), ssh-askpass(1), ssh-keygen(1), sshd(8)
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
-     versions 1.5 and 2.0.
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
 
-OpenBSD 6.0                     March 30, 2015                     OpenBSD 6.0
+BSD                           September 18, 2016                           BSD
diff -ruN openssh-7.5p1/ssh-add.1 openssh-7.5p1+x509-10.2/ssh-add.1
--- openssh-7.5p1/ssh-add.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-add.1	2017-05-20 21:07:00.000000000 +0300
@@ -14,6 +14,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -35,12 +36,20 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: March 30 2015 $
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
+.Dd $Mdocdate: September 18 2016 $
 .Dt SSH-ADD 1
 .Os
 .Sh NAME
 .Nm ssh-add
-.Nd adds private key identities to the authentication agent
+.Nd Adds private key identities to the authentication agent
 .Sh SYNOPSIS
 .Nm ssh-add
 .Op Fl cDdkLlXx
@@ -49,12 +58,20 @@
 .Op Ar
 .Nm ssh-add
 .Fl s Ar pkcs11
+.Op Fl S Ar xstore
 .Nm ssh-add
 .Fl e Ar pkcs11
 .Sh DESCRIPTION
 .Nm
 adds private key identities to the authentication agent,
 .Xr ssh-agent 1 .
+In addition identity may contain X.509 certificate that
+match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, identity
+with ECDSA key may contain extra X.509 certificates.
+Agent uses extra certificates along with certificates from
+system default X.509 store to build chain of certificates
+leading to a trusted certificate authority.
 When run without arguments, it adds the files
 .Pa ~/.ssh/id_rsa ,
 .Pa ~/.ssh/id_dsa ,
@@ -125,11 +142,19 @@
 .It Fl L
 Lists public key parameters of all identities currently represented
 by the agent.
+X.509 certificates are displayed with their
+.Dq "Distinguished Name" .
 .It Fl l
 Lists fingerprints of all identities currently represented by the agent.
 .It Fl s Ar pkcs11
 Add keys provided by the PKCS#11 shared library
 .Ar pkcs11 .
+.It Fl S Ar xstore
+File with extra X.509 certificates in PEM format concatenated together.
+Certificates are added to X.509 store and together with those from
+system default store are used in public key algorithms in RFC 6187
+format if applicable.
+Note that currently only EC keys support such format.
 .It Fl t Ar life
 Set a maximum lifetime when adding identities to an agent.
 The lifetime may be specified in seconds or in a time format
@@ -178,12 +203,17 @@
 Contains the protocol version 1 RSA authentication identity of the user.
 .It Pa ~/.ssh/id_dsa
 Contains the protocol version 2 DSA authentication identity of the user.
+It may contain private key and X.509 certificate that match it.
 .It Pa ~/.ssh/id_ecdsa
 Contains the protocol version 2 ECDSA authentication identity of the user.
+It may contain private key, X.509 certificate that match it and
+extra certificates used to build chain of certificates
+leading to a trusted certificate authority.
 .It Pa ~/.ssh/id_ed25519
 Contains the protocol version 2 Ed25519 authentication identity of the user.
 .It Pa ~/.ssh/id_rsa
 Contains the protocol version 2 RSA authentication identity of the user.
+It may contain private key and X.509 certificate that match it.
 .El
 .Pp
 Identity files should not be readable by anyone but the user.
@@ -202,7 +232,7 @@
 .Xr ssh-keygen 1 ,
 .Xr sshd 8
 .Sh AUTHORS
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
 Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
 Theo de Raadt and Dug Song
@@ -210,3 +240,4 @@
 created OpenSSH.
 Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
+Roumen Petrov contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/ssh-add.c openssh-7.5p1+x509-10.2/ssh-add.c
--- openssh-7.5p1/ssh-add.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-add.c	2017-05-20 21:07:01.000000000 +0300
@@ -13,6 +13,8 @@
  *
  * SSH2 implementation,
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * X.509 certificates support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -58,6 +60,8 @@
 #include "rsa.h"
 #include "log.h"
 #include "sshkey.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "sshbuf.h"
 #include "authfd.h"
 #include "authfile.h"
@@ -331,7 +335,7 @@
 }
 
 static int
-update_card(int agent_fd, int add, const char *id)
+update_card(int agent_fd, int add, const char *id, const char *xstore)
 {
 	char *pin = NULL;
 	int r, ret = -1;
@@ -343,6 +347,7 @@
 	}
 
 	if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin,
+	    xstore,
 	    lifetime, confirm)) == 0) {
 		fprintf(stderr, "Card %s: %s\n",
 		    add ? "added" : "removed", id);
@@ -389,6 +394,16 @@
 				    sshkey_type(idlist->keys[i]));
 				free(fp);
 			} else {
+				if (sshkey_is_x509(idlist->keys[i])) {
+					/* key_write prints x509 certificate
+					  in blob format :-( */
+					if(!Xkey_write_subject(NULL,
+					    idlist->keys[i], stdout))
+						fprintf(stderr,
+						    "Xkey_write_subject failed");
+					fprintf(stdout, "\n");
+					continue;
+				}
 				if ((r = sshkey_write(idlist->keys[i],
 				    stdout)) != 0) {
 					fprintf(stderr, "sshkey_write: %s\n",
@@ -468,6 +483,8 @@
 	fprintf(stderr, "  -x          Lock agent.\n");
 	fprintf(stderr, "  -X          Unlock agent.\n");
 	fprintf(stderr, "  -s pkcs11   Add keys from PKCS#11 provider.\n");
+	fprintf(stderr, "  -S xstore   File with extra X.509 certificates in PEM format\n");
+	fprintf(stderr, "              concatenated together.\n");
 	fprintf(stderr, "  -e pkcs11   Remove keys provided by PKCS#11 provider.\n");
 }
 
@@ -477,7 +494,7 @@
 	extern char *optarg;
 	extern int optind;
 	int agent_fd;
-	char *pkcs11provider = NULL;
+	char *pkcs11provider = NULL, *xstore = "";
 	int r, i, ch, deleting = 0, ret = 0, key_only = 0;
 	int xflag = 0, lflag = 0, Dflag = 0;
 
@@ -486,11 +503,10 @@
 	sanitise_stdfd();
 
 	__progname = ssh_get_progname(argv[0]);
-	seed_rng();
+	ssh_OpenSSL_startup();
+	fill_default_xkalg();
 
-#ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
-#endif
+	seed_rng();
 
 	setvbuf(stdout, NULL, _IOLBF, 0);
 
@@ -507,7 +523,7 @@
 		exit(2);
 	}
 
-	while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) {
+	while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:S:t:")) != -1) {
 		switch (ch) {
 		case 'E':
 			fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -541,6 +557,9 @@
 		case 's':
 			pkcs11provider = optarg;
 			break;
+		case 'S':
+			xstore = optarg;
+			break;
 		case 'e':
 			deleting = 1;
 			pkcs11provider = optarg;
@@ -578,7 +597,7 @@
 	argc -= optind;
 	argv += optind;
 	if (pkcs11provider != NULL) {
-		if (update_card(agent_fd, !deleting, pkcs11provider) == -1)
+		if (update_card(agent_fd, !deleting, pkcs11provider, xstore) == -1)
 			ret = 1;
 		goto done;
 	}
diff -ruN openssh-7.5p1/ssh-agent.0 openssh-7.5p1+x509-10.2/ssh-agent.0
--- openssh-7.5p1/ssh-agent.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-agent.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SSH-AGENT(1)                General Commands Manual               SSH-AGENT(1)
+SSH-AGENT(1)              BSD General Commands Manual             SSH-AGENT(1)
 
 NAME
-     ssh-agent M-bM-^@M-^S authentication agent
+     ssh-agent -- Authentication agent
 
 SYNOPSIS
      ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]
@@ -9,13 +9,16 @@
      ssh-agent [-c | -s] -k
 
 DESCRIPTION
-     ssh-agent is a program to hold private keys used for public key
-     authentication (RSA, DSA, ECDSA, Ed25519).  ssh-agent is usually started
-     in the beginning of an X-session or a login session, and all other
-     windows or programs are started as clients to the ssh-agent program.
-     Through use of environment variables the agent can be located and
-     automatically used for authentication when logging in to other machines
-     using ssh(1).
+     ssh-agent is a program to hold private keys used for public key authenti-
+     cation (RSA, DSA, ECDSA, Ed25519).  It may contain X.509 certificates
+     that match private keys and extra certificates used to build chain of
+     certificates leading to a trusted certificate authority.
+
+     ssh-agent is usually started in the beginning of an X-session or a login
+     session, and all other windows or programs are started as clients to the
+     ssh-agent program.  Through use of environment variables the agent can be
+     located and automatically used for authentication when logging in to
+     other machines using ssh(1).
 
      The agent initially does not have any private keys.  Keys are added using
      ssh(1) (see AddKeysToAgent in ssh_config(5) for details) or ssh-add(1).
@@ -39,9 +42,9 @@
              fork and will write debug information to standard error.
 
      -E fingerprint_hash
-             Specifies the hash algorithm used when displaying key
-             fingerprints.  Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^].  The
-             default is M-bM-^@M-^\sha256M-bM-^@M-^].
+             Specifies the hash algorithm used when displaying key finger-
+             prints.  Valid options are: ``md5'' and ``sha256''.  The default
+             is ``sha256''.
 
      -k      Kill the current agent (given by the SSH_AGENT_PID environment
              variable).
@@ -50,7 +53,7 @@
              Specify a pattern-list of acceptable paths for PKCS#11 shared
              libraries that may be added using the -s option to ssh-add(1).
              The default is to allow loading PKCS#11 libraries from
-             M-bM-^@M-^\/usr/lib/*,/usr/local/lib/*M-bM-^@M-^].  PKCS#11 libraries that do not
+             ``/usr/lib/*,/usr/local/lib/*''.  PKCS#11 libraries that do not
              match the whitelist will be refused.  See PATTERNS in
              ssh_config(5) for a description of pattern-list syntax.
 
@@ -67,12 +70,12 @@
      If a command line is given, this is executed as a subprocess of the
      agent.  When the command dies, so does the agent.
 
-     The idea is that the agent is run in the user's local PC, laptop, or
-     terminal.  Authentication data need not be stored on any other machine,
-     and authentication passphrases never go over the network.  However, the
-     connection to the agent is forwarded over SSH remote logins, and the user
-     can thus use the privileges given by the identities anywhere in the
-     network in a secure way.
+     The idea is that the agent is run in the user's local PC, laptop, or ter-
+     minal.  Authentication data need not be stored on any other machine, and
+     authentication passphrases never go over the network.  However, the con-
+     nection to the agent is forwarded over SSH remote logins, and the user
+     can thus use the privileges given by the identities anywhere in the net-
+     work in a secure way.
 
      There are two main ways to get an agent set up: The first is that the
      agent starts a new subcommand into which some environment variables are
@@ -82,13 +85,13 @@
      Bourne-type shells such as sh(1) or ksh(1) and eval `ssh-agent -c` for
      csh(1) and derivatives.
 
-     Later ssh(1) looks at these variables and uses them to establish a
-     connection to the agent.
+     Later ssh(1) looks at these variables and uses them to establish a con-
+     nection to the agent.
 
      The agent will never send a private key over its request channel.
      Instead, operations that require a private key will be performed by the
-     agent, and the result will be returned to the requester.  This way,
-     private keys are not exposed to clients using the agent.
+     agent, and the result will be returned to the requester.  This way, pri-
+     vate keys are not exposed to clients using the agent.
 
      A UNIX-domain socket is created and the name of this socket is stored in
      the SSH_AUTH_SOCK environment variable.  The socket is made accessible
@@ -102,19 +105,20 @@
 
 FILES
      $TMPDIR/ssh-XXXXXXXXXX/agent.<ppid>
-             UNIX-domain sockets used to contain the connection to the
-             authentication agent.  These sockets should only be readable by
-             the owner.  The sockets should get automatically removed when the
+             UNIX-domain sockets used to contain the connection to the authen-
+             tication agent.  These sockets should only be readable by the
+             owner.  The sockets should get automatically removed when the
              agent exits.
 
 SEE ALSO
      ssh(1), ssh-add(1), ssh-keygen(1), sshd(8)
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
-     versions 1.5 and 2.0.
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
 
-OpenBSD 6.0                    November 30, 2016                   OpenBSD 6.0
+BSD                            November 30, 2016                           BSD
diff -ruN openssh-7.5p1/ssh-agent.1 openssh-7.5p1+x509-10.2/ssh-agent.1
--- openssh-7.5p1/ssh-agent.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-agent.1	2017-05-20 21:07:00.000000000 +0300
@@ -13,6 +13,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -34,12 +35,20 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .Dd $Mdocdate: November 30 2016 $
 .Dt SSH-AGENT 1
 .Os
 .Sh NAME
 .Nm ssh-agent
-.Nd authentication agent
+.Nd Authentication agent
 .Sh SYNOPSIS
 .Nm ssh-agent
 .Op Fl c | s
@@ -56,6 +65,10 @@
 .Nm
 is a program to hold private keys used for public key authentication
 (RSA, DSA, ECDSA, Ed25519).
+It may contain X.509 certificates that match private keys and
+extra certificates used to build chain of certificates
+leading to a trusted certificate authority.
+.Pp
 .Nm
 is usually started in the beginning of an X-session or a login session, and
 all other windows or programs are started as clients to the ssh-agent
@@ -221,7 +234,7 @@
 .Xr sshd 8
 .Sh AUTHORS
 .An -nosplit
-OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
 .An Tatu Ylonen .
 .An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos , Theo de Raadt
 and
@@ -229,3 +242,5 @@
 removed many bugs, re-added newer features and created OpenSSH.
 .An Markus Friedl
 contributed the support for SSH protocol versions 1.5 and 2.0.
+.An Roumen Petrov
+contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/ssh-agent.c openssh-7.5p1+x509-10.2/ssh-agent.c
--- openssh-7.5p1/ssh-agent.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-agent.c	2017-05-20 21:07:01.000000000 +0300
@@ -13,6 +13,9 @@
  *
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -51,7 +54,11 @@
 
 #ifdef WITH_OPENSSL
 #include <openssl/evp.h>
+#include "evp-compat.h"
 #include "openbsd-compat/openssl-compat.h"
+#ifdef HAVE_FIPSCHECK_H
+#  include <fipscheck.h>
+#endif
 #endif
 
 #include <errno.h>
@@ -75,7 +82,9 @@
 #include "ssh.h"
 #include "rsa.h"
 #include "sshbuf.h"
-#include "sshkey.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
+#include "x509store.h"
 #include "authfd.h"
 #include "compat.h"
 #include "log.h"
@@ -86,7 +95,27 @@
 
 #ifdef ENABLE_PKCS11
 #include "ssh-pkcs11.h"
-#endif
+
+/* used in ssh-x509.c */
+extern STACK_OF(X509)* (*pssh_x509store_build_certchain)(X509 *cert, STACK_OF(X509) *untrusted);
+
+/* minimize dependencies */
+#if 1	/* used in x509store.c */
+
+int
+ssh_ocsp_validate(X509 *cert, X509_STORE *x509store) {
+	(void)cert;
+	(void)x509store;
+	return(-1);
+}
+
+X509_LOOKUP_METHOD* X509_LOOKUP_ldap(void);
+X509_LOOKUP_METHOD*
+X509_LOOKUP_ldap(void) {
+	return(NULL);
+}
+#endif	/* end of used in x509store.c */
+#endif	/*def ENABLE_PKCS11*/
 
 #ifndef DEFAULT_PKCS11_WHITELIST
 # define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
@@ -197,6 +226,24 @@
 	free(id);
 }
 
+static int/*bool*/
+key_match(const struct sshkey *key, struct sshkey *found) {
+	int kt, ret;
+	int bt;
+
+	kt = found->type;
+	if (key->type == kt)
+		return(sshkey_equal(key, found));
+
+	bt = X509KEY_BASETYPE(found);
+	if (kt == bt) return(0);
+	found->type = bt;
+
+	ret = sshkey_equal(key, found);
+	found->type = kt;
+	return(ret);
+}
+
 /* return matching private key for given public key */
 static Identity *
 lookup_identity(struct sshkey *key, int version)
@@ -205,7 +252,7 @@
 
 	Idtab *tab = idtab_lookup(version);
 	TAILQ_FOREACH(id, &tab->idlist, next) {
-		if (sshkey_equal(key, id->key))
+		if (key_match(key, id->key))
 			return (id);
 	}
 	return (NULL);
@@ -258,12 +305,14 @@
 	TAILQ_FOREACH(id, &tab->idlist, next) {
 		if (id->key->type == KEY_RSA1) {
 #ifdef WITH_SSH1
+			const BIGNUM *rsa_n = NULL, *rsa_e = NULL;
+			RSA_get0_key(id->key->rsa, &rsa_n, &rsa_e, NULL);
 			if ((r = sshbuf_put_u32(msg,
-			    BN_num_bits(id->key->rsa->n))) != 0 ||
+			    BN_num_bits(rsa_n))) != 0 ||
 			    (r = sshbuf_put_bignum1(msg,
-			    id->key->rsa->e)) != 0 ||
+			    rsa_e)) != 0 ||
 			    (r = sshbuf_put_bignum1(msg,
-			    id->key->rsa->n)) != 0)
+			    rsa_n)) != 0)
 				fatal("%s: buffer error: %s",
 				    __func__, ssh_err(r));
 #endif
@@ -302,6 +351,7 @@
 	struct sshbuf *msg;
 	struct ssh_digest_ctx *md;
 	struct sshkey *key;
+	BIGNUM *rsa_n = NULL, *rsa_e = NULL;
 
 	if ((msg = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __func__);
@@ -310,9 +360,10 @@
 	if ((challenge = BN_new()) == NULL)
 		fatal("%s: BN_new failed", __func__);
 
+	RSA_get0_key(key->rsa, (const BIGNUM**)&rsa_n, (const BIGNUM**)&rsa_e, NULL);
 	if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
-	    (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
-	    (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
+	    (r = sshbuf_get_bignum1(e->request, rsa_e)) != 0 ||
+	    (r = sshbuf_get_bignum1(e->request, rsa_n)) != 0 ||
 	    (r = sshbuf_get_bignum1(e->request, challenge)))
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 
@@ -371,16 +422,18 @@
 }
 #endif
 
-static char *
-agent_decode_alg(struct sshkey *key, u_int flags)
+static const char*
+agent_recode_alg(const char *pkalg, u_int flags)
 {
-	if (key->type == KEY_RSA) {
+#ifdef HAVE_EVP_SHA256
+	if (strcmp(pkalg, "ssh-rsa") == 0) {
 		if (flags & SSH_AGENT_RSA_SHA2_256)
 			return "rsa-sha2-256";
-		else if (flags & SSH_AGENT_RSA_SHA2_512)
+		if (flags & SSH_AGENT_RSA_SHA2_512)
 			return "rsa-sha2-512";
 	}
-	return NULL;
+#endif /*def HAVE_EVP_SHA256*/
+	return pkalg;
 }
 
 /* ssh2 only */
@@ -389,11 +442,14 @@
 {
 	u_char *blob, *data, *signature = NULL;
 	size_t blen, dlen, slen = 0;
-	u_int compat = 0, flags;
+	ssh_compat ctx_compat = { 0, 0 };
+	u_int flags;
 	int r, ok = -1;
 	struct sshbuf *msg;
 	struct sshkey *key;
+	char *pkalg;
 	struct identity *id;
+	int kt = KEY_UNSPEC;
 
 	if ((msg = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new failed", __func__);
@@ -402,8 +458,10 @@
 	    (r = sshbuf_get_u32(e->request, &flags)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 	if (flags & SSH_AGENT_OLD_SIGNATURE)
-		compat = SSH_BUG_SIGBLOB;
-	if ((r = sshkey_from_blob(blob, blen, &key)) != 0) {
+		ctx_compat.datafellows = SSH_BUG_SIGBLOB;
+	if (flags & SSH_AGENT_RFC6187_OPAQUE_ECDSA_SIGNATURE)
+		ctx_compat.xcompat = SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE;
+	if ((r = parse_key_from_blob(blob, blen, &key, &pkalg)) != 0) {
 		error("%s: cannot parse key blob: %s", __func__, ssh_err(r));
 		goto send;
 	}
@@ -415,14 +473,23 @@
 		verbose("%s: user refused key", __func__);
 		goto send;
 	}
-	if ((r = sshkey_sign(id->key, &signature, &slen,
-	    data, dlen, agent_decode_alg(key, flags), compat)) != 0) {
-		error("%s: sshkey_sign: %s", __func__, ssh_err(r));
+	kt = id->key->type;
+	id->key->type = key->type;
+{	const char *alg = agent_recode_alg(pkalg, flags);
+	ssh_sign_ctx ctx = { alg, id->key, &ctx_compat };
+
+	r = Xkey_sign(&ctx, &signature, &slen, data, dlen);
+}
+	if (r != 0) {
+		error("%s: Xkey_sign: %s", __func__, ssh_err(r));
 		goto send;
 	}
 	/* Success */
 	ok = 0;
  send:
+	if (kt != KEY_UNSPEC)
+		id->key->type = kt;
+	free(pkalg);
 	sshkey_free(key);
 	if (ok == 0) {
 		if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
@@ -450,6 +517,7 @@
 	u_char *blob;
 #ifdef WITH_SSH1
 	u_int bits;
+	BIGNUM *rsa_n = NULL, *rsa_e = NULL;
 #endif /* WITH_SSH1 */
 
 	switch (version) {
@@ -459,9 +527,10 @@
 			error("%s: sshkey_new failed", __func__);
 			return;
 		}
+		RSA_get0_key(key->rsa, (const BIGNUM**)&rsa_n, (const BIGNUM**)&rsa_e, NULL);
 		if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
-		    (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
-		    (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
+		    (r = sshbuf_get_bignum1(e->request, rsa_e)) != 0 ||
+		    (r = sshbuf_get_bignum1(e->request, rsa_n)) != 0)
 			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 
 		if (bits != sshkey_size(key))
@@ -565,19 +634,24 @@
 {
 	struct sshkey *k = NULL;
 	int r = SSH_ERR_INTERNAL_ERROR;
+	BIGNUM *n = NULL, *e = NULL, *d = NULL;
+	BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
 
 	*kp = NULL;
 	if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 
+	RSA_get0_key(k->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, (const BIGNUM**)&d);
+	RSA_get0_crt_params(k->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+	RSA_get0_factors(k->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
 	if ((r = sshbuf_get_u32(m, NULL)) != 0 ||		/* ignored */
-	    (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
-	    (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
-	    (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
-	    (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
+	    (r = sshbuf_get_bignum1(m, n)) != 0 ||
+	    (r = sshbuf_get_bignum1(m, e)) != 0 ||
+	    (r = sshbuf_get_bignum1(m, d)) != 0 ||
+	    (r = sshbuf_get_bignum1(m, iqmp)) != 0 ||
 	    /* SSH1 and SSL have p and q swapped */
-	    (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 ||	/* p */
-	    (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) 	/* q */
+	    (r = sshbuf_get_bignum1(m, q)) != 0 ||	/* p */
+	    (r = sshbuf_get_bignum1(m, p)) != 0) 	/* q */
 		goto out;
 
 	/* Generate additional parameters */
@@ -745,7 +819,7 @@
 static void
 process_add_smartcard_key(SocketEntry *e)
 {
-	char *provider = NULL, *pin, canonical_provider[PATH_MAX];
+	char *provider = NULL, *pin, *xstore, canonical_provider[PATH_MAX];
 	int r, i, version, count = 0, success = 0, confirm = 0;
 	u_int seconds;
 	time_t death = 0;
@@ -755,7 +829,8 @@
 	Idtab *tab;
 
 	if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
-	    (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
+	    (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0 ||
+	    (r = sshbuf_get_cstring(e->request, &xstore, NULL)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 
 	while (sshbuf_len(e->request)) {
@@ -791,6 +866,16 @@
 	if (lifetime && !death)
 		death = monotime() + lifetime;
 
+	if (xstore != NULL && xstore[0] != '\0') {
+		X509StoreOptions extra;
+
+		X509StoreOptions_init(&extra);
+		extra.certificate_file = xstore;
+		extra.revocation_file = xstrdup(""); /*ignore*/
+		ssh_x509store_addlocations(&extra);
+		X509StoreOptions_reset(&extra);
+	}
+
 	count = pkcs11_add_provider(canonical_provider, pin, &keys);
 	for (i = 0; i < count; i++) {
 		k = keys[i];
@@ -798,6 +883,7 @@
 		tab = idtab_lookup(version);
 		if (lookup_identity(k, version) == NULL) {
 			id = xcalloc(1, sizeof(Identity));
+			x509key_build_chain(k);
 			id->key = k;
 			id->provider = xstrdup(canonical_provider);
 			id->comment = xstrdup(canonical_provider); /* XXX */
@@ -1233,11 +1319,29 @@
 
 	platform_disable_tracing(0);	/* strict=no */
 
-#ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
-#endif
-
 	__progname = ssh_get_progname(av[0]);
+
+	ssh_OpenSSL_startup();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	#ifdef HAVE_FIPSCHECK_H
+		if (!FIPSCHECK_verify(NULL, NULL))
+			fatal("FIPS integrity verification test failed.");
+	#endif
+		fprintf(stderr, "%s runs in FIPS mode\n", __progname);
+	}
+#endif /*def OPENSSL_FIPS*/
+	fill_default_xkalg();
+{
+	X509StoreOptions ca;
+
+	X509StoreOptions_init(&ca);
+	X509StoreOptions_system_defaults(&ca);
+	ssh_x509store_addlocations(&ca);
+	X509StoreOptions_reset(&ca);
+}
+	pssh_x509store_build_certchain = ssh_x509store_build_certchain;
+
 	seed_rng();
 
 	while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
diff -ruN openssh-7.5p1/ssh_api.c openssh-7.5p1+x509-10.2/ssh_api.c
--- openssh-7.5p1/ssh_api.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_api.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2012 Markus Friedl.  All rights reserved.
  *
+ * X.509 certificates support,
+ * Copyright (c) 2014-2017 Roumen Petrov.  All rights reserved.
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
@@ -36,10 +39,8 @@
 int	_ssh_read_banner(struct ssh *, char **);
 int	_ssh_order_hostkeyalgs(struct ssh *);
 int	_ssh_verify_host_key(struct sshkey *, struct ssh *);
-struct sshkey *_ssh_host_public_key(int, int, struct ssh *);
-struct sshkey *_ssh_host_private_key(int, int, struct ssh *);
-int	_ssh_host_key_sign(struct sshkey *, struct sshkey *,
-    u_char **, size_t *, const u_char *, size_t, const char *, u_int);
+struct sshkey *_ssh_host_public_key(const char*, struct ssh *);
+struct sshkey *_ssh_host_private_key(const char*, struct ssh *);
 
 /*
  * stubs for the server side implementation of kex.
@@ -67,6 +68,16 @@
 	return (NULL);
 }
 
+static int
+_ssh_host_key_sign(
+	ssh_sign_ctx *ctx, struct sshkey *pub,
+	u_char **sigp, size_t *lenp,
+	const u_char *data, size_t datalen
+){
+	(void)pub;
+	return Xkey_sign(ctx, sigp, lenp, data, datalen);
+}
+
 /* API */
 
 int
@@ -111,9 +122,9 @@
 # endif
 #endif /* WITH_OPENSSL */
 		ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
-		ssh->kex->load_host_public_key=&_ssh_host_public_key;
-		ssh->kex->load_host_private_key=&_ssh_host_private_key;
-		ssh->kex->sign=&_ssh_host_key_sign;
+		ssh->kex->find_host_public_key=&_ssh_host_public_key;
+		ssh->kex->find_host_private_key=&_ssh_host_private_key;
+		ssh->kex->xsign=&_ssh_host_key_sign;
 	} else {
 #ifdef WITH_OPENSSL
 		ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
@@ -364,7 +375,7 @@
 	debug("Remote protocol version %d.%d, remote software version %.100s",
 	    remote_major, remote_minor, remote_version);
 
-	ssh->compat = compat_datafellows(remote_version);
+	SSH_XCOMPATIBILITY(ssh, remote_version);
 	if  (remote_major == 1 && remote_minor == 99) {
 		remote_major = 2;
 		remote_minor = 0;
@@ -436,30 +447,28 @@
 }
 
 struct sshkey *
-_ssh_host_public_key(int type, int nid, struct ssh *ssh)
+_ssh_host_public_key(const char* pkalg, struct ssh *ssh)
 {
 	struct key_entry *k;
 
-	debug3("%s: need %d", __func__, type);
+	debug3("%s: need %s", __func__, pkalg);
 	TAILQ_FOREACH(k, &ssh->public_keys, next) {
 		debug3("%s: check %s", __func__, sshkey_type(k->key));
-		if (k->key->type == type &&
-		    (type != KEY_ECDSA || k->key->ecdsa_nid == nid))
+		if (sshkey_match_pkalg(k->key, pkalg))
 			return (k->key);
 	}
 	return (NULL);
 }
 
 struct sshkey *
-_ssh_host_private_key(int type, int nid, struct ssh *ssh)
+_ssh_host_private_key(const char* pkalg, struct ssh *ssh)
 {
 	struct key_entry *k;
 
-	debug3("%s: need %d", __func__, type);
+	debug3("%s: need %s", __func__, pkalg);
 	TAILQ_FOREACH(k, &ssh->private_keys, next) {
 		debug3("%s: check %s", __func__, sshkey_type(k->key));
-		if (k->key->type == type &&
-		    (type != KEY_ECDSA || k->key->ecdsa_nid == nid))
+		if (sshkey_match_pkalg(k->key, pkalg))
 			return (k->key);
 	}
 	return (NULL);
@@ -531,11 +540,3 @@
 	kex_prop_free(proposal);
 	return r;
 }
-
-int
-_ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey,
-    u_char **signature, size_t *slen, const u_char *data, size_t dlen,
-    const char *alg, u_int compat)
-{
-	return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat);
-}
diff -ruN openssh-7.5p1/ssh.c openssh-7.5p1+x509-10.2/ssh.c
--- openssh-7.5p1/ssh.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh.c	2017-05-20 21:07:01.000000000 +0300
@@ -19,6 +19,9 @@
  * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
  * in Canada (German citizen).
  *
+ * X.509 certificates support:
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -77,7 +80,16 @@
 #include <openssl/err.h>
 #endif
 #include "openbsd-compat/openssl-compat.h"
+
+#ifdef HAVE_FIPSCHECK_H
+#  include <fipscheck.h>
+#endif
+
 #include "openbsd-compat/sys-queue.h"
+#ifdef LDAP_ENABLED
+/* OpenSSL extension defined in x509_by_ldap.c */
+extern void ERR_load_X509byLDAP_strings(void);
+#endif
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -91,6 +103,8 @@
 #include "buffer.h"
 #include "channels.h"
 #include "key.h"
+#include "ssh-x509.h"
+#include "key-eng.h"
 #include "authfd.h"
 #include "authfile.h"
 #include "pathnames.h"
@@ -122,6 +136,10 @@
 static char **saved_av;
 #endif
 
+/* used in ssh-x509.c */
+extern int (*pssh_x509store_verify_cert)(X509 *_cert, STACK_OF(X509) *_chain);
+extern STACK_OF(X509)* (*pssh_x509store_build_certchain)(X509 *cert, STACK_OF(X509) *untrusted);
+
 /* Flag indicating whether debug mode is on.  May be set on the command line. */
 int debug_flag = 0;
 
@@ -162,6 +180,9 @@
 /* optional user configfile */
 char *config = NULL;
 
+/* user engine configfile */
+char *engconfig = NULL;
+
 /*
  * Name of the host we are connecting to.  This is the name given on the
  * command line, or the HostName specified for the user-supplied name in a
@@ -198,9 +219,13 @@
 usage(void)
 {
 	fprintf(stderr,
-"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
+"usage: ssh [-1246AaCdfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
 "           [-D [bind_address:]port] [-E log_file] [-e escape_char]\n"
-"           [-F configfile] [-I pkcs11] [-i identity_file]\n"
+"           [-F configfile]\n"
+#ifdef USE_OPENSSL_ENGINE
+"           [-G engineconfigfile]\n"
+#endif
+"           [-I pkcs11] [-i identity_file]\n"
 "           [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n"
 "           [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\n"
 "           [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n"
@@ -530,6 +555,19 @@
 	sanitise_stdfd();
 
 	__progname = ssh_get_progname(av[0]);
+	ssh_OpenSSL_startup();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	#ifdef HAVE_FIPSCHECK_H
+		if (!FIPSCHECK_verify(NULL, NULL))
+			fatal("FIPS integrity verification test failed.");
+	#endif
+		fprintf(stderr, "%s runs in FIPS mode\n", __progname);
+	}
+#endif /*def OPENSSL_FIPS*/
+	ssh_engines_startup();
+	pssh_x509store_verify_cert = ssh_x509store_verify_cert;
+	pssh_x509store_build_certchain = ssh_x509store_build_certchain;
 
 #ifndef HAVE_SETPROCTITLE
 	/* Prepare for later setproctitle emulation */
@@ -605,8 +643,14 @@
 	argv0 = av[0];
 
  again:
-	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
-	    "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
+#ifdef USE_OPENSSL_ENGINE
+#  define ENGCONFIG "G:"
+#else
+#  define ENGCONFIG ""
+#endif
+
+	while ((opt = getopt(ac, av, "1246ab:c:de:fgi:kl:m:no:p:qstvx"
+	    "ACD:E:F:" ENGCONFIG "I:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
 		switch (opt) {
 		case '1':
 			options.protocol = SSH_PROTO_1;
@@ -639,7 +683,7 @@
 		case 'E':
 			logfile = optarg;
 			break;
-		case 'G':
+		case 'd':
 			config_test = 1;
 			break;
 		case 'Y':
@@ -716,13 +760,16 @@
 			options.gss_deleg_creds = 1;
 			break;
 		case 'i':
-			p = tilde_expand_filename(optarg, original_real_uid);
-			if (stat(p, &st) < 0)
+			p = strncmp(optarg, "engine:", 7)
+				? tilde_expand_filename(optarg, original_real_uid)
+				: NULL;
+			if (p != NULL &&
+			    stat(p, &st) < 0)
 				fprintf(stderr, "Warning: Identity file %s "
 				    "not accessible: %s.\n", p,
 				    strerror(errno));
 			else
-				add_identity_file(&options, NULL, p, 1);
+				add_identity_file(&options, NULL, p != NULL ? p : optarg, 1);
 			free(p);
 			break;
 		case 'I':
@@ -931,6 +978,11 @@
 		case 'F':
 			config = optarg;
 			break;
+#ifdef USE_OPENSSL_ENGINE
+		case 'G':
+			engconfig = optarg;
+			break;
+#endif
 		default:
 			usage();
 		}
@@ -964,8 +1016,10 @@
 	host_arg = xstrdup(host);
 
 #ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
 	ERR_load_crypto_strings();
+#ifdef LDAP_ENABLED
+	ERR_load_X509byLDAP_strings();
+#endif
 #endif
 
 	/* Initialize the command to execute on remote host. */
@@ -1019,6 +1073,28 @@
 #endif
 		);
 
+#ifdef USE_OPENSSL_ENGINE
+	/* process per-user engine configuration file */
+	if (engconfig != NULL) {
+		r = process_engconfig_file(engconfig);
+	} else {
+		r = snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
+		    _PATH_SSH_ENGINE_CONFFILE);
+		if (r > 0 && (size_t)r < sizeof(buf))
+			r = process_engconfig_file(buf);
+		else
+			r = 0;
+	}
+	if (!r) {
+		if (engconfig != NULL)
+			debug("Can't process engine config file %.100s:"
+			    " %.100s", engconfig, strerror(errno));
+		else
+			debug("Can't process default engine config file:"
+			    " %.100s", strerror(errno));
+	}
+#endif
+
 	/* Parse the configuration files */
 	process_config_files(host_arg, pw, 0);
 
@@ -1125,6 +1201,15 @@
 		    options.proxy_command);
 	}
 
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		if (options.protocol & SSH_PROTO_1)
+			fatal("Protocol 1 not allowed in FIPS mode.");
+		if (options.protocol & ~SSH_PROTO_2)
+			fatal("Only protocol 2 is allowed in FIPS mode.");
+	}
+#endif
+
 	if (options.port == 0)
 		options.port = default_ssh_port();
 	channel_set_af(options.address_family);
@@ -1461,6 +1546,9 @@
 	/* Kill ProxyCommand if it is running. */
 	ssh_kill_proxy_command();
 
+	ssh_engines_shutdown();
+	ssh_OpenSSL_shuthdown();
+
 	return exit_status;
 }
 
@@ -2069,6 +2157,7 @@
 				key_free(keys[i]);
 				continue;
 			}
+			x509key_build_chain(keys[i]);
 			identity_keys[n_ids] = keys[i];
 			identity_files[n_ids] =
 			    xstrdup(options.pkcs11_provider); /* XXX */
diff -ruN openssh-7.5p1/ssh_config openssh-7.5p1+x509-10.2/ssh_config
--- openssh-7.5p1/ssh_config	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_config	2017-05-20 21:07:00.000000000 +0300
@@ -42,6 +42,17 @@
 #   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
 #   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
 #   EscapeChar ~
+#   AllowedCertPurpose sslserver
+#   MandatoryCRL no
+#   CACertificateFile /etc/ssh/ca/ca-bundle.crt
+#   CACertificatePath /etc/ssh/ca/crt
+#   CARevocationFile /etc/ssh/ca/ca-bundle.crl
+#   CARevocationPath /etc/ssh/ca/crl
+#   UserCACertificateFile ~/.ssh/ca-bundle.crt
+#   UserCACertificatePath ~/.ssh/crt
+#   UserCARevocationFile ~/.ssh/ca-bundle.crl
+#   UserCARevocationPath ~/.ssh/crl
+#   VAType none
 #   Tunnel no
 #   TunnelDevice any:any
 #   PermitLocalCommand no
diff -ruN openssh-7.5p1/ssh_config.0 openssh-7.5p1+x509-10.2/ssh_config.0
--- openssh-7.5p1/ssh_config.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_config.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,56 +1,55 @@
-SSH_CONFIG(5)                 File Formats Manual                SSH_CONFIG(5)
+SSH_CONFIG(5)               BSD File Formats Manual              SSH_CONFIG(5)
 
 NAME
-     ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files
+     ssh_config -- Secure shell client configuration files
 
 SYNOPSIS
      ~/.ssh/config
      /etc/ssh/ssh_config
 
 DESCRIPTION
-     ssh(1) obtains configuration data from the following sources in the
-     following order:
+     ssh(1) obtains configuration data from the following sources in the fol-
+     lowing order:
 
            1.   command-line options
            2.   user's configuration file (~/.ssh/config)
            3.   system-wide configuration file (/etc/ssh/ssh_config)
 
-     For each parameter, the first obtained value will be used.  The
-     configuration files contain sections separated by Host specifications,
-     and that section is only applied for hosts that match one of the patterns
-     given in the specification.  The matched host name is usually the one
-     given on the command line (see the CanonicalizeHostname option for
-     exceptions).
+     For each parameter, the first obtained value will be used.  The configu-
+     ration files contain sections separated by Host specifications, and that
+     section is only applied for hosts that match one of the patterns given in
+     the specification.  The matched host name is usually the one given on the
+     command line (see the CanonicalizeHostname option for exceptions).
 
-     Since the first obtained value for each parameter is used, more host-
-     specific declarations should be given near the beginning of the file, and
+     Since the first obtained value for each parameter is used, more host-spe-
+     cific declarations should be given near the beginning of the file, and
      general defaults at the end.
 
      The file contains keyword-argument pairs, one per line.  Lines starting
-     with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are interpreted as comments.  Arguments may
-     optionally be enclosed in double quotes (") in order to represent
-     arguments containing spaces.  Configuration options may be separated by
-     whitespace or optional whitespace and exactly one M-bM-^@M-^X=M-bM-^@M-^Y; the latter format
-     is useful to avoid the need to quote whitespace when specifying
-     configuration options using the ssh, scp, and sftp -o option.
+     with '#' and empty lines are interpreted as comments.  Arguments may
+     optionally be enclosed in double quotes (") in order to represent argu-
+     ments containing spaces.  Configuration options may be separated by
+     whitespace or optional whitespace and exactly one '='; the latter format
+     is useful to avoid the need to quote whitespace when specifying configu-
+     ration options using the ssh, scp, and sftp -o option.
 
-     The possible keywords and their meanings are as follows (note that
-     keywords are case-insensitive and arguments are case-sensitive):
+     The possible keywords and their meanings are as follows (note that key-
+     words are case-insensitive and arguments are case-sensitive):
 
      Host    Restricts the following declarations (up to the next Host or
              Match keyword) to be only for those hosts that match one of the
              patterns given after the keyword.  If more than one pattern is
-             provided, they should be separated by whitespace.  A single M-bM-^@M-^X*M-bM-^@M-^Y
+             provided, they should be separated by whitespace.  A single '*'
              as a pattern can be used to provide global defaults for all
              hosts.  The host is usually the hostname argument given on the
-             command line (see the CanonicalizeHostname keyword for
-             exceptions).
+             command line (see the CanonicalizeHostname keyword for excep-
+             tions).
 
-             A pattern entry may be negated by prefixing it with an
-             exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y).  If a negated entry is matched, then the
-             Host entry is ignored, regardless of whether any other patterns
-             on the line match.  Negated matches are therefore useful to
-             provide exceptions for wildcard matches.
+             A pattern entry may be negated by prefixing it with an exclama-
+             tion mark ('!').  If a negated entry is matched, then the Host
+             entry is ignored, regardless of whether any other patterns on the
+             line match.  Negated matches are therefore useful to provide
+             exceptions for wildcard matches.
 
              See PATTERNS for more information on patterns.
 
@@ -63,26 +62,26 @@
              appear alone or immediately after canonical.  Other criteria may
              be combined arbitrarily.  All criteria but all and canonical
              require an argument.  Criteria may be negated by prepending an
-             exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y).
+             exclamation mark ('!').
 
              The canonical keyword matches only when the configuration file is
              being re-parsed after hostname canonicalization (see the
-             CanonicalizeHostname option.)  This may be useful to specify
-             conditions that work with canonical host names only.  The exec
-             keyword executes the specified command under the user's shell.
-             If the command returns a zero exit status then the condition is
-             considered true.  Commands containing whitespace characters must
-             be quoted.  Arguments to exec accept the tokens described in the
+             CanonicalizeHostname option.)  This may be useful to specify con-
+             ditions that work with canonical host names only.  The exec key-
+             word executes the specified command under the user's shell.  If
+             the command returns a zero exit status then the condition is con-
+             sidered true.  Commands containing whitespace characters must be
+             quoted.  Arguments to exec accept the tokens described in the
              TOKENS section.
 
-             The other keywords' criteria must be single entries or comma-
-             separated lists and may use the wildcard and negation operators
+             The other keywords' criteria must be single entries or comma-sep-
+             arated lists and may use the wildcard and negation operators
              described in the PATTERNS section.  The criteria for the host
-             keyword are matched against the target hostname, after any
-             substitution by the Hostname or CanonicalizeHostname options.
-             The originalhost keyword matches against the hostname as it was
-             specified on the command-line.  The user keyword matches against
-             the target username on the remote host.  The localuser keyword
+             keyword are matched against the target hostname, after any sub-
+             stitution by the Hostname or CanonicalizeHostname options.  The
+             originalhost keyword matches against the hostname as it was spec-
+             ified on the command-line.  The user keyword matches against the
+             target username on the remote host.  The localuser keyword
              matches against the name of the local user running ssh(1) (this
              keyword may be useful in system-wide ssh_config files).
 
@@ -104,6 +103,18 @@
              arguments are any (the default), inet (use IPv4 only), or inet6
              (use IPv6 only).
 
+     AllowedCertPurpose
+             The intended use for the X.509 server certificate. Without this
+             option no chain verification will be done. Currently accepted
+             uses are case insensitive:
+             sslserver | SSL server | SSL_server | server
+                     only SSL-server purpose
+             any | Any Purpose | Any_Purpose | AnyPurpose
+                     allow any purpose
+             skip | '' (empty)
+                     do not check purpose
+             The default is sslserver.
+
      BatchMode
              If set to yes, passphrase/password querying will be disabled.
              This option is useful in scripts and other batch jobs where no
@@ -116,16 +127,52 @@
              one address.  Note that this option does not work if
              UsePrivilegedPort is set to yes.
 
+     CACertificateFile
+             ``X509 store'' option: This file contain multiple certificates of
+             certificate signers in PEM format concatenated together. The
+             default is /etc/ssh/ca/ca-bundle.crt.
+
+     CACertificatePath
+             ``X509 store'' option: ``Hash dir'' with certificates of certifi-
+             cate signers. Each certificate should be stored in separate file
+             with name [HASH].[NUMBER], where [HASH] is certificate hash value
+             and [NUMBER] is an integer starting from zero.  The default is
+             /etc/ssh/ca/crt.
+
+     CAldapVersion
+             ``X509 store'' option: Specifies LDAP protocol version.  The
+             default depend from LDAP library.
+
+     CAldapURL
+             ``X509 store'' option: Specifies hostport and dn of LDAP URLs
+             (Uniform Resource Locators) as detailed in RFC 2255. The rest of
+             URL is build internally.  Because of OpenSSH options parser limi-
+             tation use '%3D' instead of '=' !  LDAP initialization method may
+             require URL to be escaped, i.e. use '%2C' instead of ',' (comma).
+             Escaped URL don't depend from LDAP initialization method.
+
+     CARevocationFile
+             ``X509 store'' option: This file contain multiple ``Certificate
+             Revocation List'' (CRL) of certificate signers in PEM format con-
+             catenated together.  The default is /etc/ssh/ca/ca-bundle.crl.
+
+     CARevocationPath
+             ``X509 store'' option: ``Hash dir'' with ``Certificate Revocation
+             List'' (CRL) of certificate signers. Each CRL should be stored in
+             separate file with name [HASH].r[NUMBER], where [HASH] is CRL
+             hash value and [NUMBER] is an integer starting from zero. The
+             default is /etc/ssh/ca/crl.
+
      CanonicalDomains
              When CanonicalizeHostname is enabled, this option specifies the
-             list of domain suffixes in which to search for the specified
-             destination host.
+             list of domain suffixes in which to search for the specified des-
+             tination host.
 
      CanonicalizeFallbackLocal
-             Specifies whether to fail with an error when hostname
-             canonicalization fails.  The default, yes, will attempt to look
-             up the unqualified hostname using the system resolver's search
-             rules.  A value of no will cause ssh(1) to fail instantly if
+             Specifies whether to fail with an error when hostname canonical-
+             ization fails.  The default, yes, will attempt to look up the
+             unqualified hostname using the system resolver's search rules.  A
+             value of no will cause ssh(1) to fail instantly if
              CanonicalizeHostname is enabled and the target hostname cannot be
              found in any of the domains specified by CanonicalDomains.
 
@@ -137,12 +184,12 @@
              attempt to canonicalize the hostname specified on the command
              line using the CanonicalDomains suffixes and
              CanonicalizePermittedCNAMEs rules.  If CanonicalizeHostname is
-             set to always, then canonicalization is applied to proxied
-             connections too.
+             set to always, then canonicalization is applied to proxied con-
+             nections too.
 
-             If this option is enabled, then the configuration files are
-             processed again using the new target name to pick up any new
-             configuration in matching Host and Match stanzas.
+             If this option is enabled, then the configuration files are pro-
+             cessed again using the new target name to pick up any new config-
+             uration in matching Host and Match stanzas.
 
      CanonicalizeMaxDots
              Specifies the maximum number of dot characters in a hostname
@@ -158,9 +205,9 @@
              list of domains that they may resolve to.
 
              For example, "*.a.example.com:*.b.example.com,*.c.example.com"
-             will allow hostnames matching "*.a.example.com" to be
-             canonicalized to names in the "*.b.example.com" or
-             "*.c.example.com" domains.
+             will allow hostnames matching "*.a.example.com" to be canonical-
+             ized to names in the "*.b.example.com" or "*.c.example.com"
+             domains.
 
      CertificateFile
              Specifies a file from which the user's certificate is read.  A
@@ -189,19 +236,18 @@
              process, regardless of the setting of StrictHostKeyChecking.  If
              the option is set to no, the check will not be executed.
 
-     Cipher  Specifies the cipher to use for encrypting the session in
-             protocol version 1.  Currently, blowfish, 3des (the default), and
-             des are supported, though des is only supported in the ssh(1)
-             client for interoperability with legacy protocol 1
-             implementations; its use is strongly discouraged due to
-             cryptographic weaknesses.
+     Cipher  Specifies the cipher to use for encrypting the session in proto-
+             col version 1.  Currently, blowfish, 3des (the default), and des
+             are supported, though des is only supported in the ssh(1) client
+             for interoperability with legacy protocol 1 implementations; its
+             use is strongly discouraged due to cryptographic weaknesses.
 
      Ciphers
              Specifies the ciphers allowed for protocol version 2 in order of
              preference.  Multiple ciphers must be comma-separated.  If the
-             specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified
+             specified value begins with a '+' character, then the specified
              ciphers will be appended to the default set instead of replacing
-             them.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then
+             them.  If the specified value begins with a '-' character, then
              the specified ciphers (including wildcards) will be removed from
              the default set instead of replacing them.
 
@@ -237,9 +283,9 @@
              Specifies that all local, remote, and dynamic port forwardings
              specified in the configuration files or on the command line be
              cleared.  This option is primarily useful when used from the
-             ssh(1) command line to clear port forwardings set in
-             configuration files, and is automatically set by scp(1) and
-             sftp(1).  The argument must be yes or no (the default).
+             ssh(1) command line to clear port forwardings set in configura-
+             tion files, and is automatically set by scp(1) and sftp(1).  The
+             argument must be yes or no (the default).
 
      Compression
              Specifies whether to use compression.  The argument must be yes
@@ -269,20 +315,20 @@
              on a control socket specified using the ControlPath argument.
              Additional sessions can connect to this socket using the same
              ControlPath with ControlMaster set to no (the default).  These
-             sessions will try to reuse the master instance's network
-             connection rather than initiating new ones, but will fall back to
-             connecting normally if the control socket does not exist, or is
-             not listening.
-
-             Setting this to ask will cause ssh(1) to listen for control
-             connections, but require confirmation using ssh-askpass(1).  If
-             the ControlPath cannot be opened, ssh(1) will continue without
-             connecting to a master instance.
-
-             X11 and ssh-agent(1) forwarding is supported over these
-             multiplexed connections, however the display and agent forwarded
-             will be the one belonging to the master connection i.e. it is not
-             possible to forward multiple displays or agents.
+             sessions will try to reuse the master instance's network connec-
+             tion rather than initiating new ones, but will fall back to con-
+             necting normally if the control socket does not exist, or is not
+             listening.
+
+             Setting this to ask will cause ssh(1) to listen for control con-
+             nections, but require confirmation using ssh-askpass(1).  If the
+             ControlPath cannot be opened, ssh(1) will continue without con-
+             necting to a master instance.
+
+             X11 and ssh-agent(1) forwarding is supported over these multi-
+             plexed connections, however the display and agent forwarded will
+             be the one belonging to the master connection i.e. it is not pos-
+             sible to forward multiple displays or agents.
 
              Two additional options allow for opportunistic multiplexing: try
              to use a master connection but fall back to creating a new one if
@@ -290,31 +336,29 @@
              The latter requires confirmation like the ask option.
 
      ControlPath
-             Specify the path to the control socket used for connection
-             sharing as described in the ControlMaster section above or the
-             string none to disable connection sharing.  Arguments to
-             ControlPath may use the tilde syntax to refer to a user's home
-             directory or the tokens described in the TOKENS section.  It is
-             recommended that any ControlPath used for opportunistic
-             connection sharing include at least %h, %p, and %r (or
-             alternatively %C) and be placed in a directory that is not
-             writable by other users.  This ensures that shared connections
-             are uniquely identified.
+             Specify the path to the control socket used for connection shar-
+             ing as described in the ControlMaster section above or the string
+             none to disable connection sharing.  Arguments to ControlPath may
+             use the tilde syntax to refer to a user's home directory or the
+             tokens described in the TOKENS section.  It is recommended that
+             any ControlPath used for opportunistic connection sharing include
+             at least %h, %p, and %r (or alternatively %C) and be placed in a
+             directory that is not writable by other users.  This ensures that
+             shared connections are uniquely identified.
 
      ControlPersist
              When used in conjunction with ControlMaster, specifies that the
              master connection should remain open in the background (waiting
-             for future client connections) after the initial client
-             connection has been closed.  If set to no, then the master
-             connection will not be placed into the background, and will close
-             as soon as the initial client connection is closed.  If set to
-             yes or 0, then the master connection will remain in the
-             background indefinitely (until killed or closed via a mechanism
-             such as the "ssh -O exit").  If set to a time in seconds, or a
-             time in any of the formats documented in sshd_config(5), then the
-             backgrounded master connection will automatically terminate after
-             it has remained idle (with no client connections) for the
-             specified time.
+             for future client connections) after the initial client connec-
+             tion has been closed.  If set to no, then the master connection
+             will not be placed into the background, and will close as soon as
+             the initial client connection is closed.  If set to yes or 0,
+             then the master connection will remain in the background indefi-
+             nitely (until killed or closed via a mechanism such as the "ssh
+             -O exit").  If set to a time in seconds, or a time in any of the
+             formats documented in sshd_config(5), then the backgrounded mas-
+             ter connection will automatically terminate after it has remained
+             idle (with no client connections) for the specified time.
 
      DynamicForward
              Specifies that a TCP port on the local machine be forwarded over
@@ -323,12 +367,12 @@
 
              The argument must be [bind_address:]port.  IPv6 addresses can be
              specified by enclosing addresses in square brackets.  By default,
-             the local port is bound in accordance with the GatewayPorts
-             setting.  However, an explicit bind_address may be used to bind
-             the connection to a specific address.  The bind_address of
-             localhost indicates that the listening port be bound for local
-             use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port
-             should be available from all interfaces.
+             the local port is bound in accordance with the GatewayPorts set-
+             ting.  However, an explicit bind_address may be used to bind the
+             connection to a specific address.  The bind_address of localhost
+             indicates that the listening port be bound for local use only,
+             while an empty address or '*' indicates that the port should be
+             available from all interfaces.
 
              Currently the SOCKS4 and SOCKS5 protocols are supported, and
              ssh(1) will act as a SOCKS server.  Multiple forwardings may be
@@ -340,29 +384,29 @@
              file /etc/ssh/ssh_config enables the use of the helper program
              ssh-keysign(8) during HostbasedAuthentication.  The argument must
              be yes or no (the default).  This option should be placed in the
-             non-hostspecific section.  See ssh-keysign(8) for more
-             information.
+             non-hostspecific section.  See ssh-keysign(8) for more informa-
+             tion.
 
      EscapeChar
-             Sets the escape character (default: M-bM-^@M-^X~M-bM-^@M-^Y).  The escape character
+             Sets the escape character (default: '~').  The escape character
              can also be set on the command line.  The argument should be a
-             single character, M-bM-^@M-^X^M-bM-^@M-^Y followed by a letter, or none to disable
+             single character, '^' followed by a letter, or none to disable
              the escape character entirely (making the connection transparent
              for binary data).
 
      ExitOnForwardFailure
              Specifies whether ssh(1) should terminate the connection if it
              cannot set up all requested dynamic, tunnel, local, and remote
-             port forwardings, (e.g. if either end is unable to bind and
-             listen on a specified port).  Note that ExitOnForwardFailure does
+             port forwardings, (e.g. if either end is unable to bind and lis-
+             ten on a specified port).  Note that ExitOnForwardFailure does
              not apply to connections made over port forwardings and will not,
-             for example, cause ssh(1) to exit if TCP connections to the
-             ultimate forwarding destination fail.  The argument must be yes
-             or no (the default).
+             for example, cause ssh(1) to exit if TCP connections to the ulti-
+             mate forwarding destination fail.  The argument must be yes or no
+             (the default).
 
      FingerprintHash
-             Specifies the hash algorithm used when displaying key
-             fingerprints.  Valid options are: md5 and sha256 (the default).
+             Specifies the hash algorithm used when displaying key finger-
+             prints.  Valid options are: md5 and sha256 (the default).
 
      ForwardAgent
              Specifies whether the connection to the authentication agent (if
@@ -378,15 +422,15 @@
              the agent.
 
      ForwardX11
-             Specifies whether X11 connections will be automatically
-             redirected over the secure channel and DISPLAY set.  The argument
+             Specifies whether X11 connections will be automatically redi-
+             rected over the secure channel and DISPLAY set.  The argument
              must be yes or no (the default).
 
              X11 forwarding should be enabled with caution.  Users with the
              ability to bypass file permissions on the remote host (for the
-             user's X11 authorization database) can access the local X11
-             display through the forwarded connection.  An attacker may then
-             be able to perform activities such as keystroke monitoring if the
+             user's X11 authorization database) can access the local X11 dis-
+             play through the forwarded connection.  An attacker may then be
+             able to perform activities such as keystroke monitoring if the
              ForwardX11Trusted option is also enabled.
 
      ForwardX11Timeout
@@ -401,11 +445,11 @@
              access to the original X11 display.
 
              If this option is set to no (the default), remote X11 clients
-             will be considered untrusted and prevented from stealing or
-             tampering with data belonging to trusted X11 clients.
-             Furthermore, the xauth(1) token used for the session will be set
-             to expire after 20 minutes.  Remote clients will be refused
-             access after this time.
+             will be considered untrusted and prevented from stealing or tam-
+             pering with data belonging to trusted X11 clients.  Furthermore,
+             the xauth(1) token used for the session will be set to expire
+             after 20 minutes.  Remote clients will be refused access after
+             this time.
 
              See the X11 SECURITY extension specification for full details on
              the restrictions imposed on untrusted clients.
@@ -414,14 +458,14 @@
              Specifies whether remote hosts are allowed to connect to local
              forwarded ports.  By default, ssh(1) binds local port forwardings
              to the loopback address.  This prevents other remote hosts from
-             connecting to forwarded ports.  GatewayPorts can be used to
-             specify that ssh should bind local port forwardings to the
-             wildcard address, thus allowing remote hosts to connect to
-             forwarded ports.  The argument must be yes or no (the default).
+             connecting to forwarded ports.  GatewayPorts can be used to spec-
+             ify that ssh should bind local port forwardings to the wildcard
+             address, thus allowing remote hosts to connect to forwarded
+             ports.  The argument must be yes or no (the default).
 
      GlobalKnownHostsFile
-             Specifies one or more files to use for the global host key
-             database, separated by whitespace.  The default is
+             Specifies one or more files to use for the global host key data-
+             base, separated by whitespace.  The default is
              /etc/ssh/ssh_known_hosts, /etc/ssh/ssh_known_hosts2.
 
      GSSAPIAuthentication
@@ -434,11 +478,11 @@
      HashKnownHosts
              Indicates that ssh(1) should hash host names and addresses when
              they are added to ~/.ssh/known_hosts.  These hashed names may be
-             used normally by ssh(1) and sshd(8), but they do not reveal
-             identifying information should the file's contents be disclosed.
-             The default is no.  Note that existing names and addresses in
-             known hosts files will not be converted automatically, but may be
-             manually hashed using ssh-keygen(1).
+             used normally by ssh(1) and sshd(8), but they do not reveal iden-
+             tifying information should the file's contents be disclosed.  The
+             default is no.  Note that existing names and addresses in known
+             hosts files will not be converted automatically, but may be manu-
+             ally hashed using ssh-keygen(1).
 
      HostbasedAuthentication
              Specifies whether to try rhosts based authentication with public
@@ -446,33 +490,28 @@
              default).
 
      HostbasedKeyTypes
-             Specifies the key types that will be used for hostbased
-             authentication as a comma-separated pattern list.  Alternately if
-             the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the
-             specified key types will be appended to the default set instead
-             of replacing them.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y
-             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:
+             Option compatibility. See HostbasedAlgorithms
 
-                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,
-                ssh-rsa-cert-v01@openssh.com,
-                ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-                ssh-ed25519,ssh-rsa
-
-             The -Q option of ssh(1) may be used to list supported key types.
+     HostbasedAlgorithms
+             Specifies the protocol version 2 algorithms that will be used in
+             hostbased authentication as a comma-separated pattern list.  See
+             PATTERNS for more information on patterns.  The default * allows
+             all algorithms.  Note algorithms that use X.509 certificates
+             depend from option X509KeyAlgorithm.  The list of supported algo-
+             rithms may also be obtained using "ssh -Q key".
 
      HostKeyAlgorithms
              Specifies the host key algorithms that the client wants to use in
              order of preference.  Alternately if the specified value begins
-             with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be
+             with a '+' character, then the specified key types will be
              appended to the default set instead of replacing them.  If the
-             specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified
+             specified value begins with a '-' 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:
+             The default for this option depend from X509KeyAlgorithm.  It
+             contain first X509KeyAlgorithm for RSA key, followed by
+             X509KeyAlgorithms for ECDSA keys, followed by first X509KeyAlgo-
+             rithm for DSA key, followed by
 
                 ecdsa-sha2-nistp256-cert-v01@openssh.com,
                 ecdsa-sha2-nistp384-cert-v01@openssh.com,
@@ -490,9 +529,9 @@
 
      HostKeyAlias
              Specifies an alias that should be used instead of the real host
-             name when looking up or saving the host key in the host key
-             database files.  This option is useful for tunneling SSH
-             connections or for multiple servers running on a single host.
+             name when looking up or saving the host key in the host key data-
+             base files.  This option is useful for tunneling SSH connections
+             or for multiple servers running on a single host.
 
      HostName
              Specifies the real host name to log into.  This can be used to
@@ -521,14 +560,22 @@
              will be read from the SSH_AUTH_SOCK environment variable.
 
              Arguments to IdentityAgent may use the tilde syntax to refer to a
-             user's home directory or the tokens described in the TOKENS
-             section.
+             user's home directory or the tokens described in the TOKENS sec-
+             tion.
 
      IdentityFile
              Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA
              authentication identity is read.  The default is ~/.ssh/identity
              for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa,
              ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2.
+
+             Identity for protocol version 2 may contain X.509 certificate
+             that match private key.  For x509v3-ecdsa-sha2-* public key algo-
+             rithms, file with ECDSA key may contain extra X.509 certificates.
+             Extra certificates along with certificates from X.509 store are
+             used to build chain of certificates leading to a trusted certifi-
+             cate authority.
+
              Additionally, any identities represented by the authentication
              agent will be used for authentication unless IdentitiesOnly is
              set.  If no certificates have been explicitly specified by
@@ -537,33 +584,33 @@
              a specified IdentityFile.
 
              Arguments to IdentityFile may use the tilde syntax to refer to a
-             user's home directory or the tokens described in the TOKENS
-             section.
+             user's home directory or the tokens described in the TOKENS sec-
+             tion.
 
-             It is possible to have multiple identity files specified in
-             configuration files; all these identities will be tried in
-             sequence.  Multiple IdentityFile directives will add to the list
-             of identities tried (this behaviour differs from that of other
-             configuration directives).
+             It is possible to have multiple identity files specified in con-
+             figuration files; all these identities will be tried in sequence.
+             Multiple IdentityFile directives will add to the list of identi-
+             ties tried (this behaviour differs from that of other configura-
+             tion directives).
 
              IdentityFile may be used in conjunction with IdentitiesOnly to
-             select which identities in an agent are offered during
-             authentication.  IdentityFile may also be used in conjunction
-             with CertificateFile in order to provide any certificate also
-             needed for authentication with the identity.
+             select which identities in an agent are offered during authenti-
+             cation.  IdentityFile may also be used in conjunction with
+             CertificateFile in order to provide any certificate also needed
+             for authentication with the identity.
 
      IgnoreUnknown
              Specifies a pattern-list of unknown options to be ignored if they
              are encountered in configuration parsing.  This may be used to
-             suppress errors if ssh_config contains options that are
-             unrecognised by ssh(1).  It is recommended that IgnoreUnknown be
-             listed early in the configuration file as it will not be applied
-             to unknown options that appear before it.
+             suppress errors if ssh_config contains options that are unrecog-
+             nised by ssh(1).  It is recommended that IgnoreUnknown be listed
+             early in the configuration file as it will not be applied to
+             unknown options that appear before it.
 
      Include
              Include the specified configuration file(s).  Multiple pathnames
              may be specified and each pathname may contain glob(3) wildcards
-             and, for user configurations, shell-like M-bM-^@M-^X~M-bM-^@M-^Y references to user
+             and, for user configurations, shell-like '~' references to user
              home directories.  Files without absolute paths are assumed to be
              in ~/.ssh if included in a user configuration file or /etc/ssh if
              included from the system configuration file.  Include directive
@@ -574,12 +621,12 @@
              Accepted values are af11, af12, af13, af21, af22, af23, af31,
              af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6,
              cs7, ef, lowdelay, throughput, reliability, or a numeric value.
-             This option may take one or two arguments, separated by
-             whitespace.  If one argument is specified, it is used as the
-             packet class unconditionally.  If two values are specified, the
-             first is automatically selected for interactive sessions and the
-             second for non-interactive sessions.  The default is lowdelay for
-             interactive sessions and throughput for non-interactive sessions.
+             This option may take one or two arguments, separated by white-
+             space.  If one argument is specified, it is used as the packet
+             class unconditionally.  If two values are specified, the first is
+             automatically selected for interactive sessions and the second
+             for non-interactive sessions.  The default is lowdelay for inter-
+             active sessions and throughput for non-interactive sessions.
 
      KbdInteractiveAuthentication
              Specifies whether to use keyboard-interactive authentication.
@@ -596,9 +643,9 @@
      KexAlgorithms
              Specifies the available KEX (Key Exchange) algorithms.  Multiple
              algorithms must be comma-separated.  Alternately if the specified
-             value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified methods
+             value begins with a '+' character, then the specified methods
              will be appended to the default set instead of replacing them.
-             If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the
+             If the specified value begins with a '-' character, then the
              specified methods (including wildcards) will be removed from the
              default set instead of replacing them.  The default is:
 
@@ -612,11 +659,11 @@
              obtained using "ssh -Q kex".
 
      LocalCommand
-             Specifies a command to execute on the local machine after
-             successfully connecting to the server.  The command string
-             extends to the end of the line, and is executed with the user's
-             shell.  Arguments to LocalCommand accept the tokens described in
-             the TOKENS section.
+             Specifies a command to execute on the local machine after suc-
+             cessfully connecting to the server.  The command string extends
+             to the end of the line, and is executed with the user's shell.
+             Arguments to LocalCommand accept the tokens described in the
+             TOKENS section.
 
              The command is run synchronously and does not have access to the
              session of the ssh(1) that spawned it.  It should not be used for
@@ -632,31 +679,30 @@
              second argument must be host:hostport.  IPv6 addresses can be
              specified by enclosing addresses in square brackets.  Multiple
              forwardings may be specified, and additional forwardings can be
-             given on the command line.  Only the superuser can forward
-             privileged ports.  By default, the local port is bound in
-             accordance with the GatewayPorts setting.  However, an explicit
-             bind_address may be used to bind the connection to a specific
-             address.  The bind_address of localhost indicates that the
-             listening port be bound for local use only, while an empty
-             address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from
-             all interfaces.
+             given on the command line.  Only the superuser can forward privi-
+             leged ports.  By default, the local port is bound in accordance
+             with the GatewayPorts setting.  However, an explicit bind_address
+             may be used to bind the connection to a specific address.  The
+             bind_address of localhost indicates that the listening port be
+             bound for local use only, while an empty address or '*' indicates
+             that the port should be available from all interfaces.
 
      LogLevel
              Gives the verbosity level that is used when logging messages from
-             ssh(1).  The possible values are: QUIET, FATAL, ERROR, INFO,
-             VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.  The default is INFO.
+             ssh(1).  The possible values are: QUIET, FATAL, ERROR, INFO, VER-
+             BOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.  The default is INFO.
              DEBUG and DEBUG1 are equivalent.  DEBUG2 and DEBUG3 each specify
              higher levels of verbose output.
 
      MACs    Specifies the MAC (message authentication code) algorithms in
              order of preference.  The MAC algorithm is used for data
-             integrity protection.  Multiple algorithms must be comma-
-             separated.  If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character,
-             then the specified algorithms will be appended to the default set
+             integrity protection.  Multiple algorithms must be comma-sepa-
+             rated.  If the specified value begins with a '+' character, then
+             the specified algorithms will be appended to the default set
              instead of replacing them.  If the specified value begins with a
-             M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified algorithms (including
-             wildcards) will be removed from the default set instead of
-             replacing them.
+             '-' character, then the specified algorithms (including wild-
+             cards) will be removed from the default set instead of replacing
+             them.
 
              The algorithms that contain "-etm" calculate the MAC after
              encryption (encrypt-then-mac).  These are considered safer and
@@ -673,13 +719,18 @@
              The list of available MAC algorithms may also be obtained using
              "ssh -Q mac".
 
+     MandatoryCRL
+             ``X509 store'' option: Specifies whether CRL must present in
+             store for all certificates in ``certificate chain'' with atribute
+             ``X509v3 CRL Distribution Points''.  The default is no.
+
      NoHostAuthenticationForLocalhost
              This option can be used if the home directory is shared across
              machines.  In this case localhost will refer to a different
-             machine on each of the machines and the user will get many
-             warnings about changed host keys.  However, this option disables
-             host authentication for localhost.  The argument to this keyword
-             must be yes or no (the default).
+             machine on each of the machines and the user will get many warn-
+             ings about changed host keys.  However, this option disables host
+             authentication for localhost.  The argument to this keyword must
+             be yes or no (the default).
 
      NumberOfPasswordPrompts
              Specifies the number of password prompts before giving up.  The
@@ -696,9 +747,9 @@
 
      PKCS11Provider
              Specifies which PKCS#11 provider to use.  The argument to this
-             keyword is the PKCS#11 shared library ssh(1) should use to
-             communicate with a PKCS#11 token providing the user's private RSA
-             key.
+             keyword is the PKCS#11 shared library ssh(1) should use to commu-
+             nicate with a PKCS#11 token providing the user's private EC or
+             RSA key and X.509 certificate.
 
      Port    Specifies the port number to connect on the remote host.  The
              default is 22.
@@ -722,20 +773,20 @@
              only offered to support legacy devices.
 
      ProxyCommand
-             Specifies the command to use to connect to the server.  The
-             command string extends to the end of the line, and is executed
-             using the user's shell M-bM-^@M-^XexecM-bM-^@M-^Y directive to avoid a lingering
-             shell process.
+             Specifies the command to use to connect to the server.  The com-
+             mand string extends to the end of the line, and is executed using
+             the user's shell 'exec' directive to avoid a lingering shell
+             process.
 
              Arguments to ProxyCommand accept the tokens described in the
              TOKENS section.  The command can be basically anything, and
              should read from its standard input and write to its standard
              output.  It should eventually connect an sshd(8) server running
-             on some machine, or execute sshd -i somewhere.  Host key
-             management will be done using the HostName of the host being
-             connected (defaulting to the name typed by the user).  Setting
-             the command to none disables this option entirely.  Note that
-             CheckHostIP is not available for connects with a proxy command.
+             on some machine, or execute sshd -i somewhere.  Host key manage-
+             ment will be done using the HostName of the host being connected
+             (defaulting to the name typed by the user).  Setting the command
+             to none disables this option entirely.  Note that CheckHostIP is
+             not available for connects with a proxy command.
 
              This directive is useful in conjunction with nc(1) and its proxy
              support.  For example, the following directive would connect via
@@ -744,12 +795,12 @@
                 ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
 
      ProxyJump
-             Specifies one or more jump proxies as [user@]host[:port].
-             Multiple proxies may be separated by comma characters and will be
-             visited sequentially.  Setting this option will cause ssh(1) to
-             connect to the target host by first making a ssh(1) connection to
-             the specified ProxyJump host and then establishing a TCP
-             forwarding to the ultimate target from there.
+             Specifies one or more jump proxies as [user@]host[:port].  Multi-
+             ple proxies may be separated by comma characters and will be vis-
+             ited sequentially.  Setting this option will cause ssh(1) to con-
+             nect to the target host by first making a ssh(1) connection to
+             the specified ProxyJump host and then establishing a TCP forward-
+             ing to the ultimate target from there.
 
              Note that this option will compete with the ProxyCommand option -
              whichever is specified first will prevent later instances of the
@@ -761,25 +812,20 @@
              The default is no.
 
      PubkeyAcceptedKeyTypes
-             Specifies the key types that will be used for public key
-             authentication as a comma-separated pattern list.  Alternately if
-             the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the key
-             types after it will be appended to the default instead of
-             replacing it.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y
-             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:
+             Option compatibility. See PubkeyAlgorithms
 
-                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,
-                ssh-rsa-cert-v01@openssh.com,
-                ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-                ssh-ed25519,ssh-rsa
-
-             The list of available key types may also be obtained using "ssh
-             -Q key".
+     PubkeyAlgorithms
+             Specifies the protocol version 2 algorithms used in ``publickey''
+             authentication allowed to sent to the host.  See PATTERNS for
+             more information on patterns.  The default * allows all algo-
+             rithms and depend from X509KeyAlgorithm, i.e. the option allow
+             all specified by X509KeyAlgorithm plus ``plain'' key algorithms
+             like ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-
+             sha2-nistp521, ssh-ed25519, ssh-rsa and ssh-dss.  If a X.509 cer-
+             tificate is used as identity but corresponding algorithm is not
+             allowed the client will try plain key algorithm conforming to
+             certificate public key if allowed.  The list of supported key
+             algorithms may also be obtained using "ssh -Q key".
 
      PubkeyAuthentication
              Specifies whether to try public key authentication.  The argument
@@ -790,11 +836,11 @@
              before the session key is renegotiated, optionally followed a
              maximum amount of time that may pass before the session key is
              renegotiated.  The first argument is specified in bytes and may
-             have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes,
+             have a suffix of 'K', 'M', or 'G' to indicate Kilobytes,
              Megabytes, or Gigabytes, respectively.  The default is between
-             M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher.  The optional second
-             value is specified in seconds and may use any of the units
-             documented in the TIME FORMATS section of sshd_config(5).  The
+             '1G' and '4G', depending on the cipher.  The optional second
+             value is specified in seconds and may use any of the units docu-
+             mented in the TIME FORMATS section of sshd_config(5).  The
              default value for RekeyLimit is default none, which means that
              rekeying is performed after the cipher's default amount of data
              has been sent or received and no time based rekeying is done.
@@ -813,18 +859,17 @@
              allocated on the server and reported to the client at run time.
 
              If the bind_address is not specified, the default is to only bind
-             to loopback addresses.  If the bind_address is M-bM-^@M-^X*M-bM-^@M-^Y or an empty
-             string, then the forwarding is requested to listen on all
-             interfaces.  Specifying a remote bind_address will only succeed
-             if the server's GatewayPorts option is enabled (see
-             sshd_config(5)).
+             to loopback addresses.  If the bind_address is '*' or an empty
+             string, then the forwarding is requested to listen on all inter-
+             faces.  Specifying a remote bind_address will only succeed if the
+             server's GatewayPorts option is enabled (see sshd_config(5)).
 
      RequestTTY
              Specifies whether to request a pseudo-tty for the session.  The
              argument may be one of: no (never request a TTY), yes (always
              request a TTY when standard input is a TTY), force (always
-             request a TTY) or auto (request a TTY when opening a login
-             session).  This option mirrors the -t and -T flags for ssh(1).
+             request a TTY) or auto (request a TTY when opening a login ses-
+             sion).  This option mirrors the -t and -T flags for ssh(1).
 
      RevokedHostKeys
              Specifies revoked host public keys.  Keys listed in this file
@@ -844,9 +889,9 @@
      RSAAuthentication
              Specifies whether to try RSA authentication.  The argument to
              this keyword must be yes (the default) or no.  RSA authentication
-             will only be attempted if the identity file exists, or an
-             authentication agent is running.  Note that this option applies
-             to protocol version 1 only.
+             will only be attempted if the identity file exists, or an authen-
+             tication agent is running.  Note that this option applies to pro-
+             tocol version 1 only.
 
      SendEnv
              Specifies what variables from the local environ(7) should be sent
@@ -855,11 +900,10 @@
              that the TERM environment variable is always sent whenever a
              pseudo-terminal is requested as it is required by the protocol.
              Refer to AcceptEnv in sshd_config(5) for how to configure the
-             server.  Variables are specified by name, which may contain
-             wildcard characters.  Multiple environment variables may be
-             separated by whitespace or spread across multiple SendEnv
-             directives.  The default is not to send any environment
-             variables.
+             server.  Variables are specified by name, which may contain wild-
+             card characters.  Multiple environment variables may be separated
+             by whitespace or spread across multiple SendEnv directives.  The
+             default is not to send any environment variables.
 
              See PATTERNS for more information on patterns.
 
@@ -870,11 +914,11 @@
              being sent, ssh will disconnect from the server, terminating the
              session.  It is important to note that the use of server alive
              messages is very different from TCPKeepAlive (below).  The server
-             alive messages are sent through the encrypted channel and
-             therefore will not be spoofable.  The TCP keepalive option
-             enabled by TCPKeepAlive is spoofable.  The server alive mechanism
-             is valuable when the client or server depend on knowing when a
-             connection has become inactive.
+             alive messages are sent through the encrypted channel and there-
+             fore will not be spoofable.  The TCP keepalive option enabled by
+             TCPKeepAlive is spoofable.  The server alive mechanism is valu-
+             able when the client or server depend on knowing when a connec-
+             tion has become inactive.
 
              The default value is 3.  If, for example, ServerAliveInterval
              (see below) is set to 15 and ServerAliveCountMax is left at the
@@ -912,25 +956,25 @@
      StrictHostKeyChecking
              If this flag is set to yes, ssh(1) will never automatically add
              host keys to the ~/.ssh/known_hosts file, and refuses to connect
-             to hosts whose host key has changed.  This provides maximum
-             protection against trojan horse attacks, though it can be
-             annoying when the /etc/ssh/ssh_known_hosts file is poorly
-             maintained or when connections to new hosts are frequently made.
-             This option forces the user to manually add all new hosts.  If
-             this flag is set to no, ssh will automatically add new host keys
-             to the user known hosts files.  If this flag is set to ask (the
-             default), new host keys will be added to the user known host
-             files only after the user has confirmed that is what they really
-             want to do, and ssh will refuse to connect to hosts whose host
-             key has changed.  The host keys of known hosts will be verified
-             automatically in all cases.
+             to hosts whose host key has changed.  This provides maximum pro-
+             tection against trojan horse attacks, though it can be annoying
+             when the /etc/ssh/ssh_known_hosts file is poorly maintained or
+             when connections to new hosts are frequently made.  This option
+             forces the user to manually add all new hosts.  If this flag is
+             set to no, ssh will automatically add new host keys to the user
+             known hosts files.  If this flag is set to ask (the default), new
+             host keys will be added to the user known host files only after
+             the user has confirmed that is what they really want to do, and
+             ssh will refuse to connect to hosts whose host key has changed.
+             The host keys of known hosts will be verified automatically in
+             all cases.
 
      TCPKeepAlive
              Specifies whether the system should send TCP keepalive messages
              to the other side.  If they are sent, death of the connection or
              crash of one of the machines will be properly noticed.  However,
-             this means that connections will die if the route is down
-             temporarily, and some people find it annoying.
+             this means that connections will die if the route is down tempo-
+             rarily, and some people find it annoying.
 
              The default is yes (to send TCP keepalive messages), and the
              client will notice if the network goes down or the remote host
@@ -953,8 +997,8 @@
              defaults to any.  The default is any:any.
 
      UpdateHostKeys
-             Specifies whether ssh(1) should accept notifications of
-             additional hostkeys from the server sent after authentication has
+             Specifies whether ssh(1) should accept notifications of addi-
+             tional hostkeys from the server sent after authentication has
              completed and add them to UserKnownHostsFile.  The argument must
              be yes, no (the default) or ask.  Enabling this option allows
              learning alternate hostkeys for a server and supports graceful
@@ -971,52 +1015,121 @@
              client of all the server's hostkeys.
 
      UsePrivilegedPort
-             Specifies whether to use a privileged port for outgoing
-             connections.  The argument must be yes or no (the default).  If
-             set to yes, ssh(1) must be setuid root.  Note that this option
-             must be set to yes for RhostsRSAAuthentication with older
-             servers.
-
-     User    Specifies the user to log in as.  This can be useful when a
-             different user name is used on different machines.  This saves
-             the trouble of having to remember to give the user name on the
-             command line.
+             Specifies whether to use a privileged port for outgoing connec-
+             tions.  The argument must be yes or no (the default).  If set to
+             yes, ssh(1) must be setuid root.  Note that this option must be
+             set to yes for RhostsRSAAuthentication with older servers.
+
+     User    Specifies the user to log in as.  This can be useful when a dif-
+             ferent user name is used on different machines.  This saves the
+             trouble of having to remember to give the user name on the com-
+             mand line.
+
+     UserCACertificateFile
+             ``X509 store'' option: User CACertificateFile , the default is
+             ~/.ssh/ca-bundle.crt.
+
+     UserCACertificatePath
+             ``X509 store'' option: User CACertificatePath , the default is
+             ~/.ssh/crt.
+
+     UserCAldapVersion
+             ``X509 store'' option: User CAldapVersion.
+
+     UserCAldapURL
+             ``X509 store'' option: User CAldapURL.
+
+     UserCARevocationFile
+             ``X509 store'' option: User CARevocationFile , the default is
+             ~/.ssh/ca-bundle.crl.
+
+     UserCARevocationPath
+             ``X509 store'' option: User CARevocationPath , the default is
+             ~/.ssh/crl.
 
      UserKnownHostsFile
-             Specifies one or more files to use for the user host key
-             database, separated by whitespace.  The default is
+             Specifies one or more files to use for the user host key data-
+             base, separated by whitespace.  The default is
              ~/.ssh/known_hosts, ~/.ssh/known_hosts2.
 
+     VACertificateFile
+             File with X.509 certificates in PEM format concatenated together.
+             In use when VAType is set to ocspspec.  The default value is ''
+             (empty).  Certificates from that file explicitly trust 'OCSP
+             Responder' public key.  They are used as trusted certificates in
+             addition to certificates from CACertificateFile ,
+             CACertificatePath , UserCACertificateFile and
+             UserCACertificatePath to verify responder certificate.
+
+     VAType  Specifies whether 'Online Certificate Status Protocol' (OCSP) is
+             used to validate X.509 certificates.  Accepted values are case
+             insensitive:
+                   none          do not use OCSP to validate certificates;
+                   ocspcert      validate only certificates that specify 'OCSP
+                                 Service Locator' URL;
+                   ocspspec      use specified in the configuration 'OCSP
+                                 Responder' to validate all certificates.
+             The default is none.
+
+     VAOCSPResponderURL
+             'Access Location' / 'OCSP Service Locator' URL of the OCSP
+             provider. In use when VAType is set to ocspspec.
+
      VerifyHostKeyDNS
-             Specifies whether to verify the remote key using DNS and SSHFP
-             resource records.  If this option is set to yes, the client will
-             implicitly trust keys that match a secure fingerprint from DNS.
-             Insecure fingerprints will be handled as if this option was set
-             to ask.  If this option is set to ask, information on fingerprint
-             match will be displayed, but the user will still need to confirm
-             new host keys according to the StrictHostKeyChecking option.  The
-             default is no.
+             Specifies whether to verify the remote key using DNS and
+             CERT/SSHFP resource records.  If this option is set to yes, the
+             client will implicitly trust keys that match a secure fingerprint
+             from DNS.  Insecure fingerprints will be handled as if this
+             option was set to ask.  If this option is set to ask, information
+             on fingerprint match will be displayed, but the user will still
+             need to confirm new host keys according to the
+             StrictHostKeyChecking option.  The default is no.
 
              See also VERIFYING HOST KEYS in ssh(1).
 
      VisualHostKey
              If this flag is set to yes, an ASCII art representation of the
-             remote host key fingerprint is printed in addition to the
-             fingerprint string at login and for unknown host keys.  If this
-             flag is set to no (the default), no fingerprint strings are
-             printed at login and only the fingerprint string will be printed
-             for unknown host keys.
+             remote host key fingerprint is printed in addition to the finger-
+             print string at login and for unknown host keys.  If this flag is
+             set to no (the default), no fingerprint strings are printed at
+             login and only the fingerprint string will be printed for unknown
+             host keys.
+
+     X509KeyAlgorithm
+             Specifies how X.509 certificates and signatures are used for pro-
+             tocol version 2.  It is possible to have multiple algorithms in
+             form specified in X509 Key Algorithms Format section of
+             sshd_config(5).  Programs use the first listed for ECDSA, RSA, or
+             DSA key in signing and accept all listed.
+
+             The default for certificates with ECDSA keys is:
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp256,ssh-sha256,ecdsa-sha2-nistp256
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp384,ssh-sha384,ecdsa-sha2-nistp384
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp521,ssh-sha512,ecdsa-sha2-nistp521
+
+             The default for certificates with RSA key is:
+                   X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1
+                   X509KeyAlgorithm x509v3-sign-rsa,rsa-md5
+                   X509KeyAlgorithm x509v3-ssh-rsa,rsa-sha1,ssh-rsa
+
+             The default for certificates with DSA key is:
+                   X509KeyAlgorithm x509v3-sign-dss,dss-asn1
+                   X509KeyAlgorithm x509v3-sign-dss,dss-raw
+                   X509KeyAlgorithm x509v3-ssh-dss,dss-raw,ssh-dss
 
      XAuthLocation
              Specifies the full pathname of the xauth(1) program.  The default
              is /usr/X11R6/bin/xauth.
 
 PATTERNS
-     A pattern consists of zero or more non-whitespace characters, M-bM-^@M-^X*M-bM-^@M-^Y (a
-     wildcard that matches zero or more characters), or M-bM-^@M-^X?M-bM-^@M-^Y (a wildcard that
-     matches exactly one character).  For example, to specify a set of
-     declarations for any host in the ".co.uk" set of domains, the following
-     pattern could be used:
+     A pattern consists of zero or more non-whitespace characters, '*' (a
+     wildcard that matches zero or more characters), or '?' (a wildcard that
+     matches exactly one character).  For example, to specify a set of decla-
+     rations for any host in the ".co.uk" set of domains, the following pat-
+     tern could be used:
 
            Host *.co.uk
 
@@ -1027,7 +1140,7 @@
 
      A pattern-list is a comma-separated list of patterns.  Patterns within
      pattern-lists may be negated by preceding them with an exclamation mark
-     (M-bM-^@M-^X!M-bM-^@M-^Y).  For example, to allow a key to be used from anywhere within an
+     ('!').  For example, to allow a key to be used from anywhere within an
      organization except from the "dialup" pool, the following entry (in
      authorized_keys) could be used:
 
@@ -1037,7 +1150,7 @@
      Arguments to some keywords can make use of tokens, which are expanded at
      runtime:
 
-           %%    A literal M-bM-^@M-^X%M-bM-^@M-^Y.
+           %%    A literal '%'.
            %C    Shorthand for %l%h%p%r.
            %d    Local user's home directory.
            %h    The remote hostname.
@@ -1070,8 +1183,8 @@
              This is the per-user configuration file.  The format of this file
              is described above.  This file is used by the SSH client.
              Because of the potential for abuse, this file must have strict
-             permissions: read/write for the user, and not accessible by
-             others.
+             permissions: read/write for the user, and not accessible by oth-
+             ers.
 
      /etc/ssh/ssh_config
              Systemwide configuration file.  This file provides defaults for
@@ -1083,10 +1196,11 @@
      ssh(1)
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
-     versions 1.5 and 2.0.
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
 
-OpenBSD 6.0                    February 27, 2017                   OpenBSD 6.0
+BSD                            February 27, 2017                           BSD
diff -ruN openssh-7.5p1/ssh_config.5 openssh-7.5p1+x509-10.2/ssh_config.5
--- openssh-7.5p1/ssh_config.5	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_config.5	2017-05-20 21:07:00.000000000 +0300
@@ -1,3 +1,11 @@
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,6 +20,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -39,7 +48,7 @@
 .Os
 .Sh NAME
 .Nm ssh_config
-.Nd OpenSSH SSH client configuration files
+.Nd Secure shell client configuration files
 .Sh SYNOPSIS
 .Nm ~/.ssh/config
 .Nm /etc/ssh/ssh_config
@@ -246,6 +255,20 @@
 (use IPv4 only), or
 .Cm inet6
 (use IPv6 only).
+.It Cm AllowedCertPurpose
+The intended use for the X.509 server certificate. Without this option
+no chain verification will be done. Currently accepted uses are case
+insensitive:
+.Bl -tag -width Ds -compact
+.It Cm sslserver | Cm SSL server | Cm SSL_server | Cm server
+only SSL-server purpose
+.It Cm any | Cm Any Purpose | Cm Any_Purpose | Cm AnyPurpose
+allow any purpose
+.It Cm skip | Cm '' Li (empty)
+do not check purpose
+.El
+The default is
+.Cm sslserver .
 .It Cm BatchMode
 If set to
 .Cm yes ,
@@ -265,6 +288,60 @@
 .Cm UsePrivilegedPort
 is set to
 .Cm yes .
+.It Cm CACertificateFile
+.Dq X509 store
+option:
+This file contain multiple certificates of certificate signers in
+PEM format concatenated together. The default is
+.Pa /etc/ssh/ca/ca-bundle.crt .
+.It Cm CACertificatePath
+.Dq X509 store
+option:
+.Dq "Hash dir"
+with certificates of certificate signers. Each certificate should be
+stored in separate file with name [HASH].[NUMBER], where [HASH] is
+certificate hash value and [NUMBER] is an integer starting from zero.
+The default is
+.Pa /etc/ssh/ca/crt .
+.It Cm CAldapVersion
+.Dq X509 store
+option:
+Specifies LDAP protocol version.
+The default depend from LDAP library.
+.It Cm CAldapURL
+.Dq X509 store
+option:
+Specifies hostport and dn of LDAP URLs (Uniform Resource Locators)
+as detailed in RFC 2255. The rest of URL is build internally.
+Because of OpenSSH options parser limitation use
+.Sq %3D
+instead of
+.Sq =
+!
+LDAP initialization method may require URL to be escaped, i.e. use
+.Sq %2C
+instead of
+.Sq \&,
+(comma).
+Escaped URL don't depend from LDAP initialization method.
+.It Cm CARevocationFile
+.Dq X509 store
+option:
+This file contain multiple
+.Dq "Certificate Revocation List"
+(CRL) of certificate signers in PEM format concatenated together.
+The default is
+.Pa /etc/ssh/ca/ca-bundle.crl .
+.It Cm CARevocationPath
+.Dq X509 store
+option:
+.Dq "Hash dir"
+with
+.Dq "Certificate Revocation List"
+(CRL) of certificate signers. Each CRL should be stored in separate
+file with name [HASH].r[NUMBER], where [HASH] is CRL hash value and
+[NUMBER] is an integer starting from zero. The default is
+.Pa /etc/ssh/ca/crl .
 .It Cm CanonicalDomains
 When
 .Cm CanonicalizeHostname
@@ -782,32 +859,23 @@
 .Cm no
 (the default).
 .It Cm HostbasedKeyTypes
-Specifies the key types that will be used for hostbased authentication
-as a comma-separated pattern list.
-Alternately if the specified value begins with a
-.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-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,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,ssh-rsa
-.Ed
+Option compatibility. See
+.Cm HostbasedAlgorithms
 .Pp
-The
-.Fl Q
-option of
-.Xr ssh 1
-may be used to list supported key types.
+.It Cm HostbasedAlgorithms
+Specifies the protocol version 2 algorithms that will be used in
+.Cm hostbased
+authentication as a comma-separated pattern list.
+See
+.Sx PATTERNS
+for more information on patterns.
+The default
+.Cm *
+allows all algorithms.
+Note algorithms that use X.509 certificates depend from option
+.Cm X509KeyAlgorithm .
+The list of supported algorithms may also be obtained using
+.Qq ssh -Q key .
 .It Cm HostKeyAlgorithms
 Specifies the host key algorithms
 that the client wants to use in order of preference.
@@ -820,6 +888,12 @@
 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:
+The default for this option depend from
+.Cm X509KeyAlgorithm .
+It contain first X509KeyAlgorithm for RSA key,
+followed by X509KeyAlgorithms for ECDSA keys,
+followed by first X509KeyAlgorithm for DSA key,
+followed by
 .Bd -literal -offset 3n
 ecdsa-sha2-nistp256-cert-v01@openssh.com,
 ecdsa-sha2-nistp384-cert-v01@openssh.com,
@@ -910,6 +984,15 @@
 and
 .Pa ~/.ssh/id_rsa
 for protocol version 2.
+.Pp
+Identity for protocol version 2 may contain
+X.509 certificate that match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, file
+with ECDSA key may contain extra X.509 certificates.
+Extra certificates along with certificates from X.509 store
+are used to build chain of certificates leading to
+a trusted certificate authority.
+.Pp
 Additionally, any identities represented by the authentication agent
 will be used for authentication unless
 .Cm IdentitiesOnly
@@ -1139,6 +1222,15 @@
 .Pp
 The list of available MAC algorithms may also be obtained using
 .Qq ssh -Q mac .
+.It Cm MandatoryCRL
+.Dq X509 store
+option:
+Specifies whether CRL must present in store for all certificates in
+.Dq certificate chain
+with atribute
+.Dq X509v3 CRL Distribution Points .
+The default is
+.Cm no .
 .It Cm NoHostAuthenticationForLocalhost
 This option can be used if the home directory is shared across machines.
 In this case localhost will refer to a different machine on each of
@@ -1177,7 +1269,7 @@
 The argument to this keyword is the PKCS#11 shared library
 .Xr ssh 1
 should use to communicate with a PKCS#11 token providing the user's
-private RSA key.
+private EC or RSA key and X.509 certificate.
 .It Cm Port
 Specifies the port number to connect on the remote host.
 The default is 22.
@@ -1278,28 +1370,31 @@
 The default is
 .Cm no .
 .It Cm PubkeyAcceptedKeyTypes
-Specifies the key types that will be used for public key authentication
-as a comma-separated pattern list.
-Alternately if the specified value begins with a
-.Sq +
-character, then the key types after it will be appended to the default
-instead of replacing it.
-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,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,ssh-rsa
-.Ed
-.Pp
-The list of available key types may also be obtained using
+Option compatibility. See
+.Cm PubkeyAlgorithms
+.It Cm PubkeyAlgorithms
+Specifies the protocol version 2 algorithms used in
+.Dq publickey
+authentication allowed to sent to the host.
+See
+.Sx PATTERNS
+for more information on patterns.
+The default
+.Cm *
+allows all algorithms and depend from
+.Cm X509KeyAlgorithm ,
+i.e. the option allow all specified by
+.Cm X509KeyAlgorithm
+plus
+.Dq plain
+key algorithms like
+ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521,
+ssh-ed25519, ssh-rsa and ssh-dss.
+If a X.509 certificate is used as identity
+but corresponding algorithm is not allowed
+the client will try plain key algorithm
+conforming to certificate public key if allowed.
+The list of supported key algorithms may also be obtained using
 .Qq ssh -Q key .
 .It Cm PubkeyAuthentication
 Specifies whether to try public key authentication.
@@ -1637,14 +1732,101 @@
 This can be useful when a different user name is used on different machines.
 This saves the trouble of
 having to remember to give the user name on the command line.
+.It Cm UserCACertificateFile
+.Dq X509 store
+option:
+User
+.Cm CACertificateFile
+, the default is
+.Pa ~/.ssh/ca-bundle.crt .
+.It Cm UserCACertificatePath
+.Dq X509 store
+option:
+User
+.Cm CACertificatePath
+, the default is
+.Pa ~/.ssh/crt .
+.It Cm UserCAldapVersion
+.Dq X509 store
+option:
+User
+.Cm CAldapVersion .
+.It Cm UserCAldapURL
+.Dq X509 store
+option:
+User
+.Cm CAldapURL .
+.It Cm UserCARevocationFile
+.Dq X509 store
+option:
+User
+.Cm CARevocationFile
+, the default is
+.Pa ~/.ssh/ca-bundle.crl .
+.It Cm UserCARevocationPath
+.Dq X509 store
+option:
+User
+.Cm CARevocationPath
+, the default is
+.Pa ~/.ssh/crl .
 .It Cm UserKnownHostsFile
 Specifies one or more files to use for the user
 host key database, separated by whitespace.
 The default is
 .Pa ~/.ssh/known_hosts ,
 .Pa ~/.ssh/known_hosts2 .
+.It Cm VACertificateFile
+File with X.509 certificates in PEM format concatenated together.
+In use when
+.Cm VAType
+is set to
+.Cm ocspspec .
+The default value is
+.Sq
+..
+(empty).
+Certificates from that file explicitly trust
+.Sq "OCSP Responder"
+public key.
+They are used as trusted certificates in addition to certificates from
+.Cm CACertificateFile
+,
+.Cm CACertificatePath
+,
+.Cm UserCACertificateFile
+and
+.Cm UserCACertificatePath
+to verify responder certificate.
+.It Cm VAType
+Specifies whether
+.Sq "Online Certificate Status Protocol"
+(OCSP) is used to validate X.509 certificates.
+Accepted values are case insensitive:
+.Bl -tag -offset indent -compact
+.It none
+do not use OCSP to validate certificates;
+.It ocspcert
+validate only certificates that specify
+.Sq "OCSP Service Locator"
+URL;
+.It ocspspec
+use specified in the configuration
+.Sq "OCSP Responder"
+to validate all certificates.
+.El
+The default is
+.Cm none .
+.It Cm VAOCSPResponderURL
+.Sq "Access Location"
+/
+.Sq "OCSP Service Locator"
+URL of the OCSP provider. In use when
+.Cm VAType
+is set to
+.Cm ocspspec .
 .It Cm VerifyHostKeyDNS
-Specifies whether to verify the remote key using DNS and SSHFP resource
+Specifies whether to verify the remote key using DNS and CERT/SSHFP resource
 records.
 If this option is set to
 .Cm yes ,
@@ -1676,6 +1858,77 @@
 (the default),
 no fingerprint strings are printed at login and
 only the fingerprint string will be printed for unknown host keys.
+.It Cm X509KeyAlgorithm
+Specifies how X.509 certificates and signatures are used for protocol version 2.
+It is possible to have multiple algorithms
+in form specified in
+.Sx X509 Key Algorithms Format
+section of
+.Xr sshd_config 5 .
+Programs use the first listed for
+.Cm ECDSA ,
+.Cm RSA ,
+or
+.Cm DSA
+key in signing and accept all listed.
+.Pp
+The default for certificates with ECDSA keys is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp256 , Ar ssh-sha256 , Ar ecdsa-sha2-nistp256
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp384 , Ar ssh-sha384 , Ar ecdsa-sha2-nistp384
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp521 , Ar ssh-sha512 , Ar ecdsa-sha2-nistp521
+.Sm on
+.El
+.Pp
+The default for certificates with RSA key is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-rsa , Ar rsa-sha1
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-rsa , Ar rsa-md5
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ssh-rsa , Ar rsa-sha1 , Ar ssh-rsa
+.Sm on
+.El
+.Pp
+The default for certificates with DSA key is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-dss , Ar dss-asn1
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-dss , Ar dss-raw
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ssh-dss , Ar dss-raw , Ar ssh-dss
+.Sm on
+.El
+.Pp
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
@@ -1789,7 +2042,7 @@
 .Xr ssh 1
 .Sh AUTHORS
 .An -nosplit
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by
 .An Tatu Ylonen .
 .An Aaron Campbell , Bob Beck , Markus Friedl ,
@@ -1800,3 +2053,5 @@
 created OpenSSH.
 .An Markus Friedl
 contributed the support for SSH protocol versions 1.5 and 2.0.
+.An Roumen Petrov
+contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/sshconnect1.c openssh-7.5p1+x509-10.2/sshconnect1.c
--- openssh-7.5p1/sshconnect1.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshconnect1.c	2017-05-20 21:07:01.000000000 +0300
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 
 #include <openssl/bn.h>
+#include "evp-compat.h"
 
 #include <errno.h>
 #include <stdarg.h>
@@ -91,13 +92,15 @@
 		goto out;
 	}
 	for (i = 0; i < idlist->nkeys; i++) {
+		const BIGNUM *n = NULL;
 		/* Try this identity. */
 		debug("Trying RSA authentication via agent with '%.100s'",
 		    idlist->comments[i]);
 
 		/* Tell the server that we are willing to authenticate using this key. */
 		packet_start(SSH_CMSG_AUTH_RSA);
-		packet_put_bignum(idlist->keys[i]->rsa->n);
+		RSA_get0_key(idlist->keys[i]->rsa, &n, NULL, NULL);
+		packet_put_bignum(n);
 		packet_send();
 		packet_write_wait();
 
@@ -232,7 +235,11 @@
 
 	/* Tell the server that we are willing to authenticate using this key. */
 	packet_start(SSH_CMSG_AUTH_RSA);
-	packet_put_bignum(public->rsa->n);
+	{
+	const BIGNUM *n = NULL;
+	RSA_get0_key(public->rsa, &n, NULL, NULL);
+	packet_put_bignum(n);
+	}
 	packet_send();
 	packet_write_wait();
 
@@ -354,9 +361,13 @@
 	/* Tell the server that we are willing to authenticate using this key. */
 	packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
 	packet_put_cstring(local_user);
-	packet_put_int(BN_num_bits(host_key->rsa->n));
-	packet_put_bignum(host_key->rsa->e);
-	packet_put_bignum(host_key->rsa->n);
+	{
+	const BIGNUM *n = NULL, *e = NULL;
+	RSA_get0_key(host_key->rsa, &n, &e, NULL);
+	packet_put_int(BN_num_bits(n));
+	packet_put_bignum(e);
+	packet_put_bignum(n);
+	}
 	packet_send();
 	packet_write_wait();
 
@@ -509,6 +520,8 @@
 	u_char cookie[8];
 	u_int supported_ciphers;
 	u_int server_flags, client_flags;
+	BIGNUM *sn = NULL, *se = NULL;
+	BIGNUM *hn = NULL, *he = NULL;
 
 	debug("Waiting for server public key.");
 
@@ -523,10 +536,12 @@
 	if ((server_key = key_new(KEY_RSA1)) == NULL)
 		fatal("%s: key_new(KEY_RSA1) failed", __func__);
 	bits = packet_get_int();
-	packet_get_bignum(server_key->rsa->e);
-	packet_get_bignum(server_key->rsa->n);
 
-	rbits = BN_num_bits(server_key->rsa->n);
+	RSA_get0_key(server_key->rsa, (const BIGNUM**)&sn, (const BIGNUM**)&se, NULL);
+	packet_get_bignum(se);
+	packet_get_bignum(sn);
+
+	rbits = BN_num_bits(sn);
 	if (bits != rbits) {
 		logit("Warning: Server lies about size of server public key: "
 		    "actual size is %d bits vs. announced %d.", rbits, bits);
@@ -536,10 +551,11 @@
 	if ((host_key = key_new(KEY_RSA1)) == NULL)
 		fatal("%s: key_new(KEY_RSA1) failed", __func__);
 	bits = packet_get_int();
-	packet_get_bignum(host_key->rsa->e);
-	packet_get_bignum(host_key->rsa->n);
+	RSA_get0_key(host_key->rsa, (const BIGNUM**)&hn, (const BIGNUM**)&he, NULL);
+	packet_get_bignum(he);
+	packet_get_bignum(hn);
 
-	rbits = BN_num_bits(host_key->rsa->n);
+	rbits = BN_num_bits(hn);
 	if (bits != rbits) {
 		logit("Warning: Server lies about size of server host key: "
 		    "actual size is %d bits vs. announced %d.", rbits, bits);
@@ -555,14 +571,14 @@
 	packet_check_eom();
 
 	debug("Received server public key (%d bits) and host key (%d bits).",
-	    BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
+	    BN_num_bits(sn), BN_num_bits(hn));
 
 	if (verify_host_key(host, hostaddr, host_key) == -1)
 		fatal("Host key verification failed.");
 
 	client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
 
-	derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id);
+	derive_ssh1_session_id(hn, sn, cookie, session_id);
 
 	/*
 	 * Generate an encryption key for the session.   The key is a 256 bit
@@ -597,14 +613,14 @@
 	 * Encrypt the integer using the public key and host key of the
 	 * server (key with smaller modulus first).
 	 */
-	if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
+	if (BN_cmp(sn, hn) < 0) {
 		/* Public key has smaller modulus. */
-		if (BN_num_bits(host_key->rsa->n) <
-		    BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
+		if (BN_num_bits(hn) <
+		    BN_num_bits(sn) + SSH_KEY_BITS_RESERVED) {
 			fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
 			    "SSH_KEY_BITS_RESERVED %d",
-			    BN_num_bits(host_key->rsa->n),
-			    BN_num_bits(server_key->rsa->n),
+			    BN_num_bits(hn),
+			    BN_num_bits(sn),
 			    SSH_KEY_BITS_RESERVED);
 		}
 		if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
@@ -612,12 +628,12 @@
 			fatal("%s: rsa_public_encrypt failed", __func__);
 	} else {
 		/* Host key has smaller modulus (or they are equal). */
-		if (BN_num_bits(server_key->rsa->n) <
-		    BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
+		if (BN_num_bits(sn) <
+		    BN_num_bits(hn) + SSH_KEY_BITS_RESERVED) {
 			fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
 			    "SSH_KEY_BITS_RESERVED %d",
-			    BN_num_bits(server_key->rsa->n),
-			    BN_num_bits(host_key->rsa->n),
+			    BN_num_bits(sn),
+			    BN_num_bits(hn),
 			    SSH_KEY_BITS_RESERVED);
 		}
 		if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
diff -ruN openssh-7.5p1/sshconnect2.c openssh-7.5p1+x509-10.2/sshconnect2.c
--- openssh-7.5p1/sshconnect2.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshconnect2.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,9 @@
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
  *
+ * X509 certificate support,
+ * Copyright (c) 2006-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -49,11 +52,11 @@
 #include "xmalloc.h"
 #include "ssh.h"
 #include "ssh2.h"
-#include "buffer.h"
 #include "packet.h"
 #include "compat.h"
 #include "cipher.h"
-#include "key.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "kex.h"
 #include "myproposal.h"
 #include "sshconnect.h"
@@ -117,7 +120,7 @@
 	for (i = 0; i < options.num_system_hostfiles; i++)
 		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
 
-	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
+	oavail = avail = xstrdup(options.hostkeyalgorithms);
 	maxlen = strlen(avail) + 1;
 	first = xmalloc(maxlen);
 	last = xmalloc(maxlen);
@@ -131,10 +134,12 @@
 	} while (0)
 
 	while ((alg = strsep(&avail, ",")) && *alg != '\0') {
-		if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
+		int subtype;
+		key_types_from_name(alg, &ktype, &subtype);
+		if (ktype == KEY_UNSPEC)
 			fatal("%s: unknown alg %s", __func__, alg);
-		if (lookup_key_in_hostkeys_by_type(hostkeys,
-		    sshkey_type_plain(ktype), NULL))
+		if (lookup_key_in_hostkeys_by_types(hostkeys,
+		    sshkey_type_plain(ktype), subtype, NULL))
 			ALG_APPEND(first, alg);
 		else
 			ALG_APPEND(last, alg);
@@ -235,6 +240,7 @@
 	packet_send();
 	packet_write_wait();
 #endif
+	free(s);
 }
 
 /*
@@ -250,6 +256,7 @@
 	TAILQ_ENTRY(identity) next;
 	int	agent_fd;		/* >=0 if agent supports key */
 	struct sshkey	*key;		/* public/private key */
+	const char	*pkalg;		/* public key algorithm (static) */
 	char	*filename;		/* comment for agent-only keys */
 	int	tried;
 	int	isprivate;		/* key points to the private key */
@@ -604,7 +611,7 @@
 		debug("unknown pkalg %s", pkalg);
 		goto done;
 	}
-	if ((key = key_from_blob(pkblob, blen)) == NULL) {
+	if ((key = xkey_from_blob(pkalg, pkblob, blen)) == NULL) {
 		debug("no key from blob. pkalg %s", pkalg);
 		goto done;
 	}
@@ -995,33 +1002,18 @@
 	return 0;
 }
 
-static const char *
-key_sign_encode(const struct sshkey *key)
-{
-	struct ssh *ssh = active_state;
-
-	if (key->type == KEY_RSA) {
-		switch (ssh->kex->rsa_sha2) {
-		case 256:
-			return "rsa-sha2-256";
-		case 512:
-			return "rsa-sha2-512";
-		}
-	}
-	return key_ssh_name(key);
-}
-
 static int
-identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
-    const u_char *data, size_t datalen, u_int compat)
+identity_sign(struct identity *id, ssh_sign_ctx *id_ctx,
+    u_char **sigp, size_t *lenp, const u_char *data, size_t datalen)
 {
 	Key *prv;
 	int ret;
+	ssh_sign_ctx ctx = { id_ctx->alg, id->key, id_ctx->compat };
 
 	/* the agent supports this key */
 	if (id->key != NULL && id->agent_fd != -1)
-		return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
-		    data, datalen, key_sign_encode(id->key), compat);
+		return Xssh_agent_sign(id->agent_fd, &ctx,
+		    sigp, lenp, data, datalen);
 
 	/*
 	 * we have already loaded the private key or
@@ -1029,14 +1021,14 @@
 	 */
 	if (id->key != NULL &&
 	    (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
-		return (sshkey_sign(id->key, sigp, lenp, data, datalen,
-		    key_sign_encode(id->key), compat));
-
+		return Xkey_sign(&ctx, sigp, lenp, data, datalen);
 	/* load the private key from the file */
 	if ((prv = load_identity_file(id)) == NULL)
 		return SSH_ERR_KEY_NOT_FOUND;
-	ret = sshkey_sign(prv, sigp, lenp, data, datalen,
-	    key_sign_encode(prv), compat);
+	if (id->key != NULL)
+	    prv->type = id->key->type;
+	ctx.key = prv;
+	ret = Xkey_sign(&ctx, sigp, lenp, data, datalen);
 	sshkey_free(prv);
 	return (ret);
 }
@@ -1070,14 +1062,16 @@
 	u_int bloblen, skip = 0;
 	int matched, ret = -1, have_sig = 1;
 	char *fp;
+	const char *pkalg;
 
+	pkalg = id->pkalg;
 	if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
 	    SSH_FP_DEFAULT)) == NULL)
 		return 0;
 	debug3("%s: %s %s", __func__, key_type(id->key), fp);
 	free(fp);
 
-	if (key_to_blob(id->key, &blob, &bloblen) == 0) {
+	if (xkey_to_blob(pkalg, id->key, &blob, &bloblen) == 0) {
 		/* we cannot handle this key */
 		debug3("sign_and_send_pubkey: cannot handle key");
 		return 0;
@@ -1102,7 +1096,7 @@
 	} else {
 		buffer_put_cstring(&b, authctxt->method->name);
 		buffer_put_char(&b, have_sig);
-		buffer_put_cstring(&b, key_sign_encode(id->key));
+		buffer_put_cstring(&b, pkalg);
 	}
 	buffer_put_string(&b, blob, bloblen);
 
@@ -1151,8 +1145,11 @@
 	}
 
 	/* generate signature */
-	ret = identity_sign(id, &signature, &slen,
-	    buffer_ptr(&b), buffer_len(&b), datafellows);
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, NULL, &ctx_compat };
+
+	ret = identity_sign(id, &ctx, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
+}
 	if (ret != 0) {
 		if (ret != SSH_ERR_KEY_NOT_FOUND)
 			error("%s: signing failed: %s", __func__, ssh_err(ret));
@@ -1173,7 +1170,7 @@
 		buffer_put_cstring(&b, authctxt->method->name);
 		buffer_put_char(&b, have_sig);
 		if (!(datafellows & SSH_BUG_PKAUTH))
-			buffer_put_cstring(&b, key_ssh_name(id->key));
+			buffer_put_cstring(&b, pkalg);
 		buffer_put_string(&b, blob, bloblen);
 	}
 	free(blob);
@@ -1201,10 +1198,12 @@
 {
 	u_char *blob;
 	u_int bloblen, have_sig = 0;
+	const char *pkalg;
 
-	debug3("send_pubkey_test");
+	pkalg = id->pkalg;
+	debug3("send_pubkey_test: %s", pkalg);
 
-	if (key_to_blob(id->key, &blob, &bloblen) == 0) {
+	if (xkey_to_blob(pkalg, id->key, &blob, &bloblen) == 0) {
 		/* we cannot handle this key */
 		debug3("send_pubkey_test: cannot handle key");
 		return 0;
@@ -1218,7 +1217,7 @@
 	packet_put_cstring(authctxt->method->name);
 	packet_put_char(have_sig);
 	if (!(datafellows & SSH_BUG_PKAUTH))
-		packet_put_cstring(key_sign_encode(id->key));
+		packet_put_cstring(pkalg);
 	packet_put_string(blob, bloblen);
 	free(blob);
 	packet_send();
@@ -1233,13 +1232,14 @@
 	int r, perm_ok = 0, quit = 0, i;
 	struct stat st;
 
-	if (stat(id->filename, &st) < 0) {
+	if (strncmp(id->filename, "engine:", 7) != 0 &&
+	    stat(id->filename, &st) < 0) {
 		(id->userprovided ? logit : debug3)("no such identity: %s: %s",
 		    id->filename, strerror(errno));
 		return NULL;
 	}
 	snprintf(prompt, sizeof prompt,
-	    "Enter passphrase for key '%.100s': ", id->filename);
+	    "Enter passphrase for key '%.400s': ", id->filename);
 	for (i = 0; i <= options.number_of_password_prompts; i++) {
 		if (i == 0)
 			passphrase = "";
@@ -1309,6 +1309,7 @@
 	size_t j;
 	struct ssh_identitylist *idlist;
 
+	debug2("preparing keys");
 	TAILQ_INIT(&agent);	/* keys from the agent */
 	TAILQ_INIT(&files);	/* keys from the config file */
 	preferred = &authctxt->keys;
@@ -1415,21 +1416,10 @@
 		TAILQ_REMOVE(&files, id, next);
 		TAILQ_INSERT_TAIL(preferred, id, next);
 	}
-	/* finally, filter by PubkeyAcceptedKeyTypes */
-	TAILQ_FOREACH_SAFE(id, preferred, next, id2) {
-		if (id->key != NULL &&
-		    match_pattern_list(sshkey_ssh_name(id->key),
-		    options.pubkey_key_types, 0) != 1) {
-			debug("Skipping %s key %s - "
-			    "not in PubkeyAcceptedKeyTypes",
-			    sshkey_ssh_name(id->key), id->filename);
-			TAILQ_REMOVE(preferred, id, next);
-			sshkey_free(id->key);
-			free(id->filename);
-			memset(id, 0, sizeof(*id));
-			continue;
-		}
-		debug2("key: %s (%p)%s%s", id->filename, id->key,
+	TAILQ_FOREACH(id, preferred, next) {
+		debug2("%s: %s (%p)%s%s",
+		    id->pkalg != NULL ? id->pkalg : "key",
+		    id->filename, (void*)id->key,
 		    id->userprovided ? ", explicit" : "",
 		    id->agent_fd != -1 ? ", agent" : "");
 	}
@@ -1460,18 +1450,112 @@
 		id->tried = 0;
 }
 
+static void
+set_keytype(Key *k, int kt) {
+	const char *n1, *n2;
+
+	if (k->type == kt) return;
+
+	/* sshkey_ssh_name returns pointer to static */
+	n1 = sshkey_ssh_name(k);
+	k->type = kt;
+	n2 = sshkey_ssh_name(k);
+	debug("Offering key-type '%s', original was '%s'", n2, n1);
+}
+
+static inline int
+pkalg_match(const char *pkalg, const char *pattern) {
+	if (pattern == NULL) return 1; /* NULL match all, i.e. like '*' */
+	return match_pattern_list(pkalg, pattern, 0) == 1;
+}
+
 static int
 try_identity(Identity *id)
 {
-	if (!id->key)
+	int kt;
+	struct ssh *ssh = active_state; /* TODO ssh session */
+	Key *key = id->key;
+
+	if (ssh == NULL) return (0);
+	if (key == NULL)
+		return (0);
+	kt = key->type;
+	if (kt == KEY_RSA1)
 		return (0);
-	if (key_type_plain(id->key->type) == KEY_RSA &&
+	if (sshkey_is_cert(key)) {
+		id->pkalg = sshkey_ssh_name(key);
+		return 1;
+	}
+
+{	struct kex *kex = ssh->kex;
+	const char *pkalg;
+
+{	/* try "X.509" algorithms only */
+	const SSHX509KeyAlgs *xkalg;
+	int loc;
+
+	for (
+	    loc = ssh_xkalg_typeind(kt, key->ecdsa_nid, &xkalg, -1);
+	    loc >= 0;
+	    loc = ssh_xkalg_typeind(kt, key->ecdsa_nid, &xkalg, loc)
+	) {
+		if (kt != xkalg->type) continue;
+
+		pkalg = xkalg->name;
+
+		if (!pkalg_match(pkalg, options.pubkey_algorithms))
+			continue;
+
+		if (!pkalg_match(pkalg, kex->pkalgs))
+			continue;
+
+		id->pkalg = pkalg;
+		return 1;
+	}
+}
+
+	/* try "plain" key algorithm */
+	kt = sshkey_type_plain(kt);
+	if (kt == KEY_RSA &&
 	    (datafellows & SSH_BUG_RSASIGMD5) != 0) {
 		debug("Skipped %s key %s for RSA/MD5 server",
-		    key_type(id->key), id->filename);
+		    sshkey_type(key), id->filename);
 		return (0);
 	}
-	return (id->key->type != KEY_RSA1);
+#ifdef HAVE_EVP_SHA256
+	if (kt == KEY_RSA && (kex->pkalgs != NULL)) {
+		/* server must announce support for following algorithms */
+		pkalg = "rsa-sha2-256";
+		if (match_pattern_list(pkalg, kex->pkalgs, 0) == 1)
+			if (pkalg_match(pkalg, options.pubkey_algorithms))
+				goto done;
+
+		pkalg = "rsa-sha2-512";
+		if (match_pattern_list(pkalg, kex->pkalgs, 0) == 1)
+			if (pkalg_match(pkalg, options.pubkey_algorithms))
+				goto done;
+	}
+#endif /*def HAVE_EVP_SHA256*/
+
+	pkalg = sshkey_ssh_name_plain(key);
+	if (!pkalg_match(pkalg, options.pubkey_algorithms)) {
+		debug("Skipped %s key %s as algorithm %s is not allowed by configuration",
+		    sshkey_type(key), id->filename, pkalg);
+		return 0;
+	}
+
+	if (!pkalg_match(pkalg, kex->pkalgs)) {
+		debug("Skipped %s key %s as algorithm %s is not accepted by peer",
+		    sshkey_type(key), id->filename, pkalg);
+		return 0;
+	}
+
+done:
+	set_keytype(id->key, kt);
+
+	id->pkalg = pkalg;
+	return 1;
+}
 }
 
 int
@@ -1727,6 +1811,7 @@
 	struct ssh *ssh = active_state;
 	struct sshkey *private = NULL;
 	struct sshbuf *b = NULL;
+	const char *pkalg;
 	const char *service;
 	u_char *sig = NULL, *keyblob = NULL;
 	char *fp = NULL, *chost = NULL, *lname = NULL;
@@ -1786,8 +1871,9 @@
 		error("%s: sshkey_fingerprint failed", __func__);
 		goto out;
 	}
+	pkalg = sshkey_ssh_name(private);
 	debug("%s: trying hostkey %s %s",
-	    __func__, sshkey_ssh_name(private), fp);
+	    __func__, pkalg, fp);
 
 	/* figure out a name for the client host */
 	if ((lname = get_local_name(packet_get_connection_in())) == NULL) {
@@ -1807,8 +1893,9 @@
 		error("%s: sshbuf_new failed", __func__);
 		goto out;
 	}
-	if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) {
-		error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
+	r = Xkey_to_blob(pkalg, private, &keyblob, &keylen);
+	if (r != SSH_ERR_SUCCESS) {
+		error("%s: key to blob: %s", __func__, ssh_err(r));
 		goto out;
 	}
 	if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
@@ -1827,12 +1914,15 @@
 #ifdef DEBUG_PK
 	sshbuf_dump(b, stderr);
 #endif
+{	ssh_compat ctx_compat = { datafellows, xcompat };
+	ssh_sign_ctx ctx = { pkalg, private, &ctx_compat };
 	if (authctxt->sensitive->external_keysign)
 		r = ssh_keysign(private, &sig, &siglen,
 		    sshbuf_ptr(b), sshbuf_len(b));
-	else if ((r = sshkey_sign(private, &sig, &siglen,
-	    sshbuf_ptr(b), sshbuf_len(b), NULL, datafellows)) != 0)
-		debug("%s: sshkey_sign: %s", __func__, ssh_err(r));
+	else if ((r = Xkey_sign(&ctx, &sig, &siglen,
+		    sshbuf_ptr(b), sshbuf_len(b))) != 0)
+		debug("%s: Xkey_sign: %s", __func__, ssh_err(r));
+}
 	if (r != 0) {
 		error("sign using hostkey %s %s failed",
 		    sshkey_ssh_name(private), fp);
diff -ruN openssh-7.5p1/sshconnect.c openssh-7.5p1+x509-10.2/sshconnect.c
--- openssh-7.5p1/sshconnect.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshconnect.c	2017-05-20 21:07:01.000000000 +0300
@@ -11,6 +11,29 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X.509 certificates support,
+ * Copyright (c) 2002-2015 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
@@ -51,6 +74,7 @@
 #include "uidswap.h"
 #include "compat.h"
 #include "key.h"
+#include "ssh-x509.h"
 #include "sshconnect.h"
 #include "hostfile.h"
 #include "log.h"
@@ -525,8 +549,8 @@
 {
 	/* Send our own protocol version identification. */
 	if (compat20) {
-		xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
-		    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
+		xasprintf(&client_version_string, "SSH-%d.%d-%.100s PKIX[%s]\r\n",
+		    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, PACKAGE_VERSION);
 	} else {
 		xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
 		    PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
@@ -630,7 +654,7 @@
 	debug("Remote protocol version %d.%d, remote software version %.100s",
 	    remote_major, remote_minor, remote_version);
 
-	active_state->compat = compat_datafellows(remote_version);
+	SSH_XCOMPATIBILITY(active_state, remote_version);
 	mismatch = 0;
 
 	switch (remote_major) {
@@ -815,6 +839,7 @@
 	char *ip = NULL, *host = NULL;
 	char hostline[1000], *hostp, *fp, *ra;
 	char msg[1024];
+	char extramsg[1024], *subject = NULL;
 	const char *type;
 	const struct hostkey_entry *host_found, *ip_found;
 	int len, cancelled_forwarding = 0;
@@ -983,16 +1008,30 @@
 					    "No matching host key fingerprint"
 					    " found in DNS.\n");
 			}
+			if (key_is_x509(host_key)) {
+				subject = x509key_subject(host_key);
+				snprintf(extramsg, sizeof(extramsg),
+				    "Distinguished name is '%s'.\n",
+				    subject);
+			} else {
+				subject = NULL;
+				*extramsg = '\0';
+			}
 			snprintf(msg, sizeof(msg),
 			    "The authenticity of host '%.200s (%s)' can't be "
 			    "established%s\n"
 			    "%s key fingerprint is %s.%s%s\n%s"
+			    "%s"
 			    "Are you sure you want to continue connecting "
 			    "(yes/no)? ",
 			    host, ip, msg1, type, fp,
 			    options.visual_host_key ? "\n" : "",
 			    options.visual_host_key ? ra : "",
-			    msg2);
+			    msg2, extramsg);
+			if(subject != NULL) {
+				free(subject);
+				subject = NULL;
+			}
 			free(ra);
 			free(fp);
 			if (!confirm(msg))
@@ -1065,7 +1104,7 @@
 		if (readonly == ROQUIET)
 			goto fail;
 		if (options.check_host_ip && host_ip_differ) {
-			char *key_msg;
+			const char *key_msg;
 			if (ip_status == HOST_NEW)
 				key_msg = "is unknown";
 			else if (ip_status == HOST_OK)
@@ -1324,10 +1363,16 @@
 				if (flags & DNS_VERIFY_MATCH) {
 					matching_host_key_dns = 1;
 				} else {
+					const char *rr = "";
 					warn_changed_key(plain);
-					error("Update the SSHFP RR in DNS "
+					if (key_is_x509(host_key)) {
+						rr = "CERT";
+					} else {
+						rr = "SSHFP";
+					}
+					error("Update the %s RR in DNS "
 					    "with the new host key to get rid "
-					    "of this message.");
+					    "of this message.", rr);
 				}
 			}
 		}
@@ -1389,6 +1434,7 @@
 		fatal("ssh1 is not supported");
 #endif
 	}
+	free(host);
 	free(local_user);
 }
 
@@ -1422,15 +1468,29 @@
 		KEY_ED25519,
 		-1
 	};
+	int subtype[] = {
+#ifdef OPENSSL_HAS_ECC
+		NID_X9_62_prime256v1,
+		NID_secp384r1,
+# ifdef OPENSSL_HAS_NISTP521
+		NID_secp521r1,
+# endif
+#endif /* OPENSSL_HAS_ECC */
+		-1 /* non-ECC keys has to be processed once */,
+		-1
+	};
 	int i, ret = 0;
 	char *fp, *ra;
 	const struct hostkey_entry *found;
 
 	for (i = 0; type[i] != -1; i++) {
-		if (type[i] == key->type)
-			continue;
-		if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
-			continue;
+	int k;
+	k = (type[i] == KEY_ECDSA) ? 0 : (sizeof(subtype) / sizeof(*subtype) - 2);
+	do {
+		if (type[i] == key->type && subtype[k] == key->ecdsa_nid)
+			goto nextsubtype;
+		if (!lookup_key_in_hostkeys_by_types(hostkeys, type[i], subtype[k], &found))
+			goto nextsubtype;
 		fp = sshkey_fingerprint(found->key,
 		    options.fingerprint_hash, SSH_FP_DEFAULT);
 		ra = sshkey_fingerprint(found->key,
@@ -1443,11 +1503,19 @@
 		    key_type(found->key),
 		    found->host, found->file, found->line,
 		    key_type(found->key), fp);
+		if (key_is_x509(found->key)) {
+			char *subject = x509key_subject(found->key);
+			logit("Distinguished name found is '%s'.", subject);
+			free(subject);
+		}
 		if (options.visual_host_key)
 			logit("%s", ra);
 		free(ra);
 		free(fp);
 		ret = 1;
+nextsubtype:
+		k++;
+	} while(subtype[k] != -1);
 	}
 	return ret;
 }
@@ -1470,6 +1538,11 @@
 	error("It is also possible that a host key has just been changed.");
 	error("The fingerprint for the %s key sent by the remote host is\n%s.",
 	    key_type(host_key), fp);
+	if (key_is_x509(host_key)) {
+		char *subject = x509key_subject(host_key);
+		error("Distinguished name sent by remote host is '%s'.", subject);
+		free(subject);
+	}
 	error("Please contact your system administrator.");
 
 	free(fp);
diff -ruN openssh-7.5p1/sshd.0 openssh-7.5p1+x509-10.2/sshd.0
--- openssh-7.5p1/sshd.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,28 +1,29 @@
-SSHD(8)                     System Manager's Manual                    SSHD(8)
+SSHD(8)                   BSD System Manager's Manual                  SSHD(8)
 
 NAME
-     sshd M-bM-^@M-^S OpenSSH SSH daemon
+     sshd -- Secure shell daemon
 
 SYNOPSIS
-     sshd [-46DdeiqTt] [-C connection_spec] [-c host_certificate_file]
-          [-E log_file] [-f config_file] [-g login_grace_time]
-          [-h host_key_file] [-o option] [-p port] [-u len]
+     sshd [-46DdeiqTt] [-b bits] [-C connection_spec]
+          [-c host_certificate_file] [-E log_file] [-f config_file]
+          [-g login_grace_time] [-h host_key_file] [-k key_gen_time]
+          [-o option] [-p port] [-u len]
 
 DESCRIPTION
-     sshd (OpenSSH Daemon) is the daemon program for ssh(1).  Together these
-     programs replace rlogin and rsh, and provide secure encrypted
-     communications between two untrusted hosts over an insecure network.
+     sshd (SecSH Daemon) is the daemon program for ssh(1).  Together these
+     programs replace rlogin and rsh, and provide secure encrypted communica-
+     tions between two untrusted hosts over an insecure network.
 
      sshd listens for connections from clients.  It is normally started at
      boot from /etc/rc.  It forks a new daemon for each incoming connection.
-     The forked daemons handle key exchange, encryption, authentication,
-     command execution, and data exchange.
+     The forked daemons handle key exchange, encryption, authentication, com-
+     mand execution, and data exchange.
 
      sshd can be configured using command-line options or a configuration file
-     (by default sshd_config(5)); command-line options override values
-     specified in the configuration file.  sshd rereads its configuration file
-     when it receives a hangup signal, SIGHUP, by executing itself with the
-     name and options it was started with, e.g. /usr/sbin/sshd.
+     (by default sshd_config(5)); command-line options override values speci-
+     fied in the configuration file.  sshd rereads its configuration file when
+     it receives a hangup signal, SIGHUP, by executing itself with the name
+     and options it was started with, e.g. /usr/sbin/sshd.
 
      The options are as follows:
 
@@ -30,21 +31,26 @@
 
      -6      Forces sshd to use IPv6 addresses only.
 
+     -b bits
+             Specifies the number of bits in the ephemeral protocol version 1
+             server key (default 1024).
+
      -C connection_spec
              Specify the connection parameters to use for the -T extended test
              mode.  If provided, any Match directives in the configuration
              file that would apply to the specified user, host, and address
-             will be set before the configuration is written to standard
-             output.  The connection parameters are supplied as keyword=value
-             pairs.  The keywords are M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and
-             M-bM-^@M-^\addrM-bM-^@M-^].  All are required and may be supplied in any order,
-             either with multiple -C options or as a comma-separated list.
+             will be set before the configuration is written to standard out-
+             put.  The connection parameters are supplied as keyword=value
+             pairs.  The keywords are ``user'', ``host'', ``laddr'',
+             ``lport'', and ``addr''.  All are required and may be supplied in
+             any order, either with multiple -C options or as a comma-sepa-
+             rated list.
 
      -c host_certificate_file
              Specifies a path to a certificate file to identify sshd during
              key exchange.  The certificate file must match a host key file
-             specified using the -h option or the HostKey configuration
-             directive.
+             specified using the -h option or the HostKey configuration direc-
+             tive.
 
      -D      When this option is specified, sshd will not detach and does not
              become a daemon.  This allows easy monitoring of sshd.
@@ -62,8 +68,8 @@
 
      -f config_file
              Specifies the name of the configuration file.  The default is
-             /etc/ssh/sshd_config.  sshd refuses to start if there is no
-             configuration file.
+             /etc/ssh/sshd_config.  sshd refuses to start if there is no con-
+             figuration file.
 
      -g login_grace_time
              Gives the grace time for clients to authenticate themselves
@@ -75,25 +81,47 @@
              Specifies a file from which a host key is read.  This option must
              be given if sshd is not run as root (as the normal host key files
              are normally not readable by anyone but root).  The default is
-             /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key,
-             /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key.  It
-             is possible to have multiple host key files for the different
-             host key algorithms.
-
-     -i      Specifies that sshd is being run from inetd(8).
+             /etc/ssh/ssh_host_key for protocol version 1, and
+             /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key.
+             /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for
+             protocol version 2.  It is possible to have multiple host key
+             files for the different protocol versions and host key algo-
+             rithms.
+
+             Host key for protocol version 2 may contain X.509 certificate
+             that match private key.  For x509v3-ecdsa-sha2-* public key algo-
+             rithms, file with ECDSA key may contain extra X.509 certificates.
+             Extra certificates along with certificates from X.509 store are
+             used to build chain of certificates leading to a trusted certifi-
+             cate authority.
+
+     -i      Specifies that sshd is being run from inetd(8).  If SSH protocol
+             1 is enabled, sshd should not  normally be run from inetd because
+             it needs to generate the server key before it can respond to the
+             client, and this may take some time.  Clients may have to wait
+             too long if the key was regenerated every time.
+
+     -k key_gen_time
+             Specifies how often the ephemeral protocol version 1 server key
+             is regenerated (default 3600 seconds, or one hour).  The motiva-
+             tion for regenerating the key fairly often is that the key is not
+             stored anywhere, and after about an hour it becomes impossible to
+             recover the key for decrypting intercepted communications even if
+             the machine is cracked into or physically seized.  A value of
+             zero indicates that the key will never be regenerated.
 
      -o option
-             Can be used to give options in the format used in the
-             configuration file.  This is useful for specifying options for
-             which there is no separate command-line flag.  For full details
-             of the options, and their values, see sshd_config(5).
+             Can be used to give options in the format used in the configura-
+             tion file.  This is useful for specifying options for which there
+             is no separate command-line flag.  For full details of the
+             options, and their values, see sshd_config(5).
 
      -p port
              Specifies the port on which the server listens for connections
-             (default 22).  Multiple port options are permitted.  Ports
-             specified in the configuration file with the Port option are
-             ignored when a command-line port is specified.  Ports specified
-             using the ListenAddress option override command-line ports.
+             (default 22).  Multiple port options are permitted.  Ports speci-
+             fied in the configuration file with the Port option are ignored
+             when a command-line port is specified.  Ports specified using the
+             ListenAddress option override command-line ports.
 
      -q      Quiet mode.  Nothing is sent to the system log.  Normally the
              beginning, authentication, and termination of each connection is
@@ -101,8 +129,8 @@
 
      -T      Extended test mode.  Check the validity of the configuration
              file, output the effective configuration to stdout and then exit.
-             Optionally, Match rules may be applied by specifying the
-             connection parameters using one or more -C options.
+             Optionally, Match rules may be applied by specifying the connec-
+             tion parameters using one or more -C options.
 
      -t      Test mode.  Only check the validity of the configuration file and
              sanity of the keys.  This is useful for updating sshd reliably as
@@ -111,51 +139,67 @@
      -u len  This option is used to specify the size of the field in the utmp
              structure that holds the remote host name.  If the resolved host
              name is longer than len, the dotted decimal value will be used
-             instead.  This allows hosts with very long host names that
-             overflow this field to still be uniquely identified.  Specifying
-             -u0 indicates that only dotted decimal addresses should be put
-             into the utmp file.  -u0 may also be used to prevent sshd from
-             making DNS requests unless the authentication mechanism or
-             configuration requires it.  Authentication mechanisms that may
-             require DNS include HostbasedAuthentication and using a
-             from="pattern-list" option in a key file.  Configuration options
-             that require DNS include using a USER@HOST pattern in AllowUsers
-             or DenyUsers.
+             instead.  This allows hosts with very long host names that over-
+             flow this field to still be uniquely identified.  Specifying -u0
+             indicates that only dotted decimal addresses should be put into
+             the utmp file.  -u0 may also be used to prevent sshd from making
+             DNS requests unless the authentication mechanism or configuration
+             requires it.  Authentication mechanisms that may require DNS
+             include RhostsRSAAuthentication, HostbasedAuthentication, and
+             using a from="pattern-list" option in a key file.  Configuration
+             options that require DNS include using a USER@HOST pattern in
+             AllowUsers or DenyUsers.
 
 AUTHENTICATION
-     The OpenSSH SSH daemon supports SSH protocol 2 only.  Each host has a
-     host-specific key, used to identify the host.  Whenever a client
-     connects, the daemon responds with its public host key.  The client
-     compares the host key against its own database to verify that it has not
-     changed.  Forward security is provided through a Diffie-Hellman key
+     The SecSH daemon supports SSH protocols 1 and 2.  The default is to use
+     protocol 2 only, though this can be changed via the Protocol option in
+     sshd_config(5).  Protocol 1 should not be used and is only offered to
+     support legacy devices.
+
+     Each host has a host-specific key, used to identify the host.  Partial
+     forward security for protocol 1 is provided through an additional server
+     key, normally 1024 bits, generated when the server starts.  This key is
+     normally regenerated every hour if it has been used, and is never stored
+     on disk.  Whenever a client connects, the daemon responds with its public
+     host and server keys.  The client compares the RSA host key against its
+     own database to verify that it has not changed.  The client then gener-
+     ates a 256-bit random number.  It encrypts this random number using both
+     the host key and the server key, and sends the encrypted number to the
+     server.  Both sides then use this random number as a session key which is
+     used to encrypt all further communications in the session.  The rest of
+     the session is encrypted using a conventional cipher, currently Blowfish
+     or 3DES, with 3DES being used by default.  The client selects the encryp-
+     tion algorithm to use from those offered by the server.
+
+     For protocol 2, forward security is provided through a Diffie-Hellman key
      agreement.  This key agreement results in a shared session key.  The rest
      of the session is encrypted using a symmetric cipher, currently 128-bit
      AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.  The
      client selects the encryption algorithm to use from those offered by the
-     server.  Additionally, session integrity is provided through a
-     cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64,
+     server.  Additionally, session integrity is provided through a crypto-
+     graphic message authentication code (hmac-md5, hmac-sha1, umac-64,
      umac-128, hmac-ripemd160, hmac-sha2-256 or hmac-sha2-512).
 
      Finally, the server and the client enter an authentication dialog.  The
-     client tries to authenticate itself using host-based authentication,
-     public key authentication, challenge-response authentication, or password
+     client tries to authenticate itself using host-based authentication, pub-
+     lic key authentication, challenge-response authentication, or password
      authentication.
 
      Regardless of the authentication type, the account is checked to ensure
      that it is accessible.  An account is not accessible if it is locked,
-     listed in DenyUsers or its group is listed in DenyGroups .  The
-     definition of a locked account is system dependant. Some platforms have
-     their own account database (eg AIX) and some modify the passwd field (
-     M-bM-^@M-^X*LK*M-bM-^@M-^Y on Solaris and UnixWare, M-bM-^@M-^X*M-bM-^@M-^Y on HP-UX, containing M-bM-^@M-^XNologinM-bM-^@M-^Y on
-     Tru64, a leading M-bM-^@M-^X*LOCKED*M-bM-^@M-^Y on FreeBSD and a leading M-bM-^@M-^X!M-bM-^@M-^Y on most
-     Linuxes).  If there is a requirement to disable password authentication
-     for the account while allowing still public-key, then the passwd field
-     should be set to something other than these values (eg M-bM-^@M-^XNPM-bM-^@M-^Y or M-bM-^@M-^X*NP*M-bM-^@M-^Y ).
+     listed in DenyUsers or its group is listed in DenyGroups .  The defini-
+     tion of a locked account is system dependant. Some platforms have their
+     own account database (eg AIX) and some modify the passwd field ( '*LK*'
+     on Solaris and UnixWare, '*' on HP-UX, containing 'Nologin' on Tru64, a
+     leading '*LOCKED*' on FreeBSD and a leading '!' on most Linuxes).  If
+     there is a requirement to disable password authentication for the account
+     while allowing still public-key, then the passwd field should be set to
+     something other than these values (eg 'NP' or '*NP*' ).
 
      If the client successfully authenticates itself, a dialog for preparing
      the session is entered.  At this time the client may request things like
-     allocating a pseudo-tty, forwarding X11 connections, forwarding TCP
-     connections, or forwarding the authentication agent connection over the
+     allocating a pseudo-tty, forwarding X11 connections, forwarding TCP con-
+     nections, or forwarding the authentication agent connection over the
      secure channel.
 
      After this, the client either requests a shell or execution of a command.
@@ -163,8 +207,8 @@
      data at any time, and such data is forwarded to/from the shell or command
      on the server side, and the user terminal in the client side.
 
-     When the user program terminates and all forwarded X11 and other
-     connections have been closed, the server sends command exit status to the
+     When the user program terminates and all forwarded X11 and other connec-
+     tions have been closed, the server sends command exit status to the
      client, and both sides exit.
 
 LOGIN PROCESS
@@ -190,23 +234,22 @@
            7.   Changes to user's home directory.
 
            8.   If ~/.ssh/rc exists and the sshd_config(5) PermitUserRC option
-                is set, runs it; else if /etc/ssh/sshrc exists, runs it;
-                otherwise runs xauth.  The M-bM-^@M-^\rcM-bM-^@M-^] files are given the X11
-                authentication protocol and cookie in standard input.  See
-                SSHRC, below.
+                is set, runs it; else if /etc/ssh/sshrc exists, runs it; oth-
+                erwise runs xauth.  The ``rc'' files are given the X11 authen-
+                tication protocol and cookie in standard input.  See SSHRC,
+                below.
 
            9.   Runs user's shell or command.  All commands are run under the
-                user's login shell as specified in the system password
-                database.
+                user's login shell as specified in the system password data-
+                base.
 
 SSHRC
      If the file ~/.ssh/rc exists, sh(1) runs it after reading the environment
-     files but before starting the user's shell or command.  It must not
-     produce any output on stdout; stderr must be used instead.  If X11
-     forwarding is in use, it will receive the "proto cookie" pair in its
-     standard input (and DISPLAY in its environment).  The script must call
-     xauth(1) because sshd will not run xauth automatically to add X11
-     cookies.
+     files but before starting the user's shell or command.  It must not pro-
+     duce any output on stdout; stderr must be used instead.  If X11 forward-
+     ing is in use, it will receive the "proto cookie" pair in its standard
+     input (and DISPLAY in its environment).  The script must call xauth(1)
+     because sshd will not run xauth automatically to add X11 cookies.
 
      The primary purpose of this file is to run any initialization routines
      which may be needed before the user's home directory becomes accessible;
@@ -232,27 +275,46 @@
 AUTHORIZED_KEYS FILE FORMAT
      AuthorizedKeysFile specifies the files containing public keys for public
      key authentication; if this option is not specified, the default is
-     ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2.  Each line of the
-     file contains one key (empty lines and lines starting with a M-bM-^@M-^X#M-bM-^@M-^Y are
-     ignored as comments).  Public keys consist of the following space-
-     separated fields: options, keytype, base64-encoded key, comment.  The
-     options field is optional.  The keytype is M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^],
-     M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or
-     M-bM-^@M-^\ssh-rsaM-bM-^@M-^]; the comment field is not used for anything (but may be
-     convenient for the user to identify the key).
-
-     Note that lines in this file can be several hundred bytes long (because
-     of the size of the public key encoding) up to a limit of 8 kilobytes,
-     which permits DSA keys up to 8 kilobits and RSA keys up to 16 kilobits.
-     You don't want to type them in; instead, copy the id_dsa.pub,
-     id_ecdsa.pub, id_ed25519.pub, or the id_rsa.pub file and edit it.
-
-     sshd enforces a minimum RSA key modulus size of 768 bits.
-
-     The options (if present) consist of comma-separated option
-     specifications.  No spaces are permitted, except within double quotes.
-     The following option specifications are supported (note that option
-     keywords are case-insensitive):
+     ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2.  For protocol version
+     2 keys file may contain X.509 certificates or X.509 certificate
+     ``Distinguished Name''.  Each line of the file contains one key (empty
+     lines and lines starting with a '#' are ignored as comments).  Protocol 1
+     public keys consist of the following space-separated fields: options,
+     bits, exponent, modulus, comment.  Protocol 2 public key consist of:
+     options, keytype, base64-encoded key, comment.  The options field is
+     optional; its presence is determined by whether the line starts with a
+     number or not (the options field never starts with a number).  The bits,
+     exponent, modulus, and comment fields give the RSA key for protocol ver-
+     sion 1; the comment field is not used for anything (but may be convenient
+     for the user to identify the key).  For protocol version 2 the keytype is
+     ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'',
+     ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', ``ssh-dss'' or ``ssh-rsa''.  In
+     addition, for protocol version 2 user can use X.509 certificates.  In
+     this case keytype is ``x509v3-sign-rsa'', ``x509v3-ecdsa-sha2-nistp256'',
+     ``x509v3-ecdsa-sha2-nistp384'', ``x509v3-ecdsa-sha2-nistp521'', or
+     ``x509v3-sign-dss''.  Instead of ``base64 encoded key'' line must contain
+     base64 encoded X.509 certicate (old style) or a keyword (new style),
+     optionally followed by symbol '=' (equal) or ':' (colon), zero or more
+     spaces and X.509 certificate ``Distinguished Name'' (Subject). Keyword is
+     case insensitive and can be one of 'Subject' , 'Distinguished Name' ,
+     'Distinguished-Name' , 'Distinguished_Name' , 'DistinguishedName' or
+     'DN'.  Separator of Subject items can be '/' (slash), ',' (comma) or
+     mixed and order is not important.
+
+     Note that lines in this file are usually several hundred bytes long
+     (because of the size of the public key encoding) up to a limit of 8 kilo-
+     bytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16
+     kilobits.  You don't want to type them in; instead, copy the
+     identity.pub, id_dsa.pub, id_ecdsa.pub, id_ed25519.pub, or the id_rsa.pub
+     file and edit it.
+
+     sshd enforces a minimum RSA key modulus size for protocol 1 and protocol
+     2 keys of 768 bits.
+
+     The options (if present) consist of comma-separated option specifica-
+     tions.  No spaces are permitted, except within double quotes.  The fol-
+     lowing option specifications are supported (note that option keywords are
+     case-insensitive):
 
      agent-forwarding
              Enable authentication agent forwarding previously disabled by the
@@ -260,8 +322,8 @@
 
      cert-authority
              Specifies that the listed key is a certification authority (CA)
-             that is trusted to validate signed certificates for user
-             authentication.
+             that is trusted to validate signed certificates for user authen-
+             tication.
 
              Certificates may encode access restrictions similar to these key
              options.  If both certificate restrictions and key options are
@@ -271,8 +333,8 @@
              Specifies that the command is executed whenever this key is used
              for authentication.  The command supplied by the user (if any) is
              ignored.  The command is run on a pty if the client requests a
-             pty; otherwise it is run without a tty.  If an 8-bit clean
-             channel is required, one must not request a pty or should specify
+             pty; otherwise it is run without a tty.  If an 8-bit clean chan-
+             nel is required, one must not request a pty or should specify
              no-pty.  A quote may be included in the command by quoting it
              with a backslash.
 
@@ -305,9 +367,9 @@
              present in the comma-separated list of patterns.  See PATTERNS in
              ssh_config(5) for more information on patterns.
 
-             In addition to the wildcard matching that may be applied to
-             hostnames or addresses, a from stanza may match IP addresses
-             using CIDR address/masklen notation.
+             In addition to the wildcard matching that may be applied to host-
+             names or addresses, a from stanza may match IP addresses using
+             CIDR address/masklen notation.
 
              The purpose of this option is to optionally increase security:
              public key authentication by itself does not trust the network or
@@ -339,35 +401,35 @@
              Limit local port forwarding with ssh(1) -L such that it may only
              connect to the specified host and port.  IPv6 addresses can be
              specified by enclosing the address in square brackets.  Multiple
-             permitopen options may be applied separated by commas.  No
-             pattern matching is performed on the specified hostnames, they
-             must be literal domains or addresses.  A port specification of *
+             permitopen options may be applied separated by commas.  No pat-
+             tern matching is performed on the specified hostnames, they must
+             be literal domains or addresses.  A port specification of *
              matches any port.
 
      port-forwarding
              Enable port forwarding previously disabled by the restrict
 
      principals="principals"
-             On a cert-authority line, specifies allowed principals for
-             certificate authentication as a comma-separated list.  At least
-             one name from the list must appear in the certificate's list of
-             principals for the certificate to be accepted.  This option is
-             ignored for keys that are not marked as trusted certificate
-             signers using the cert-authority option.
+             On a cert-authority line, specifies allowed principals for cer-
+             tificate authentication as a comma-separated list.  At least one
+             name from the list must appear in the certificate's list of prin-
+             cipals for the certificate to be accepted.  This option is
+             ignored for keys that are not marked as trusted certificate sign-
+             ers using the cert-authority option.
 
      pty     Permits tty allocation previously disabled by the restrict
              option.
 
      restrict
-             Enable all restrictions, i.e. disable port, agent and X11
-             forwarding, as well as disabling PTY allocation and execution of
+             Enable all restrictions, i.e. disable port, agent and X11 for-
+             warding, as well as disabling PTY allocation and execution of
              ~/.ssh/rc.  If any future restriction capabilities are added to
              authorized_keys files they will be included in this set.
 
      tunnel="n"
              Force a tun(4) device on the server.  Without this option, the
-             next available device will be used if the client requests a
-             tunnel.
+             next available device will be used if the client requests a tun-
+             nel.
 
      user-rc
              Enables execution of ~/.ssh/rc previously disabled by the
@@ -387,6 +449,7 @@
         AAAAC3...51R== example.net
         permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss
         AAAAB5...21S==
+        x509v3-sign-dss subject=/C=XX/ST=World/O=SecSH Test Team...
         tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
         jane@example.net
         restrict,command="uptime" ssh-rsa AAAA1C8...32Tv==
@@ -396,77 +459,77 @@
 
 SSH_KNOWN_HOSTS FILE FORMAT
      The /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts files contain host
-     public keys for all known hosts.  The global file should be prepared by
-     the administrator (optional), and the per-user file is maintained
-     automatically: whenever the user connects to an unknown host, its key is
-     added to the per-user file.
+     public keys, X.509 certificates (old style) or X.509 certificate
+     ``Distinguished Name'' for all known hosts.  The global file should be
+     prepared by the administrator (optional), and the per-user file is main-
+     tained automatically: whenever the user connects to an unknown host, its
+     key is added to the per-user file.
 
      Each line in these files contains the following fields: markers
-     (optional), hostnames, keytype, base64-encoded key, comment.  The fields
-     are separated by spaces.
+     (optional), hostnames, bits, exponent, modulus, comment.  The fields are
+     separated by spaces.
 
      The marker is optional, but if it is present then it must be one of
-     M-bM-^@M-^\@cert-authorityM-bM-^@M-^], to indicate that the line contains a certification
-     authority (CA) key, or M-bM-^@M-^\@revokedM-bM-^@M-^], to indicate that the key contained on
-     the line is revoked and must not ever be accepted.  Only one marker
+     ``@cert-authority'', to indicate that the line contains a certification
+     authority (CA) key, or ``@revoked'', to indicate that the key contained
+     on the line is revoked and must not ever be accepted.  Only one marker
      should be used on a key line.
 
-     Hostnames is a comma-separated list of patterns (M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y act as
-     wildcards); each pattern in turn is matched against the canonical host
-     name (when authenticating a client) or against the user-supplied name
-     (when authenticating a server).  A pattern may also be preceded by M-bM-^@M-^X!M-bM-^@M-^Y to
-     indicate negation: if the host name matches a negated pattern, it is not
+     Hostnames is a comma-separated list of patterns ('*' and '?' act as wild-
+     cards); each pattern in turn is matched against the canonical host name
+     (when authenticating a client) or against the user-supplied name (when
+     authenticating a server).  A pattern may also be preceded by '!' to indi-
+     cate negation: if the host name matches a negated pattern, it is not
      accepted (by that line) even if it matched another pattern on the line.
-     A hostname or address may optionally be enclosed within M-bM-^@M-^X[M-bM-^@M-^Y and M-bM-^@M-^X]M-bM-^@M-^Y
-     brackets then followed by M-bM-^@M-^X:M-bM-^@M-^Y and a non-standard port number.
+     A hostname or address may optionally be enclosed within '[' and ']'
+     brackets then followed by ':' and a non-standard port number.
 
      Alternately, hostnames may be stored in a hashed form which hides host
      names and addresses should the file's contents be disclosed.  Hashed
-     hostnames start with a M-bM-^@M-^X|M-bM-^@M-^Y character.  Only one hashed hostname may
-     appear on a single line and none of the above negation or wildcard
-     operators may be applied.
-
-     The keytype and base64-encoded key are taken directly from the host key;
-     they can be obtained, for example, from /etc/ssh/ssh_host_rsa_key.pub.
-     The optional comment field continues to the end of the line, and is not
-     used.
+     hostnames start with a '|' character.  Only one hashed hostname may
+     appear on a single line and none of the above negation or wildcard opera-
+     tors may be applied.
+
+     Bits, exponent, and modulus are taken directly from the RSA host key;
+     they can be obtained, for example, from /etc/ssh/ssh_host_key.pub.  The
+     optional comment field continues to the end of the line, and is not used.
 
-     Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are ignored as comments.
+     Lines starting with '#' and empty lines are ignored as comments.
 
      When performing host authentication, authentication is accepted if any
      matching line has the proper key; either one that matches exactly or, if
      the server has presented a certificate for authentication, the key of the
      certification authority that signed the certificate.  For a key to be
-     trusted as a certification authority, it must use the M-bM-^@M-^\@cert-authorityM-bM-^@M-^]
+     trusted as a certification authority, it must use the ``@cert-authority''
      marker described above.
 
      The known hosts file also provides a facility to mark keys as revoked,
      for example when it is known that the associated private key has been
-     stolen.  Revoked keys are specified by including the M-bM-^@M-^\@revokedM-bM-^@M-^] marker at
-     the beginning of the key line, and are never accepted for authentication
-     or as certification authorities, but instead will produce a warning from
-     ssh(1) when they are encountered.
-
-     It is permissible (but not recommended) to have several lines or
-     different host keys for the same names.  This will inevitably happen when
-     short forms of host names from different domains are put in the file.  It
-     is possible that the files contain conflicting information;
-     authentication is accepted if valid information can be found from either
-     file.
+     stolen.  Revoked keys are specified by including the ``@revoked'' marker
+     at the beginning of the key line, and are never accepted for authentica-
+     tion or as certification authorities, but instead will produce a warning
+     from ssh(1) when they are encountered.
+
+     It is permissible (but not recommended) to have several lines or differ-
+     ent host keys for the same names.  This will inevitably happen when short
+     forms of host names from different domains are put in the file.  It is
+     possible that the files contain conflicting information; authentication
+     is accepted if valid information can be found from either file.
 
      Note that the lines in these files are typically hundreds of characters
      long, and you definitely don't want to type in the host keys by hand.
-     Rather, generate them by a script, ssh-keyscan(1) or by taking, for
-     example, /etc/ssh/ssh_host_rsa_key.pub and adding the host names at the
-     front.  ssh-keygen(1) also offers some basic automated editing for
-     ~/.ssh/known_hosts including removing hosts matching a host name and
-     converting all host names to their hashed representations.
+     Rather, generate them by a script, ssh-keyscan(1) or by taking
+     /etc/ssh/ssh_host_key.pub and adding the host names at the front.
+     ssh-keygen(1) also offers some basic automated editing for
+     ~/.ssh/known_hosts including removing hosts matching a host name and con-
+     verting all host names to their hashed representations.
 
      An example ssh_known_hosts file:
 
         # Comments allowed at start of line
         closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net
         cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
+        x509host x509v3-sign-rsa Subject:/C=XX.....
         # A hashed hostname
         |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
         AAAA1234.....=
@@ -485,12 +548,11 @@
      ~/.rhosts
              This file is used for host-based authentication (see ssh(1) for
              more information).  On some machines this file may need to be
-             world-readable if the user's home directory is on an NFS
-             partition, because sshd reads it as root.  Additionally, this
-             file must be owned by the user, and must not have write
-             permissions for anyone else.  The recommended permission for most
-             machines is read/write for the user, and not accessible by
-             others.
+             world-readable if the user's home directory is on an NFS parti-
+             tion, because sshd reads it as root.  Additionally, this file
+             must be owned by the user, and must not have write permissions
+             for anyone else.  The recommended permission for most machines is
+             read/write for the user, and not accessible by others.
 
      ~/.shosts
              This file is used in exactly the same way as .rhosts, but allows
@@ -498,16 +560,17 @@
              rlogin/rsh.
 
      ~/.ssh/
-             This directory is the default location for all user-specific
-             configuration and authentication information.  There is no
-             general requirement to keep the entire contents of this directory
-             secret, but the recommended permissions are read/write/execute
-             for the user, and not accessible by others.
+             This directory is the default location for all user-specific con-
+             figuration and authentication information.  There is no general
+             requirement to keep the entire contents of this directory secret,
+             but the recommended permissions are read/write/execute for the
+             user, and not accessible by others.
 
      ~/.ssh/authorized_keys
-             Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used
-             for logging in as this user.  The format of this file is
-             described above.  The content of the file is not highly
+             Lists the public keys (DSA, ECDSA, Ed25519, RSA), X.509 certifi-
+             cates or X.509 certificate ``Distinguished Names'' (recommended)
+             that can be used for logging in as this user.  The format of this
+             file is described above.  The content of the file is not highly
              sensitive, but the recommended permissions are read/write for the
              user, and not accessible by others.
 
@@ -515,28 +578,33 @@
              are writable by other users, then the file could be modified or
              replaced by unauthorized users.  In this case, sshd will not
              allow it to be used unless the StrictModes option has been set to
-             M-bM-^@M-^\noM-bM-^@M-^].
+             ``no''.
 
      ~/.ssh/environment
              This file is read into the environment at login (if it exists).
              It can only contain empty lines, comment lines (that start with
-             M-bM-^@M-^X#M-bM-^@M-^Y), and assignment lines of the form name=value.  The file
+             '#'), and assignment lines of the form name=value.  The file
              should be writable only by the user; it need not be readable by
              anyone else.  Environment processing is disabled by default and
              is controlled via the PermitUserEnvironment option.
 
      ~/.ssh/known_hosts
-             Contains a list of host keys for all hosts the user has logged
-             into that are not already in the systemwide list of known host
-             keys.  The format of this file is described above.  This file
-             should be writable only by root/the owner and can, but need not
-             be, world-readable.
+             Contains a list of host keys or X.509 certificates for all hosts
+             the user has logged into that are not already in the systemwide
+             list of known host keys.  The format of this file is described
+             above.  This file should be writable only by root/the owner and
+             can, but need not be, world-readable.
 
      ~/.ssh/rc
              Contains initialization routines to be run before the user's home
              directory becomes accessible.  This file should be writable only
              by the user, and need not be readable by anyone else.
 
+     /etc/hosts.allow
+     /etc/hosts.deny
+             Access controls that should be enforced by tcp-wrappers are
+             defined here.  Further details are described in hosts_access(5).
+
      /etc/hosts.equiv
              This file is for host-based authentication (see ssh(1)).  It
              should only be writable by root.
@@ -561,36 +629,58 @@
              allows host-based authentication without permitting login with
              rlogin/rsh.
 
+     /etc/ssh/ca/ca-bundle.crt
+     /etc/ssh/ca/ca-bundle.crl
+             The first file contain multiple X.509 certificates and the second
+             ``Certificate Revocation List'' (CRLs) of certificate signers in
+             PEM format concatenated together.  Used to verify and validate
+             client X.509 certificate.
+
+     /etc/ssh/ca/crt
+     /etc/ssh/ca/crl
+             ``Hash dirs'' with X.509 certificates, the first directory or
+             CLRs, the second, of X.509 certificate signers.  Each X.509 cer-
+             tificate should be stored in separate file with name [HASH].[NUM-
+             BER] or [HASH].r[NUMBER] for the CRL, where [HASH] is X.509 cer-
+             tificate or CRL hash value and [NUMBER] is an integer starting
+             from zero.  Used to verify and validate client X.509 certificate.
+
+     /etc/ssh/ssh_host_key
      /etc/ssh/ssh_host_dsa_key
      /etc/ssh/ssh_host_ecdsa_key
      /etc/ssh/ssh_host_ed25519_key
      /etc/ssh/ssh_host_rsa_key
-             These files contain the private parts of the host keys.  These
-             files should only be owned by root, readable only by root, and
-             not accessible to others.  Note that sshd does not start if these
-             files are group/world-accessible.
+             These files contain the private parts of the host keys.  For pro-
+             tocol version 2 keys file may contain private part and X.509 cer-
+             tificate that match it.  These files should only be owned by
+             root, readable only by root, and not accessible to others.  Note
+             that sshd does not start if these files are group/world-accessi-
+             ble.
 
+     /etc/ssh/ssh_host_key.pub
      /etc/ssh/ssh_host_dsa_key.pub
      /etc/ssh/ssh_host_ecdsa_key.pub
      /etc/ssh/ssh_host_ed25519_key.pub
      /etc/ssh/ssh_host_rsa_key.pub
              These files contain the public parts of the host keys.  These
              files should be world-readable but writable only by root.  Their
-             contents should match the respective private parts.  These files
-             are not really used for anything; they are provided for the
-             convenience of the user so their contents can be copied to known
-             hosts files.  These files are created using ssh-keygen(1).
+             contents should match the respective private parts.  Note that
+             when corresponding host key contain X.509 certificate these files
+             must contains that certificate.  These files are not really used
+             for anything; they are provided for the convenience of the user
+             so their contents can be copied to known hosts files.  These
+             files are created using ssh-keygen(1).
 
      /etc/ssh/ssh_known_hosts
              Systemwide list of known host keys.  This file should be prepared
-             by the system administrator to contain the public host keys of
-             all machines in the organization.  The format of this file is
-             described above.  This file should be writable only by root/the
-             owner and should be world-readable.
+             by the system administrator to contain the public host keys or
+             X.509 certificates of all machines in the organization.  The for-
+             mat of this file is described above.  This file should be
+             writable only by root/the owner and should be world-readable.
 
      /etc/ssh/sshd_config
-             Contains configuration data for sshd.  The file format and
-             configuration options are described in sshd_config(5).
+             Contains configuration data for sshd.  The file format and con-
+             figuration options are described in sshd_config(5).
 
      /etc/ssh/sshrc
              Similar to ~/.ssh/rc, it can be used to specify machine-specific
@@ -607,20 +697,25 @@
              Contains the process ID of the sshd listening for connections (if
              there are several daemons running concurrently for different
              ports, this contains the process ID of the one started last).
-             The content of this file is not sensitive; it can be world-
-             readable.
+             The content of this file is not sensitive; it can be world-read-
+             able.
 
 SEE ALSO
      scp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1),
-     ssh-keyscan(1), chroot(2), login.conf(5), moduli(5), sshd_config(5),
-     inetd(8), sftp-server(8)
+     ssh-keyscan(1), chroot(2), hosts_access(5), login.conf(5), moduli(5),
+     sshd_config(5), inetd(8), sftp-server(8)
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
      versions 1.5 and 2.0.  Niels Provos and Markus Friedl contributed support
-     for privilege separation.
+     for privilege separation.  Roumen Petrov contributed support for X.509
+     certificates.
+
+CAVEATS
+     System security is not improved unless rshd, rlogind, and rexecd are dis-
+     abled (thus completely disabling rlogin and rsh into the machine).
 
-OpenBSD 6.0                    January 30, 2017                    OpenBSD 6.0
+BSD                            January 30, 2017                            BSD
diff -ruN openssh-7.5p1/sshd.8 openssh-7.5p1+x509-10.2/sshd.8
--- openssh-7.5p1/sshd.8	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd.8	2017-05-20 21:07:00.000000000 +0300
@@ -1,3 +1,11 @@
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,6 +20,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -39,24 +48,26 @@
 .Os
 .Sh NAME
 .Nm sshd
-.Nd OpenSSH SSH daemon
+.Nd Secure shell daemon
 .Sh SYNOPSIS
 .Nm sshd
 .Bk -words
 .Op Fl 46DdeiqTt
+.Op Fl b Ar bits
 .Op Fl C Ar connection_spec
 .Op Fl c Ar host_certificate_file
 .Op Fl E Ar log_file
 .Op Fl f Ar config_file
 .Op Fl g Ar login_grace_time
 .Op Fl h Ar host_key_file
+.Op Fl k Ar key_gen_time
 .Op Fl o Ar option
 .Op Fl p Ar port
 .Op Fl u Ar len
 .Ek
 .Sh DESCRIPTION
 .Nm
-(OpenSSH Daemon) is the daemon program for
+(SecSH Daemon) is the daemon program for
 .Xr ssh 1 .
 Together these programs replace rlogin and rsh,
 and provide secure encrypted communications between two untrusted hosts
@@ -94,6 +105,9 @@
 Forces
 .Nm
 to use IPv6 addresses only.
+.It Fl b Ar bits
+Specifies the number of bits in the ephemeral protocol version 1
+server key (default 1024).
 .It Fl C Ar connection_spec
 Specify the connection parameters to use for the
 .Fl T
@@ -164,18 +178,44 @@
 is not run as root (as the normal
 host key files are normally not readable by anyone but root).
 The default is
+.Pa /etc/ssh/ssh_host_key
+for protocol version 1, and
 .Pa /etc/ssh/ssh_host_dsa_key ,
-.Pa /etc/ssh/ssh_host_ecdsa_key ,
+.Pa /etc/ssh/ssh_host_ecdsa_key .
 .Pa /etc/ssh/ssh_host_ed25519_key
 and
-.Pa /etc/ssh/ssh_host_rsa_key .
+.Pa /etc/ssh/ssh_host_rsa_key
+for protocol version 2.
 It is possible to have multiple host key files for
-the different host key algorithms.
+the different protocol versions and host key algorithms.
+.Pp
+Host key for protocol version 2 may contain
+X.509 certificate that match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, file
+with ECDSA key may contain extra X.509 certificates.
+Extra certificates along with certificates from X.509 store
+are used to build chain of certificates leading to
+a trusted certificate authority.
 .It Fl i
 Specifies that
 .Nm
 is being run from
 .Xr inetd 8 .
+If SSH protocol 1 is enabled,
+.Nm
+should not  normally be run
+from inetd because it needs to generate the server key before it can
+respond to the client, and this may take some time.
+Clients may have to wait too long if the key was regenerated every time.
+.It Fl k Ar key_gen_time
+Specifies how often the ephemeral protocol version 1 server key is
+regenerated (default 3600 seconds, or one hour).
+The motivation for regenerating the key fairly
+often is that the key is not stored anywhere, and after about an hour
+it becomes impossible to recover the key for decrypting intercepted
+communications even if the machine is cracked into or physically
+seized.
+A value of zero indicates that the key will never be regenerated.
 .It Fl o Ar option
 Can be used to give options in the format used in the configuration file.
 This is useful for specifying options for which there is no separate
@@ -234,7 +274,8 @@
 from making DNS requests unless the authentication
 mechanism or configuration requires it.
 Authentication mechanisms that may require DNS include
-.Cm HostbasedAuthentication
+.Cm RhostsRSAAuthentication ,
+.Cm HostbasedAuthentication ,
 and using a
 .Cm from="pattern-list"
 option in a key file.
@@ -245,14 +286,42 @@
 .Cm DenyUsers .
 .El
 .Sh AUTHENTICATION
-The OpenSSH SSH daemon supports SSH protocol 2 only.
+The SecSH daemon supports SSH protocols 1 and 2.
+The default is to use protocol 2 only,
+though this can be changed via the
+.Cm Protocol
+option in
+.Xr sshd_config 5 .
+Protocol 1 should not be used
+and is only offered to support legacy devices.
+.Pp
 Each host has a host-specific key,
 used to identify the host.
+Partial forward security for protocol 1 is provided through
+an additional server key,
+normally 1024 bits,
+generated when the server starts.
+This key is normally regenerated every hour if it has been used, and
+is never stored on disk.
 Whenever a client connects, the daemon responds with its public
-host key.
+host and server keys.
 The client compares the
-host key against its own database to verify that it has not changed.
-Forward security is provided through a Diffie-Hellman key agreement.
+RSA host key against its own database to verify that it has not changed.
+The client then generates a 256-bit random number.
+It encrypts this
+random number using both the host key and the server key, and sends
+the encrypted number to the server.
+Both sides then use this
+random number as a session key which is used to encrypt all further
+communications in the session.
+The rest of the session is encrypted
+using a conventional cipher, currently Blowfish or 3DES, with 3DES
+being used by default.
+The client selects the encryption algorithm
+to use from those offered by the server.
+.Pp
+For protocol 2,
+forward security is provided through a Diffie-Hellman key agreement.
 This key agreement results in a shared session key.
 The rest of the session is encrypted using a symmetric cipher, currently
 128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
@@ -420,30 +489,74 @@
 .Pa ~/.ssh/authorized_keys
 and
 .Pa ~/.ssh/authorized_keys2 .
+For protocol version 2 keys file may contain X.509 certificates
+or X.509 certificate
+.Dq "Distinguished Name" .
 Each line of the file contains one
 key (empty lines and lines starting with a
 .Ql #
 are ignored as
 comments).
-Public keys consist of the following space-separated fields:
+Protocol 1 public keys consist of the following space-separated fields:
+options, bits, exponent, modulus, comment.
+Protocol 2 public key consist of:
 options, keytype, base64-encoded key, comment.
-The options field is optional.
-The keytype is
+The options field is optional;
+its presence is determined by whether the line starts
+with a number or not (the options field never starts with a number).
+The bits, exponent, modulus, and comment fields give the RSA key for
+protocol version 1; the
+comment field is not used for anything (but may be convenient for the
+user to identify the key).
+For protocol version 2 the keytype is
 .Dq ecdsa-sha2-nistp256 ,
 .Dq ecdsa-sha2-nistp384 ,
 .Dq ecdsa-sha2-nistp521 ,
 .Dq ssh-ed25519 ,
 .Dq ssh-dss
 or
-.Dq ssh-rsa ;
-the comment field is not used for anything (but may be convenient for the
-user to identify the key).
+.Dq ssh-rsa .
+In addition, for protocol version 2 user can use X.509 certificates.
+In this case keytype is
+.Dq x509v3-sign-rsa ,
+.Dq x509v3-ecdsa-sha2-nistp256 ,
+.Dq x509v3-ecdsa-sha2-nistp384 ,
+.Dq x509v3-ecdsa-sha2-nistp521 ,
+or
+.Dq x509v3-sign-dss .
+Instead of
+.Dq "base64 encoded key"
+line must contain base64 encoded X.509 certicate (old style) or
+a keyword (new style), optionally followed by symbol
+.Sq =
+(equal) or
+.Sq \&:
+(colon), zero or more spaces and X.509 certificate
+.Dq "Distinguished Name"
+(Subject). Keyword is case insensitive and can be one of
+.Sq Subject
+,
+.Sq "Distinguished Name"
+,
+.Sq Distinguished-Name
+,
+.Sq Distinguished_Name
+,
+.Sq DistinguishedName
+or
+.Sq DN .
+Separator of Subject items can be
+.Sq /
+(slash),
+.Sq \&,
+(comma) or mixed and order is not important.
 .Pp
-Note that lines in this file can be several hundred bytes long
+Note that lines in this file are usually several hundred bytes long
 (because of the size of the public key encoding) up to a limit of
 8 kilobytes, which permits DSA keys up to 8 kilobits and RSA
 keys up to 16 kilobits.
 You don't want to type them in; instead, copy the
+.Pa identity.pub ,
 .Pa id_dsa.pub ,
 .Pa id_ecdsa.pub ,
 .Pa id_ed25519.pub ,
@@ -452,7 +565,8 @@
 file and edit it.
 .Pp
 .Nm
-enforces a minimum RSA key modulus size of 768 bits.
+enforces a minimum RSA key modulus size for protocol 1
+and protocol 2 keys of 768 bits.
 .Pp
 The options (if present) consist of comma-separated option
 specifications.
@@ -616,6 +730,7 @@
 AAAAC3...51R== example.net
 permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss
 AAAAB5...21S==
+x509v3-sign-dss subject=/C=XX/ST=World/O=SecSH Test Team...
 tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
 jane@example.net
 restrict,command="uptime" ssh-rsa AAAA1C8...32Tv==
@@ -628,14 +743,16 @@
 .Pa /etc/ssh/ssh_known_hosts
 and
 .Pa ~/.ssh/known_hosts
-files contain host public keys for all known hosts.
+files contain host public keys, X.509 certificates (old style) or X.509 certificate
+.Dq "Distinguished Name"
+for all known hosts.
 The global file should
 be prepared by the administrator (optional), and the per-user file is
 maintained automatically: whenever the user connects to an unknown host,
 its key is added to the per-user file.
 .Pp
 Each line in these files contains the following fields: markers (optional),
-hostnames, keytype, base64-encoded key, comment.
+hostnames, bits, exponent, modulus, comment.
 The fields are separated by spaces.
 .Pp
 The marker is optional, but if it is present then it must be one of
@@ -676,9 +793,9 @@
 Only one hashed hostname may appear on a single line and none of the above
 negation or wildcard operators may be applied.
 .Pp
-The keytype and base64-encoded key are taken directly from the host key; they
+Bits, exponent, and modulus are taken directly from the RSA host key; they
 can be obtained, for example, from
-.Pa /etc/ssh/ssh_host_rsa_key.pub .
+.Pa /etc/ssh/ssh_host_key.pub .
 The optional comment field continues to the end of the line, and is not used.
 .Pp
 Lines starting with
@@ -717,8 +834,8 @@
 long, and you definitely don't want to type in the host keys by hand.
 Rather, generate them by a script,
 .Xr ssh-keyscan 1
-or by taking, for example,
-.Pa /etc/ssh/ssh_host_rsa_key.pub
+or by taking
+.Pa /etc/ssh/ssh_host_key.pub
 and adding the host names at the front.
 .Xr ssh-keygen 1
 also offers some basic automated editing for
@@ -731,6 +848,7 @@
 # Comments allowed at start of line
 closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net
 cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
+x509host x509v3-sign-rsa Subject:/C=XX.....
 # A hashed hostname
 |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
 AAAA1234.....=
@@ -782,7 +900,10 @@
 and not accessible by others.
 .Pp
 .It Pa ~/.ssh/authorized_keys
-Lists the public keys (DSA, ECDSA, Ed25519, RSA)
+Lists the public keys (DSA, ECDSA, Ed25519, RSA),
+X.509 certificates or X.509 certificate
+.Dq Distinguished Names
+(recommended)
 that can be used for logging in as this user.
 The format of this file is described above.
 The content of the file is not highly sensitive, but the recommended
@@ -813,7 +934,7 @@
 option.
 .Pp
 .It Pa ~/.ssh/known_hosts
-Contains a list of host keys for all hosts the user has logged into
+Contains a list of host keys or X.509 certificates for all hosts the user has logged into
 that are not already in the systemwide list of known host keys.
 The format of this file is described above.
 This file should be writable only by root/the owner and
@@ -825,6 +946,12 @@
 This file should be writable only by the user, and need not be
 readable by anyone else.
 .Pp
+.It Pa /etc/hosts.allow
+.It Pa /etc/hosts.deny
+Access controls that should be enforced by tcp-wrappers are defined here.
+Further details are described in
+.Xr hosts_access 5 .
+.Pp
 .It Pa /etc/hosts.equiv
 This file is for host-based authentication (see
 .Xr ssh 1 ) .
@@ -857,17 +984,39 @@
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
+.It Pa /etc/ssh/ca/ca-bundle.crt
+.It Pa /etc/ssh/ca/ca-bundle.crl
+The first file contain multiple X.509 certificates and the second
+.Dq "Certificate Revocation List"
+(CRLs) of certificate signers in PEM format concatenated together.
+Used to verify and validate client X.509 certificate.
+.Pp
+.It Pa /etc/ssh/ca/crt
+.It Pa /etc/ssh/ca/crl
+.Dq "Hash dirs"
+with X.509 certificates, the first directory or CLRs, the second, of
+X.509 certificate signers.
+Each X.509 certificate should be stored in separate file with name
+[HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where [HASH] is
+X.509 certificate or CRL hash value and [NUMBER] is an integer starting
+from zero.
+Used to verify and validate client X.509 certificate.
+.Pp
+.It Pa /etc/ssh/ssh_host_key
 .It Pa /etc/ssh/ssh_host_dsa_key
 .It Pa /etc/ssh/ssh_host_ecdsa_key
 .It Pa /etc/ssh/ssh_host_ed25519_key
 .It Pa /etc/ssh/ssh_host_rsa_key
 These files contain the private parts of the host keys.
+For protocol version 2 keys file may contain private part
+and X.509 certificate that match it.
 These files should only be owned by root, readable only by root, and not
 accessible to others.
 Note that
 .Nm
 does not start if these files are group/world-accessible.
 .Pp
+.It Pa /etc/ssh/ssh_host_key.pub
 .It Pa /etc/ssh/ssh_host_dsa_key.pub
 .It Pa /etc/ssh/ssh_host_ecdsa_key.pub
 .It Pa /etc/ssh/ssh_host_ed25519_key.pub
@@ -876,6 +1025,8 @@
 These files should be world-readable but writable only by
 root.
 Their contents should match the respective private parts.
+Note that when corresponding host key contain X.509 certificate
+these files must contains that certificate.
 These files are not
 really used for anything; they are provided for the convenience of
 the user so their contents can be copied to known hosts files.
@@ -885,7 +1036,7 @@
 .It Pa /etc/ssh/ssh_known_hosts
 Systemwide list of known host keys.
 This file should be prepared by the
-system administrator to contain the public host keys of all machines in the
+system administrator to contain the public host keys or X.509 certificates of all machines in the
 organization.
 The format of this file is described above.
 This file should be writable only by root/the owner and
@@ -929,13 +1080,14 @@
 .Xr ssh-keygen 1 ,
 .Xr ssh-keyscan 1 ,
 .Xr chroot 2 ,
+.Xr hosts_access 5 ,
 .Xr login.conf 5 ,
 .Xr moduli 5 ,
 .Xr sshd_config 5 ,
 .Xr inetd 8 ,
 .Xr sftp-server 8
 .Sh AUTHORS
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
 Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
 Theo de Raadt and Dug Song
@@ -945,3 +1097,15 @@
 protocol versions 1.5 and 2.0.
 Niels Provos and Markus Friedl contributed support
 for privilege separation.
+Roumen Petrov contributed support for X.509 certificates.
+.Sh CAVEATS
+System security is not improved unless
+.Nm rshd ,
+.Nm rlogind ,
+and
+.Nm rexecd
+are disabled (thus completely disabling
+.Xr rlogin
+and
+.Xr rsh
+into the machine).
diff -ruN openssh-7.5p1/sshd.c openssh-7.5p1+x509-10.2/sshd.c
--- openssh-7.5p1/sshd.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd.c	2017-05-20 21:07:01.000000000 +0300
@@ -21,6 +21,9 @@
  * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  * Copyright (c) 2002 Niels Provos.  All rights reserved.
  *
+ * X.509 certificates support:
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -77,9 +80,14 @@
 #include <openssl/dh.h>
 #include <openssl/bn.h>
 #include <openssl/rand.h>
+#include "evp-compat.h"
 #include "openbsd-compat/openssl-compat.h"
 #endif
 
+#ifdef HAVE_FIPSCHECK_H
+#  include <fipscheck.h>
+#endif
+
 #ifdef HAVE_SECUREWARE
 #include <sys/security.h>
 #include <prot.h>
@@ -87,12 +95,12 @@
 
 #include "xmalloc.h"
 #include "ssh.h"
+#include "ssh1.h"
 #include "ssh2.h"
 #include "rsa.h"
 #include "sshpty.h"
 #include "packet.h"
 #include "log.h"
-#include "buffer.h"
 #include "misc.h"
 #include "match.h"
 #include "servconf.h"
@@ -100,7 +108,8 @@
 #include "compat.h"
 #include "cipher.h"
 #include "digest.h"
-#include "key.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "kex.h"
 #include "myproposal.h"
 #include "authfile.h"
@@ -123,6 +132,13 @@
 #include "version.h"
 #include "ssherr.h"
 
+#ifdef LIBWRAP
+#include <tcpd.h>
+#include <syslog.h>
+int allow_severity;
+int deny_severity;
+#endif /* LIBWRAP */
+
 /* Re-exec fds */
 #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
 #define REEXEC_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
@@ -131,6 +147,10 @@
 
 extern char *__progname;
 
+/* used in ssh-x509.c */
+extern int (*pssh_x509store_verify_cert)(X509 *cert, STACK_OF(X509) *_chain);
+extern STACK_OF(X509)* (*pssh_x509store_build_certchain)(X509 *cert, STACK_OF(X509) *untrusted);
+
 /* Server configuration options. */
 ServerOptions options;
 
@@ -195,12 +215,22 @@
  * not very useful.  Currently, memory locking is not implemented.
  */
 struct {
+	Key	*server_key;		/* ephemeral server key */
+	Key	*ssh1_host_key;		/* ssh1 host key */
 	Key	**host_keys;		/* all private host keys */
 	Key	**host_pubkeys;		/* all public host keys */
 	Key	**host_certificates;	/* all public host certificates */
+	int	have_ssh1_key;
 	int	have_ssh2_key;
+	u_char	ssh1_cookie[SSH_SESSION_KEY_LENGTH];
 } sensitive_data;
 
+/*
+ * Flag indicating whether the RSA server key needs to be regenerated.
+ * Is set in the SIGALRM handler and cleared when the key is regenerated.
+ */
+static volatile sig_atomic_t key_do_regen = 0;
+
 /* This is set to true when a signal is received. */
 static volatile sig_atomic_t received_sighup = 0;
 static volatile sig_atomic_t received_sigterm = 0;
@@ -223,6 +253,7 @@
 int use_privsep = -1;
 struct monitor *pmonitor = NULL;
 int privsep_is_preauth = 1;
+static int privsep_chroot = 1;
 
 /* global authentication context */
 Authctxt *the_authctxt = NULL;
@@ -239,6 +270,10 @@
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
+
+#ifdef WITH_SSH1
+static void do_ssh1_kex(void);
+#endif
 static void do_ssh2_kex(void);
 
 /*
@@ -357,19 +392,81 @@
 	    ssh_remote_ipaddr(active_state), ssh_remote_port(active_state));
 }
 
+/*
+ * Signal handler for the key regeneration alarm.  Note that this
+ * alarm only occurs in the daemon waiting for connections, and it does not
+ * do anything with the private key or random state before forking.
+ * Thus there should be no concurrency control/asynchronous execution
+ * problems.
+ */
+static void
+generate_ephemeral_server_key(void)
+{
+	verbose("Generating %s%d bit RSA key.",
+	    sensitive_data.server_key ? "new " : "", options.server_key_bits);
+	if (sensitive_data.server_key != NULL)
+		key_free(sensitive_data.server_key);
+	sensitive_data.server_key = key_generate(KEY_RSA1,
+	    options.server_key_bits);
+	verbose("RSA key generation complete.");
+
+	arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
+}
+
+/*ARGSUSED*/
+static void
+key_regeneration_alarm(int sig)
+{
+	int save_errno = errno;
+
+	signal(SIGALRM, SIG_DFL);
+	errno = save_errno;
+	key_do_regen = 1;
+}
+
 static void
 sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
 {
 	u_int i;
+	int mismatch;
 	int remote_major, remote_minor;
-	char *s;
+	int major, minor;
+	char *s, *newline = "\n";
+	char pkix_comment[256];
 	char buf[256];			/* Must not be larger than remote_version. */
 	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,
+	if ((options.protocol & SSH_PROTO_1) &&
+	    (options.protocol & SSH_PROTO_2)) {
+		major = PROTOCOL_MAJOR_1;
+		minor = 99;
+	} else if (options.protocol & SSH_PROTO_2) {
+		major = PROTOCOL_MAJOR_2;
+		minor = PROTOCOL_MINOR_2;
+		newline = "\r\n";
+	} else {
+		major = PROTOCOL_MAJOR_1;
+		minor = PROTOCOL_MINOR_1;
+	}
+
+	if (options.protocol & SSH_PROTO_2) {
+		const char *fips = "";
+#ifdef OPENSSL_FIPS
+	/* NOTE in FIPS mode code refuse to load protocol 1 keys (see
+	 * authfile.c). Result is that code below clear bit SSH_PROTO_1
+	 * from protocol option if !have_ssh1_key.
+	 */
+		if (FIPS_mode()) fips= " FIPS";
+#endif
+		sprintf(pkix_comment, " PKIX["PACKAGE_VERSION"%s]", fips);
+	}
+	else
+		*pkix_comment = '\0';
+
+	xasprintf(&server_version_string, "SSH-%d.%d-%s%s%s%s%s",
+	    major, minor, SSH_VERSION, pkix_comment,
 	    *options.version_addendum == '\0' ? "" : " ",
-	    options.version_addendum);
+	    options.version_addendum, newline);
 
 	/* Send our protocol version identification. */
 	if (atomicio(vwrite, sock_out, server_version_string,
@@ -423,7 +520,7 @@
 	debug("Client protocol version %d.%d; client software version %.100s",
 	    remote_major, remote_minor, remote_version);
 
-	ssh->compat = compat_datafellows(remote_version);
+	SSH_XCOMPATIBILITY(ssh, remote_version);
 
 	if ((ssh->compat & SSH_BUG_PROBE) != 0) {
 		logit("probed from %s port %d with %s.  Don't panic.",
@@ -446,13 +543,42 @@
 		    "refusing connection", remote_version);
 	}
 
+	mismatch = 0;
+	switch (remote_major) {
+	case 1:
+		if (remote_minor == 99) {
+			if (options.protocol & SSH_PROTO_2)
+				enable_compat20();
+			else
+				mismatch = 1;
+			break;
+		}
+		if (!(options.protocol & SSH_PROTO_1)) {
+			mismatch = 1;
+			break;
+		}
+		if (remote_minor < 3) {
+			packet_disconnect("Your ssh version is too old and "
+			    "is no longer supported.  Please install a newer version.");
+		} else if (remote_minor == 3) {
+			/* note that this disables agent-forwarding */
+			enable_compat13();
+		}
+		break;
+	case 2:
+		if (options.protocol & SSH_PROTO_2) {
+			enable_compat20();
+			break;
+		}
+		/* FALLTHROUGH */
+	default:
+		mismatch = 1;
+		break;
+	}
 	chop(server_version_string);
 	debug("Local version string %.200s", server_version_string);
 
-	if (remote_major == 2 ||
-	    (remote_major == 1 && remote_minor == 99)) {
-		enable_compat20();
-	} else {
+	if (mismatch) {
 		s = "Protocol major versions differ.\n";
 		(void) atomicio(vwrite, sock_out, s, strlen(s));
 		close(sock_in);
@@ -471,6 +597,10 @@
 {
 	int i;
 
+	if (sensitive_data.server_key) {
+		key_free(sensitive_data.server_key);
+		sensitive_data.server_key = NULL;
+	}
 	for (i = 0; i < options.num_host_key_files; i++) {
 		if (sensitive_data.host_keys[i]) {
 			key_free(sensitive_data.host_keys[i]);
@@ -481,6 +611,8 @@
 			sensitive_data.host_certificates[i] = NULL;
 		}
 	}
+	sensitive_data.ssh1_host_key = NULL;
+	explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
 }
 
 /* Demote private to public keys for network child */
@@ -490,14 +622,24 @@
 	Key *tmp;
 	int i;
 
+	if (sensitive_data.server_key) {
+		tmp = key_demote(sensitive_data.server_key);
+		key_free(sensitive_data.server_key);
+		sensitive_data.server_key = tmp;
+	}
+
 	for (i = 0; i < options.num_host_key_files; i++) {
 		if (sensitive_data.host_keys[i]) {
 			tmp = key_demote(sensitive_data.host_keys[i]);
 			key_free(sensitive_data.host_keys[i]);
 			sensitive_data.host_keys[i] = tmp;
+			if (tmp->type == KEY_RSA1)
+				sensitive_data.ssh1_host_key = tmp;
 		}
 		/* Certs do not need demotion */
 	}
+
+	/* We do not clear ssh1_host key and cookie.  XXX - Okay Niels? */
 }
 
 static void
@@ -541,7 +683,7 @@
 	demote_sensitive_data();
 
 	/* Demote the child */
-	if (getuid() == 0 || geteuid() == 0) {
+	if (privsep_chroot) {
 		/* Change our root directory */
 		if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
 			fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -691,16 +833,25 @@
 
 	buffer_init(&b);
 	for (i = 0; i < options.num_host_key_files; i++) {
+		const char *pkalg;
 		key = sensitive_data.host_keys[i];
 		if (key == NULL)
 			key = sensitive_data.host_pubkeys[i];
-		if (key == NULL)
+		if (key == NULL || key->type == KEY_RSA1)
 			continue;
+		/*TODO multi-algorithm keys*/
+		pkalg = sshkey_ssh_name(key);
 		/* Check that the key is accepted in HostkeyAlgorithms */
-		if (match_pattern_list(sshkey_ssh_name(key),
+		if (match_pattern_list(pkalg,
 		    options.hostkeyalgorithms, 0) != 1) {
-			debug3("%s: %s key not permitted by HostkeyAlgorithms",
-			    __func__, sshkey_ssh_name(key));
+			debug3("%s: %s not permitted by HostkeyAlgorithms",
+			    __func__, pkalg);
+			continue;
+		}
+		if (key_is_x509(key)) {
+			if (buffer_len(&b) > 0)
+				buffer_append(&b, ",", 1);
+			buffer_append(&b, pkalg, strlen(pkalg));
 			continue;
 		}
 		switch (key->type) {
@@ -710,16 +861,18 @@
 		case KEY_ED25519:
 			if (buffer_len(&b) > 0)
 				buffer_append(&b, ",", 1);
-			p = key_ssh_name(key);
-			buffer_append(&b, p, strlen(p));
+			buffer_append(&b, pkalg, strlen(pkalg));
 
-			/* for RSA we also support SHA2 signatures */
+		#ifdef HAVE_EVP_SHA256
+			/* for RSA we also support SHA2 algorithms */
 			if (key->type == KEY_RSA) {
 				p = ",rsa-sha2-512,rsa-sha2-256";
 				buffer_append(&b, p, strlen(p));
 			}
+		#endif /*def HAVE_EVP_SHA256*/
 			break;
 		}
+
 		/* If the private key has a cert peer, then list that too */
 		key = sensitive_data.host_certificates[i];
 		if (key == NULL)
@@ -744,7 +897,7 @@
 }
 
 static Key *
-get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
+get_hostkey_by_type(int type, int subtype, int need_private, struct ssh *ssh)
 {
 	int i;
 	Key *key;
@@ -764,25 +917,39 @@
 			break;
 		}
 		if (key != NULL && key->type == type &&
-		    (key->type != KEY_ECDSA || key->ecdsa_nid == nid))
+		    (subtype == -1 || subtype == key->ecdsa_nid)
+		)
 			return need_private ?
 			    sensitive_data.host_keys[i] : key;
 	}
 	return NULL;
 }
 
+
+static Key* get_hostkey_by_alg(const char*, int, struct ssh *ssh);
+
 Key *
-get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
+get_hostkey_public_by_alg(const char* alg, struct ssh *ssh)
 {
-	return get_hostkey_by_type(type, nid, 0, ssh);
+	return get_hostkey_by_alg(alg, 0, ssh);
 }
 
 Key *
-get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
+get_hostkey_private_by_alg(const char* alg, struct ssh *ssh)
+{
+	return get_hostkey_by_alg(alg, 1, ssh);
+}
+
+static Key*
+get_hostkey_by_alg(const char* alg, int need_private, struct ssh *ssh)
 {
-	return get_hostkey_by_type(type, nid, 1, ssh);
+	int keytype, subtype;
+
+	key_types_from_name(alg, &keytype, &subtype);
+	return get_hostkey_by_type(keytype, subtype, need_private, ssh);
 }
 
+
 Key *
 get_hostkey_by_index(int ind)
 {
@@ -841,14 +1008,16 @@
 	if ((buf = sshbuf_new()) == NULL)
 		fatal("%s: sshbuf_new", __func__);
 	for (i = nkeys = 0; i < options.num_host_key_files; i++) {
+		const char* pkalg;
 		key = get_hostkey_public_by_index(i, ssh);
 		if (key == NULL || key->type == KEY_UNSPEC ||
-		    sshkey_is_cert(key))
+		    key->type == KEY_RSA1 || sshkey_is_cert(key))
 			continue;
 		fp = sshkey_fingerprint(key, options.fingerprint_hash,
 		    SSH_FP_DEFAULT);
+		pkalg = sshkey_ssh_name(key);
 		debug3("%s: key %d: %s %s", __func__, i,
-		    sshkey_ssh_name(key), fp);
+		    pkalg, fp);
 		free(fp);
 		if (nkeys == 0) {
 			packet_start(SSH2_MSG_GLOBAL_REQUEST);
@@ -856,7 +1025,7 @@
 			packet_put_char(0); /* want-reply */
 		}
 		sshbuf_reset(buf);
-		if ((r = sshkey_putb(key, buf)) != 0)
+		if ((r = Xkey_putb(pkalg, key, buf)) != 0)
 			fatal("%s: couldn't put hostkey %d: %s",
 			    __func__, i, ssh_err(r));
 		packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf));
@@ -909,9 +1078,10 @@
 #endif
 	);
 	fprintf(stderr,
-"usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n"
+"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
 "            [-E log_file] [-f config_file] [-g login_grace_time]\n"
-"            [-h host_key_file] [-o option] [-p port] [-u len]\n"
+"            [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n"
+"            [-u len]\n"
 	);
 	exit(1);
 }
@@ -928,6 +1098,13 @@
 	/*
 	 * Protocol from reexec master to child:
 	 *	string	configuration
+	 *	u_int	ephemeral_key_follows
+	 *	bignum	e		(only if ephemeral_key_follows == 1)
+	 *	bignum	n			"
+	 *	bignum	d			"
+	 *	bignum	iqmp			"
+	 *	bignum	p			"
+	 *	bignum	q			"
 	 *	string rngseed		(only if OpenSSL is not self-seeded)
 	 */
 	if ((m = sshbuf_new()) == NULL)
@@ -935,6 +1112,27 @@
 	if ((r = sshbuf_put_stringb(m, conf)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 
+#ifdef WITH_SSH1
+	if (sensitive_data.server_key != NULL &&
+	    sensitive_data.server_key->type == KEY_RSA1) {
+		const BIGNUM *n = NULL, *e = NULL, *d = NULL;
+		const BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
+		RSA_get0_key(sensitive_data.server_key->rsa, &n, &e, &d);
+		RSA_get0_crt_params(sensitive_data.server_key->rsa, NULL, NULL, &iqmp);
+		RSA_get0_factors(sensitive_data.server_key->rsa, &p, &q);
+		if ((r = sshbuf_put_u32(m, 1)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, e)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, n)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, d)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, iqmp)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, p)) != 0 ||
+		    (r = sshbuf_put_bignum1(m, q)) != 0)
+			fatal("%s: buffer error: %s", __func__, ssh_err(r));
+	} else
+#endif
+		if ((r = sshbuf_put_u32(m, 0)) != 0)
+			fatal("%s: buffer error: %s", __func__, ssh_err(r));
+
 #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
 	rexec_send_rng_seed(m);
 #endif
@@ -968,6 +1166,29 @@
 		buffer_append(conf, cp, len);
 	free(cp);
 
+	if (buffer_get_int(&m)) {
+#ifdef WITH_SSH1
+		BIGNUM *n = NULL, *e = NULL, *d = NULL;
+		BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
+		if (sensitive_data.server_key != NULL)
+			key_free(sensitive_data.server_key);
+		sensitive_data.server_key = key_new_private(KEY_RSA1);
+		RSA_get0_key(sensitive_data.server_key->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, (const BIGNUM**)&d);
+		RSA_get0_crt_params(sensitive_data.server_key->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+		RSA_get0_factors(sensitive_data.server_key->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
+		buffer_get_bignum(&m, e);
+		buffer_get_bignum(&m, n);
+		buffer_get_bignum(&m, d);
+		buffer_get_bignum(&m, iqmp);
+		buffer_get_bignum(&m, p);
+		buffer_get_bignum(&m, q);
+		if (rsa_generate_additional_parameters(
+		    sensitive_data.server_key->rsa) != 0)
+			fatal("%s: rsa_generate_additional_parameters "
+			    "error", __func__);
+#endif
+	}
+
 #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
 	rexec_recv_rng_seed(&m);
 #endif
@@ -1096,7 +1317,7 @@
 {
 	fd_set *fdset;
 	int i, j, ret, maxfd;
-	int startups = 0;
+	int key_used = 0, startups = 0;
 	int startup_p[2] = { -1 , -1 };
 	struct sockaddr_storage from;
 	socklen_t fromlen;
@@ -1143,6 +1364,11 @@
 				unlink(options.pid_file);
 			exit(received_sigterm == SIGTERM ? 0 : 255);
 		}
+		if (key_used && key_do_regen) {
+			generate_ephemeral_server_key();
+			key_used = 0;
+			key_do_regen = 0;
+		}
 		if (ret < 0)
 			continue;
 
@@ -1285,6 +1511,19 @@
 				close(config_s[0]);
 				close(config_s[1]);
 			}
+
+			/*
+			 * Mark that the key has been used (it
+			 * was "given" to the child).
+			 */
+			if ((options.protocol & SSH_PROTO_1) &&
+			    key_used == 0) {
+				/* Schedule server key regeneration alarm. */
+				signal(SIGALRM, key_regeneration_alarm);
+				alarm(options.key_regeneration_time);
+				key_used = 1;
+			}
+
 			close(*newsock);
 
 			/*
@@ -1379,6 +1618,18 @@
 	(void)set_auth_parameters(ac, av);
 #endif
 	__progname = ssh_get_progname(av[0]);
+	ssh_OpenSSL_startup();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	#ifdef HAVE_FIPSCHECK_H
+		if (!FIPSCHECK_verify(NULL, NULL))
+			fatal("FIPS integrity verification test failed.");
+	#endif
+		fprintf(stderr, "%s runs in FIPS mode\n", __progname);
+	}
+#endif /*def OPENSSL_FIPS*/
+	pssh_x509store_verify_cert = ssh_x509store_verify_cert;
+	pssh_x509store_build_certchain = ssh_x509store_build_certchain;
 
 	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
 	saved_argc = ac;
@@ -1443,6 +1694,7 @@
 		case 'i':
 			inetd_flag = 1;
 			break;
+#ifndef __ANDROID__
 		case 'r':
 			rexec_flag = 0;
 			break;
@@ -1450,6 +1702,7 @@
 			rexeced_flag = 1;
 			inetd_flag = 1;
 			break;
+#endif /*def __ANDROID__*/
 		case 'Q':
 			/* ignored */
 			break;
@@ -1457,7 +1710,8 @@
 			options.log_level = SYSLOG_LEVEL_QUIET;
 			break;
 		case 'b':
-			/* protocol 1, ignored */
+			options.server_key_bits = (int)strtonum(optarg, 256,
+			    32768, NULL);
 			break;
 		case 'p':
 			options.ports_from_cmdline = 1;
@@ -1478,7 +1732,10 @@
 			}
 			break;
 		case 'k':
-			/* protocol 1, ignored */
+			if ((options.key_regeneration_time = convtime(optarg)) == -1) {
+				fprintf(stderr, "Invalid key regeneration interval.\n");
+				exit(1);
+			}
 			break;
 		case 'h':
 			if (options.num_host_key_files >= MAX_HOSTKEYS) {
@@ -1519,6 +1776,9 @@
 			break;
 		}
 	}
+#ifdef __ANDROID__
+	rexec_flag = 0; /*TODO reexec does not work on android*/
+#endif
 	if (rexeced_flag || inetd_flag)
 		rexec_flag = 0;
 	if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
@@ -1528,10 +1788,6 @@
 	else
 		closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
 
-#ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
-#endif
-
 	/* If requested, redirect the logs to the specified logfile. */
 	if (logfile != NULL)
 		log_redirect_stderr_to(logfile);
@@ -1560,6 +1816,9 @@
 	drop_cray_privs();
 #endif
 
+	sensitive_data.server_key = NULL;
+	sensitive_data.ssh1_host_key = NULL;
+	sensitive_data.have_ssh1_key = 0;
 	sensitive_data.have_ssh2_key = 0;
 
 	/*
@@ -1612,6 +1871,9 @@
 	 * and warns for trivial misconfigurations that could break login.
 	 */
 	if (options.num_auth_methods != 0) {
+		if ((options.protocol & SSH_PROTO_1))
+			fatal("AuthenticationMethods is not supported with "
+			    "SSH protocol 1");
 		for (n = 0; n < options.num_auth_methods; n++) {
 			if (auth2_methods_valid(options.auth_methods[n],
 			    1) == 0)
@@ -1631,7 +1893,7 @@
 		exit(1);
 	}
 
-	debug("sshd version %s, %s", SSH_VERSION,
+	debug("sshd version %s, %s", SSH_RELEASE,
 #ifdef WITH_OPENSSL
 	    SSLeay_version(SSLEAY_VERSION)
 #else
@@ -1640,8 +1902,9 @@
 	);
 
 	/* Store privilege separation user for later use if required. */
+	privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
 	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
-		if (use_privsep || options.kerberos_authentication)
+		if (privsep_chroot || options.kerberos_authentication)
 			fatal("Privilege separation user %s does not exist",
 			    SSH_PRIVSEP_USER);
 	} else {
@@ -1689,12 +1952,13 @@
 		sensitive_data.host_keys[i] = key;
 		sensitive_data.host_pubkeys[i] = pubkey;
 
-		if (key == NULL && pubkey != NULL && have_agent) {
+		if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 &&
+		    have_agent) {
 			debug("will rely on agent for hostkey %s",
 			    options.host_key_files[i]);
-			keytype = pubkey->type;
+			keytype = X509KEY_BASETYPE(pubkey);
 		} else if (key != NULL) {
-			keytype = key->type;
+			keytype = X509KEY_BASETYPE(key);
 		} else {
 			error("Could not load host key: %s",
 			    options.host_key_files[i]);
@@ -1704,6 +1968,10 @@
 		}
 
 		switch (keytype) {
+		case KEY_RSA1:
+			sensitive_data.ssh1_host_key = key;
+			sensitive_data.have_ssh1_key = 1;
+			break;
 		case KEY_RSA:
 		case KEY_DSA:
 		case KEY_ECDSA:
@@ -1716,10 +1984,19 @@
 		    SSH_FP_DEFAULT)) == NULL)
 			fatal("sshkey_fingerprint failed");
 		debug("%s host key #%d: %s %s",
-		    key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
+		    key ? "private" : "agent", i, keytype == KEY_RSA1 ?
+		    sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp);
 		free(fp);
 	}
-	if (!sensitive_data.have_ssh2_key) {
+	if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
+		logit("Disabling protocol version 1. Could not load host key");
+		options.protocol &= ~SSH_PROTO_1;
+	}
+	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
+		logit("Disabling protocol version 2. Could not load host key");
+		options.protocol &= ~SSH_PROTO_2;
+	}
+	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
 		logit("sshd: no hostkeys available -- exiting.");
 		exit(1);
 	}
@@ -1767,7 +2044,36 @@
 		    key_type(key));
 	}
 
-	if (use_privsep) {
+#ifdef WITH_SSH1
+	/* Check certain values for sanity. */
+	if (options.protocol & SSH_PROTO_1) {
+		const BIGNUM *hn = NULL;
+		if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+		    options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) {
+			fprintf(stderr, "Bad server key size.\n");
+			exit(1);
+		}
+		/*
+		 * Check that server and host key lengths differ sufficiently. This
+		 * is necessary to make double encryption work with rsaref. Oh, I
+		 * hate software patents. I dont know if this can go? Niels
+		 */
+		RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &hn, NULL, NULL);
+		if (options.server_key_bits >
+		    BN_num_bits(hn) -
+		    SSH_KEY_BITS_RESERVED && options.server_key_bits <
+		    BN_num_bits(hn) +
+		    SSH_KEY_BITS_RESERVED) {
+			options.server_key_bits =
+			    BN_num_bits(hn) +
+			    SSH_KEY_BITS_RESERVED;
+			debug("Forcing server key to %d bits to make it differ from host key.",
+			    options.server_key_bits);
+		}
+	}
+#endif
+
+	if (privsep_chroot) {
 		struct stat st;
 
 		if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
@@ -1856,6 +2162,9 @@
 		platform_pre_listen();
 		server_listen();
 
+		if (options.protocol & SSH_PROTO_1)
+			generate_ephemeral_server_key();
+
 		signal(SIGHUP, sighup_handler);
 		signal(SIGCHLD, main_sigchld_handler);
 		signal(SIGTERM, sigterm_handler);
@@ -1985,6 +2294,24 @@
 #ifdef SSH_AUDIT_EVENTS
 	audit_connection_from(remote_ip, remote_port);
 #endif
+#ifdef LIBWRAP
+	allow_severity = options.log_facility|LOG_INFO;
+	deny_severity = options.log_facility|LOG_WARNING;
+	/* Check whether logins are denied from this host. */
+	if (packet_connection_is_on_socket()) {
+		struct request_info req;
+
+		request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0);
+		fromhost(&req);
+
+		if (!hosts_access(&req)) {
+			debug("Connection refused by tcp wrapper");
+			refuse(&req);
+			/* NOTREACHED */
+			fatal("libwrap refuse returns");
+		}
+	}
+#endif /* LIBWRAP */
 
 	/* Log the connection. */
 	laddr = get_local_ipaddr(sock_in);
@@ -2005,6 +2332,11 @@
 		alarm(options.login_grace_time);
 
 	sshd_exchange_identification(ssh, sock_in, sock_out);
+
+	/* In inetd mode, generate ephemeral key only for proto 1 connections */
+	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
+		generate_ephemeral_server_key();
+
 	packet_set_nonblocking();
 
 	/* allocate authentication context */
@@ -2022,7 +2354,7 @@
 	if (use_privsep) {
 		if (privsep_preauth(authctxt) == 1)
 			goto authenticated;
-	} else if (have_agent) {
+	} else if (compat20 && have_agent) {
 		if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
 			error("Unable to get agent socket: %s", ssh_err(r));
 			have_agent = 0;
@@ -2031,9 +2363,17 @@
 
 	/* perform the key exchange */
 	/* authenticate user and start session */
-	do_ssh2_kex();
-	do_authentication2(authctxt);
-
+	if (compat20) {
+		do_ssh2_kex();
+		do_authentication2(authctxt);
+	} else {
+#ifdef WITH_SSH1
+		do_ssh1_kex();
+		do_authentication(authctxt);
+#else
+		fatal("ssh1 not supported");
+#endif
+	}
 	/*
 	 * If we use privilege separation, the unprivileged child transfers
 	 * the current keystate and exits
@@ -2081,13 +2421,16 @@
 	if (use_privsep) {
 		privsep_postauth(authctxt);
 		/* the monitor process [priv] will not return */
+		if (!compat20)
+			destroy_sensitive_data();
 	}
 
 	packet_set_timeout(options.client_alive_interval,
 	    options.client_alive_count_max);
 
 	/* Try to send all our hostkeys to the client */
-	notify_hostkeys(active_state);
+	if (compat20)
+		notify_hostkeys(active_state);
 
 	/* Start session. */
 	do_authenticated(authctxt);
@@ -2116,28 +2459,260 @@
 	exit(0);
 }
 
+#ifdef WITH_SSH1
+/*
+ * Decrypt session_key_int using our private server key and private host key
+ * (key with larger modulus first).
+ */
 int
-sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen,
-    const u_char *data, size_t dlen, const char *alg, u_int flag)
+ssh1_session_key(BIGNUM *session_key_int)
+{
+	struct ssh *ssh = active_state; /* XXX */
+	int rsafail = 0;
+	const BIGNUM *sn = NULL, *hn = NULL;
+
+	RSA_get0_key(sensitive_data.server_key->rsa, &sn, NULL, NULL);
+	RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &hn, NULL, NULL);
+	if (BN_cmp(sn,
+	    hn) > 0) {
+		/* Server key has bigger modulus. */
+		if (BN_num_bits(sn) <
+		    BN_num_bits(hn) +
+		    SSH_KEY_BITS_RESERVED) {
+			fatal("do_connection: %s port %d: "
+			    "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
+			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+			    BN_num_bits(sn),
+			    BN_num_bits(hn),
+			    SSH_KEY_BITS_RESERVED);
+		}
+		if (rsa_private_decrypt(session_key_int, session_key_int,
+		    sensitive_data.server_key->rsa) != 0)
+			rsafail++;
+		if (rsa_private_decrypt(session_key_int, session_key_int,
+		    sensitive_data.ssh1_host_key->rsa) != 0)
+			rsafail++;
+	} else {
+		/* Host key has bigger modulus (or they are equal). */
+		if (BN_num_bits(hn) <
+		    BN_num_bits(sn) +
+		    SSH_KEY_BITS_RESERVED) {
+			fatal("do_connection: %s port %d: "
+			    "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
+			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+			    BN_num_bits(hn),
+			    BN_num_bits(sn),
+			    SSH_KEY_BITS_RESERVED);
+		}
+		if (rsa_private_decrypt(session_key_int, session_key_int,
+		    sensitive_data.ssh1_host_key->rsa) != 0)
+			rsafail++;
+		if (rsa_private_decrypt(session_key_int, session_key_int,
+		    sensitive_data.server_key->rsa) != 0)
+			rsafail++;
+	}
+	return (rsafail);
+}
+
+/*
+ * SSH1 key exchange
+ */
+static void
+do_ssh1_kex(void)
 {
+	struct ssh *ssh = active_state; /* XXX */
+	int i, len;
+	int rsafail = 0;
+	BIGNUM *session_key_int, *fake_key_int, *real_key_int;
+	u_char session_key[SSH_SESSION_KEY_LENGTH];
+	u_char fake_key_bytes[4096 / 8];
+	size_t fake_key_len;
+	u_char cookie[8];
+	u_int cipher_type, auth_mask, protocol_flags;
+	const BIGNUM *sn = NULL, *se = NULL;
+	const BIGNUM *hn = NULL, *he = NULL;
+
+	/*
+	 * Generate check bytes that the client must send back in the user
+	 * packet in order for it to be accepted; this is used to defy ip
+	 * spoofing attacks.  Note that this only works against somebody
+	 * doing IP spoofing from a remote machine; any machine on the local
+	 * network can still see outgoing packets and catch the random
+	 * cookie.  This only affects rhosts authentication, and this is one
+	 * of the reasons why it is inherently insecure.
+	 */
+	arc4random_buf(cookie, sizeof(cookie));
+
+	/*
+	 * Send our public key.  We include in the packet 64 bits of random
+	 * data that must be matched in the reply in order to prevent IP
+	 * spoofing.
+	 */
+	packet_start(SSH_SMSG_PUBLIC_KEY);
+	for (i = 0; i < 8; i++)
+		packet_put_char(cookie[i]);
+
+	/* Store our public server RSA key. */
+	RSA_get0_key(sensitive_data.server_key->rsa, &sn, &se, NULL);
+	packet_put_int(BN_num_bits(sn));
+	packet_put_bignum(se);
+	packet_put_bignum(sn);
+
+	/* Store our public host RSA key. */
+	RSA_get0_key(sensitive_data.ssh1_host_key->rsa, &hn, &he, NULL);
+	packet_put_int(BN_num_bits(hn));
+	packet_put_bignum(he);
+	packet_put_bignum(hn);
+
+	/* Put protocol flags. */
+	packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
+
+	/* Declare which ciphers we support. */
+	packet_put_int(cipher_mask_ssh1(0));
+
+	/* Declare supported authentication types. */
+	auth_mask = 0;
+	if (options.rhosts_rsa_authentication)
+		auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
+	if (options.rsa_authentication)
+		auth_mask |= 1 << SSH_AUTH_RSA;
+	if (options.challenge_response_authentication == 1)
+		auth_mask |= 1 << SSH_AUTH_TIS;
+	if (options.password_authentication)
+		auth_mask |= 1 << SSH_AUTH_PASSWORD;
+	packet_put_int(auth_mask);
+
+	/* Send the packet and wait for it to be sent. */
+	packet_send();
+	packet_write_wait();
+
+	debug("Sent %d bit server key and %d bit host key.",
+	    BN_num_bits(sn),
+	    BN_num_bits(hn));
+
+	/* Read clients reply (cipher type and session key). */
+	packet_read_expect(SSH_CMSG_SESSION_KEY);
+
+	/* Get cipher type and check whether we accept this. */
+	cipher_type = packet_get_char();
+
+	if (!(cipher_mask_ssh1(0) & (1 << cipher_type)))
+		packet_disconnect("Warning: client selects unsupported cipher.");
+
+	/* Get check bytes from the packet.  These must match those we
+	   sent earlier with the public key packet. */
+	for (i = 0; i < 8; i++)
+		if (cookie[i] != packet_get_char())
+			packet_disconnect("IP Spoofing check bytes do not match.");
+
+	debug("Encryption type: %.200s", cipher_name(cipher_type));
+
+	/* Get the encrypted integer. */
+	if ((real_key_int = BN_new()) == NULL)
+		fatal("do_ssh1_kex: BN_new failed");
+	packet_get_bignum(real_key_int);
+
+	protocol_flags = packet_get_int();
+	packet_set_protocol_flags(protocol_flags);
+	packet_check_eom();
+
+	/* Setup a fake key in case RSA decryption fails */
+	if ((fake_key_int = BN_new()) == NULL)
+		fatal("do_ssh1_kex: BN_new failed");
+	fake_key_len = BN_num_bytes(real_key_int);
+	if (fake_key_len > sizeof(fake_key_bytes))
+		fake_key_len = sizeof(fake_key_bytes);
+	arc4random_buf(fake_key_bytes, fake_key_len);
+	if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL)
+		fatal("do_ssh1_kex: BN_bin2bn failed");
+
+	/* Decrypt real_key_int using host/server keys */
+	rsafail = PRIVSEP(ssh1_session_key(real_key_int));
+	/* If decryption failed, use the fake key. Else, the real key. */
+	if (rsafail)
+		session_key_int = fake_key_int;
+	else
+		session_key_int = real_key_int;
+
+	/*
+	 * Extract session key from the decrypted integer.  The key is in the
+	 * least significant 256 bits of the integer; the first byte of the
+	 * key is in the highest bits.
+	 */
+	(void) BN_mask_bits(session_key_int, sizeof(session_key) * 8);
+	len = BN_num_bytes(session_key_int);
+	if (len < 0 || (u_int)len > sizeof(session_key)) {
+		error("%s: bad session key len from %s port %d: "
+		    "session_key_int %d > sizeof(session_key) %lu", __func__,
+		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+		    len, (u_long)sizeof(session_key));
+		rsafail++;
+	} else {
+		explicit_bzero(session_key, sizeof(session_key));
+		BN_bn2bin(session_key_int,
+		    session_key + sizeof(session_key) - len);
+
+		derive_ssh1_session_id(
+		    hn,
+		    sn,
+		    cookie, session_id);
+		/*
+		 * Xor the first 16 bytes of the session key with the
+		 * session id.
+		 */
+		for (i = 0; i < 16; i++)
+			session_key[i] ^= session_id[i];
+	}
+
+	/* Destroy the private and public keys. No longer. */
+	destroy_sensitive_data();
+
+	if (use_privsep)
+		mm_ssh1_session_id(session_id);
+
+	/* Destroy the decrypted integer.  It is no longer needed. */
+	BN_clear_free(real_key_int);
+	BN_clear_free(fake_key_int);
+
+	/* Set the session key.  From this on all communications will be encrypted. */
+	packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);
+
+	/* Destroy our copy of the session key.  It is no longer needed. */
+	explicit_bzero(session_key, sizeof(session_key));
+
+	debug("Received session key; encryption turned on.");
+
+	/* Send an acknowledgment packet.  Note that this packet is sent encrypted. */
+	packet_start(SSH_SMSG_SUCCESS);
+	packet_send();
+	packet_write_wait();
+}
+#endif
+
+int
+Xsshd_hostkey_sign(
+	ssh_sign_ctx *ctx, struct sshkey *pubkey,
+	u_char **signature, size_t *slen,
+	const u_char *data, size_t dlen
+) {
 	int r;
 	u_int xxx_slen, xxx_dlen = dlen;
 
-	if (privkey) {
-		if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen,
-		    alg) < 0))
-			fatal("%s: key_sign failed", __func__);
+	if (ctx->key) {
+		if (PRIVSEP(xkey_sign(ctx, signature, &xxx_slen, data, xxx_dlen) < 0))
+			fatal("%s: xkey_sign failed", __func__);
 		if (slen)
 			*slen = xxx_slen;
 	} else if (use_privsep) {
-		if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen,
-		    alg) < 0)
-			fatal("%s: pubkey_sign failed", __func__);
+		ssh_sign_ctx mm_ctx = { ctx->alg, pubkey, ctx->compat };
+		if (mm_xkey_sign(&mm_ctx, signature, &xxx_slen, data, xxx_dlen) < 0)
+			fatal("%s: pubkey xkey_sign failed", __func__);
 		if (slen)
 			*slen = xxx_slen;
 	} else {
-		if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen,
-		    data, dlen, alg, datafellows)) != 0)
+		ssh_sign_ctx a_ctx = { ctx->alg, pubkey, ctx->compat };
+		r = Xssh_agent_sign(auth_sock, &a_ctx, signature, slen, data, dlen);
+		if (r != 0)
 			fatal("%s: ssh_agent_sign failed: %s",
 			    __func__, ssh_err(r));
 	}
@@ -2193,10 +2768,10 @@
 	kex->server = 1;
 	kex->client_version_string=client_version_string;
 	kex->server_version_string=server_version_string;
-	kex->load_host_public_key=&get_hostkey_public_by_type;
-	kex->load_host_private_key=&get_hostkey_private_by_type;
+	kex->find_host_public_key=&get_hostkey_public_by_alg;
+	kex->find_host_private_key=&get_hostkey_private_by_alg;
 	kex->host_key_index=&get_hostkey_index;
-	kex->sign = sshd_hostkey_sign;
+	kex->xsign = Xsshd_hostkey_sign;
 
 	dispatch_run(DISPATCH_BLOCK, &kex->done, active_state);
 
diff -ruN openssh-7.5p1/sshd_config openssh-7.5p1+x509-10.2/sshd_config
--- openssh-7.5p1/sshd_config	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd_config	2017-05-20 21:07:00.000000000 +0300
@@ -15,11 +15,92 @@
 #ListenAddress 0.0.0.0
 #ListenAddress ::
 
+# The default requires explicit activation of protocol 1
+#Protocol 2
+
+# HostKey for protocol version 1
+#HostKey /etc/ssh/ssh_host_key
+# HostKeys for protocol version 2
 #HostKey /etc/ssh/ssh_host_rsa_key
 #HostKey /etc/ssh/ssh_host_dsa_key
 #HostKey /etc/ssh/ssh_host_ecdsa_key
 #HostKey /etc/ssh/ssh_host_ed25519_key
 
+# "key type names" for X.509 certificates with EC key
+#X509KeyAlgorithm x509v3-ecdsa-sha2-nistp256,sha256,ecdsa-sha2-nistp256
+#X509KeyAlgorithm x509v3-ecdsa-sha2-nistp384,sha384,ecdsa-sha2-nistp384
+#X509KeyAlgorithm x509v3-ecdsa-sha2-nistp521,sha512,ecdsa-sha2-nistp521
+
+# "key type names" for X.509 certificates with RSA key
+# Note first defined is used in signature operations!
+#X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1
+#X509KeyAlgorithm x509v3-sign-rsa,rsa-md5
+
+# "key type names" for X.509 certificates with DSA key
+# Note first defined is used in signature operations!
+#X509KeyAlgorithm x509v3-sign-dss,dss-asn1
+#X509KeyAlgorithm x509v3-sign-dss,dss-raw
+
+# The intended use for the X509 client certificate. Without this option
+# no chain verification will be done. Currently accepted uses are case
+# insensitive:
+#  - "sslclient", "SSL client", "SSL_client" or "client"
+#  - "any", "Any Purpose", "Any_Purpose" or "AnyPurpose"
+#  - "skip" or ""(empty): don`t check purpose.
+#AllowedCertPurpose sslclient
+
+# Specifies whether self-issued(self-signed) X.509 certificate can be
+# allowed only by entry in AutorizedKeysFile that contain matching
+# public key or certificate blob.
+#KeyAllowSelfIssued no
+
+# Specifies whether CRL must present in store for all certificates in
+# certificate chain with atribute "cRLDistributionPoints"
+#MandatoryCRL no
+
+# A file with multiple certificates of certificate signers
+# in PEM format concatenated together.
+#CACertificateFile /etc/ssh/ca/ca-bundle.crt
+
+# A directory with certificates of certificate signers.
+# The certificates should have name of the form: [HASH].[NUMBER]
+# or have symbolic links to them of this form.
+#CACertificatePath /etc/ssh/ca/crt
+
+# A file with multiple CRL of certificate signers
+# in PEM format concatenated together.
+#CARevocationFile /etc/ssh/ca/ca-bundle.crl
+
+# A directory with CRL of certificate signers.
+# The CRL should have name of the form: [HASH].r[NUMBER]
+# or have symbolic links to them of this form.
+#CARevocationPath /etc/ssh/ca/crl
+
+# LDAP protocol version.
+# Example:
+# CAldapVersion 2
+
+# Note because of OpenSSH options parser limitation
+# use %3D instead of = !
+# LDAP initialization may require URL to be escaped, i.e.
+# use %2C instead of ,(comma). Escaped URL don't depend from
+# LDAP initialization method.
+# Example:
+# CAldapURL ldap://localhost:389/dc%3Dexample%2Cdc%3Dcom
+
+# SSH can use "Online Certificate Status Protocol"(OCSP)
+# to validate certificate. Set VAType to
+#  - none    : do not use OCSP to validate certificates;
+#  - ocspcert: validate only certificates that specify `OCSP
+#      Service Locator' URL;
+#  - ocspspec: use specified in the configuration 'OCSP Responder'
+#      to validate all certificates.
+#VAType none
+
+# Lifetime and size of ephemeral version 1 server key
+#KeyRegenerationInterval 1h
+#ServerKeyBits 1024
+
 # Ciphers and keying
 #RekeyLimit default none
 
@@ -35,6 +116,7 @@
 #MaxAuthTries 6
 #MaxSessions 10
 
+#RSAAuthentication yes
 #PubkeyAuthentication yes
 
 # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
@@ -47,9 +129,11 @@
 #AuthorizedKeysCommandUser nobody
 
 # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
+# similar for protocol version 2
 #HostbasedAuthentication no
 # Change to yes if you don't trust ~/.ssh/known_hosts for
-# HostbasedAuthentication
+# RhostsRSAAuthentication and HostbasedAuthentication
 #IgnoreUserKnownHosts no
 # Don't read the user's ~/.rhosts and ~/.shosts files
 #IgnoreRhosts yes
@@ -93,6 +177,7 @@
 #PrintLastLog yes
 #TCPKeepAlive yes
 #UseLogin no
+#UsePrivilegeSeparation sandbox
 #PermitUserEnvironment no
 #Compression delayed
 #ClientAliveInterval 0
diff -ruN openssh-7.5p1/sshd_config.0 openssh-7.5p1+x509-10.2/sshd_config.0
--- openssh-7.5p1/sshd_config.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd_config.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,29 +1,38 @@
-SSHD_CONFIG(5)                File Formats Manual               SSHD_CONFIG(5)
+SSHD_CONFIG(5)              BSD File Formats Manual             SSHD_CONFIG(5)
 
 NAME
-     sshd_config M-bM-^@M-^S OpenSSH SSH daemon configuration file
+     sshd_config -- Secure shell daemon configuration file
 
 SYNOPSIS
      /etc/ssh/sshd_config
 
 DESCRIPTION
      sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file
-     specified with -f on the command line).  The file contains keyword-
-     argument pairs, one per line.  Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines
-     are interpreted as comments.  Arguments may optionally be enclosed in
-     double quotes (") in order to represent arguments containing spaces.
-
-     The possible keywords and their meanings are as follows (note that
-     keywords are case-insensitive and arguments are case-sensitive):
+     specified with -f on the command line).  The file contains keyword-argu-
+     ment pairs, one per line.  Lines starting with '#' and empty lines are
+     interpreted as comments.  Arguments may optionally be enclosed in double
+     quotes (") in order to represent arguments containing spaces.
+
+     The possible keywords and their meanings are as follows (note that key-
+     words are case-insensitive and arguments are case-sensitive):
+
+     AcceptedAlgorithms
+             Specifies the protocol version 2 algorithms as a comma-separated
+             pattern list that will be announced to client if client supports
+             extension negotiation mechanism.  See PATTERNS in ssh_config(5)
+             for more information on patterns.  The default ``*'' will
+             announce all algorithms.  Note algorithms that use X.509 certifi-
+             cates depend from option X509KeyAlgorithm.  The list of available
+             key algorithms may also be obtained using "ssh -Q key".
 
      AcceptEnv
              Specifies what environment variables sent by the client will be
              copied into the session's environ(7).  See SendEnv in
-             ssh_config(5) for how to configure the client.  The TERM
-             environment variable is always sent whenever the client requests
-             a pseudo-terminal as it is required by the protocol.  Variables
-             are specified by name, which may contain the wildcard characters
-             M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y.  Multiple environment variables may be separated by
+             ssh_config(5) for how to configure the client.  The TERM environ-
+             ment variable is always sent whenever the client requests a
+             pseudo-terminal as it is required by the protocol.  Variables are
+             specified by name, which may contain the wildcard characters '*'
+             and '?'.  Multiple environment variables may be separated by
              whitespace or spread across multiple AcceptEnv directives.  Be
              warned that some environment variables could be used to bypass
              restricted user environments.  For this reason, care should be
@@ -41,6 +50,18 @@
              improve security unless users are also denied shell access, as
              they can always install their own forwarders.
 
+     AllowedCertPurpose
+             The intended use for the X.509 client certificate. Without this
+             option no chain verification will be done. Currently accepted
+             uses are case insensitive:
+             sslclient | SSL client | SSL_client | client
+                     only SSL-client purpose
+             any | Any Purpose | Any_Purpose | AnyPurpose
+                     allow any purpose
+             skip | '' (empty)
+                     do not check purpose
+             The default is sslclient.
+
      AllowGroups
              This keyword can be followed by a list of group name patterns,
              separated by spaces.  If specified, login is allowed only for
@@ -56,8 +77,8 @@
      AllowStreamLocalForwarding
              Specifies whether StreamLocal (Unix-domain socket) forwarding is
              permitted.  The available options are yes (the default) or all to
-             allow StreamLocal forwarding, no to prevent all StreamLocal
-             forwarding, local to allow local (from the perspective of ssh(1))
+             allow StreamLocal forwarding, no to prevent all StreamLocal for-
+             warding, local to allow local (from the perspective of ssh(1))
              forwarding only or remote to allow remote forwarding only.  Note
              that disabling StreamLocal forwarding does not improve security
              unless users are also denied shell access, as they can always
@@ -98,32 +119,33 @@
 
              For example, "publickey,password publickey,keyboard-interactive"
              would require the user to complete public key authentication,
-             followed by either password or keyboard interactive
-             authentication.  Only methods that are next in one or more lists
-             are offered at each stage, so for this example it would not be
-             possible to attempt password or keyboard-interactive
-             authentication before public key.
+             followed by either password or keyboard interactive authentica-
+             tion.  Only methods that are next in one or more lists are
+             offered at each stage, so for this example it would not be possi-
+             ble to attempt password or keyboard-interactive authentication
+             before public key.
 
              For keyboard interactive authentication it is also possible to
              restrict authentication to a specific device by appending a colon
-             followed by the device identifier bsdauth, pam, or skey,
-             depending on the server configuration.  For example,
-             "keyboard-interactive:bsdauth" would restrict keyboard
-             interactive authentication to the bsdauth device.
-
-             If the publickey method is listed more than once, sshd(8)
-             verifies that keys that have been used successfully are not
-             reused for subsequent authentications.  For example,
+             followed by the device identifier bsdauth, pam, or skey, depend-
+             ing on the server configuration.  For example,
+             "keyboard-interactive:bsdauth" would restrict keyboard interac-
+             tive authentication to the bsdauth device.
+
+             If the publickey method is listed more than once, sshd(8) veri-
+             fies that keys that have been used successfully are not reused
+             for subsequent authentications.  For example,
              "publickey,publickey" requires successful authentication using
              two different public keys.
 
-             Note that each authentication method listed should also be
-             explicitly enabled in the configuration.
+             This option will yield a fatal error if enabled if protocol 1 is
+             also enabled.  Note that each authentication method listed should
+             also be explicitly enabled in the configuration.
 
      AuthorizedKeysCommand
              Specifies a program to be used to look up the user's public keys.
-             The program must be owned by root, not writable by group or
-             others and specified by an absolute path.  Arguments to
+             The program must be owned by root, not writable by group or oth-
+             ers and specified by an absolute path.  Arguments to
              AuthorizedKeysCommand accept the tokens described in the TOKENS
              section.  If no arguments are specified then the username of the
              target user is used.
@@ -131,9 +153,9 @@
              The program should produce on standard output zero or more lines
              of authorized_keys output (see AUTHORIZED_KEYS in sshd(8)).  If a
              key supplied by AuthorizedKeysCommand does not successfully
-             authenticate and authorize the user then public key
-             authentication continues using the usual AuthorizedKeysFile
-             files.  By default, no AuthorizedKeysCommand is run.
+             authenticate and authorize the user then public key authentica-
+             tion continues using the usual AuthorizedKeysFile files.  By
+             default, no AuthorizedKeysCommand is run.
 
      AuthorizedKeysCommandUser
              Specifies the user under whose account the AuthorizedKeysCommand
@@ -146,28 +168,28 @@
              Specifies the file that contains the public keys used for user
              authentication.  The format is described in the AUTHORIZED_KEYS
              FILE FORMAT section of sshd(8).  Arguments to AuthorizedKeysFile
-             accept the tokens described in the TOKENS section.  After
-             expansion, AuthorizedKeysFile is taken to be an absolute path or
-             one relative to the user's home directory.  Multiple files may be
+             accept the tokens described in the TOKENS section.  After expan-
+             sion, AuthorizedKeysFile is taken to be an absolute path or one
+             relative to the user's home directory.  Multiple files may be
              listed, separated by whitespace.  Alternately this option may be
              set to none to skip checking for user keys in files.  The default
              is ".ssh/authorized_keys .ssh/authorized_keys2".
 
      AuthorizedPrincipalsCommand
              Specifies a program to be used to generate the list of allowed
-             certificate principals as per AuthorizedPrincipalsFile.  The
-             program must be owned by root, not writable by group or others
-             and specified by an absolute path.  Arguments to
+             certificate principals as per AuthorizedPrincipalsFile.  The pro-
+             gram must be owned by root, not writable by group or others and
+             specified by an absolute path.  Arguments to
              AuthorizedPrincipalsCommand accept the tokens described in the
              TOKENS section.  If no arguments are specified then the username
              of the target user is used.
 
              The program should produce on standard output zero or more lines
              of AuthorizedPrincipalsFile output.  If either
-             AuthorizedPrincipalsCommand or AuthorizedPrincipalsFile is
-             specified, then certificates offered by the client for
-             authentication must contain a principal that is listed.  By
-             default, no AuthorizedPrincipalsCommand is run.
+             AuthorizedPrincipalsCommand or AuthorizedPrincipalsFile is speci-
+             fied, then certificates offered by the client for authentication
+             must contain a principal that is listed.  By default, no
+             AuthorizedPrincipalsCommand is run.
 
      AuthorizedPrincipalsCommandUser
              Specifies the user under whose account the
@@ -184,18 +206,18 @@
              which must appear in the certificate for it to be accepted for
              authentication.  Names are listed one per line preceded by key
              options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)).
-             Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored.
+             Empty lines and comments starting with '#' are ignored.
 
              Arguments to AuthorizedPrincipalsFile accept the tokens described
              in the TOKENS section.  After expansion, AuthorizedPrincipalsFile
              is taken to be an absolute path or one relative to the user's
-             home directory.  The default is none, i.e. not to use a
-             principals file M-bM-^@M-^S in this case, the username of the user must
-             appear in a certificate's principals list for it to be accepted.
-
-             Note that AuthorizedPrincipalsFile is only used when
-             authentication proceeds using a CA listed in TrustedUserCAKeys
-             and is not consulted for certification authorities trusted via
+             home directory.  The default is none, i.e. not to use a princi-
+             pals file - in this case, the username of the user must appear in
+             a certificate's principals list for it to be accepted.
+
+             Note that AuthorizedPrincipalsFile is only used when authentica-
+             tion proceeds using a CA listed in TrustedUserCAKeys and is not
+             consulted for certification authorities trusted via
              ~/.ssh/authorized_keys, though the principals= key option offers
              a similar facility (see sshd(8) for details).
 
@@ -203,6 +225,43 @@
              before authentication is allowed.  If the argument is none then
              no banner is displayed.  By default, no banner is displayed.
 
+     CACertificateFile
+             ``X509 store'' option: This file contain multiple certificates of
+             certificate signers in PEM format concatenated together. The
+             default is /etc/ssh/ca/ca-bundle.crt.
+
+     CACertificatePath
+             ``X509 store'' option: ``Hash dir'' with certificates of certifi-
+             cate signers. Each certificate should be stored in separate file
+             with name [HASH].[NUMBER], where [HASH] is certificate hash value
+             and [NUMBER] is an integer starting from zero.  The default is
+             /etc/ssh/ca/crt.
+
+     CAldapVersion
+             ``X509 store'' option: Specifies LDAP protocol version.  The
+             default is not specified and depend from LDAP library.
+
+     CAldapURL
+             ``X509 store'' option: Specifies hostport and dn(distinguished
+             name) of LDAP URLs (Uniform Resource Locators) as detailed in RFC
+             2255.  The rest of URL is build internally.  Because of OpenSSH
+             options parser limitation use '%3D' instead of '=' !  LDAP ini-
+             tialization method may require URL to be escaped, i.e. use '%2C'
+             instead of ',' (comma).  Escaped URL don't depend from LDAP ini-
+             tialization method.
+
+     CARevocationFile
+             ``X509 store'' option: This file contain multiple ``Certificate
+             Revocation List'' (CRL) of certificate signers in PEM format con-
+             catenated together.  The default is /etc/ssh/ca/ca-bundle.crl.
+
+     CARevocationPath
+             ``X509 store'' option: ``Hash dir'' with ``Certificate Revocation
+             List'' (CRL) of certificate signers. Each CRL should be stored in
+             separate file with name [HASH].r[NUMBER], where [HASH] is CRL
+             hash value and [NUMBER] is an integer starting from zero. The
+             default is /etc/ssh/ca/crl.
+
      ChallengeResponseAuthentication
              Specifies whether challenge-response authentication is allowed
              (e.g. via PAM or through authentication styles supported in
@@ -210,22 +269,22 @@
 
      ChrootDirectory
              Specifies the pathname of a directory to chroot(2) to after
-             authentication.  At session startup sshd(8) checks that all
-             components of the pathname are root-owned directories which are
-             not writable by any other user or group.  After the chroot,
-             sshd(8) changes the working directory to the user's home
-             directory.  Arguments to ChrootDirectory accept the tokens
-             described in the TOKENS section.
-
-             The ChrootDirectory must contain the necessary files and
-             directories to support the user's session.  For an interactive
-             session this requires at least a shell, typically sh(1), and
-             basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4),
-             stderr(4), and tty(4) devices.  For file transfer sessions using
-             SFTP no additional configuration of the environment is necessary
-             if the in-process sftp-server is used, though sessions which use
-             logging may require /dev/log inside the chroot directory on some
-             operating systems (see sftp-server(8) for details).
+             authentication.  At session startup sshd(8) checks that all com-
+             ponents of the pathname are root-owned directories which are not
+             writable by any other user or group.  After the chroot, sshd(8)
+             changes the working directory to the user's home directory.
+             Arguments to ChrootDirectory accept the tokens described in the
+             TOKENS section.
+
+             The ChrootDirectory must contain the necessary files and directo-
+             ries to support the user's session.  For an interactive session
+             this requires at least a shell, typically sh(1), and basic /dev
+             nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4),
+             and tty(4) devices.  For file transfer sessions using SFTP no
+             additional configuration of the environment is necessary if the
+             in-process sftp-server is used, though sessions which use logging
+             may require /dev/log inside the chroot directory on some operat-
+             ing systems (see sftp-server(8) for details).
 
              For safety, it is very important that the directory hierarchy be
              prevented from modification by other processes on the system
@@ -236,10 +295,10 @@
 
      Ciphers
              Specifies the ciphers allowed.  Multiple ciphers must be comma-
-             separated.  If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character,
+             separated.  If the specified value begins with a '+' character,
              then the specified ciphers will be appended to the default set
              instead of replacing them.  If the specified value begins with a
-             M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified ciphers (including wildcards)
+             '-' character, then the specified ciphers (including wildcards)
              will be removed from the default set instead of replacing them.
 
              The supported ciphers are:
@@ -270,17 +329,16 @@
              cipher".
 
      ClientAliveCountMax
-             Sets the number of client alive messages which may be sent
-             without sshd(8) receiving any messages back from the client.  If
-             this threshold is reached while client alive messages are being
-             sent, sshd will disconnect the client, terminating the session.
-             It is important to note that the use of client alive messages is
-             very different from TCPKeepAlive.  The client alive messages are
-             sent through the encrypted channel and therefore will not be
-             spoofable.  The TCP keepalive option enabled by TCPKeepAlive is
-             spoofable.  The client alive mechanism is valuable when the
-             client or server depend on knowing when a connection has become
-             inactive.
+             Sets the number of client alive messages which may be sent with-
+             out sshd(8) receiving any messages back from the client.  If this
+             threshold is reached while client alive messages are being sent,
+             sshd will disconnect the client, terminating the session.  It is
+             important to note that the use of client alive messages is very
+             different from TCPKeepAlive.  The client alive messages are sent
+             through the encrypted channel and therefore will not be spoofa-
+             ble.  The TCP keepalive option enabled by TCPKeepAlive is spoofa-
+             ble.  The client alive mechanism is valuable when the client or
+             server depend on knowing when a connection has become inactive.
 
              The default value is 3.  If ClientAliveInterval is set to 15, and
              ClientAliveCountMax is left at the default, unresponsive SSH
@@ -302,8 +360,8 @@
              This keyword can be followed by a list of group name patterns,
              separated by spaces.  Login is disallowed for users whose primary
              group or supplementary group list matches one of the patterns.
-             Only group names are valid; a numerical group ID is not
-             recognized.  By default, login is allowed for all groups.  The
+             Only group names are valid; a numerical group ID is not recog-
+             nized.  By default, login is allowed for all groups.  The
              allow/deny directives are processed in the following order:
              DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups.
 
@@ -312,15 +370,14 @@
      DenyUsers
              This keyword can be followed by a list of user name patterns,
              separated by spaces.  Login is disallowed for user names that
-             match one of the patterns.  Only user names are valid; a
-             numerical user ID is not recognized.  By default, login is
-             allowed for all users.  If the pattern takes the form USER@HOST
-             then USER and HOST are separately checked, restricting logins to
-             particular users from particular hosts.  HOST criteria may
-             additionally contain addresses to match in CIDR address/masklen
-             format.  The allow/deny directives are processed in the following
-             order: DenyUsers, AllowUsers, DenyGroups, and finally
-             AllowGroups.
+             match one of the patterns.  Only user names are valid; a numeri-
+             cal user ID is not recognized.  By default, login is allowed for
+             all users.  If the pattern takes the form USER@HOST then USER and
+             HOST are separately checked, restricting logins to particular
+             users from particular hosts.  HOST criteria may additionally con-
+             tain addresses to match in CIDR address/masklen format.  The
+             allow/deny directives are processed in the following order:
+             DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups.
 
              See PATTERNS in ssh_config(5) for more information on patterns.
 
@@ -351,9 +408,9 @@
              forwardings to the loopback address.  This prevents other remote
              hosts from connecting to forwarded ports.  GatewayPorts can be
              used to specify that sshd should allow remote port forwardings to
-             bind to non-loopback addresses, thus allowing other hosts to
-             connect.  The argument may be no to force remote port forwardings
-             to be available to the local host only, yes to force remote port
+             bind to non-loopback addresses, thus allowing other hosts to con-
+             nect.  The argument may be no to force remote port forwardings to
+             be available to the local host only, yes to force remote port
              forwardings to bind to the wildcard address, or clientspecified
              to allow the client to select the address to which the forwarding
              is bound.  The default is no.
@@ -376,25 +433,17 @@
              machines.  The default is yes.
 
      HostbasedAcceptedKeyTypes
-             Specifies the key types that will be accepted for hostbased
-             authentication as a comma-separated pattern list.  Alternately if
-             the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the
-             specified key types will be appended to the default set instead
-             of replacing them.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y
-             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:
+             Option compatibility. See HostbasedAlgorithms
 
-                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,
-                ssh-rsa-cert-v01@openssh.com,
-                ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-                ssh-ed25519,ssh-rsa
-
-             The list of available key types may also be obtained using "ssh
-             -Q key".
+     HostbasedAlgorithms
+             Specifies the protocol version 2 algorithms that will be accepted
+             in ``hostbased'' authentication as a comma-separated pattern
+             list.  See PATTERNS in ssh_config(5) for more information on pat-
+             terns.  The default ``*'' will allow all algorithms.  Also algo-
+             rithms has to be accepted by patterns of option
+             AcceptedAlgorithms.  Note algorithms that use X.509 certificates
+             depend from option X509KeyAlgorithm.  The list of available key
+             algorithms may also be obtained using "ssh -Q key".
 
      HostbasedAuthentication
              Specifies whether rhosts or /etc/hosts.equiv authentication
@@ -411,24 +460,35 @@
              no.
 
      HostCertificate
-             Specifies a file containing a public host certificate.  The
-             certificate's public key must match a private host key already
-             specified by HostKey.  The default behaviour of sshd(8) is not to
+             Specifies a file containing a public host certificate.  The cer-
+             tificate's public key must match a private host key already spec-
+             ified by HostKey.  The default behaviour of sshd(8) is not to
              load any certificates.
 
      HostKey
              Specifies a file containing a private host key used by SSH.  The
-             defaults are /etc/ssh/ssh_host_dsa_key,
-             /etc/ssh/ssh_host_ecdsa_key, /etc/ssh/ssh_host_ed25519_key and
-             /etc/ssh/ssh_host_rsa_key.
+             default is /etc/ssh/ssh_host_key for protocol version 1, and
+             /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key,
+             /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for
+             protocol version 2.
 
              Note that sshd(8) will refuse to use a file if it is group/world-
              accessible and that the HostKeyAlgorithms option restricts which
              of the keys are actually used by sshd(8).
 
-             It is possible to have multiple host key files.  It is also
-             possible to specify public host key files instead.  In this case
-             operations on the private key will be delegated to an
+             It is possible to have multiple host key files.  rsa1 keys are
+             used for version 1 and dsa, ecdsa, ed25519 or rsa are used for
+             version 2 of the SSH protocol.
+
+             Host key for protocol version 2 may contain X.509 certificate
+             that match private key.  For x509v3-ecdsa-sha2-* public key algo-
+             rithms, file with ECDSA key may contain extra X.509 certificates.
+             Extra certificates along with certificates from X.509 store are
+             used to build chain of certificates leading to a trusted certifi-
+             cate authority.
+
+             It is also possible to specify public host key files instead.  In
+             this case operations on the private key will be delegated to an
              ssh-agent(1).
 
      HostKeyAgent
@@ -439,42 +499,31 @@
 
      HostKeyAlgorithms
              Specifies the host key algorithms that the server offers.  The
-             default for this option is:
-
-                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,
-                ssh-rsa-cert-v01@openssh.com,
-                ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-                ssh-ed25519,ssh-rsa
-
-             The list of available key types may also be obtained using "ssh
-             -Q key".
+             default ``*'' allows all algorithms.  The list of available key
+             algorithms may also be obtained using "ssh -Q key".
 
      IgnoreRhosts
              Specifies that .rhosts and .shosts files will not be used in
-             HostbasedAuthentication.
+             RhostsRSAAuthentication or HostbasedAuthentication.
 
              /etc/hosts.equiv and /etc/shosts.equiv are still used.  The
              default is yes.
 
      IgnoreUserKnownHosts
              Specifies whether sshd(8) should ignore the user's
-             ~/.ssh/known_hosts during HostbasedAuthentication.  The default
-             is no.
+             ~/.ssh/known_hosts during RhostsRSAAuthentication or
+             HostbasedAuthentication.  The default is no.
 
-     IPQoS   Specifies the IPv4 type-of-service or DSCP class for the
-             connection.  Accepted values are af11, af12, af13, af21, af22,
-             af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3,
-             cs4, cs5, cs6, cs7, ef, lowdelay, throughput, reliability, or a
-             numeric value.  This option may take one or two arguments,
-             separated by whitespace.  If one argument is specified, it is
-             used as the packet class unconditionally.  If two values are
-             specified, the first is automatically selected for interactive
-             sessions and the second for non-interactive sessions.  The
-             default is lowdelay for interactive sessions and throughput for
-             non-interactive sessions.
+     IPQoS   Specifies the IPv4 type-of-service or DSCP class for the connec-
+             tion.  Accepted values are af11, af12, af13, af21, af22, af23,
+             af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5,
+             cs6, cs7, ef, lowdelay, throughput, reliability, or a numeric
+             value.  This option may take one or two arguments, separated by
+             whitespace.  If one argument is specified, it is used as the
+             packet class unconditionally.  If two values are specified, the
+             first is automatically selected for interactive sessions and the
+             second for non-interactive sessions.  The default is lowdelay for
+             interactive sessions and throughput for non-interactive sessions.
 
      KbdInteractiveAuthentication
              Specifies whether to allow keyboard-interactive authentication.
@@ -495,9 +544,9 @@
              The default is no.
 
      KerberosOrLocalPasswd
-             If password authentication through Kerberos fails then the
-             password will be validated via any additional local mechanism
-             such as /etc/passwd.  The default is yes.
+             If password authentication through Kerberos fails then the pass-
+             word will be validated via any additional local mechanism such as
+             /etc/passwd.  The default is yes.
 
      KerberosTicketCleanup
              Specifies whether to automatically destroy the user's ticket
@@ -506,9 +555,9 @@
      KexAlgorithms
              Specifies the available KEX (Key Exchange) algorithms.  Multiple
              algorithms must be comma-separated.  Alternately if the specified
-             value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified methods
+             value begins with a '+' character, then the specified methods
              will be appended to the default set instead of replacing them.
-             If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the
+             If the specified value begins with a '-' character, then the
              specified methods (including wildcards) will be removed from the
              default set instead of replacing them.  The supported algorithms
              are:
@@ -533,9 +582,32 @@
              The list of available key exchange algorithms may also be
              obtained using "ssh -Q kex".
 
+     KeyAllowSelfIssued
+             Specifies whether only encoded public key or X.509 certificate
+             listed in AutorizedKeysFile can allow self-signed X.509 certifi-
+             cate to be used for user authentication.  The default is ``no''.
+             Unsupported if deamon is build without ``X509 store''.
+
+             A certificate (including self-signed) is accepted for user
+             authentication if encoded public key or encoded X.509 certificate
+             or distinguished name is listed in AutorizedKeysFile, if is valid
+             and if is verified by certificates from ``X509 store''.  See
+             verify(1).  If option is set to ``yes'' self-signed certificate
+             is accepted when its public key match public key extracted from
+             entry in AutorizedKeysFile.  In this case validity of certificate
+             is not checked.
+
+     KeyRegenerationInterval
+             In protocol version 1, the ephemeral server key is automatically
+             regenerated after this many seconds (if it has been used).  The
+             purpose of regeneration is to prevent decrypting captured ses-
+             sions by later breaking into the machine and stealing the keys.
+             The key is never stored anywhere.  If the value is 0, the key is
+             never regenerated.  The default is 3600 (seconds).
+
      ListenAddress
-             Specifies the local addresses sshd(8) should listen on.  The
-             following forms may be used:
+             Specifies the local addresses sshd(8) should listen on.  The fol-
+             lowing forms may be used:
 
                    ListenAddress host|IPv4_addr|IPv6_addr
                    ListenAddress host|IPv4_addr:port
@@ -546,9 +618,9 @@
              addresses.  Multiple ListenAddress options are permitted.
 
      LoginGraceTime
-             The server disconnects after this time if the user has not
-             successfully logged in.  If the value is 0, there is no time
-             limit.  The default is 120 seconds.
+             The server disconnects after this time if the user has not suc-
+             cessfully logged in.  If the value is 0, there is no time limit.
+             The default is 120 seconds.
 
      LogLevel
              Gives the verbosity level that is used when logging messages from
@@ -558,14 +630,14 @@
              higher levels of debugging output.  Logging with a DEBUG level
              violates the privacy of users and is not recommended.
 
-     MACs    Specifies the available MAC (message authentication code)
-             algorithms.  The MAC algorithm is used for data integrity
-             protection.  Multiple algorithms must be comma-separated.  If the
-             specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified
-             algorithms will be appended to the default set instead of
-             replacing them.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y
-             character, then the specified algorithms (including wildcards)
-             will be removed from the default set instead of replacing them.
+     MACs    Specifies the available MAC (message authentication code) algo-
+             rithms.  The MAC algorithm is used for data integrity protection.
+             Multiple algorithms must be comma-separated.  If the specified
+             value begins with a '+' character, then the specified algorithms
+             will be appended to the default set instead of replacing them.
+             If the specified value begins with a '-' character, then the
+             specified algorithms (including wildcards) will be removed from
+             the default set instead of replacing them.
 
              The algorithms that contain "-etm" calculate the MAC after
              encryption (encrypt-then-mac).  These are considered safer and
@@ -601,6 +673,11 @@
              The list of available MAC algorithms may also be obtained using
              "ssh -Q mac".
 
+     MandatoryCRL
+             ``X509 store'' option: Specifies whether CRL must present in
+             store for all certificates in ``certificate chain'' with atribute
+             ``X509v3 CRL Distribution Points''.  The default is no.
+
      Match   Introduces a conditional block.  If all of the criteria on the
              Match line are satisfied, the keywords on the following lines
              override those set in the global section of the config file,
@@ -612,13 +689,13 @@
              the single token All which matches all criteria.  The available
              criteria are User, Group, Host, LocalAddress, LocalPort, and
              Address.  The match patterns may consist of single entries or
-             comma-separated lists and may use the wildcard and negation
-             operators described in the PATTERNS section of ssh_config(5).
+             comma-separated lists and may use the wildcard and negation oper-
+             ators described in the PATTERNS section of ssh_config(5).
 
              The patterns in an Address criteria may additionally contain
              addresses to match in CIDR address/masklen format, such as
-             192.0.2.0/24 or 2001:db8::/32.  Note that the mask length
-             provided must be consistent with the address - it is an error to
+             192.0.2.0/24 or 2001:db8::/32.  Note that the mask length pro-
+             vided must be consistent with the address - it is an error to
              specify a mask length that is too long for the address or one
              with bits set in this host portion of the address.  For example,
              192.0.2.0/33 and 192.0.2.0/8, respectively.
@@ -633,14 +710,16 @@
              Banner, ChrootDirectory, ClientAliveCountMax,
              ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand,
              GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes,
-             HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS,
+             HostbasedAlgorithms, HostbasedAuthentication,
+             HostbasedUsesNameFromPacketOnly, IPQoS,
              KbdInteractiveAuthentication, KerberosAuthentication,
              MaxAuthTries, MaxSessions, PasswordAuthentication,
              PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY,
              PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes,
-             PubkeyAuthentication, RekeyLimit, RevokedKeys,
-             StreamLocalBindMask, StreamLocalBindUnlink, TrustedUserCAKeys,
-             X11DisplayOffset, X11Forwarding and X11UseLocalHost.
+             PubkeyAlgorithms, PubkeyAuthentication, RekeyLimit, RevokedKeys,
+             RhostsRSAAuthentication, RSAAuthentication, StreamLocalBindMask,
+             StreamLocalBindUnlink, TrustedUserCAKeys, X11DisplayOffset,
+             X11Forwarding and X11UseLocalHost.
 
      MaxAuthTries
              Specifies the maximum number of authentication attempts permitted
@@ -653,12 +732,12 @@
              sessions may be established by clients that support connection
              multiplexing.  Setting MaxSessions to 1 will effectively disable
              session multiplexing, whereas setting it to 0 will prevent all
-             shell, login and subsystem sessions while still permitting
-             forwarding.  The default is 10.
+             shell, login and subsystem sessions while still permitting for-
+             warding.  The default is 10.
 
      MaxStartups
-             Specifies the maximum number of concurrent unauthenticated
-             connections to the SSH daemon.  Additional connections will be
+             Specifies the maximum number of concurrent unauthenticated con-
+             nections to the SSH daemon.  Additional connections will be
              dropped until authentication succeeds or the LoginGraceTime
              expires for a connection.  The default is 10:30:100.
 
@@ -666,9 +745,9 @@
              three colon separated values start:rate:full (e.g. "10:30:60").
              sshd(8) will refuse connection attempts with a probability of
              rate/100 (30%) if there are currently start (10) unauthenticated
-             connections.  The probability increases linearly and all
-             connection attempts are refused if the number of unauthenticated
-             connections reaches full (60).
+             connections.  The probability increases linearly and all connec-
+             tion attempts are refused if the number of unauthenticated con-
+             nections reaches full (60).
 
      PasswordAuthentication
              Specifies whether password authentication is allowed.  The
@@ -680,21 +759,20 @@
              default is no.
 
      PermitOpen
-             Specifies the destinations to which TCP port forwarding is
-             permitted.  The forwarding specification must be one of the
-             following forms:
+             Specifies the destinations to which TCP port forwarding is per-
+             mitted.  The forwarding specification must be one of the follow-
+             ing forms:
 
                    PermitOpen host:port
                    PermitOpen IPv4_addr:port
                    PermitOpen [IPv6_addr]:port
 
-             Multiple forwards may be specified by separating them with
-             whitespace.  An argument of any can be used to remove all
-             restrictions and permit any forwarding requests.  An argument of
-             none can be used to prohibit all forwarding requests.  The
-             wildcard M-bM-^@M-^X*M-bM-^@M-^Y can be used for host or port to allow all hosts or
-             ports, respectively.  By default all port forwarding requests are
-             permitted.
+             Multiple forwards may be specified by separating them with white-
+             space.  An argument of any can be used to remove all restrictions
+             and permit any forwarding requests.  An argument of none can be
+             used to prohibit all forwarding requests.  The wildcard '*' can
+             be used for host or port to allow all hosts or ports, respec-
+             tively.  By default all port forwarding requests are permitted.
 
      PermitRootLogin
              Specifies whether root can log in using ssh(1).  The argument
@@ -718,10 +796,10 @@
              yes.
 
      PermitTunnel
-             Specifies whether tun(4) device forwarding is allowed.  The
-             argument must be yes, point-to-point (layer 3), ethernet (layer
-             2), or no.  Specifying yes permits both point-to-point and
-             ethernet.  The default is no.
+             Specifies whether tun(4) device forwarding is allowed.  The argu-
+             ment must be yes, point-to-point (layer 3), ethernet (layer 2),
+             or no.  Specifying yes permits both point-to-point and ethernet.
+             The default is no.
 
              Independent of this setting, the permissions of the selected
              tun(4) device must allow access to the user.
@@ -738,9 +816,8 @@
              yes.
 
      PidFile
-             Specifies the file that contains the process ID of the SSH
-             daemon, or none to not write one.  The default is
-             /var/run/sshd.pid.
+             Specifies the file that contains the process ID of the SSH dae-
+             mon, or none to not write one.  The default is /var/run/sshd.pid.
 
      Port    Specifies the port number that sshd(8) listens on.  The default
              is 22.  Multiple options of this type are permitted.  See also
@@ -756,26 +833,31 @@
              in interactively.  (On some systems it is also printed by the
              shell, /etc/profile, or equivalent.)  The default is yes.
 
-     PubkeyAcceptedKeyTypes
-             Specifies the key types that will be accepted for public key
-             authentication as a comma-separated pattern list.  Alternately if
-             the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the
-             specified key types will be appended to the default set instead
-             of replacing them.  If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y
-             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:
+     Protocol
+             Specifies the protocol versions sshd(8) supports.  The possible
+             values are '1' and '2'.  Multiple versions must be comma-sepa-
+             rated.  The default is '2'.  Protocol 1 suffers from a number of
+             cryptographic weaknesses and should not be used.  It is only
+             offered to support legacy devices.
+
+             Note that the order of the protocol list does not indicate pref-
+             erence, because the client selects among multiple protocol ver-
+             sions offered by the server.  Specifying 2,1 is identical to 1,2.
 
-                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,
-                ssh-rsa-cert-v01@openssh.com,
-                ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-                ssh-ed25519,ssh-rsa
+     PubkeyAcceptedKeyTypes
+             Option compatibility. See PubkeyAlgorithms
 
-             The list of available key types may also be obtained using "ssh
-             -Q key".
+     PubkeyAlgorithms
+             Specifies the protocol version 2 algorithms that will be accepted
+             for ``publickey'' authentication as a comma-separated pattern
+             list.  See PATTERNS in ssh_config(5) for more information on pat-
+             terns.  The default * will allow all algorithms.  Also algorithms
+             has to be accepted by patterns of option AcceptedAlgorithms.
+             Note algorithms that use X.509 certificates depend from
+             X509KeyAlgorithm and is enough patter to match one of names set
+             in X509KeyAlgorithm for a certain key-type to enable all from
+             that key-type.  The list of available key algorithms may also be
+             obtained using "ssh -Q key".
 
      PubkeyAuthentication
              Specifies whether public key authentication is allowed.  The
@@ -786,24 +868,37 @@
              before the session key is renegotiated, optionally followed a
              maximum amount of time that may pass before the session key is
              renegotiated.  The first argument is specified in bytes and may
-             have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes,
+             have a suffix of 'K', 'M', or 'G' to indicate Kilobytes,
              Megabytes, or Gigabytes, respectively.  The default is between
-             M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher.  The optional second
-             value is specified in seconds and may use any of the units
-             documented in the TIME FORMATS section.  The default value for
-             RekeyLimit is default none, which means that rekeying is
-             performed after the cipher's default amount of data has been sent
-             or received and no time based rekeying is done.
+             '1G' and '4G', depending on the cipher.  The optional second
+             value is specified in seconds and may use any of the units docu-
+             mented in the TIME FORMATS section.  The default value for
+             RekeyLimit is default none, which means that rekeying is per-
+             formed after the cipher's default amount of data has been sent or
+             received and no time based rekeying is done.
 
      RevokedKeys
              Specifies revoked public keys file, or none to not use one.  Keys
-             listed in this file will be refused for public key
-             authentication.  Note that if this file is not readable, then
-             public key authentication will be refused for all users.  Keys
-             may be specified as a text file, listing one public key per line,
-             or as an OpenSSH Key Revocation List (KRL) as generated by
-             ssh-keygen(1).  For more information on KRLs, see the KEY
-             REVOCATION LISTS section in ssh-keygen(1).
+             listed in this file will be refused for public key authentica-
+             tion.  Note that if this file is not readable, then public key
+             authentication will be refused for all users.  Keys may be speci-
+             fied as a text file, listing one public key per line, or as an
+             OpenSSH Key Revocation List (KRL) as generated by ssh-keygen(1).
+             For more information on KRLs, see the KEY REVOCATION LISTS sec-
+             tion in ssh-keygen(1).
+
+     RhostsRSAAuthentication
+             Specifies whether rhosts or /etc/hosts.equiv authentication
+             together with successful RSA host authentication is allowed.  The
+             default is no.  This option applies to protocol version 1 only.
+
+     RSAAuthentication
+             Specifies whether pure RSA authentication is allowed.  The
+             default is yes.  This option applies to protocol version 1 only.
+
+     ServerKeyBits
+             Defines the number of bits in the ephemeral protocol version 1
+             server key.  The default and minimum value is 1024.
 
      StreamLocalBindMask
              Sets the octal file creation mode mask (umask) used when creating
@@ -839,8 +934,8 @@
              Arguments should be a subsystem name and a command (with optional
              arguments) to execute upon subsystem request.
 
-             The command sftp-server implements the SFTP file transfer
-             subsystem.
+             The command sftp-server implements the SFTP file transfer subsys-
+             tem.
 
              Alternately the name internal-sftp implements an in-process SFTP
              server.  This may simplify configurations using ChrootDirectory
@@ -858,11 +953,10 @@
              Specifies whether the system should send TCP keepalive messages
              to the other side.  If they are sent, death of the connection or
              crash of one of the machines will be properly noticed.  However,
-             this means that connections will die if the route is down
-             temporarily, and some people find it annoying.  On the other
-             hand, if TCP keepalives are not sent, sessions may hang
-             indefinitely on the server, leaving "ghost" users and consuming
-             server resources.
+             this means that connections will die if the route is down tempo-
+             rarily, and some people find it annoying.  On the other hand, if
+             TCP keepalives are not sent, sessions may hang indefinitely on
+             the server, leaving "ghost" users and consuming server resources.
 
              The default is yes (to send TCP keepalive messages), and the
              server will notice if the network goes down or the client host
@@ -871,17 +965,17 @@
              To disable TCP keepalive messages, the value should be set to no.
 
      TrustedUserCAKeys
-             Specifies a file containing public keys of certificate
-             authorities that are trusted to sign user certificates for
-             authentication, or none to not use one.  Keys are listed one per
-             line; empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are allowed.  If
-             a certificate is presented for authentication and has its signing
-             CA key listed in this file, then it may be used for
-             authentication for any user listed in the certificate's
-             principals list.  Note that certificates that lack a list of
-             principals will not be permitted for authentication using
-             TrustedUserCAKeys.  For more details on certificates, see the
-             CERTIFICATES section in ssh-keygen(1).
+             Specifies a file containing public keys of certificate authori-
+             ties that are trusted to sign user certificates for authentica-
+             tion, or none to not use one.  Keys are listed one per line;
+             empty lines and comments starting with '#' are allowed.  If a
+             certificate is presented for authentication and has its signing
+             CA key listed in this file, then it may be used for authentica-
+             tion for any user listed in the certificate's principals list.
+             Note that certificates that lack a list of principals will not be
+             permitted for authentication using TrustedUserCAKeys.  For more
+             details on certificates, see the CERTIFICATES section in
+             ssh-keygen(1).
 
      UseDNS  Specifies whether sshd(8) should look up the remote host name,
              and to check that the resolved host name for the remote IP
@@ -904,10 +998,44 @@
              If UsePAM is enabled, you will not be able to run sshd(8) as a
              non-root user.  The default is no.
 
+     UsePrivilegeSeparation
+             Specifies whether sshd(8) separates privileges by creating an
+             unprivileged child process to deal with incoming network traffic.
+             After successful authentication, another process will be created
+             that has the privilege of the authenticated user.  The goal of
+             privilege separation is to prevent privilege escalation by con-
+             taining any corruption within the unprivileged processes.  The
+             argument must be yes, no, or sandbox.  If UsePrivilegeSeparation
+             is set to sandbox then the pre-authentication unprivileged
+             process is subject to additional restrictions.  The default is
+             sandbox.
+
+     VACertificateFile
+             File with X.509 certificates in PEM format concatenated together.
+             In use when VAType is set to ocspspec.  The default value is ''
+             (empty).  Certificates from that file explicitly trust 'OCSP
+             Responder' public key.  They are used as trusted certificates in
+             addition to certificates from CACertificateFile and
+             CACertificatePath to verify responder certificate.
+
+     VAType  Specifies whether 'Online Certificate Status Protocol' (OCSP) is
+             used to validate X.509 certificates.  Accepted values are case
+             insensitive:
+                   none          do not use OCSP to validate certificates;
+                   ocspcert      validate only certificates that specify 'OCSP
+                                 Service Locator' URL;
+                   ocspspec      use specified in the configuration 'OCSP
+                                 Responder' to validate all certificates.
+             The default is none.
+
+     VAOCSPResponderURL
+             'Access Location' / 'OCSP Service Locator' URL of the OCSP
+             provider. In use when VAType is set to ocspspec.
+
      VersionAddendum
-             Optionally specifies additional text to append to the SSH
-             protocol banner sent by the server upon connection.  The default
-             is none.
+             Optionally specifies additional text to append to the SSH proto-
+             col banner sent by the server upon connection.  The default is
+             none.
 
      X11DisplayOffset
              Specifies the first display number available for sshd(8)'s X11
@@ -926,10 +1054,10 @@
              and substitution occur on the client side.  The security risk of
              using X11 forwarding is that the client's X11 display server may
              be exposed to attack when the SSH client requests forwarding (see
-             the warnings for ForwardX11 in ssh_config(5)).  A system
-             administrator may have a stance in which they want to protect
-             clients that may expose themselves to attack by unwittingly
-             requesting X11 forwarding, which can warrant a no setting.
+             the warnings for ForwardX11 in ssh_config(5)).  A system adminis-
+             trator may have a stance in which they want to protect clients
+             that may expose themselves to attack by unwittingly requesting
+             X11 forwarding, which can warrant a no setting.
 
              Note that disabling X11 forwarding does not prevent users from
              forwarding X11 traffic, as users can always install their own
@@ -943,21 +1071,51 @@
              localhost.  This prevents remote hosts from connecting to the
              proxy display.  However, some older X11 clients may not function
              with this configuration.  X11UseLocalhost may be set to no to
-             specify that the forwarding server should be bound to the
-             wildcard address.  The argument must be yes or no.  The default
-             is yes.
+             specify that the forwarding server should be bound to the wild-
+             card address.  The argument must be yes or no.  The default is
+             yes.
+
+     X509KeyAlgorithm
+             Specifies how X.509 certificates and signatures are used for pro-
+             tocol version 2.  It is possible to have multiple algorithms in
+             form specified in X509 Key Algorithms Format.  Programs use the
+             first listed for ECDSA, RSA, or DSA key in signing and accept all
+             listed.
+
+             The default for certificates with ECDSA keys is:
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp256,ssh-sha256,ecdsa-sha2-nistp256
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp384,ssh-sha384,ecdsa-sha2-nistp384
+                   X509KeyAlgorithm
+                   x509v3-ecdsa-sha2-nistp521,ssh-sha512,ecdsa-sha2-nistp521
+
+             The default for certificates with RSA key is:
+                   X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1
+                   X509KeyAlgorithm x509v3-sign-rsa,rsa-md5
+                   X509KeyAlgorithm x509v3-ssh-rsa,rsa-sha1,ssh-rsa
+
+             The default for certificates with DSA key is:
+                   X509KeyAlgorithm x509v3-sign-dss,dss-asn1
+                   X509KeyAlgorithm x509v3-sign-dss,dss-raw
+                   X509KeyAlgorithm x509v3-ssh-dss,dss-raw,ssh-dss
+
+             Note for EC curves nistp256, nistp384, and nistp521 correspond
+             crypto(3) library curves prime256v1, secp384r1, and secp521r1.
+             Support of EC curves depend from library version.  See ecparam(1)
+             to find how to list curves supported by library.
 
      XAuthLocation
              Specifies the full pathname of the xauth(1) program, or none to
              not use one.  The default is /usr/X11R6/bin/xauth.
 
 TIME FORMATS
-     sshd(8) command-line arguments and configuration file options that
-     specify time may be expressed using a sequence of the form:
-     time[qualifier], where time is a positive integer value and qualifier is
-     one of the following:
+     sshd(8) command-line arguments and configuration file options that spec-
+     ify time may be expressed using a sequence of the form: time[qualifier],
+     where time is a positive integer value and qualifier is one of the fol-
+     lowing:
 
-           M-bM-^_M-(noneM-bM-^_M-)  seconds
+           <none>  seconds
            s | S   seconds
            m | M   minutes
            h | H   hours
@@ -977,7 +1135,7 @@
      Arguments to some keywords can make use of tokens, which are expanded at
      runtime:
 
-           %%    A literal M-bM-^@M-^X%M-bM-^@M-^Y.
+           %%    A literal '%'.
            %F    The fingerprint of the CA key.
            %f    The fingerprint of the key or certificate.
            %h    The home directory of the user.
@@ -1000,21 +1158,45 @@
 
      ChrootDirectory accepts the tokens %%, %h, and %u.
 
+X509 Key Algorithms Format
+     sshd command-line arguments and configuration file options that specify
+     'X509 Key Algorithms' expressed using a sequence of the form:
+     key-type-name,digest-name[,signature-identifier], where key-type-name is
+     key type name, digest-name is
+           rsa-sha1    : RSA key and signature using the SHA-1 hash;
+           rsa-md5     : RSA key and signature using the MD5 hash;
+           dss-asn1    : DSA key and signature as specified in ``RFC 3279'' ;
+           dss-raw     : DSA key and signature in ``ssh-dss'' format as speci-
+                       fied in ``RFC 4253''.
+           ssh-sha256
+           ssh-sha384
+           ssh-sha512  : ECDSA key and signature as specified in ``RFC 6187''.
+     and optional signature-identifier.  When signature-identifier is omited
+     key-type-name is used as identifier.
+
+     For compatibility with old versions following signatures are suported:
+           sha256
+           sha384
+           sha512      : ECDSA key and signature encoded using ASN.1 notation.
+     Server sshd(8) and client ssh(1) switch automatically to above signature
+     if is detected old verson.
+
 FILES
      /etc/ssh/sshd_config
              Contains configuration data for sshd(8).  This file should be
-             writable by root only, but it is recommended (though not
-             necessary) that it be world-readable.
+             writable by root only, but it is recommended (though not neces-
+             sary) that it be world-readable.
 
 SEE ALSO
      sftp-server(8), sshd(8)
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
      versions 1.5 and 2.0.  Niels Provos and Markus Friedl contributed support
-     for privilege separation.
+     for privilege separation.  Roumen Petrov contributed support for X.509
+     certificates.
 
-OpenBSD 6.0                     March 14, 2017                     OpenBSD 6.0
+BSD                             March 22, 2017                             BSD
diff -ruN openssh-7.5p1/sshd_config.5 openssh-7.5p1+x509-10.2/sshd_config.5
--- openssh-7.5p1/sshd_config.5	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshd_config.5	2017-05-20 21:07:00.000000000 +0300
@@ -1,3 +1,11 @@
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,6 +20,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -34,12 +43,12 @@
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" $OpenBSD: sshd_config.5,v 1.243 2017/03/14 07:19:07 djm Exp $
-.Dd $Mdocdate: March 14 2017 $
+.Dd $Mdocdate: March 22 2017 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
 .Nm sshd_config
-.Nd OpenSSH SSH daemon configuration file
+.Nd Secure shell daemon configuration file
 .Sh SYNOPSIS
 .Nm /etc/ssh/sshd_config
 .Sh DESCRIPTION
@@ -61,6 +70,20 @@
 keywords and their meanings are as follows (note that
 keywords are case-insensitive and arguments are case-sensitive):
 .Bl -tag -width Ds
+.It Cm AcceptedAlgorithms
+Specifies the protocol version 2 algorithms as a comma-separated pattern
+list that will be announced to client if client supports extension
+negotiation mechanism.
+See PATTERNS in
+.Xr ssh_config 5
+for more information on patterns.
+The default
+.Dq *
+will announce all algorithms.
+Note algorithms that use X.509 certificates depend from option
+.Cm X509KeyAlgorithm .
+The list of available key algorithms may also be obtained using
+.Qq ssh -Q key .
 .It Cm AcceptEnv
 Specifies what environment variables sent by the client will be copied into
 the session's
@@ -105,6 +128,20 @@
 Note that disabling agent forwarding does not improve security
 unless users are also denied shell access, as they can always install
 their own forwarders.
+.It Cm AllowedCertPurpose
+The intended use for the X.509 client certificate. Without this option
+no chain verification will be done. Currently accepted uses are case
+insensitive:
+.Bl -tag -width Ds -compact
+.It Cm sslclient | Cm SSL client | Cm SSL_client | Cm client
+only SSL-client purpose
+.It Cm any | Cm Any Purpose | Cm Any_Purpose | Cm AnyPurpose
+allow any purpose
+.It Cm skip | Cm '' Li (empty)
+do not check purpose
+.El
+The default is
+.Cm sslclient .
 .It Cm AllowGroups
 This keyword can be followed by a list of group name patterns, separated
 by spaces.
@@ -223,6 +260,8 @@
 .Qq publickey,publickey
 requires successful authentication using two different public keys.
 .Pp
+This option will yield a fatal
+error if enabled if protocol 1 is also enabled.
 Note that each authentication method listed should also be explicitly enabled
 in the configuration.
 .It Cm AuthorizedKeysCommand
@@ -370,6 +409,60 @@
 .Cm none
 then no banner is displayed.
 By default, no banner is displayed.
+.It Cm CACertificateFile
+.Dq X509 store
+option:
+This file contain multiple certificates of certificate signers in
+PEM format concatenated together. The default is
+.Pa /etc/ssh/ca/ca-bundle.crt .
+.It Cm CACertificatePath
+.Dq X509 store
+option:
+.Dq "Hash dir"
+with certificates of certificate signers. Each certificate should be
+stored in separate file with name [HASH].[NUMBER], where [HASH] is
+certificate hash value and [NUMBER] is an integer starting from zero.
+The default is
+.Pa /etc/ssh/ca/crt .
+.It Cm CAldapVersion
+.Dq X509 store
+option:
+Specifies LDAP protocol version.
+The default is not specified and depend from LDAP library.
+.It Cm CAldapURL
+.Dq X509 store
+option:
+Specifies hostport and dn(distinguished name) of LDAP URLs (Uniform Resource Locators) as detailed in RFC 2255.
+The rest of URL is build internally.
+Because of OpenSSH options parser limitation use
+.Sq %3D
+instead of
+.Sq =
+!
+LDAP initialization method may require URL to be escaped, i.e. use
+.Sq %2C
+instead of
+.Sq \&,
+(comma).
+Escaped URL don't depend from LDAP initialization method.
+.It Cm CARevocationFile
+.Dq X509 store
+option:
+This file contain multiple
+.Dq "Certificate Revocation List"
+(CRL) of certificate signers in PEM format concatenated together.
+The default is
+.Pa /etc/ssh/ca/ca-bundle.crl .
+.It Cm CARevocationPath
+.Dq X509 store
+option:
+.Dq "Hash dir"
+with
+.Dq "Certificate Revocation List"
+(CRL) of certificate signers. Each CRL should be stored in separate
+file with name [HASH].r[NUMBER], where [HASH] is CRL hash value and
+[NUMBER] is an integer starting from zero. The default is
+.Pa /etc/ssh/ca/crl .
 .It Cm ChallengeResponseAuthentication
 Specifies whether challenge-response authentication is allowed (e.g. via
 PAM or through authentication styles supported in
@@ -647,28 +740,24 @@
 The default is
 .Cm yes .
 .It Cm HostbasedAcceptedKeyTypes
-Specifies the key types that will be accepted for hostbased authentication
-as a comma-separated pattern list.
-Alternately if the specified value begins with a
-.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-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,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,ssh-rsa
-.Ed
+Option compatibility. See
+.Cm HostbasedAlgorithms
 .Pp
-The list of available key types may also be obtained using
+.It Cm HostbasedAlgorithms
+Specifies the protocol version 2 algorithms that will be accepted in
+.Dq hostbased
+authentication as a comma-separated pattern list.
+See PATTERNS in
+.Xr ssh_config 5
+for more information on patterns.
+The default
+.Dq *
+will allow all algorithms.
+Also algorithms has to be accepted by patterns of option
+.Cm AcceptedAlgorithms .
+Note algorithms that use X.509 certificates depend from option
+.Cm X509KeyAlgorithm .
+The list of available key algorithms may also be obtained using
 .Qq ssh -Q key .
 .It Cm HostbasedAuthentication
 Specifies whether rhosts or /etc/hosts.equiv authentication together
@@ -704,12 +793,15 @@
 .It Cm HostKey
 Specifies a file containing a private host key
 used by SSH.
-The defaults are
+The default is
+.Pa /etc/ssh/ssh_host_key
+for protocol version 1, and
 .Pa /etc/ssh/ssh_host_dsa_key ,
 .Pa /etc/ssh/ssh_host_ecdsa_key ,
 .Pa /etc/ssh/ssh_host_ed25519_key
 and
-.Pa /etc/ssh/ssh_host_rsa_key .
+.Pa /etc/ssh/ssh_host_rsa_key
+for protocol version 2.
 .Pp
 Note that
 .Xr sshd 8
@@ -720,6 +812,23 @@
 .Xr sshd 8 .
 .Pp
 It is possible to have multiple host key files.
+.Cm rsa1
+keys are used for version 1 and
+.Cm dsa ,
+.Cm ecdsa ,
+.Cm ed25519
+or
+.Cm rsa
+are used for version 2 of the SSH protocol.
+.Pp
+Host key for protocol version 2 may contain
+X.509 certificate that match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, file
+with ECDSA key may contain extra X.509 certificates.
+Extra certificates along with certificates from X.509 store
+are used to build chain of certificates leading to
+a trusted certificate authority.
+.Pp
 It is also possible to specify public host key files instead.
 In this case operations on the private key will be delegated
 to an
@@ -735,18 +844,10 @@
 .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,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,ssh-rsa
-.Ed
-.Pp
-The list of available key types may also be obtained using
+The default
+.Dq *
+allows all algorithms.
+The list of available key algorithms may also be obtained using
 .Qq ssh -Q key .
 .It Cm IgnoreRhosts
 Specifies that
@@ -754,6 +855,8 @@
 and
 .Pa .shosts
 files will not be used in
+.Cm RhostsRSAAuthentication
+or
 .Cm HostbasedAuthentication .
 .Pp
 .Pa /etc/hosts.equiv
@@ -768,6 +871,8 @@
 should ignore the user's
 .Pa ~/.ssh/known_hosts
 during
+.Cm RhostsRSAAuthentication
+or
 .Cm HostbasedAuthentication .
 The default is
 .Cm no .
@@ -888,6 +993,38 @@
 .Pp
 The list of available key exchange algorithms may also be obtained using
 .Qq ssh -Q kex .
+.It Cm KeyAllowSelfIssued
+Specifies whether only encoded public key or X.509 certificate listed in
+.Cm AutorizedKeysFile
+can allow self-signed X.509 certificate to be used for user authentication.
+The default is
+.Dq no .
+Unsupported if deamon is build without
+.Dq X509 store .
+.Pp
+A certificate (including self-signed) is accepted for user authentication
+if encoded public key or encoded X.509 certificate or distinguished name
+is listed in
+.Cm AutorizedKeysFile ,
+if is valid and if is verified by certificates from
+.Dq X509 store .
+See
+.Xr verify 1 .
+If option is set to
+.Dq yes
+self-signed certificate is accepted when its public key
+match public key extracted from entry in
+.Cm AutorizedKeysFile .
+In this case validity of certificate is not checked.
+.It Cm KeyRegenerationInterval
+In protocol version 1, the ephemeral server key is automatically regenerated
+after this many seconds (if it has been used).
+The purpose of regeneration is to prevent
+decrypting captured sessions by later breaking into the machine and
+stealing the keys.
+The key is never stored anywhere.
+If the value is 0, the key is never regenerated.
+The default is 3600 (seconds).
 .It Cm ListenAddress
 Specifies the local addresses
 .Xr sshd 8
@@ -1006,6 +1143,15 @@
 .Pp
 The list of available MAC algorithms may also be obtained using
 .Qq ssh -Q mac .
+.It Cm MandatoryCRL
+.Dq X509 store
+option:
+Specifies whether CRL must present in store for all certificates in
+.Dq certificate chain
+with atribute
+.Dq X509v3 CRL Distribution Points .
+The default is
+.Cm no .
 .It Cm Match
 Introduces a conditional block.
 If all of the criteria on the
@@ -1075,6 +1221,7 @@
 .Cm GatewayPorts ,
 .Cm GSSAPIAuthentication ,
 .Cm HostbasedAcceptedKeyTypes ,
+.Cm HostbasedAlgorithms ,
 .Cm HostbasedAuthentication ,
 .Cm HostbasedUsesNameFromPacketOnly ,
 .Cm IPQoS ,
@@ -1090,9 +1237,12 @@
 .Cm PermitTunnel ,
 .Cm PermitUserRC ,
 .Cm PubkeyAcceptedKeyTypes ,
+.Cm PubkeyAlgorithms ,
 .Cm PubkeyAuthentication ,
 .Cm RekeyLimit ,
 .Cm RevokedKeys ,
+.Cm RhostsRSAAuthentication ,
+.Cm RSAAuthentication ,
 .Cm StreamLocalBindMask ,
 .Cm StreamLocalBindUnlink ,
 .Cm TrustedUserCAKeys ,
@@ -1289,29 +1439,50 @@
 or equivalent.)
 The default is
 .Cm yes .
+.It Cm Protocol
+Specifies the protocol versions
+.Xr sshd 8
+supports.
+The possible values are
+.Sq 1
+and
+.Sq 2 .
+Multiple versions must be comma-separated.
+The default is
+.Sq 2 .
+Protocol 1 suffers from a number of cryptographic weaknesses and should
+not be used.
+It is only offered to support legacy devices.
+.Pp
+Note that the order of the protocol list does not indicate preference,
+because the client selects among multiple protocol versions offered
+by the server.
+Specifying
+.Cm 2,1
+is identical to
+.Cm 1,2 .
 .It Cm PubkeyAcceptedKeyTypes
-Specifies the key types that will be accepted for public key authentication
-as a comma-separated pattern list.
-Alternately if the specified value begins with a
-.Sq +
-character, then the specified key types will be appended to the default set
-instead of replacing them.
-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,
-ssh-rsa-cert-v01@openssh.com,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-ssh-ed25519,ssh-rsa
-.Ed
+Option compatibility. See
+.Cm PubkeyAlgorithms
 .Pp
-The list of available key types may also be obtained using
+.It Cm PubkeyAlgorithms
+Specifies the protocol version 2 algorithms that will be accepted for
+.Dq publickey
+authentication as a comma-separated pattern list.
+See PATTERNS in
+.Xr ssh_config 5
+for more information on patterns.
+The default
+.Cm *
+will allow all algorithms.
+Also algorithms has to be accepted by patterns of option
+.Cm AcceptedAlgorithms .
+Note algorithms that use X.509 certificates depend from
+.Cm X509KeyAlgorithm
+and is enough patter to match one of names set in
+.Cm X509KeyAlgorithm
+for a certain key-type to enable all from that key-type.
+The list of available key algorithms may also be obtained using
 .Qq ssh -Q key .
 .It Cm PubkeyAuthentication
 Specifies whether public key authentication is allowed.
@@ -1354,6 +1525,20 @@
 .Xr ssh-keygen 1 .
 For more information on KRLs, see the KEY REVOCATION LISTS section in
 .Xr ssh-keygen 1 .
+.It Cm RhostsRSAAuthentication
+Specifies whether rhosts or /etc/hosts.equiv authentication together
+with successful RSA host authentication is allowed.
+The default is
+.Cm no .
+This option applies to protocol version 1 only.
+.It Cm RSAAuthentication
+Specifies whether pure RSA authentication is allowed.
+The default is
+.Cm yes .
+This option applies to protocol version 1 only.
+.It Cm ServerKeyBits
+Defines the number of bits in the ephemeral protocol version 1 server key.
+The default and minimum value is 1024.
 .It Cm StreamLocalBindMask
 Sets the octal file creation mode mask
 .Pq umask
@@ -1494,6 +1679,73 @@
 as a non-root user.
 The default is
 .Cm no .
+.It Cm UsePrivilegeSeparation
+Specifies whether
+.Xr sshd 8
+separates privileges by creating an unprivileged child process
+to deal with incoming network traffic.
+After successful authentication, another process will be created that has
+the privilege of the authenticated user.
+The goal of privilege separation is to prevent privilege
+escalation by containing any corruption within the unprivileged processes.
+The argument must be
+.Cm yes ,
+.Cm no ,
+or
+.Cm sandbox .
+If
+.Cm UsePrivilegeSeparation
+is set to
+.Cm sandbox
+then the pre-authentication unprivileged process is subject to additional
+restrictions.
+The default is
+.Cm sandbox .
+.It Cm VACertificateFile
+File with X.509 certificates in PEM format concatenated together.
+In use when
+.Cm VAType
+is set to
+.Cm ocspspec .
+The default value is
+.Sq
+..
+(empty).
+Certificates from that file explicitly trust
+.Sq "OCSP Responder"
+public key.
+They are used as trusted certificates in addition to certificates from
+.Cm CACertificateFile
+and
+.Cm CACertificatePath
+to verify responder certificate.
+.It Cm VAType
+Specifies whether
+.Sq "Online Certificate Status Protocol"
+(OCSP) is used to validate X.509 certificates.
+Accepted values are case insensitive:
+.Bl -tag -offset indent -compact
+.It none
+do not use OCSP to validate certificates;
+.It ocspcert
+validate only certificates that specify
+.Sq "OCSP Service Locator"
+URL;
+.It ocspspec
+use specified in the configuration
+.Sq "OCSP Responder"
+to validate all certificates.
+.El
+The default is
+.Cm none .
+.It Cm VAOCSPResponderURL
+.Sq "Access Location"
+/
+.Sq "OCSP Service Locator"
+URL of the OCSP provider. In use when
+.Cm VAType
+is set to
+.Cm ocspspec .
 .It Cm VersionAddendum
 Optionally specifies additional text to append to the SSH protocol banner
 sent by the server upon connection.
@@ -1561,6 +1813,83 @@
 .Cm no .
 The default is
 .Cm yes .
+.It Cm X509KeyAlgorithm
+Specifies how X.509 certificates and signatures are used for protocol version 2.
+It is possible to have multiple algorithms
+in form specified in
+.Sx X509 Key Algorithms Format .
+Programs use the first listed for
+.Cm ECDSA ,
+.Cm RSA ,
+or
+.Cm DSA
+key in signing and
+accept all listed.
+.Pp
+The default for certificates with ECDSA keys is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp256 , Ar ssh-sha256 , Ar ecdsa-sha2-nistp256
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp384 , Ar ssh-sha384 , Ar ecdsa-sha2-nistp384
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ecdsa-sha2-nistp521 , Ar ssh-sha512 , Ar ecdsa-sha2-nistp521
+.Sm on
+.El
+.Pp
+The default for certificates with RSA key is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-rsa , Ar rsa-sha1
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-rsa , Ar rsa-md5
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ssh-rsa , Ar rsa-sha1 , Ar ssh-rsa
+.Sm on
+.El
+.Pp
+The default for certificates with DSA key is:
+.Bl -item -offset indent -compact
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-dss , Ar dss-asn1
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-sign-dss , Ar dss-raw
+.Sm on
+.It
+.Cm X509KeyAlgorithm
+.Sm off
+.Ar x509v3-ssh-dss , Ar dss-raw , Ar ssh-dss
+.Sm on
+.El
+.Pp
+Note for EC curves nistp256, nistp384, and nistp521 correspond
+.Xr crypto 3
+library curves prime256v1, secp384r1, and secp521r1.
+Support of EC curves depend from library version.
+See
+.Xr ecparam 1
+to find how to list curves supported by library.
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
@@ -1655,6 +1984,60 @@
 .Pp
 .Cm ChrootDirectory
 accepts the tokens %%, %h, and %u.
+.Sh X509 Key Algorithms Format
+.Nm sshd
+command-line arguments and configuration file options that specify
+.Sq X509 Key Algorithms
+expressed using a sequence of the form:
+.Sm off
+.Ar key-type-name , Ar digest-name
+.Op Ar \&, signature-identifier ,
+.Sm on
+where
+.Ar key-type-name
+is key type name,
+.Ar digest-name
+is
+.Bl -tag -compact -offset indent
+.It Cm rsa-sha1
+: RSA key and signature using the SHA-1 hash;
+.It Cm rsa-md5
+: RSA key and signature using the MD5 hash;
+.It Cm dss-asn1
+: DSA key and signature as specified in
+.Dq RFC 3279
+;
+.It Cm dss-raw
+: DSA key and signature in
+.Dq ssh-dss
+format as specified in
+.Dq RFC 4253 .
+.It Cm ssh-sha256
+.It Cm ssh-sha384
+.It Cm ssh-sha512
+: ECDSA key and signature as specified in
+.Dq RFC 6187 .
+.El
+and optional
+.Ar signature-identifier .
+When
+.Ar signature-identifier
+is omited
+.Ar key-type-name
+is used as identifier.
+.Pp
+For compatibility with old versions following signatures are suported:
+.Bl -tag -compact -offset indent
+.It Cm sha256
+.It Cm sha384
+.It Cm sha512
+: ECDSA key and signature encoded using ASN.1 notation.
+.El
+Server
+.Xr sshd 8
+and client
+.Xr ssh 1
+switch automatically to above signature if is detected old verson.
 .Sh FILES
 .Bl -tag -width Ds
 .It Pa /etc/ssh/sshd_config
@@ -1668,7 +2051,7 @@
 .Xr sshd 8
 .Sh AUTHORS
 .An -nosplit
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by
 .An Tatu Ylonen .
 .An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos ,
@@ -1683,3 +2066,5 @@
 and
 .An Markus Friedl
 contributed support for privilege separation.
+.An Roumen Petrov
+contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/ssh-dss.c openssh-7.5p1+x509-10.2/ssh-dss.c
--- openssh-7.5p1/ssh-dss.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-dss.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,8 @@
 /* $OpenBSD: ssh-dss.c,v 1.35 2016/04/21 06:08:02 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Dr. Stephen Henson.  All rights reserved.
+ * Copyright (c) 2011 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,16 +44,123 @@
 #include "digest.h"
 #define SSHKEY_INTERNAL
 #include "sshkey.h"
+#include "evp-compat.h"
+#include "xmalloc.h"
+#include "log.h"
 
 #define INTBLOB_LEN	20
 #define SIGBLOB_LEN	(2*INTBLOB_LEN)
 
+/*NOTE; Do not define USE_LEGACY_DSS_... if build
+  is with FIPS capable OpenSSL */
+/* Define if you want yo use legacy sign code */
+#undef USE_LEGACY_DSS_SIGN
+/* Define if you want yo use legacy verify code */
+#undef USE_LEGACY_DSS_VERIFY
+
+
+#ifndef USE_LEGACY_DSS_SIGN
+/* caller must free result */
+static DSA_SIG*
+ssh_DSA_sign(DSA *dsa, const u_char *data, u_int datalen)
+{
+	DSA_SIG *sig = NULL;
+
+	EVP_PKEY *pkey = NULL;
+	u_char *tsig = NULL;
+	u_int slen, len;
+	int ret;
+
+	pkey = EVP_PKEY_new();
+	if (pkey == NULL) {
+		error("%s: out of memory", __func__);
+		goto done;
+	}
+
+	EVP_PKEY_set1_DSA(pkey, dsa);
+
+	slen = EVP_PKEY_size(pkey);
+	tsig = xmalloc(slen);	/*fatal on error*/
+
+{
+	EVP_MD_CTX *md;
+
+	md = EVP_MD_CTX_new();
+	if (md == NULL) {
+		ret = -1;
+		error("%s: out of memory", __func__);
+		goto clean;
+	}
+
+	ret = EVP_SignInit_ex(md, EVP_dss1(), NULL);
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_SignInit_ex fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ret = EVP_SignUpdate(md, data, datalen);
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_SignUpdate fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ret = EVP_SignFinal(md, tsig, &len, pkey);
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: sign failed: %.*s"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+clean:
+	EVP_MD_CTX_free(md);
+}
+
+	if (ret > 0) {
+		/* decode DSA signature */
+		const u_char *psig = tsig;
+		sig = d2i_DSA_SIG(NULL, &psig, len);
+	}
+
+done:
+	if (tsig != NULL) {
+		/* clean up */
+		memset(tsig, 'd', slen);
+		free(tsig);
+	}
+
+	if (pkey != NULL) EVP_PKEY_free(pkey);
+
+	return sig;
+}
+#endif /* ndef USE_LEGACY_DSS_SIGN */
+
+
 int
 ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen, u_int compat)
 {
 	DSA_SIG *sig = NULL;
-	u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
+#ifdef USE_LEGACY_DSS_SIGN
+	u_char digest[SSH_DIGEST_MAX_LENGTH];
+#endif /*def USE_LEGACY_DSS_SIGN*/
+	u_char sigblob[SIGBLOB_LEN];
 	size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 	struct sshbuf *b = NULL;
 	int ret = SSH_ERR_INVALID_ARGUMENT;
@@ -67,24 +176,33 @@
 	if (dlen == 0)
 		return SSH_ERR_INTERNAL_ERROR;
 
+#ifdef USE_LEGACY_DSS_SIGN
 	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
 	    digest, sizeof(digest))) != 0)
 		goto out;
 
-	if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
+	sig = DSA_do_sign(digest, dlen, key->dsa);
+#else
+	sig = ssh_DSA_sign(key->dsa, data, datalen);
+#endif
+	if (sig == NULL) {
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
 
-	rlen = BN_num_bytes(sig->r);
-	slen = BN_num_bytes(sig->s);
+{	const BIGNUM *ps, *pr;
+	DSA_SIG_get0(sig, &pr, &ps);
+
+	rlen = BN_num_bytes(pr);
+	slen = BN_num_bytes(ps);
 	if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
 		ret = SSH_ERR_INTERNAL_ERROR;
 		goto out;
 	}
 	explicit_bzero(sigblob, SIGBLOB_LEN);
-	BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
-	BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
+	BN_bn2bin(pr, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
+	BN_bn2bin(ps, sigblob + SIGBLOB_LEN - slen);
+}
 
 	if (compat & SSH_BUG_SIGBLOB) {
 		if (sigp != NULL) {
@@ -119,20 +237,117 @@
 		ret = 0;
 	}
  out:
+#ifdef USE_LEGACY_DSS_SIGN
 	explicit_bzero(digest, sizeof(digest));
+#endif
 	if (sig != NULL)
 		DSA_SIG_free(sig);
 	sshbuf_free(b);
 	return ret;
 }
 
+
+#ifndef USE_LEGACY_DSS_VERIFY
+static int
+ssh_DSA_verify(DSA *dsa, DSA_SIG *sig, const u_char *data, u_int datalen)
+{
+	int ret = -1;
+	u_char *tsig = NULL;
+	u_int len;
+	EVP_PKEY *pkey = NULL;
+
+	/* Sig is in DSA_SIG structure, convert to encoded buffer */
+
+	len = i2d_DSA_SIG(sig, NULL);
+	tsig = xmalloc(len);	/*fatal on error*/
+
+	{ /* encode a DSA signature */
+		u_char *psig = tsig;
+		i2d_DSA_SIG(sig, &psig);
+	}
+
+	pkey = EVP_PKEY_new();
+	if (pkey == NULL) {
+		error("%s: out of memory", __func__);
+		goto done;
+	}
+	EVP_PKEY_set1_DSA(pkey, dsa);
+
+{ /* now verify signature */
+	EVP_MD_CTX *md;
+
+	md = EVP_MD_CTX_new();
+	if (md == NULL) {
+		ret = -1;
+		error("%s: out of memory", __func__);
+		goto clean;
+	}
+
+	ret = EVP_VerifyInit(md, EVP_dss1());
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyInit fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ret = EVP_VerifyUpdate(md, data, datalen);
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyUpdate fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ret = EVP_VerifyFinal(md, tsig, len, pkey);
+	if (ret <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyFinal fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+clean:
+	EVP_MD_CTX_free(md);
+}
+
+done:
+	if (pkey != NULL) EVP_PKEY_free(pkey);
+
+	if (tsig != NULL) {
+		/* clean up */
+		memset(tsig, 'd', len);
+		free(tsig);
+	}
+
+	return ret <= 0
+		? SSH_ERR_LIBCRYPTO_ERROR
+		: SSH_ERR_SUCCESS;
+}
+#endif /*ndef USE_LEGACY_DSS_VERIFY*/
+
+
 int
 ssh_dss_verify(const struct sshkey *key,
     const u_char *signature, size_t signaturelen,
     const u_char *data, size_t datalen, u_int compat)
 {
 	DSA_SIG *sig = NULL;
-	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
+#ifdef USE_LEGACY_DSS_VERIFY
+	u_char digest[SSH_DIGEST_MAX_LENGTH];
+#endif
+	u_char *sigblob = NULL;
 	size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 	int ret = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *b = NULL;
@@ -175,19 +390,35 @@
 		goto out;
 	}
 
-	/* parse signature */
-	if ((sig = DSA_SIG_new()) == NULL ||
-	    (sig->r = BN_new()) == NULL ||
-	    (sig->s = BN_new()) == NULL) {
+{	/* parse signature */
+	BIGNUM *pr, *ps;
+
+	ret = 0;
+	pr = BN_bin2bn(sigblob, INTBLOB_LEN, NULL);
+	ps = BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, NULL);
+	if ((pr == NULL) || (ps == NULL)) {
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+		goto parse_out;
+	}
+
+	sig = DSA_SIG_new();
+	if (sig == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
-		goto out;
+		goto parse_out;
 	}
-	if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
-	    (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
+
+	if (!DSA_SIG_set0(sig, pr, ps))
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
+
+parse_out:
+	if (ret != 0) {
+		BN_free(pr);
+		BN_free(ps);
 		goto out;
 	}
+}
 
+#ifdef USE_LEGACY_DSS_VERIFY
 	/* sha1 the data */
 	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
 	    digest, sizeof(digest))) != 0)
@@ -204,9 +435,14 @@
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
+#else
+	ret = ssh_DSA_verify(key->dsa, sig, data, datalen);
+#endif
 
  out:
+#ifdef USE_LEGACY_DSS_VERIFY
 	explicit_bzero(digest, sizeof(digest));
+#endif
 	if (sig != NULL)
 		DSA_SIG_free(sig);
 	sshbuf_free(b);
diff -ruN openssh-7.5p1/ssh-ecdsa.c openssh-7.5p1+x509-10.2/ssh-ecdsa.c
--- openssh-7.5p1/ssh-ecdsa.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-ecdsa.c	2017-05-20 21:07:01.000000000 +0300
@@ -34,6 +34,7 @@
 #include <openssl/ec.h>
 #include <openssl/ecdsa.h>
 #include <openssl/evp.h>
+#include "evp-compat.h"
 
 #include <string.h>
 
@@ -80,9 +81,13 @@
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
-	if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
-	    (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
+{
+	const BIGNUM *pr, *ps;
+	ECDSA_SIG_get0(sig, &pr, &ps);
+	if ((ret = sshbuf_put_bignum2(bb, pr)) != 0 ||
+	    (ret = sshbuf_put_bignum2(bb, ps)) != 0)
 		goto out;
+}
 	if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
 	    (ret = sshbuf_put_stringb(b, bb)) != 0)
 		goto out;
@@ -146,16 +151,39 @@
 		goto out;
 	}
 
-	/* parse signature */
-	if ((sig = ECDSA_SIG_new()) == NULL) {
+{	/* parse signature */
+	BIGNUM *pr, *ps;
+
+	ret = 0;
+	pr = BN_new();
+	ps = BN_new();
+	if ((pr == NULL) || (ps == NULL)) {
 		ret = SSH_ERR_ALLOC_FAIL;
-		goto out;
+		goto parse_out;
 	}
-	if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
-	    sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
+
+	if (sshbuf_get_bignum2(sigbuf, pr) != 0 ||
+	    sshbuf_get_bignum2(sigbuf, ps) != 0) {
 		ret = SSH_ERR_INVALID_FORMAT;
+		goto parse_out;
+	}
+
+	if ((sig = ECDSA_SIG_new()) == NULL) {
+		ret = SSH_ERR_ALLOC_FAIL;
+		goto parse_out;
+	}
+
+	if (!ECDSA_SIG_set0(sig, pr, ps))
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+
+parse_out:
+	if (ret != 0) {
+		BN_free(pr);
+		BN_free(ps);
 		goto out;
 	}
+}
+
 	if (sshbuf_len(sigbuf) != 0) {
 		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 		goto out;
diff -ruN openssh-7.5p1/ssh_engine.0 openssh-7.5p1+x509-10.2/ssh_engine.0
--- openssh-7.5p1/ssh_engine.0	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_engine.0	2017-05-20 21:07:00.000000000 +0300
@@ -0,0 +1,64 @@
+SSH_ENGINE(5)               BSD File Formats Manual              SSH_ENGINE(5)
+
+NAME
+     ssh_engine -- SecSH engine configuration file
+
+SYNOPSIS
+     ~/.ssh/engine
+
+DESCRIPTION
+     ssh(1) obtains additional openssl(1) engine post initialization configu-
+     ration from the following source:
+
+           1.   user's configuration file (~/.ssh/engine)
+
+     The configuration files contain sections separated by ``Engine'' specifi-
+     cation, and each section is applied only for engine that match name given
+     in specification.  Each engine command is executed immediately after
+     parsing of line.
+
+     The configuration file has the following format:
+
+     Empty lines and lines starting with '#' are comments.  Otherwise a line
+     is of the format ``command argument''.  Commands may be separated by
+     whitespace or optional whitespace and exactly one '='.  Argument may
+     optionally be enclosed in double quotes (") in order to represent command
+     argument containing spaces.
+
+     Engine  Restricts the following declarations (up to the next Engine key-
+             word) to be only for engine that match name given after the key-
+             word
+
+     [Command]
+             Specific to engine 'control commands'.  Use openssl(1) engine -vv
+             command to list supported control commands with desctription.
+
+FILES
+     ~/.ssh/engine
+             This is the per-user openssl(1) engine configuration file.  The
+             format of this file is described above.  This file is used by the
+             SSH client.  Because of the potential for abuse, this file must
+             have strict permissions: read/write for the user, and not acces-
+             sible by others.
+
+EXAMPLES
+     An example SecSH engine configuration file:
+
+        # Comments allowed at start of line
+        Engine e_nss
+        CONFIG_DIR /home/sample/.mozilla/firefox/xxxxxxxx.default/
+        # Above command specifies the NSS config directory.
+        # Refer to mozilla.org documentation how to find you profile directoty.
+
+SEE ALSO
+     ssh(1)
+
+AUTHORS
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
+     Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
+
+BSD                             August 15, 2011                            BSD
diff -ruN openssh-7.5p1/ssh_engine.5 openssh-7.5p1+x509-10.2/ssh_engine.5
--- openssh-7.5p1/ssh_engine.5	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh_engine.5	2017-05-20 21:07:00.000000000 +0300
@@ -0,0 +1,120 @@
+.\"
+.\" Author: Roumen Petrov
+.\" Copyright (c) 2011-2017 Roumen Petrov, Sofia, Bulgaria
+.\"                    All rights reserved
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
+.Dd $Mdocdate: August 15 2011 $
+.Dt SSH_ENGINE 5
+.Os
+.Sh NAME
+.Nm ssh_engine
+.Nd SecSH engine configuration file
+.Sh SYNOPSIS
+.Nm ~/.ssh/engine
+.Sh DESCRIPTION
+.Xr ssh 1
+obtains additional
+.Xr openssl 1
+engine post initialization configuration from
+the following source:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+user's configuration file
+.Pq Pa ~/.ssh/engine
+.El
+.Pp
+The configuration files contain sections separated by
+.Dq Engine
+specification, and each section is applied only for
+engine that match name given in specification.
+Each engine command is executed immediately after
+parsing of line.
+.Pp
+The configuration file has the following format:
+.Pp
+Empty lines and lines starting with
+.Ql #
+are comments.
+Otherwise a line is of the format
+.Dq command argument .
+Commands may be separated by whitespace or
+optional whitespace and exactly one
+.Ql = .
+Argument may optionally be enclosed in double quotes
+.Pq \&"
+in order to represent command argument containing spaces.
+.Pp
+.Bl -tag -width Ds
+.It Cm Engine
+Restricts the following declarations (up to the next
+.Cm Engine
+keyword) to be only for engine that match name given after the keyword
+.It Cm [Command]
+Specific to engine
+.Sq control commands .
+Use
+.Xr openssl 1
+.Va engine -vv
+command to list supported control commands with desctription.
+.El
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa ~/.ssh/engine
+This is the per-user
+.Xr openssl 1
+engine configuration file.
+The format of this file is described above.
+This file is used by the SSH client.
+Because of the potential for abuse, this file must have strict permissions:
+read/write for the user, and not accessible by others.
+.El
+.Sh EXAMPLES
+An example SecSH engine configuration file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+Engine e_nss
+CONFIG_DIR /home/sample/.mozilla/firefox/xxxxxxxx.default/
+# Above command specifies the NSS config directory.
+# Refer to mozilla.org documentation how to find you profile directoty.
+.Ed
+.Sh SEE ALSO
+.Xr ssh 1
+.Sh AUTHORS
+PKIX-SSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
+Roumen Petrov contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/sshkey.c openssh-7.5p1+x509-10.2/sshkey.c
--- openssh-7.5p1/sshkey.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshkey.c	2017-05-20 21:07:01.000000000 +0300
@@ -3,6 +3,8 @@
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
  * Copyright (c) 2010,2011 Damien Miller.  All rights reserved.
+ * X509 certificate support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +36,7 @@
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
+#include "evp-compat.h"
 #endif
 
 #include "crypto_api.h"
@@ -52,11 +55,15 @@
 #include "misc.h"
 #include "sshbuf.h"
 #include "rsa.h"
+#include "xmalloc.h"
 #include "cipher.h"
 #include "digest.h"
 #define SSHKEY_INTERNAL
 #include "sshkey.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "match.h"
+#include "log.h"
 
 /* openssh private key file format */
 #define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
@@ -93,8 +100,10 @@
 	{ NULL, "RSA1", KEY_RSA1, 0, 0, 0 },
 # endif
 	{ "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
+#ifdef HAVE_EVP_SHA256
 	{ "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
 	{ "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
+#endif /*def HAVE_EVP_SHA256*/
 	{ "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 },
 # ifdef OPENSSL_HAS_ECC
 	{ "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
@@ -124,6 +133,19 @@
 {
 	const struct keytype *kt;
 
+	if (key_is_x509(k)) {
+		switch (key_type_plain(k->type)) {
+		case KEY_RSA:
+			return k->rsa ? "RSA+cert" : "X509(rsa)";
+		case KEY_ECDSA:
+			return k->ecdsa ? "ECDSA+cert" : "X509(ecdsa)";
+		case KEY_DSA:
+			return k->dsa ? "DSA+cert" : "X509(dsa)";
+		default:
+			break;
+		}
+	}
+
 	for (kt = keytypes; kt->type != -1; kt++) {
 		if (kt->type == k->type)
 			return kt->shortname;
@@ -137,6 +159,7 @@
 	const struct keytype *kt;
 
 	for (kt = keytypes; kt->type != -1; kt++) {
+		if (!kt->name) continue; /* restore to openssh up to 6.2p2 */
 		if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
 			return kt->name;
 	}
@@ -158,6 +181,11 @@
 const char *
 sshkey_ssh_name(const struct sshkey *k)
 {
+	const char* p;
+
+	p = ssh_x509key_name(k);
+	if (p) return(p);
+
 	return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
 }
 
@@ -172,6 +200,10 @@
 sshkey_type_from_name(const char *name)
 {
 	const struct keytype *kt;
+	int k;
+
+	k = ssh_x509key_type(name);
+	if (k != KEY_UNSPEC) return(k);
 
 	for (kt = keytypes; kt->type != -1; kt++) {
 		/* Only allow shortname matches for plain key types */
@@ -182,11 +214,41 @@
 	return KEY_UNSPEC;
 }
 
+void
+sshkey_types_from_name(const char *name, int *type, int *subtype) {
+
+	if (type == NULL || subtype == NULL) {
+		fatal("%s: NULL arguments", __func__);
+		return; /* unreachible code */
+	}
+
+	if (strncmp(name, "x509v3-ecdsa-", 13) == 0) {
+		int plain_type;
+		sshkey_types_from_name(name+7, &plain_type, subtype);
+		/* NOTE order of key "enum types" is important as
+		 * after KEY_<FOO> is defined KEY_X509_<FOO>
+		 */
+		*type = plain_type + 1;
+		return;
+	}
+
+	*type = sshkey_type_from_name((char*)name);
+
+	if (*type == KEY_ECDSA || *type == KEY_ECDSA_CERT)
+		*subtype = sshkey_ecdsa_nid_from_name(name);
+	else
+		*subtype = -1;
+}
+
 int
 sshkey_ecdsa_nid_from_name(const char *name)
 {
 	const struct keytype *kt;
 
+	if (strncmp(name, "x509v3-ecdsa-", 13) == 0) {
+		return sshkey_ecdsa_nid_from_name(name+7);
+	}
+
 	for (kt = keytypes; kt->type != -1; kt++) {
 		if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
 			continue;
@@ -203,6 +265,19 @@
 	size_t nlen, rlen = 0;
 	const struct keytype *kt;
 
+	if (!certs_only || !plain_only) {
+		Buffer b;
+
+		fill_default_xkalg();
+		buffer_init(&b);
+	{	char sep_s[2] = { sep, '\0' };
+		ssh_xkalg_listall(&b, sep_s);
+	}
+		ret = xstrdup(buffer_ptr(&b));
+		rlen = buffer_len(&b);
+		buffer_free(&b);
+	}
+
 	for (kt = keytypes; kt->type != -1; kt++) {
 		if (kt->name == NULL)
 			continue;
@@ -225,6 +300,27 @@
 }
 
 int
+sshkey_ind_alg(const char **name, int loc) {
+	int k, n;
+	const struct keytype *p;
+
+	k = (loc < 0) ? 0 : (loc + 1);
+	n = sizeof(keytypes) / sizeof(keytypes[0]);
+	if (k < n) p = &keytypes[k];
+
+	for (; k < n; k++, p++) {
+		if (p->name == NULL) continue;
+		if (p->cert)	continue;
+
+		if (name != NULL)
+			*name = p->name;
+
+		return k;
+	}
+	return -1;
+}
+
+int
 sshkey_names_valid2(const char *names, int allow_wildcard)
 {
 	char *s, *cp, *p;
@@ -249,11 +345,26 @@
 				 * If any has a positive or negative match then
 				 * the component is accepted.
 				 */
+				{
+					const SSHX509KeyAlgs *xkalg;
+					int loc;
+					for (
+					    loc = ssh_xkalg_ind(&xkalg, -1);
+					    loc >= 0;
+					    loc = ssh_xkalg_ind(&xkalg, loc)
+					) {
+						if (match_pattern_list(xkalg->name,
+						    p, 0) == 1)
+							break;
+					}
+					if (loc >= 0)
+						break;
+				}
 				for (kt = keytypes; kt->type != -1; kt++) {
 					if (kt->type == KEY_RSA1)
 						continue;
 					if (match_pattern_list(kt->name,
-					    p, 0) != 0)
+					    p, 0) == 1)
 						break;
 				}
 				if (kt->type != -1)
@@ -270,15 +381,26 @@
 u_int
 sshkey_size(const struct sshkey *k)
 {
+	if (key_is_x509(k))
+		return ssh_x509_key_size(k);
+
 	switch (k->type) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT:
-		return BN_num_bits(k->rsa->n);
+		{
+		const BIGNUM *n = NULL;
+		RSA_get0_key(k->rsa, &n, NULL, NULL);
+		return BN_num_bits(n);
+		}
 	case KEY_DSA:
 	case KEY_DSA_CERT:
-		return BN_num_bits(k->dsa->p);
+		{
+		const BIGNUM *p = NULL;
+		DSA_get0_pqg(k->dsa, &p, NULL, NULL);
+		return BN_num_bits(p);
+		}
 	case KEY_ECDSA:
 	case KEY_ECDSA_CERT:
 		return sshkey_curve_nid_to_bits(k->ecdsa_nid);
@@ -313,14 +435,18 @@
 }
 
 /* Return the cert-less equivalent to a certified key type */
+/* Also for X.509 certificate return base key type */
 int
 sshkey_type_plain(int type)
 {
 	switch (type) {
+	case KEY_X509_RSA:
 	case KEY_RSA_CERT:
 		return KEY_RSA;
+	case KEY_X509_DSA:
 	case KEY_DSA_CERT:
 		return KEY_DSA;
+	case KEY_X509_ECDSA:
 	case KEY_ECDSA_CERT:
 		return KEY_ECDSA;
 	case KEY_ED25519_CERT:
@@ -331,6 +457,7 @@
 }
 
 #ifdef WITH_OPENSSL
+#ifdef OPENSSL_HAS_ECC
 /* XXX: these are really begging for a table-driven approach */
 int
 sshkey_curve_name_to_nid(const char *name)
@@ -414,6 +541,14 @@
 	else
 		return SSH_DIGEST_SHA512;
 }
+
+#else /*ndef OPENSSL_HAS_ECC*/
+
+int   sshkey_curve_name_to_nid(const char *name)	{ (void)name;	return -1; }
+u_int sshkey_curve_nid_to_bits(int nid)			{ (void)nid;	return  0; }
+int   sshkey_ecdsa_bits_to_nid(int bits)		{ (void)bits;	return -1; }
+
+#endif /*ndef OPENSSL_HAS_ECC*/
 #endif /* WITH_OPENSSL */
 
 static void
@@ -470,35 +605,62 @@
 	k->ecdsa_nid = -1;
 	k->dsa = NULL;
 	k->rsa = NULL;
+	k->x509_data = NULL;
 	k->cert = NULL;
 	k->ed25519_sk = NULL;
 	k->ed25519_pk = NULL;
-	switch (k->type) {
+	switch (X509KEY_BASETYPE(k)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT:
+		{
+		BIGNUM *n = NULL, *e = NULL;
+
 		if ((rsa = RSA_new()) == NULL ||
-		    (rsa->n = BN_new()) == NULL ||
-		    (rsa->e = BN_new()) == NULL) {
+		    (n = BN_new()) == NULL ||
+		    (e = BN_new()) == NULL ||
+		    !RSA_set0_key(rsa, n, e, NULL)
+		) {
+			BN_free(n);
+			BN_free(e);
 			if (rsa != NULL)
 				RSA_free(rsa);
 			free(k);
 			return NULL;
 		}
 		k->rsa = rsa;
+		}
 		break;
 	case KEY_DSA:
 	case KEY_DSA_CERT:
-		if ((dsa = DSA_new()) == NULL ||
-		    (dsa->p = BN_new()) == NULL ||
-		    (dsa->q = BN_new()) == NULL ||
-		    (dsa->g = BN_new()) == NULL ||
-		    (dsa->pub_key = BN_new()) == NULL) {
-			if (dsa != NULL)
+		{	BIGNUM *p = NULL, *q = NULL, *g = NULL;
+
+			if ((dsa = DSA_new()) == NULL ||
+			    (p = BN_new()) == NULL ||
+			    (q = BN_new()) == NULL ||
+			    (g = BN_new()) == NULL ||
+			    !DSA_set0_pqg(dsa, p, q, g)
+			) {
+				BN_free(p);
+				BN_free(q);
+				BN_free(g);
+				if (dsa != NULL)
+					DSA_free(dsa);
+				free(k);
+				return NULL;
+			}
+		}
+		{	BIGNUM *pub_key = NULL;
+
+			if ((pub_key = BN_new()) == NULL ||
+			    !DSA_set0_key(dsa, pub_key, NULL)
+			) {
+				BN_free(pub_key);
 				DSA_free(dsa);
-			free(k);
-			return NULL;
+				free(k);
+				return NULL;
+			}
 		}
 		k->dsa = dsa;
 		break;
@@ -531,24 +693,56 @@
 int
 sshkey_add_private(struct sshkey *k)
 {
-	switch (k->type) {
+	switch (X509KEY_BASETYPE(k)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
 	case KEY_RSA_CERT:
 #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
-		if (bn_maybe_alloc_failed(k->rsa->d) ||
-		    bn_maybe_alloc_failed(k->rsa->iqmp) ||
-		    bn_maybe_alloc_failed(k->rsa->q) ||
-		    bn_maybe_alloc_failed(k->rsa->p) ||
-		    bn_maybe_alloc_failed(k->rsa->dmq1) ||
-		    bn_maybe_alloc_failed(k->rsa->dmp1))
-			return SSH_ERR_ALLOC_FAIL;
+		{	BIGNUM *d = NULL;
+
+			if (bn_maybe_alloc_failed(d) ||
+			    !RSA_set0_key(k->rsa, NULL, NULL, d)
+			) {
+				BN_free(d);
+				return SSH_ERR_ALLOC_FAIL;
+			}
+		}
+		{	BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
+
+			if (bn_maybe_alloc_failed(dmp1) ||
+			    bn_maybe_alloc_failed(dmq1) ||
+			    bn_maybe_alloc_failed(iqmp) ||
+			    !RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp)
+			) {
+				BN_free(dmp1);
+				BN_free(dmq1);
+				BN_free(iqmp);
+				return SSH_ERR_ALLOC_FAIL;
+			}
+		}
+		{	BIGNUM *p = NULL, *q = NULL;
+
+			if (bn_maybe_alloc_failed(p) ||
+			    bn_maybe_alloc_failed(q) ||
+			    !RSA_set0_factors(k->rsa, p, q)
+			) {
+				BN_free(p);
+				BN_free(q);
+				return SSH_ERR_ALLOC_FAIL;
+			}
+		}
 		break;
 	case KEY_DSA:
 	case KEY_DSA_CERT:
-		if (bn_maybe_alloc_failed(k->dsa->priv_key))
+		{
+		BIGNUM *priv_key = NULL;
+
+		if (bn_maybe_alloc_failed(priv_key) ||
+		    !DSA_set0_key(k->dsa, NULL, priv_key)
+		)
 			return SSH_ERR_ALLOC_FAIL;
+		}
 		break;
 #undef bn_maybe_alloc_failed
 	case KEY_ECDSA:
@@ -587,7 +781,7 @@
 {
 	if (k == NULL)
 		return;
-	switch (k->type) {
+	switch (X509KEY_BASETYPE(k)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
@@ -629,6 +823,10 @@
 	default:
 		break;
 	}
+	if (k->x509_data != NULL) {
+		SSH_X509_free(k->x509_data);
+		k->x509_data = NULL;
+	}
 	if (sshkey_is_cert(k))
 		cert_free(k->cert);
 	explicit_bzero(k, sizeof(*k));
@@ -650,6 +848,58 @@
 	return 1;
 }
 
+int
+sshrsa_equal_public(const RSA* a, const RSA* b) {
+	if (a == NULL || b == NULL)
+		return 0;
+
+{
+	const BIGNUM *a_n = NULL, *a_e = NULL;
+	const BIGNUM *b_n = NULL, *b_e = NULL;
+
+	RSA_get0_key(a, &a_n, &a_e, NULL);
+	RSA_get0_key(b, &b_n, &b_e, NULL);
+
+	if (BN_cmp(a_e, b_e) != 0 ||
+	    BN_cmp(a_n, b_n) != 0
+	)
+		return 0;
+}
+	return 1;
+}
+
+int
+sshdsa_equal_public(const DSA* a, const DSA* b) {
+	if (a == NULL || b == NULL)
+		return 0;
+
+{
+	const BIGNUM *a_p = NULL, *a_q = NULL, *a_g = NULL;
+	const BIGNUM *b_p = NULL, *b_q = NULL, *b_g = NULL;
+
+	DSA_get0_pqg(a, &a_p, &a_q, &a_g);
+	DSA_get0_pqg(b, &b_p, &b_q, &b_g);
+
+	if ((BN_cmp(a_p, b_p) != 0) ||
+	    (BN_cmp(a_q, b_q) != 0) ||
+	    (BN_cmp(a_g, b_g) != 0)
+	)
+		return 0;
+}
+{
+	const BIGNUM *a_pub_key = NULL;
+	const BIGNUM *b_pub_key = NULL;
+
+	DSA_get0_key(a, &a_pub_key, NULL);
+	DSA_get0_key(b, &b_pub_key, NULL);
+
+	if (BN_cmp(a_pub_key, b_pub_key) != 0)
+		return 0;
+}
+
+	return 1;
+}
+
 /*
  * Compare public portions of key only, allowing comparisons between
  * certificates and plain keys too.
@@ -665,21 +915,24 @@
 	    sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
 		return 0;
 
-	switch (a->type) {
+	if (key_is_x509(a) && key_is_x509(b))
+		return ssh_x509_equal(a, b) == 0;
+/*
+#else
+  Either public key or X.509 certificate must present. In latter
+  case public key is extracted from X.509 certificate and stored
+  into 'key'(rsa,dsa,..) member of key structure.
+*/
+
+	switch (X509KEY_BASETYPE(a)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
-		return a->rsa != NULL && b->rsa != NULL &&
-		    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
-		    BN_cmp(a->rsa->n, b->rsa->n) == 0;
+		return sshrsa_equal_public(a->rsa, b->rsa);
 	case KEY_DSA_CERT:
 	case KEY_DSA:
-		return a->dsa != NULL && b->dsa != NULL &&
-		    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
-		    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
-		    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
-		    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
+		return sshdsa_equal_public(a->dsa, b->dsa);
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
 	case KEY_ECDSA:
@@ -723,6 +976,20 @@
 	return sshkey_equal_public(a, b);
 }
 
+int/*bool*/
+sshkey_match_pkalg(struct sshkey *key, const char* pkalg) {
+	int keytype, subtype;
+
+	if (key == NULL) return 0;
+	if (pkalg == NULL) return 0;
+
+	sshkey_types_from_name(pkalg, &keytype, &subtype);
+	return (
+	    (keytype == key->type) &&
+	    (subtype == key->ecdsa_nid)
+	);
+}
+
 static int
 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)
 {
@@ -732,6 +999,9 @@
 	if (key == NULL)
 		return SSH_ERR_INVALID_ARGUMENT;
 
+	if (key_is_x509(key))
+		return X509key_to_buf(key, b);
+
 	if (sshkey_is_cert(key)) {
 		if (key->cert == NULL)
 			return SSH_ERR_EXPECTED_CERT;
@@ -755,14 +1025,22 @@
 		break;
 #ifdef WITH_OPENSSL
 	case KEY_DSA:
+		{
+		const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
+
 		if (key->dsa == NULL)
 			return SSH_ERR_INVALID_ARGUMENT;
+
+		DSA_get0_pqg(key->dsa, &p, &q, &g);
+		DSA_get0_key(key->dsa, &pub_key, NULL);
+
 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
+		    (ret = sshbuf_put_bignum2(b, p)) != 0 ||
+		    (ret = sshbuf_put_bignum2(b, q)) != 0 ||
+		    (ret = sshbuf_put_bignum2(b, g)) != 0 ||
+		    (ret = sshbuf_put_bignum2(b, pub_key)) != 0)
 			return ret;
+		}
 		break;
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
@@ -776,12 +1054,19 @@
 		break;
 # endif
 	case KEY_RSA:
+		{
+		const BIGNUM *n = NULL, *e = NULL;
+
 		if (key->rsa == NULL)
 			return SSH_ERR_INVALID_ARGUMENT;
+
+		RSA_get0_key(key->rsa, &n, &e, NULL);
+
 		if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
-		    (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
+		    (ret = sshbuf_put_bignum2(b, e)) != 0 ||
+		    (ret = sshbuf_put_bignum2(b, n)) != 0)
 			return ret;
+		}
 		break;
 #endif /* WITH_OPENSSL */
 	case KEY_ED25519:
@@ -880,6 +1165,11 @@
 		*retp = NULL;
 	if (lenp != NULL)
 		*lenp = 0;
+#ifdef OPENSSL_FIPS
+	/* avoid digest like md5 if FIPS mode is activated */
+	if (ssh_digest_alg_name(dgst_alg) == NULL)
+		dgst_alg = SSH_DIGEST_SHA256;
+#endif
 	if (ssh_digest_bytes(dgst_alg) == 0) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
@@ -887,8 +1177,12 @@
 
 	if (k->type == KEY_RSA1) {
 #ifdef WITH_OPENSSL
-		int nlen = BN_num_bytes(k->rsa->n);
-		int elen = BN_num_bytes(k->rsa->e);
+		const BIGNUM *n = NULL, *e = NULL;
+
+		RSA_get0_key(k->rsa, &n, &e, NULL);
+		{
+		int nlen = BN_num_bytes(n);
+		int elen = BN_num_bytes(e);
 
 		if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) {
 			r = SSH_ERR_INVALID_FORMAT;
@@ -899,8 +1193,9 @@
 			r = SSH_ERR_ALLOC_FAIL;
 			goto out;
 		}
-		BN_bn2bin(k->rsa->n, blob);
-		BN_bn2bin(k->rsa->e, blob + nlen);
+		BN_bn2bin(n, blob);
+		BN_bn2bin(e, blob + nlen);
+		}
 #endif /* WITH_OPENSSL */
 	} else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)
 		goto out;
@@ -1118,8 +1413,7 @@
 	/* output upper border */
 	p = retval;
 	*p++ = '+';
-	for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
-		*p++ = '-';
+	i = 0;
 	memcpy(p, title, tlen);
 	p += tlen;
 	for (i += tlen; i < FLDSIZE_X; i++)
@@ -1138,12 +1432,17 @@
 
 	/* output lower border */
 	*p++ = '+';
-	for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
-		*p++ = '-';
+	i = 0;
 	memcpy(p, hash, hlen);
 	p += hlen;
 	for (i += hlen; i < FLDSIZE_X; i++)
 		*p++ = '-';
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		/* width is enought to write over text*/
+		strcpy(p - 6, "[FIPS]");
+	}
+#endif
 	*p++ = '+';
 
 	return retval;
@@ -1157,6 +1456,11 @@
 	u_char *dgst_raw;
 	size_t dgst_raw_len;
 
+#ifdef OPENSSL_FIPS
+	/* avoid digest like md5 if FIPS mode is activated */
+	if (ssh_digest_alg_name(dgst_alg) == NULL)
+		dgst_alg = SSH_DIGEST_SHA256;
+#endif
 	if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
 		return NULL;
 	switch (dgst_rep) {
@@ -1232,8 +1536,15 @@
 int
 sshkey_read(struct sshkey *ret, char **cpp)
 {
+    return sshkey_read_pkalg(ret, cpp, NULL);
+}
+
+int
+sshkey_read_pkalg(Key *ret, char **cpp, char **pkalg)
+{
 	struct sshkey *k;
 	int retval = SSH_ERR_INVALID_FORMAT;
+	char pkname[64];
 	char *ep, *cp, *space;
 	int r, type, curve_nid = -1;
 	struct sshbuf *blob;
@@ -1246,24 +1557,33 @@
 
 	cp = *cpp;
 
-	switch (ret->type) {
+	/* caller is responsible to free memory allocated for pkalg */
+	if (pkalg) {
+		*pkalg = NULL;
+	}
+
+	switch (X509KEY_BASETYPE(ret)) {
 	case KEY_RSA1:
 #ifdef WITH_SSH1
+		{
+		BIGNUM *n = NULL, *e = NULL;
 		/* Get number of bits. */
 		bits = strtoul(cp, &ep, 10);
 		if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL ||
 		    bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)
 			return SSH_ERR_INVALID_FORMAT;	/* Bad bit count... */
 		/* Get public exponent, public modulus. */
-		if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)
+		RSA_get0_key(ret->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
+		if ((r = read_decimal_bignum(&ep, e)) < 0)
 			return r;
-		if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)
+		if ((r = read_decimal_bignum(&ep, n)) < 0)
 			return r;
 		/* validate the claimed number of bits */
-		if (BN_num_bits(ret->rsa->n) != (int)bits)
+		if (BN_num_bits(n) != (int)bits)
 			return SSH_ERR_KEY_BITS_MISMATCH;
 		*cpp = ep;
 		retval = 0;
+		}
 #endif /* WITH_SSH1 */
 		break;
 	case KEY_UNSPEC:
@@ -1286,11 +1606,17 @@
 		*space = ' ';
 		if (type == KEY_UNSPEC)
 			return SSH_ERR_INVALID_FORMAT;
+		*space = '\0';
+		strcpy(pkname, cp);
+		*space = ' ';
 		cp = space+1;
 		if (*cp == '\0')
 			return SSH_ERR_INVALID_FORMAT;
 		if (ret->type != KEY_UNSPEC && ret->type != type)
 			return SSH_ERR_KEY_TYPE_MISMATCH;
+		k = X509key_from_subject(pkname, cp, &ep);
+		if(k != NULL)
+			goto noblob;
 		if ((blob = sshbuf_new()) == NULL)
 			return SSH_ERR_ALLOC_FAIL;
 		/* trim comment */
@@ -1322,6 +1648,7 @@
 			sshkey_free(k);
 			return SSH_ERR_EC_CURVE_MISMATCH;
 		}
+noblob:
 		ret->type = type;
 		if (sshkey_is_cert(ret)) {
 			if (!sshkey_is_cert(k)) {
@@ -1376,12 +1703,17 @@
 #endif
 			break;
 		}
+		/* Test with loaded key, as for X.509 certificates
+		   we consider keys as equivalent if base type match
+		 */
+		if (key_is_x509(k))
+			x509key_move_identity(k, ret);
+
 		*cpp = ep;
 		retval = 0;
-/*XXXX*/
+		if (pkalg)
+			*pkalg = xstrdup(pkname); /*fatal on error*/
 		sshkey_free(k);
-		if (retval != 0)
-			break;
 		break;
 	default:
 		return SSH_ERR_INVALID_ARGUMENT;
@@ -1425,19 +1757,20 @@
 #ifdef WITH_SSH1
 	u_int bits = 0;
 	char *dec_e = NULL, *dec_n = NULL;
+	const BIGNUM *n = NULL, *e = NULL;
 
-	if (key->rsa == NULL || key->rsa->e == NULL ||
-	    key->rsa->n == NULL) {
+	RSA_get0_key(key->rsa, &n, &e, NULL);
+	if (key->rsa == NULL || e == NULL || n == NULL) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
-	if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
-	    (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
+	if ((dec_e = BN_bn2dec(e)) == NULL ||
+	    (dec_n = BN_bn2dec(n)) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
 		goto out;
 	}
 	/* size of modulus 'n' */
-	if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
+	if ((bits = BN_num_bits(n)) <= 0) {
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
@@ -1485,6 +1818,11 @@
 	struct sshbuf *b = NULL;
 	int r = SSH_ERR_INTERNAL_ERROR;
 
+	if (sshkey_is_x509(key))
+		return x509key_write(key, f)
+		    ? SSH_ERR_SUCCESS
+		    : SSH_ERR_INTERNAL_ERROR;
+
 	if ((b = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 	if ((r = sshkey_format_text(key, b)) != 0)
@@ -1766,19 +2104,31 @@
 	int ret = SSH_ERR_INTERNAL_ERROR;
 
 	*pkp = NULL;
-	switch (k->type) {
+	switch(X509KEY_BASETYPE(k)) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA:
 	case KEY_DSA_CERT:
 		if ((n = sshkey_new(k->type)) == NULL)
 			return SSH_ERR_ALLOC_FAIL;
-		if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
-		    (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
-		    (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
-		    (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
+
+		{
+		const BIGNUM *k_p = NULL, *k_q = NULL, *k_g = NULL, *k_pub_key = NULL;
+		BIGNUM *n_p = NULL, *n_q = NULL, *n_g = NULL, *n_pub_key = NULL;
+
+		DSA_get0_pqg(k->dsa, &k_p, &k_q, &k_g);
+		DSA_get0_key(k->dsa, &k_pub_key, NULL);
+
+		DSA_get0_pqg(n->dsa, (const BIGNUM**)&n_p, (const BIGNUM**)&n_q, (const BIGNUM**)&n_g);
+		DSA_get0_key(n->dsa, (const BIGNUM**)&n_pub_key, NULL);
+
+		if ((BN_copy(n_p, k_p) == NULL) ||
+		    (BN_copy(n_q, k_q) == NULL) ||
+		    (BN_copy(n_g, k_g) == NULL) ||
+		    (BN_copy(n_pub_key, k_pub_key) == NULL)) {
 			sshkey_free(n);
 			return SSH_ERR_ALLOC_FAIL;
 		}
+		}
 		break;
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
@@ -1803,11 +2153,19 @@
 	case KEY_RSA_CERT:
 		if ((n = sshkey_new(k->type)) == NULL)
 			return SSH_ERR_ALLOC_FAIL;
-		if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
-		    (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
+		{
+		const BIGNUM *k_n = NULL, *k_e = NULL;
+		BIGNUM *n_n = NULL, *n_e = NULL;
+
+		RSA_get0_key(k->rsa, &k_n, &k_e, NULL);
+		RSA_get0_key(n->rsa, (const BIGNUM**)&n_n, (const BIGNUM**)&n_e, NULL);
+
+		if ((BN_copy(n_n, k_n) == NULL) ||
+		    (BN_copy(n_e, k_e) == NULL)) {
 			sshkey_free(n);
 			return SSH_ERR_ALLOC_FAIL;
 		}
+		}
 		break;
 #endif /* WITH_OPENSSL */
 	case KEY_ED25519:
@@ -1831,6 +2189,9 @@
 			return ret;
 		}
 	}
+
+	x509key_copy_identity(k, n);
+
 	*pkp = n;
 	return 0;
 }
@@ -1958,9 +2319,10 @@
 }
 
 static int
-sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
-    int allow_cert)
-{
+sshkey_parse_from_blob(
+	struct sshbuf *b, int allow_cert,
+	struct sshkey **keyp, char **pkalgp
+) {
 	int type, ret = SSH_ERR_INTERNAL_ERROR;
 	char *ktype = NULL, *curve = NULL;
 	struct sshkey *key = NULL;
@@ -1976,6 +2338,16 @@
 #endif
 	if (keyp != NULL)
 		*keyp = NULL;
+	if (pkalgp != NULL)
+		*pkalgp = NULL;
+
+	ret = X509key_from_buf(b, keyp);
+	if (ret != SSH_ERR_INVALID_FORMAT) {
+		if (pkalgp != NULL)
+			*pkalgp = xstrdup(sshkey_ssh_name(*keyp));
+		return ret;
+	}
+
 	if ((copy = sshbuf_fromb(b)) == NULL) {
 		ret = SSH_ERR_ALLOC_FAIL;
 		goto out;
@@ -1986,6 +2358,7 @@
 	}
 
 	type = sshkey_type_from_name(ktype);
+	debug3("key_from_blob(..., ...) ktype=%.30s", ktype);
 	if (!allow_cert && sshkey_type_is_cert(type)) {
 		ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
 		goto out;
@@ -2004,11 +2377,17 @@
 			ret = SSH_ERR_ALLOC_FAIL;
 			goto out;
 		}
-		if (sshbuf_get_bignum2(b, key->rsa->e) != 0 ||
-		    sshbuf_get_bignum2(b, key->rsa->n) != 0) {
+		{
+		BIGNUM *n = NULL, *e = NULL;
+
+		RSA_get0_key(key->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
+
+		if (sshbuf_get_bignum2(b, e) != 0 ||
+		    sshbuf_get_bignum2(b, n) != 0) {
 			ret = SSH_ERR_INVALID_FORMAT;
 			goto out;
 		}
+		}
 #ifdef DEBUG_PK
 		RSA_print_fp(stderr, key->rsa, 8);
 #endif
@@ -2025,13 +2404,21 @@
 			ret = SSH_ERR_ALLOC_FAIL;
 			goto out;
 		}
-		if (sshbuf_get_bignum2(b, key->dsa->p) != 0 ||
-		    sshbuf_get_bignum2(b, key->dsa->q) != 0 ||
-		    sshbuf_get_bignum2(b, key->dsa->g) != 0 ||
-		    sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) {
+		{
+		BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+		BIGNUM *dsa_pub_key = NULL;
+
+		DSA_get0_pqg(key->dsa, (const BIGNUM**)&dsa_p, (const BIGNUM**)&dsa_q, (const BIGNUM**)&dsa_g);
+		DSA_get0_key(key->dsa, (const BIGNUM**)&dsa_pub_key, NULL);
+
+		if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
+		    sshbuf_get_bignum2(b, dsa_q) != 0 ||
+		    sshbuf_get_bignum2(b, dsa_g) != 0 ||
+		    sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
 			ret = SSH_ERR_INVALID_FORMAT;
 			goto out;
 		}
+		}
 #ifdef DEBUG_PK
 		DSA_print_fp(stderr, key->dsa, 8);
 #endif
@@ -2050,6 +2437,7 @@
 			goto out;
 		}
 		key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);
+		debug3("key_from_blob(..., ...) ktype/nid=%.50s / %d", ktype, key->ecdsa_nid);
 		if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
 			ret = SSH_ERR_INVALID_FORMAT;
 			goto out;
@@ -2134,6 +2522,10 @@
 		*keyp = key;
 		key = NULL;
 	}
+	if (pkalgp != NULL) {
+		*pkalgp = ktype;
+		ktype = NULL;
+	}
  out:
 	sshbuf_free(copy);
 	sshkey_free(key);
@@ -2147,20 +2539,33 @@
 	return ret;
 }
 
+static int
+sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, int allow_cert) {
+	return sshkey_parse_from_blob(b, allow_cert, keyp, NULL);
+}
+
 int
-sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
-{
+sshkeyalg_from_blob(
+	const u_char *blob, size_t blen,
+	struct sshkey **keyp, char **pkalgp
+) {
 	struct sshbuf *b;
 	int r;
 
 	if ((b = sshbuf_from(blob, blen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
-	r = sshkey_from_blob_internal(b, keyp, 1);
+	r = sshkey_parse_from_blob(b, 1, keyp, pkalgp);
 	sshbuf_free(b);
 	return r;
 }
 
 int
+sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
+{
+	return sshkeyalg_from_blob(blob, blen, keyp, NULL);
+}
+
+int
 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
 {
 	return sshkey_from_blob_internal(b, keyp, 1);
@@ -2190,6 +2595,7 @@
 		*lenp = 0;
 	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
+
 	switch (key->type) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA_CERT:
@@ -2222,6 +2628,7 @@
 {
 	if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
+
 	switch (key->type) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA_CERT:
@@ -2260,10 +2667,11 @@
 	pk->dsa = NULL;
 	pk->ecdsa = NULL;
 	pk->rsa = NULL;
+	pk->x509_data = NULL;
 	pk->ed25519_pk = NULL;
 	pk->ed25519_sk = NULL;
 
-	switch (k->type) {
+	switch (X509KEY_BASETYPE(k)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA_CERT:
 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
@@ -2271,25 +2679,55 @@
 		/* FALLTHROUGH */
 	case KEY_RSA1:
 	case KEY_RSA:
+		{
+		BIGNUM *n = NULL, *e = NULL;
+
+		RSA_get0_key(k->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
+
 		if ((pk->rsa = RSA_new()) == NULL ||
-		    (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
-		    (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
+		    (e = BN_dup(e)) == NULL ||
+		    (n = BN_dup(n)) == NULL ||
+		    !RSA_set0_key(pk->rsa, n, e, NULL)
+		) {
+			BN_free(e);
+			BN_free(n);
 			ret = SSH_ERR_ALLOC_FAIL;
 			goto fail;
-			}
+		}
+		}
 		break;
 	case KEY_DSA_CERT:
 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
 			goto fail;
 		/* FALLTHROUGH */
 	case KEY_DSA:
-		if ((pk->dsa = DSA_new()) == NULL ||
-		    (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
-		    (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
-		    (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
-		    (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
-			ret = SSH_ERR_ALLOC_FAIL;
-			goto fail;
+		{	BIGNUM *p = NULL, *q = NULL, *g = NULL;
+
+			DSA_get0_pqg(k->dsa, (const BIGNUM**)&p, (const BIGNUM**)&q, (const BIGNUM**)&g);
+			if ((pk->dsa = DSA_new()) == NULL ||
+			    (p = BN_dup(p)) == NULL ||
+			    (q = BN_dup(q)) == NULL ||
+			    (g = BN_dup(g)) == NULL ||
+			    !DSA_set0_pqg(pk->dsa, p, q, g)
+			) {
+				BN_free(p);
+				BN_free(q);
+				BN_free(g);
+				ret = SSH_ERR_ALLOC_FAIL;
+				goto fail;
+			}
+		}
+
+		{	BIGNUM *pub_key = NULL;
+
+			DSA_get0_key(k->dsa, (const BIGNUM**)&pub_key, NULL);
+			if ((pub_key = BN_dup(pub_key)) == NULL ||
+			    !DSA_set0_key(pk->dsa, pub_key, NULL)
+			) {
+				BN_free(pub_key);
+				ret = SSH_ERR_ALLOC_FAIL;
+				goto fail;
+			}
 		}
 		break;
 	case KEY_ECDSA_CERT:
@@ -2330,6 +2768,9 @@
 		sshkey_free(pk);
 		return ret;
 	}
+
+	x509key_demote(k, pk);
+
 	*dkp = pk;
 	return 0;
 }
@@ -2411,11 +2852,18 @@
 	switch (k->type) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA_CERT:
-		if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
-		    (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
-		    (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
-		    (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
+		{
+		const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
+
+		DSA_get0_pqg(k->dsa, &p, &q, &g);
+		DSA_get0_key(k->dsa, &pub_key, NULL);
+
+		if ((ret = sshbuf_put_bignum2(cert, p)) != 0 ||
+		    (ret = sshbuf_put_bignum2(cert, q)) != 0 ||
+		    (ret = sshbuf_put_bignum2(cert, g)) != 0 ||
+		    (ret = sshbuf_put_bignum2(cert, pub_key)) != 0)
 			goto out;
+		}
 		break;
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA_CERT:
@@ -2428,9 +2876,14 @@
 		break;
 # endif /* OPENSSL_HAS_ECC */
 	case KEY_RSA_CERT:
-		if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
-		    (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
+		{
+		const BIGNUM *n = NULL, *e = NULL;
+
+		RSA_get0_key(k->rsa, &n, &e, NULL);
+		if ((ret = sshbuf_put_bignum2(cert, e)) != 0 ||
+		    (ret = sshbuf_put_bignum2(cert, n)) != 0)
 			goto out;
+		}
 		break;
 #endif /* WITH_OPENSSL */
 	case KEY_ED25519_CERT:
@@ -2581,49 +3034,79 @@
 int
 sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
 {
+	const char *pkalg;
 	int r = SSH_ERR_INTERNAL_ERROR;
 
-	if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
+	pkalg = sshkey_ssh_name(key);
+	if ((r = sshbuf_put_cstring(b, pkalg)) != 0)
 		goto out;
-	switch (key->type) {
+	switch (X509KEY_BASETYPE(key)) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA:
-		if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
+		{
+		const BIGNUM *n = NULL, *e = NULL, *d = NULL;
+		const BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
+
+		RSA_get0_key(key->rsa, &n, &e, &d);
+		RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
+		RSA_get0_factors(key->rsa, &p, &q);
+		if ((r = sshbuf_put_bignum2(b, n)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, e)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, d)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, p)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, q)) != 0)
 			goto out;
+		}
 		break;
 	case KEY_RSA_CERT:
+		{
+		const BIGNUM *d = NULL, *iqmp = NULL, *p = NULL, *q = NULL;
+
 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
 			r = SSH_ERR_INVALID_ARGUMENT;
 			goto out;
 		}
+		RSA_get0_key(key->rsa, NULL, NULL, &d);
+		RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
+		RSA_get0_factors(key->rsa, &p, &q);
 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
+		    (r = sshbuf_put_bignum2(b, d)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, p)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, q)) != 0)
 			goto out;
+		}
 		break;
 	case KEY_DSA:
-		if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
+		{
+		const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+		const BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+		DSA_get0_pqg(key->dsa, &p, &q, &g);
+		DSA_get0_key(key->dsa, &pub_key, &priv_key);
+
+		if ((r = sshbuf_put_bignum2(b, p)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, q)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, g)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, pub_key)) != 0 ||
+		    (r = sshbuf_put_bignum2(b, priv_key)) != 0)
 			goto out;
+		}
 		break;
 	case KEY_DSA_CERT:
+		{
+		const BIGNUM *priv_key = NULL;
+
 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
 			r = SSH_ERR_INVALID_ARGUMENT;
 			goto out;
 		}
+		DSA_get0_key(key->dsa, NULL, &priv_key);
 		if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
-		    (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
+		    (r = sshbuf_put_bignum2(b, priv_key)) != 0)
 			goto out;
+		}
 		break;
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
@@ -2669,6 +3152,11 @@
 		r = SSH_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
+
+	r = X509key_encode_identity(pkalg, key, b);
+	if (r != SSH_ERR_SUCCESS)
+		goto out;
+
 	/* success */
 	r = 0;
  out:
@@ -2692,25 +3180,39 @@
 	if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
 		goto out;
 	type = sshkey_type_from_name(tname);
-	switch (type) {
+	switch (X509TYPE_BASE(tname, type)) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA:
 		if ((k = sshkey_new_private(type)) == NULL) {
 			r = SSH_ERR_ALLOC_FAIL;
 			goto out;
 		}
-		if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
+		{
+		BIGNUM *p = NULL, *q = NULL, *g = NULL;
+		BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+		DSA_get0_pqg(k->dsa, (const BIGNUM**)&p, (const BIGNUM**)&q, (const BIGNUM**)&g);
+		DSA_get0_key(k->dsa, (const BIGNUM**)&pub_key, (const BIGNUM**)&priv_key);
+
+		if ((r = sshbuf_get_bignum2(buf, p)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, q)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, g)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, pub_key)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, priv_key)) != 0)
 			goto out;
+		}
 		break;
 	case KEY_DSA_CERT:
+		{
+		BIGNUM *priv_key = NULL;
+
 		if ((r = sshkey_froms(buf, &k)) != 0 ||
-		    (r = sshkey_add_private(k)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
+		    (r = sshkey_add_private(k)) != 0)
+			goto out;
+		DSA_get0_key(k->dsa, NULL, (const BIGNUM**)&priv_key);
+		if ((r = sshbuf_get_bignum2(buf, priv_key)) != 0)
 			goto out;
+		}
 		break;
 # ifdef OPENSSL_HAS_ECC
 	case KEY_ECDSA:
@@ -2765,28 +3267,45 @@
 		break;
 # endif /* OPENSSL_HAS_ECC */
 	case KEY_RSA:
+		{
+		BIGNUM *n = NULL, *e = NULL, *d = NULL;
+		BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
+
 		if ((k = sshkey_new_private(type)) == NULL) {
 			r = SSH_ERR_ALLOC_FAIL;
 			goto out;
 		}
-		if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
+		RSA_get0_key(k->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, (const BIGNUM**)&d);
+		RSA_get0_crt_params(k->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+		RSA_get0_factors(k->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
+		if ((r = sshbuf_get_bignum2(buf, n)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, e)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, d)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, p)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, q)) != 0 ||
 		    (r = rsa_generate_additional_parameters(k->rsa)) != 0)
 			goto out;
+		}
 		break;
 	case KEY_RSA_CERT:
+		{
+		BIGNUM *d = NULL, *iqmp = NULL, *p = NULL, *q = NULL;
+
 		if ((r = sshkey_froms(buf, &k)) != 0 ||
-		    (r = sshkey_add_private(k)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
-		    (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
+		    (r = sshkey_add_private(k)) != 0) {
+			goto out;
+		}
+		RSA_get0_key(k->rsa, NULL, NULL, (const BIGNUM**)&d);
+		RSA_get0_crt_params(k->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+		RSA_get0_factors(k->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
+		if ((r = sshbuf_get_bignum2(buf, d)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, p)) != 0 ||
+		    (r = sshbuf_get_bignum2(buf, q)) != 0 ||
 		    (r = rsa_generate_additional_parameters(k->rsa)) != 0)
 			goto out;
+		}
 		break;
 #endif /* WITH_OPENSSL */
 	case KEY_ED25519:
@@ -2823,9 +3342,13 @@
 		r = SSH_ERR_KEY_TYPE_UNKNOWN;
 		goto out;
 	}
+	r = X509key_decode_identity(tname, buf, k);
+	if (r != SSH_ERR_SUCCESS) {
+		goto out;
+	}
 #ifdef WITH_OPENSSL
 	/* enable blinding */
-	switch (k->type) {
+	switch (X509KEY_BASETYPE(k)) {
 	case KEY_RSA:
 	case KEY_RSA_CERT:
 	case KEY_RSA1:
@@ -3404,7 +3927,7 @@
 	return r;
 }
 
-#if WITH_SSH1
+#ifdef WITH_SSH1
 /*
  * Serialises the authentication (private) key to a blob, encrypting it with
  * passphrase.  The identification of the blob (lowest 64 bits of n) will
@@ -3441,17 +3964,23 @@
 	arc4random_buf(cp, 2);
 	memcpy(cp + 2, cp, 2);
 
+	{
+	const BIGNUM *d = NULL, *iqmp = NULL, *p = NULL, *q = NULL;
 	/*
 	 * Store the private key (n and e will not be stored because they
 	 * will be stored in plain text, and storing them also in encrypted
 	 * format would just give known plaintext).
 	 * Note: q and p are stored in reverse order to SSL.
 	 */
-	if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||
-	    (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||
-	    (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||
-	    (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)
+	RSA_get0_key(key->rsa, NULL, NULL, &d);
+	RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
+	RSA_get0_factors(key->rsa, &p, &q);
+	if ((r = sshbuf_put_bignum1(buffer, d)) != 0 ||
+	    (r = sshbuf_put_bignum1(buffer, iqmp)) != 0 ||
+	    (r = sshbuf_put_bignum1(buffer, q)) != 0 ||
+	    (r = sshbuf_put_bignum1(buffer, p)) != 0)
 		goto out;
+	}
 
 	/* Pad the part to be encrypted to a size that is a multiple of 8. */
 	explicit_bzero(buf, 8);
@@ -3474,12 +4003,16 @@
 	    (r = sshbuf_put_u32(encrypted, 0)) != 0)
 		goto out;
 
+	{
+	const BIGNUM *n = NULL, *e = NULL;
 	/* Store public key.  This will be in plain text. */
-	if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
-	    (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 ||
-	    (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 ||
+	RSA_get0_key(key->rsa, &n, &e, NULL);
+	if ((r = sshbuf_put_u32(encrypted, BN_num_bits(n))) != 0 ||
+	    (r = sshbuf_put_bignum1(encrypted, n)) != 0 ||
+	    (r = sshbuf_put_bignum1(encrypted, e)) != 0 ||
 	    (r = sshbuf_put_cstring(encrypted, comment)) != 0)
 		goto out;
+	}
 
 	/* Allocate space for the private part of the key in the buffer. */
 	if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)
@@ -3526,7 +4059,7 @@
 	if ((bio = BIO_new(BIO_s_mem())) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 
-	switch (key->type) {
+	switch (X509KEY_BASETYPE(key)) {
 	case KEY_DSA:
 		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
 		    cipher, passphrase, len, NULL, NULL);
@@ -3545,6 +4078,9 @@
 		success = 0;
 		break;
 	}
+	if (success && key_is_x509(key)) {
+		success = x509key_write_identity_bio_pem(bio, key);
+	}
 	if (success == 0) {
 		r = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
@@ -3568,9 +4104,15 @@
     const char *passphrase, const char *comment,
     int force_new_format, const char *new_format_cipher, int new_format_rounds)
 {
-	switch (key->type) {
+	switch (X509KEY_BASETYPE(key)) {
 #ifdef WITH_SSH1
 	case KEY_RSA1:
+	#ifdef OPENSSL_FIPS
+		if (FIPS_mode()) {
+			error("FIPS mode - save of protocol 1 identity is not supported");
+			return SSH_ERR_INVALID_ARGUMENT;
+		}
+	#endif
 		return sshkey_private_rsa1_to_blob(key, blob,
 		    passphrase, comment);
 #endif /* WITH_SSH1 */
@@ -3632,11 +4174,16 @@
 	    (r = sshbuf_get_u32(copy, NULL)) != 0)	/* key bits */
 		goto out;
 
+	{
+	BIGNUM *n = NULL, *e = NULL;
 	/* Read the public key from the buffer. */
-	if ((pub = sshkey_new(KEY_RSA1)) == NULL ||
-	    (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||
-	    (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)
+	if ((pub = sshkey_new(KEY_RSA1)) == NULL)
 		goto out;
+	RSA_get0_key(pub->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
+	if ((r = sshbuf_get_bignum1(copy, n)) != 0 ||
+	    (r = sshbuf_get_bignum1(copy, e)) != 0)
+		goto out;
+	}
 
 	/* Finally, the comment */
 	if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)
@@ -3702,12 +4249,16 @@
 	    (r = sshbuf_get_u32(copy, NULL)) != 0)	/* reserved */
 		goto out;
 
+	{
+	BIGNUM *n = NULL, *e = NULL;
 	/* Read the public key and comment from the buffer. */
+	RSA_get0_key(prv->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
 	if ((r = sshbuf_get_u32(copy, NULL)) != 0 ||	/* key bits */
-	    (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
-	    (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
+	    (r = sshbuf_get_bignum1(copy, n)) != 0 ||
+	    (r = sshbuf_get_bignum1(copy, e)) != 0 ||
 	    (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
 		goto out;
+	}
 
 	/* Check that it is a supported cipher. */
 	cipher = cipher_by_number(cipher_type);
@@ -3735,12 +4286,18 @@
 		goto out;
 	}
 
+	{
+	BIGNUM *d = NULL, *iqmp = NULL, *p = NULL, *q = NULL;
 	/* Read the rest of the private key. */
-	if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
-	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
-	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
-	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
+	RSA_get0_key(prv->rsa, NULL, NULL, (const BIGNUM**)&d);
+	RSA_get0_crt_params(prv->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+	RSA_get0_factors(prv->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
+	if ((r = sshbuf_get_bignum1(decrypted, d)) != 0 ||
+	    (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 ||
+	    (r = sshbuf_get_bignum1(decrypted, q)) != 0 ||
+	    (r = sshbuf_get_bignum1(decrypted, p)) != 0)
 		goto out;
+	}
 
 	/* calculate p-1 and q-1 */
 	if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
@@ -3783,13 +4340,12 @@
 	if (keyp != NULL)
 		*keyp = NULL;
 
-	if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
+	debug("read PEM private key begin");
+	if (sshbuf_len(blob) == 0 || sshbuf_len(blob) > INT_MAX)
+		return SSH_ERR_INVALID_ARGUMENT;
+	bio = BIO_new_mem_buf(buffer_ptr(blob), buffer_len(blob));
+	if (bio == NULL )
 		return SSH_ERR_ALLOC_FAIL;
-	if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
-	    (int)sshbuf_len(blob)) {
-		r = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
 
 	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
 	    (char *)passphrase)) == NULL) {
@@ -3801,6 +4357,13 @@
 		 * passphrase is required/incorrect.
 		 */
 		switch (ERR_GET_LIB(pem_err)) {
+		case 0: {
+			r = (pem_reason == 0)
+			    ?	/*crypto build with FIPS 1.2* module*/
+				SSH_ERR_KEY_WRONG_PASSPHRASE
+			    : SSH_ERR_LIBCRYPTO_ERROR;
+			goto out;
+			}
 		case ERR_LIB_PEM:
 			switch (pem_reason) {
 			case PEM_R_BAD_PASSWORD_READ:
@@ -3817,7 +4380,9 @@
 			case EVP_R_BAD_DECRYPT:
 				r = SSH_ERR_KEY_WRONG_PASSPHRASE;
 				goto out;
+#ifdef EVP_R_BN_DECODE_ERROR	/*OpenSSL < 1.1*/
 			case EVP_R_BN_DECODE_ERROR:
+#endif
 			case EVP_R_DECODE_ERROR:
 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
 			case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3835,7 +4400,7 @@
 		r = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
-	if (pk->type == EVP_PKEY_RSA &&
+	if (EVP_PKEY_id(pk) == EVP_PKEY_RSA &&
 	    (type == KEY_UNSPEC || type == KEY_RSA)) {
 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
 			r = SSH_ERR_ALLOC_FAIL;
@@ -3850,7 +4415,7 @@
 			r = SSH_ERR_LIBCRYPTO_ERROR;
 			goto out;
 		}
-	} else if (pk->type == EVP_PKEY_DSA &&
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA &&
 	    (type == KEY_UNSPEC || type == KEY_DSA)) {
 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
 			r = SSH_ERR_ALLOC_FAIL;
@@ -3862,7 +4427,7 @@
 		DSA_print_fp(stderr, prv->dsa, 8);
 #endif
 #ifdef OPENSSL_HAS_ECC
-	} else if (pk->type == EVP_PKEY_EC &&
+	} else if (EVP_PKEY_id(pk) == EVP_PKEY_EC &&
 	    (type == KEY_UNSPEC || type == KEY_ECDSA)) {
 		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
 			r = SSH_ERR_ALLOC_FAIL;
@@ -3888,6 +4453,15 @@
 		r = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
+	if (prv) {
+		BIO_free(bio);
+		bio = BIO_new_mem_buf(buffer_ptr(blob), buffer_len(blob));
+		if (bio != NULL) {
+			x509key_parse_cert(prv, pk, bio);
+		} else {
+			r = SSH_ERR_ALLOC_FAIL;
+		}
+	}
 	r = 0;
 	if (keyp != NULL) {
 		*keyp = prv;
@@ -3916,6 +4490,12 @@
 	switch (type) {
 #ifdef WITH_SSH1
 	case KEY_RSA1:
+	#ifdef OPENSSL_FIPS
+		if (FIPS_mode()) {
+			error("FIPS mode - parse of protocol 1 identity in not supported");
+			return NULL;
+		}
+	#endif
 		return sshkey_parse_private_rsa1(blob, passphrase,
 		    keyp, commentp);
 #endif /* WITH_SSH1 */
@@ -3957,6 +4537,9 @@
 
 #ifdef WITH_SSH1
 	/* it's a SSH v1 key if the public key part is readable */
+#ifdef OPENSSL_FIPS
+	if (!FIPS_mode())
+#endif
 	if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) {
 		return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,
 		    passphrase, keyp, commentp);
diff -ruN openssh-7.5p1/ssh-keygen.0 openssh-7.5p1+x509-10.2/ssh-keygen.0
--- openssh-7.5p1/ssh-keygen.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keygen.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SSH-KEYGEN(1)               General Commands Manual              SSH-KEYGEN(1)
+SSH-KEYGEN(1)             BSD General Commands Manual            SSH-KEYGEN(1)
 
 NAME
-     ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion
+     ssh-keygen -- Authentication key generation, management and conversion
 
 SYNOPSIS
      ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]
@@ -55,12 +55,12 @@
 
      Normally this program generates the key and asks for a file in which to
      store the private key.  The public key is stored in a file with the same
-     name but M-bM-^@M-^\.pubM-bM-^@M-^] appended.  The program also asks for a passphrase.  The
+     name but ``.pub'' appended.  The program also asks for a passphrase.  The
      passphrase may be empty to indicate no passphrase (host keys must have an
      empty passphrase), or it may be a string of arbitrary length.  A
      passphrase is similar to a password, except it can be a phrase with a
-     series of words, punctuation, numbers, whitespace, or any string of
-     characters you want.  Good passphrases are 10-30 characters long, are not
+     series of words, punctuation, numbers, whitespace, or any string of char-
+     acters you want.  Good passphrases are 10-30 characters long, are not
      simple sentences or otherwise easily guessable (English prose has only
      1-2 bits of entropy per character, and provides very bad passphrases),
      and contain a mix of upper and lowercase letters, numbers, and non-
@@ -74,7 +74,7 @@
      For RSA1 keys and keys stored in the newer OpenSSH format, there is also
      a comment field in the key file that is only for convenience to the user
      to help identify the key.  The comment can tell what the key is for, or
-     whatever is useful.  The comment is initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the
+     whatever is useful.  The comment is initialized to ``user@host'' when the
      key is created, but can be changed using the -c option.
 
      After a key is generated, instructions below detail where the keys should
@@ -85,16 +85,16 @@
      -A      For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for
              which host keys do not exist, generate the host keys with the
              default key file path, an empty passphrase, default bits for the
-             key type, and default comment.  This is used by /etc/rc to
-             generate new host keys.
+             key type, and default comment.  This is used by /etc/rc to gener-
+             ate new host keys.
 
      -a rounds
              When saving a new-format private key (i.e. an ed25519 key or any
-             SSH protocol 2 key when the -o flag is set), this option
-             specifies the number of KDF (key derivation function) rounds
-             used.  Higher numbers result in slower passphrase verification
-             and increased resistance to brute-force password cracking (should
-             the keys be stolen).
+             SSH protocol 2 key when the -o flag is set), this option speci-
+             fies the number of KDF (key derivation function) rounds used.
+             Higher numbers result in slower passphrase verification and
+             increased resistance to brute-force password cracking (should the
+             keys be stolen).
 
              When screening DH-GEX candidates ( using the -T command).  This
              option specifies the number of primality tests to perform.
@@ -104,8 +104,8 @@
 
      -b bits
              Specifies the number of bits in the key to create.  For RSA keys,
-             the minimum size is 1024 bits and the default is 2048 bits.
-             Generally, 2048 bits is considered sufficient.  DSA keys must be
+             the minimum size is 1024 bits and the default is 2048 bits.  Gen-
+             erally, 2048 bits is considered sufficient.  DSA keys must be
              exactly 1024 bits as specified by FIPS 186-2.  For ECDSA keys,
              the -b flag determines the key length by selecting from one of
              three elliptic curve sizes: 256, 384 or 521 bits.  Attempting to
@@ -123,21 +123,19 @@
              key has one, and for the new comment.
 
      -D pkcs11
-             Download the RSA public keys provided by the PKCS#11 shared
-             library pkcs11.  When used in combination with -s, this option
-             indicates that a CA key resides in a PKCS#11 token (see the
-             CERTIFICATES section for details).
+             Download the X.509 certificate provided by the PKCS#11 shared
+             library pkcs11.
 
      -E fingerprint_hash
-             Specifies the hash algorithm used when displaying key
-             fingerprints.  Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^].  The
-             default is M-bM-^@M-^\sha256M-bM-^@M-^].
+             Specifies the hash algorithm used when displaying key finger-
+             prints.  Valid options are: ``md5'' and ``sha256''.  The default
+             is ``sha256''.
 
      -e      This option will read a private or public OpenSSH key file and
              print to stdout the key in one of the formats specified by the -m
-             option.  The default export format is M-bM-^@M-^\RFC4716M-bM-^@M-^].  This option
-             allows exporting OpenSSH keys for use by other programs,
-             including several commercial SSH implementations.
+             option.  The default export format is ``RFC4716''.  This option
+             allows exporting OpenSSH keys for use by other programs, includ-
+             ing several commercial SSH implementations.
 
      -F hostname
              Search for the specified hostname in a known_hosts file, listing
@@ -175,21 +173,21 @@
              in the format specified by the -m option and print an OpenSSH
              compatible private (or public) key to stdout.  This option allows
              importing keys from other software, including several commercial
-             SSH implementations.  The default import format is M-bM-^@M-^\RFC4716M-bM-^@M-^].
+             SSH implementations.  The default import format is ``RFC4716''.
 
      -J num_lines
-             Exit after screening the specified number of lines while
-             performing DH candidate screening using the -T option.
+             Exit after screening the specified number of lines while perform-
+             ing DH candidate screening using the -T option.
 
      -j start_line
              Start screening at the specified line number while performing DH
              candidate screening using the -T option.
 
      -K checkpt
-             Write the last line processed to the file checkpt while
-             performing DH candidate screening using the -T option.  This will
-             be used to skip lines in the input file that have already been
-             processed if the job is restarted.
+             Write the last line processed to the file checkpt while perform-
+             ing DH candidate screening using the -T option.  This will be
+             used to skip lines in the input file that have already been pro-
+             cessed if the job is restarted.
 
      -k      Generate a KRL file.  In this mode, ssh-keygen will generate a
              KRL file at the location specified via the -f flag that revokes
@@ -202,28 +200,29 @@
 
      -l      Show fingerprint of specified public key file.  Private RSA1 keys
              are also supported.  For RSA and DSA keys ssh-keygen tries to
-             find the matching public key file and prints its fingerprint.  If
-             combined with -v, a visual ASCII art representation of the key is
-             supplied with the fingerprint.
+             find the matching public key file and prints its fingerprint.
+             When identity contain X.509 certificate its prints certificate
+             fingerprint.  If combined with -v, a visual ASCII art representa-
+             tion of the key is supplied with the fingerprint.
 
      -M memory
-             Specify the amount of memory to use (in megabytes) when
-             generating candidate moduli for DH-GEX.
+             Specify the amount of memory to use (in megabytes) when generat-
+             ing candidate moduli for DH-GEX.
 
      -m key_format
-             Specify a key format for the -i (import) or -e (export)
-             conversion options.  The supported key formats are: M-bM-^@M-^\RFC4716M-bM-^@M-^]
-             (RFC 4716/SSH2 public or private key), M-bM-^@M-^\PKCS8M-bM-^@M-^] (PEM PKCS8 public
-             key) or M-bM-^@M-^\PEMM-bM-^@M-^] (PEM public key).  The default conversion format is
-             M-bM-^@M-^\RFC4716M-bM-^@M-^].
+             Specify a key format for the -i (import) or -e (export) conver-
+             sion options.  The supported key formats are: ``RFC4716'' (RFC
+             4716/SSH2 public or private key), ``PKCS8'' (PEM PKCS8 public
+             key) or ``PEM'' (PEM public key).  The default conversion format
+             is ``RFC4716''.
 
      -N new_passphrase
              Provides the new passphrase.
 
      -n principals
              Specify one or more principals (user or host names) to be
-             included in a certificate when signing a key.  Multiple
-             principals may be specified, separated by commas.  Please see the
+             included in a certificate when signing a key.  Multiple princi-
+             pals may be specified, separated by commas.  Please see the
              CERTIFICATES section for details.
 
      -O option
@@ -232,9 +231,9 @@
              for details.  The options that are valid for user certificates
              are:
 
-             clear   Clear all enabled permissions.  This is useful for
-                     clearing the default set of permissions so permissions
-                     may be added individually.
+             clear   Clear all enabled permissions.  This is useful for clear-
+                     ing the default set of permissions so permissions may be
+                     added individually.
 
              force-command=command
                      Forces the execution of command instead of any shell or
@@ -273,17 +272,17 @@
 
              source-address=address_list
                      Restrict the source addresses from which the certificate
-                     is considered valid.  The address_list is a comma-
-                     separated list of one or more address/netmask pairs in
-                     CIDR format.
+                     is considered valid.  The address_list is a comma-sepa-
+                     rated list of one or more address/netmask pairs in CIDR
+                     format.
 
              At present, no options are valid for host keys.
 
-     -o      Causes ssh-keygen to save private keys using the new OpenSSH
-             format rather than the more compatible PEM format.  The new
-             format has increased resistance to brute-force password cracking
-             but is not supported by versions of OpenSSH prior to 6.5.
-             Ed25519 keys always use the new private key format.
+     -o      Causes ssh-keygen to save private keys using the new OpenSSH for-
+             mat rather than the more compatible PEM format.  The new format
+             has increased resistance to brute-force password cracking but is
+             not supported by versions of OpenSSH prior to 6.5.  Ed25519 keys
+             always use the new private key format.
 
      -P passphrase
              Provides the (old) passphrase.
@@ -304,7 +303,8 @@
 
      -r hostname
              Print the SSHFP fingerprint resource record named hostname for
-             the specified public key file.
+             the specified public key file.  In case of X.509 certificates
+             print CERT resource record.
 
      -S start
              Specify start point (in hex) when generating candidate moduli for
@@ -324,18 +324,18 @@
 
      -t dsa | ecdsa | ed25519 | rsa | rsa1
              Specifies the type of key to create.  The possible values are
-             M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or
-             M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2.
+             ``rsa1'' for protocol version 1 and ``dsa'', ``ecdsa'',
+             ``ed25519'', or ``rsa'' for protocol version 2.
 
-     -u      Update a KRL.  When specified with -k, keys listed via the
-             command line are added to the existing KRL rather than a new KRL
+     -u      Update a KRL.  When specified with -k, keys listed via the com-
+             mand line are added to the existing KRL rather than a new KRL
              being created.
 
      -V validity_interval
-             Specify a validity interval when signing a certificate.  A
-             validity interval may consist of a single time, indicating that
-             the certificate is valid beginning now and expiring at that time,
-             or may consist of two times separated by a colon to indicate an
+             Specify a validity interval when signing a certificate.  A valid-
+             ity interval may consist of a single time, indicating that the
+             certificate is valid beginning now and expiring at that time, or
+             may consist of two times separated by a colon to indicate an
              explicit time interval.  The start time may be specified as a
              date in YYYYMMDD format, a time in YYYYMMDDHHMMSS format or a
              relative time (to the current time) consisting of a minus sign
@@ -344,16 +344,17 @@
              as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time
              starting with a plus character.
 
-             For example: M-bM-^@M-^\+52w1dM-bM-^@M-^] (valid from now to 52 weeks and one day
-             from now), M-bM-^@M-^\-4w:+4wM-bM-^@M-^] (valid from four weeks ago to four weeks
-             from now), M-bM-^@M-^\20100101123000:20110101123000M-bM-^@M-^] (valid from 12:30 PM,
-             January 1st, 2010 to 12:30 PM, January 1st, 2011), M-bM-^@M-^\-1d:20110101M-bM-^@M-^]
-             (valid from yesterday to midnight, January 1st, 2011).
+             For example: ``+52w1d'' (valid from now to 52 weeks and one day
+             from now), ``-4w:+4w'' (valid from four weeks ago to four weeks
+             from now), ``20100101123000:20110101123000'' (valid from 12:30
+             PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
+             ``-1d:20110101'' (valid from yesterday to midnight, January 1st,
+             2011).
 
      -v      Verbose mode.  Causes ssh-keygen to print debugging messages
-             about its progress.  This is helpful for debugging moduli
-             generation.  Multiple -v options increase the verbosity.  The
-             maximum is 3.
+             about its progress.  This is helpful for debugging moduli genera-
+             tion.  Multiple -v options increase the verbosity.  The maximum
+             is 3.
 
      -W generator
              Specify desired generator when testing candidate moduli for DH-
@@ -367,15 +368,15 @@
              distinguish this certificate from others from the same CA.  The
              default serial number is zero.
 
-             When generating a KRL, the -z flag is used to specify a KRL
-             version number.
+             When generating a KRL, the -z flag is used to specify a KRL ver-
+             sion number.
 
 MODULI GENERATION
      ssh-keygen may be used to generate groups for the Diffie-Hellman Group
      Exchange (DH-GEX) protocol.  Generating these groups is a two-step
      process: first, candidate primes are generated using a fast, but memory
-     intensive process.  These candidate primes are then tested for
-     suitability (a CPU-intensive process).
+     intensive process.  These candidate primes are then tested for suitabil-
+     ity (a CPU-intensive process).
 
      Generation of primes is performed using the -G option.  The desired
      length of the primes may be specified by the -b option.  For example:
@@ -383,8 +384,8 @@
            # ssh-keygen -G moduli-2048.candidates -b 2048
 
      By default, the search for primes begins at a random point in the desired
-     length range.  This may be overridden using the -S option, which
-     specifies a different start point (in hex).
+     length range.  This may be overridden using the -S option, which speci-
+     fies a different start point (in hex).
 
      Once a set of candidates have been generated, they must be screened for
      suitability.  This may be performed using the -T option.  In this mode
@@ -413,8 +414,8 @@
      Note that OpenSSH certificates are a different, and much simpler, format
      to the X.509 certificates used in ssl(8).
 
-     ssh-keygen supports two types of certificates: user and host.  User
-     certificates authenticate users to servers, whereas host certificates
+     ssh-keygen supports two types of certificates: user and host.  User cer-
+     tificates authenticate users to servers, whereas host certificates
      authenticate server hosts to users.  To generate a user certificate:
 
            $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
@@ -426,39 +427,33 @@
 
      The host certificate will be output to /path/to/host_key-cert.pub.
 
-     It is possible to sign using a CA key stored in a PKCS#11 token by
-     providing the token library using -D and identifying the CA key by
-     providing its public half as an argument to -s:
-
-           $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
-
      In all cases, key_id is a "key identifier" that is logged by the server
      when the certificate is used for authentication.
 
      Certificates may be limited to be valid for a set of principal
      (user/host) names.  By default, generated certificates are valid for all
-     users or hosts.  To generate a certificate for a specified set of
-     principals:
+     users or hosts.  To generate a certificate for a specified set of princi-
+     pals:
 
            $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
            $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub
 
      Additional limitations on the validity and use of user certificates may
-     be specified through certificate options.  A certificate option may
-     disable features of the SSH session, may be valid only when presented
-     from particular source addresses or may force the use of a specific
-     command.  For a list of valid certificate options, see the documentation
-     for the -O option above.
+     be specified through certificate options.  A certificate option may dis-
+     able features of the SSH session, may be valid only when presented from
+     particular source addresses or may force the use of a specific command.
+     For a list of valid certificate options, see the documentation for the -O
+     option above.
 
      Finally, certificates may be defined with a validity lifetime.  The -V
-     option allows specification of certificate start and end times.  A
-     certificate that is presented at a time outside this range will not be
-     considered valid.  By default, certificates are valid from UNIX Epoch to
-     the distant future.
-
-     For certificates to be used for user or host authentication, the CA
-     public key must be trusted by sshd(8) or ssh(1).  Please refer to those
-     manual pages for details.
+     option allows specification of certificate start and end times.  A cer-
+     tificate that is presented at a time outside this range will not be con-
+     sidered valid.  By default, certificates are valid from UNIX Epoch to the
+     distant future.
+
+     For certificates to be used for user or host authentication, the CA pub-
+     lic key must be trusted by sshd(8) or ssh(1).  Please refer to those man-
+     ual pages for details.
 
 KEY REVOCATION LISTS
      ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs).
@@ -469,16 +464,16 @@
      KRLs may be generated using the -k flag.  This option reads one or more
      files from the command line and generates a new KRL.  The files may
      either contain a KRL specification (see below) or public keys, listed one
-     per line.  Plain public keys are revoked by listing their hash or
-     contents in the KRL and certificates revoked by serial number or key ID
-     (if the serial is zero or not available).
+     per line.  Plain public keys are revoked by listing their hash or con-
+     tents in the KRL and certificates revoked by serial number or key ID (if
+     the serial is zero or not available).
 
      Revoking keys using a KRL specification offers explicit control over the
      types of record used to revoke keys and may be used to directly revoke
-     certificates by serial number or key ID without having the complete
-     original certificate on hand.  A KRL specification consists of lines
-     containing one of the following directives followed by a colon and some
-     directive-specific information.
+     certificates by serial number or key ID without having the complete orig-
+     inal certificate on hand.  A KRL specification consists of lines contain-
+     ing one of the following directives followed by a colon and some direc-
+     tive-specific information.
 
      serial: serial_number[-serial_number]
              Revokes a certificate with the specified serial number.  Serial
@@ -522,8 +517,8 @@
              key.  ssh(1) will read this file when a login attempt is made.
 
      ~/.ssh/identity.pub
-             Contains the protocol version 1 RSA public key for
-             authentication.  The contents of this file should be added to
+             Contains the protocol version 1 RSA public key for authentica-
+             tion.  The contents of this file should be added to
              ~/.ssh/authorized_keys on all machines where the user wishes to
              log in using RSA authentication.  There is no need to keep the
              contents of this file secret.
@@ -533,13 +528,22 @@
      ~/.ssh/id_ed25519
      ~/.ssh/id_rsa
              Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA
-             authentication identity of the user.  This file should not be
-             readable by anyone but the user.  It is possible to specify a
-             passphrase when generating the key; that passphrase will be used
-             to encrypt the private part of this file using 128-bit AES.  This
-             file is not automatically accessed by ssh-keygen but it is
-             offered as the default file for the private key.  ssh(1) will
-             read this file when a login attempt is made.
+             authentication identity of the user.
+
+             This file should not be readable by anyone but the user.
+
+             In case of RSA, ECDSA or DSA identity may contain private key and
+             X.509 certificate that match it.  For public key algorithms
+             defined in ``RFC6187'', like x509v3-ecdsa-sha2-* file may contain
+             extra X.509 certificates.  Those certificates are used to build
+             chain of certificates leading to a trusted certificate authority.
+
+             It is possible to specify a passphrase when generating the key;
+             that passphrase will be used to encrypt the private part of this
+             file using 128-bit AES.  This file is not automatically accessed
+             by ssh-keygen but it is offered as the default file for the pri-
+             vate key.  ssh(1) will read this file when a login attempt is
+             made.
 
      ~/.ssh/id_dsa.pub
      ~/.ssh/id_ecdsa.pub
@@ -549,7 +553,17 @@
              key for authentication.  The contents of this file should be
              added to ~/.ssh/authorized_keys on all machines where the user
              wishes to log in using public key authentication.  There is no
-             need to keep the contents of this file secret.
+             need to keep the contents of this file secret.  If file
+             ~/.ssh/id_rsa, ~/.ssh/id_ecdsa or ~/.ssh/id_dsa contain
+             RSA/ECDSA/DSA private key and X.509 certificates public key file
+             must contain certificate that match private key!  Use ssh-keygen
+             with option -y to regenerate its content.  Note in case with
+             X.509 certificate you can append content to
+             ~/.ssh/authorized_keys or to add certificate ``Distinguished
+             Name'' / ``Subject'' in corresponding format to ``authorized
+             keys'' file. See sshd(8).  Using distinguished name is prefered
+             as X.509 certificate could be renewed and after renewal there is
+             no need to update ``authorized keys'' file.
 
      /etc/moduli
              Contains Diffie-Hellman groups used for DH-GEX.  The file format
@@ -558,13 +572,16 @@
 SEE ALSO
      ssh(1), ssh-add(1), ssh-agent(1), moduli(5), sshd(8)
 
-     The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006.
+CONFORMING TO
+     J. Galbraith and R. Thayer, The Secure Shell (SSH) Public Key File
+     Format, RFC 4716, November 2006.
 
 AUTHORS
-     OpenSSH is a derivative of the original and free ssh 1.2.12 release by
+     PKIX-SSH is a derivative of the original and free ssh 1.2.12 release by
      Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
-     de Raadt and Dug Song removed many bugs, re-added newer features and
-     created OpenSSH.  Markus Friedl contributed the support for SSH protocol
-     versions 1.5 and 2.0.
+     de Raadt and Dug Song removed many bugs, re-added newer features and cre-
+     ated OpenSSH.  Markus Friedl contributed the support for SSH protocol
+     versions 1.5 and 2.0.  Roumen Petrov contributed support for X.509 cer-
+     tificates.
 
-OpenBSD 6.0                      June 16, 2016                     OpenBSD 6.0
+BSD                           September 18, 2016                           BSD
diff -ruN openssh-7.5p1/ssh-keygen.1 openssh-7.5p1+x509-10.2/ssh-keygen.1
--- openssh-7.5p1/ssh-keygen.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keygen.1	2017-05-20 21:07:00.000000000 +0300
@@ -14,6 +14,7 @@
 .\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
 .\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
 .\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -35,12 +36,20 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: June 16 2016 $
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
+.Dd $Mdocdate: September 18 2016 $
 .Dt SSH-KEYGEN 1
 .Os
 .Sh NAME
 .Nm ssh-keygen
-.Nd authentication key generation, management and conversion
+.Nd Authentication key generation, management and conversion
 .Sh SYNOPSIS
 .Bk -words
 .Nm ssh-keygen
@@ -269,13 +278,8 @@
 The program will prompt for the file containing the private keys, for
 the passphrase if the key has one, and for the new comment.
 .It Fl D Ar pkcs11
-Download the RSA public keys provided by the PKCS#11 shared library
+Download the X.509 certificate provided by the PKCS#11 shared library
 .Ar pkcs11 .
-When used in combination with
-.Fl s ,
-this option indicates that a CA key resides in a PKCS#11 token (see the
-.Sx CERTIFICATES
-section for details).
 .It Fl E Ar fingerprint_hash
 Specifies the hash algorithm used when displaying key fingerprints.
 Valid options are:
@@ -388,6 +392,7 @@
 For RSA and DSA keys
 .Nm
 tries to find the matching public key file and prints its fingerprint.
+When identity contain X.509 certificate its prints certificate fingerprint.
 If combined with
 .Fl v ,
 a visual ASCII art representation of the key is supplied with the
@@ -511,6 +516,7 @@
 Print the SSHFP fingerprint resource record named
 .Ar hostname
 for the specified public key file.
+In case of X.509 certificates print CERT resource record.
 .It Fl S Ar start
 Specify start point (in hex) when generating candidate moduli for DH-GEX.
 .It Fl s Ar ca_key
@@ -679,15 +685,6 @@
 The host certificate will be output to
 .Pa /path/to/host_key-cert.pub .
 .Pp
-It is possible to sign using a CA key stored in a PKCS#11 token by
-providing the token library using
-.Fl D
-and identifying the CA key by providing its public half as an argument
-to
-.Fl s :
-.Pp
-.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
-.Pp
 In all cases,
 .Ar key_id
 is a "key identifier" that is logged by the server when the certificate
@@ -821,7 +818,17 @@
 .It Pa ~/.ssh/id_rsa
 Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA
 authentication identity of the user.
+.Pp
 This file should not be readable by anyone but the user.
+.Pp
+In case of RSA, ECDSA or DSA identity may contain private key
+and X.509 certificate that match it.
+For public key algorithms defined in
+.Dq RFC6187 ,
+like x509v3-ecdsa-sha2-* file may contain extra X.509 certificates.
+Those certificates are used to build chain of certificates
+leading to a trusted certificate authority.
+.Pp
 It is possible to
 specify a passphrase when generating the key; that passphrase will be
 used to encrypt the private part of this file using 128-bit AES.
@@ -842,6 +849,30 @@
 on all machines
 where the user wishes to log in using public key authentication.
 There is no need to keep the contents of this file secret.
+If file
+.Pa ~/.ssh/id_rsa ,
+.Pa ~/.ssh/id_ecdsa
+or
+.Pa ~/.ssh/id_dsa
+contain RSA/ECDSA/DSA private key and X.509 certificates
+public key file must contain certificate that match private key!
+Use
+.Nm
+with option -y to regenerate its content.
+Note in case with X.509 certificate you can append content to
+.Pa ~/.ssh/authorized_keys
+or to add certificate
+.Dq Distinguished Name
+/
+.Dq Subject
+in corresponding format to
+.Dq authorized keys
+file. See
+.Xr sshd 8 .
+Using distinguished name is prefered as X.509 certificate could
+be renewed and after renewal there is no need to update
+.Dq authorized keys
+file.
 .Pp
 .It Pa /etc/moduli
 Contains Diffie-Hellman groups used for DH-GEX.
@@ -854,13 +885,16 @@
 .Xr ssh-agent 1 ,
 .Xr moduli 5 ,
 .Xr sshd 8
+.Sh CONFORMING TO
 .Rs
+.%A J. Galbraith
+.%A R. Thayer
+.%D November 2006
 .%R RFC 4716
-.%T "The Secure Shell (SSH) Public Key File Format"
-.%D 2006
+.%T The Secure Shell (SSH) Public Key File Format
 .Re
 .Sh AUTHORS
-OpenSSH is a derivative of the original and free
+PKIX-SSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
 Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
 Theo de Raadt and Dug Song
@@ -868,3 +902,4 @@
 created OpenSSH.
 Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
+Roumen Petrov contributed support for X.509 certificates.
diff -ruN openssh-7.5p1/ssh-keygen.c openssh-7.5p1+x509-10.2/ssh-keygen.c
--- openssh-7.5p1/ssh-keygen.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keygen.c	2017-05-20 21:07:01.000000000 +0300
@@ -10,6 +10,29 @@
  * software must be clearly marked as such, and if the derived work is
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
+ *
+ * X.509 certificates support,
+ * Copyright (c) 2005 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
@@ -22,6 +45,10 @@
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include "openbsd-compat/openssl-compat.h"
+#include "evp-compat.h"
+#ifdef HAVE_FIPSCHECK_H
+#  include <fipscheck.h>
+#endif
 #endif
 
 #include <errno.h>
@@ -53,6 +80,7 @@
 #include "dns.h"
 #include "ssh.h"
 #include "ssh2.h"
+#include "ssh-xkalg.h"
 #include "ssherr.h"
 #include "ssh-pkcs11.h"
 #include "atomicio.h"
@@ -483,13 +511,25 @@
 
 	switch (key->type) {
 	case KEY_DSA:
-		buffer_get_bignum_bits(b, key->dsa->p);
-		buffer_get_bignum_bits(b, key->dsa->g);
-		buffer_get_bignum_bits(b, key->dsa->q);
-		buffer_get_bignum_bits(b, key->dsa->pub_key);
-		buffer_get_bignum_bits(b, key->dsa->priv_key);
+		{
+		BIGNUM *p = NULL, *q = NULL, *g = NULL;
+		BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+		DSA_get0_pqg(key->dsa, (const BIGNUM**)&p, (const BIGNUM**)&q, (const BIGNUM**)&g);
+		DSA_get0_key(key->dsa, (const BIGNUM**)&pub_key, (const BIGNUM**)&priv_key);
+
+		buffer_get_bignum_bits(b, p);
+		buffer_get_bignum_bits(b, g);
+		buffer_get_bignum_bits(b, q);
+		buffer_get_bignum_bits(b, pub_key);
+		buffer_get_bignum_bits(b, priv_key);
+		}
 		break;
 	case KEY_RSA:
+		{
+		BIGNUM *n = NULL, *rsa_e = NULL, *d = NULL;
+		BIGNUM *iqmp = NULL, *p = NULL, *q = NULL;
+
 		if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
 		    (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
 		    (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
@@ -504,18 +544,23 @@
 			e += e3;
 			debug("e %lx", e);
 		}
-		if (!BN_set_word(key->rsa->e, e)) {
+		RSA_get0_key(key->rsa, (const BIGNUM**)&n, (const BIGNUM**)&rsa_e, (const BIGNUM**)&d);
+		if (!BN_set_word(rsa_e, e)) {
 			sshbuf_free(b);
 			sshkey_free(key);
 			return NULL;
 		}
-		buffer_get_bignum_bits(b, key->rsa->d);
-		buffer_get_bignum_bits(b, key->rsa->n);
-		buffer_get_bignum_bits(b, key->rsa->iqmp);
-		buffer_get_bignum_bits(b, key->rsa->q);
-		buffer_get_bignum_bits(b, key->rsa->p);
+		RSA_get0_crt_params(key->rsa, NULL, NULL, (const BIGNUM**)&iqmp);
+		RSA_get0_factors(key->rsa, (const BIGNUM**)&p, (const BIGNUM**)&q);
+
+		buffer_get_bignum_bits(b, d);
+		buffer_get_bignum_bits(b, n);
+		buffer_get_bignum_bits(b, iqmp);
+		buffer_get_bignum_bits(b, q);
+		buffer_get_bignum_bits(b, p);
 		if ((r = rsa_generate_additional_parameters(key->rsa)) != 0)
 			fatal("generate RSA parameters failed: %s", ssh_err(r));
+		}
 		break;
 	}
 	rlen = sshbuf_len(b);
@@ -623,7 +668,7 @@
 		    identity_file);
 	}
 	fclose(fp);
-	switch (EVP_PKEY_type(pubkey->type)) {
+	switch (EVP_PKEY_id(pubkey)) {
 	case EVP_PKEY_RSA:
 		if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
 			fatal("sshkey_new failed");
@@ -647,7 +692,7 @@
 #endif
 	default:
 		fatal("%s: unsupported pubkey type %d", __func__,
-		    EVP_PKEY_type(pubkey->type));
+		    EVP_PKEY_id(pubkey));
 	}
 	EVP_PKEY_free(pubkey);
 	return;
@@ -1598,6 +1643,13 @@
 	pkcs11_init(1);
 #endif
 	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
+
+	/* NOTE ca_sing is not applicable with X.509 certificate
+	 * support. If USE_LEGACY_PKCS11_RSAKEY is defined in
+	 * ssh-pkcs11.c comment next line
+	 */
+	pkcs11provider = NULL;
+
 	if (pkcs11provider != NULL) {
 		if ((ca = load_pkcs11_key(tmp)) == NULL)
 			fatal("No PKCS#11 key matching %s found", ca_key_path);
@@ -2285,9 +2337,17 @@
 
 	__progname = ssh_get_progname(argv[0]);
 
-#ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
-#endif
+	ssh_OpenSSL_startup();
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+	#ifdef HAVE_FIPSCHECK_H
+		if (!FIPSCHECK_verify(NULL, NULL))
+			fatal("FIPS integrity verification test failed.");
+	#endif
+		fprintf(stderr, "%s runs in FIPS mode\n", __progname);
+	}
+#endif /*def OPENSSL_FIPS*/
+	fill_default_xkalg();
 	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
 
 	seed_rng();
@@ -2510,6 +2570,13 @@
 		}
 	}
 
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && use_new_format) {
+		fprintf(stderr, "'New format' is not allowed in FIPS mode");
+		exit(1);
+	}
+#endif
+
 	/* reinit */
 	log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
 
diff -ruN openssh-7.5p1/sshkey.h openssh-7.5p1+x509-10.2/sshkey.h
--- openssh-7.5p1/sshkey.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshkey.h	2017-05-20 21:07:00.000000000 +0300
@@ -2,6 +2,8 @@
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * X.509 certificates support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,13 +33,18 @@
 #ifdef WITH_OPENSSL
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
-# ifdef OPENSSL_HAS_ECC
+# if defined(OPENSSL_HAS_ECC) || defined(HAVE_OPENSSL_EC_H)
 #  include <openssl/ec.h>
+#  if OPENSSL_VERSION_NUMBER < 0x00908000L
+    /* before OpenSSL 0.9.8 */
+#   define EC_KEY	void
+#  endif
 # else /* OPENSSL_HAS_ECC */
 #  define EC_KEY	void
 #  define EC_GROUP	void
 #  define EC_POINT	void
 # endif /* OPENSSL_HAS_ECC */
+#include <openssl/x509.h>
 #else /* WITH_OPENSSL */
 # define RSA		void
 # define DSA		void
@@ -55,8 +62,11 @@
 enum sshkey_types {
 	KEY_RSA1,
 	KEY_RSA,
+	KEY_X509_RSA,
 	KEY_DSA,
+	KEY_X509_DSA,
 	KEY_ECDSA,
+	KEY_X509_ECDSA,
 	KEY_ED25519,
 	KEY_RSA_CERT,
 	KEY_DSA_CERT,
@@ -66,7 +76,11 @@
 };
 
 /* Default fingerprint hash */
+#ifdef HAVE_EVP_SHA256
 #define SSH_FP_HASH_DEFAULT	SSH_DIGEST_SHA256
+#else
+#define SSH_FP_HASH_DEFAULT	SSH_DIGEST_SHA1
+#endif
 
 /* Fingerprint representation formats */
 enum sshkey_fp_rep {
@@ -95,6 +109,30 @@
 	struct sshkey	*signature_key;
 };
 
+
+typedef struct ssh_x509_st SSH_X509;
+
+SSH_X509*	SSH_X509_new(void);
+void		SSH_X509_free(SSH_X509* xd);
+X509*		SSH_X509_get_cert(SSH_X509 *xd);
+
+/* NOTE
+ * Final solution:
+ * a) should not use {KEY_X509_RSA"|DSA|ECDSA} is switch statements, i.e
+ *   X.509 support has to be redesigned to use "plain key type"
+ *   and if is key_is_x509() to perform specific operations;
+ * b) code has to be redesigned to use "keyname" (strings) to allow
+ *   a key to be used with multiple names.
+ * Temporary solution.
+ * - macro X509KEY_BASETYPE that return KEY_{RSA|DSA|ECDSA};
+ * - use macro where is posible;
+ * - remove macro after implementation of a) and b).
+ */
+
+#define X509KEY_BASETYPE(key)		(sshkey_is_x509(key) ? sshkey_type_plain(key->type) : key->type)
+#define X509TYPE_BASE(name, type)	(ssh_x509key_type(name) != KEY_UNSPEC ? sshkey_type_plain(type) : type)
+
+
 /* XXX opaquify? */
 struct sshkey {
 	int	 type;
@@ -105,6 +143,7 @@
 	EC_KEY	*ecdsa;
 	u_char	*ed25519_sk;
 	u_char	*ed25519_pk;
+	SSH_X509 *x509_data;
 	struct sshkey_cert *cert;
 };
 
@@ -116,9 +155,13 @@
 struct sshkey	*sshkey_new_private(int);
 void		 sshkey_free(struct sshkey *);
 int		 sshkey_demote(const struct sshkey *, struct sshkey **);
+int		 sshrsa_equal_public(const RSA*, const RSA*);
+int		 sshdsa_equal_public(const DSA*, const DSA*);
 int		 sshkey_equal_public(const struct sshkey *,
     const struct sshkey *);
 int		 sshkey_equal(const struct sshkey *, const struct sshkey *);
+		 /*bool*/
+int	 	 sshkey_match_pkalg(struct sshkey *key, const char* pkalg);
 char		*sshkey_fingerprint(const struct sshkey *,
     int, enum sshkey_fp_rep);
 int		 sshkey_fingerprint_raw(const struct sshkey *k,
@@ -127,11 +170,14 @@
 const char	*sshkey_cert_type(const struct sshkey *);
 int		 sshkey_write(const struct sshkey *, FILE *);
 int		 sshkey_read(struct sshkey *, char **);
+int		 sshkey_read_pkalg(struct sshkey *, char **, char **);
 u_int		 sshkey_size(const struct sshkey *);
 
 int		 sshkey_generate(int type, u_int bits, struct sshkey **keyp);
 int		 sshkey_from_private(const struct sshkey *, struct sshkey **);
 int	 sshkey_type_from_name(const char *);
+void	 sshkey_types_from_name(const char *name, int *type, int *subtype);
+int	 sshkey_is_x509(const struct sshkey *);
 int	 sshkey_is_cert(const struct sshkey *);
 int	 sshkey_type_is_cert(int);
 int	 sshkey_type_plain(int);
@@ -158,6 +204,10 @@
 int		 sshkey_names_valid2(const char *, int);
 char		*sshkey_alg_list(int, int, int, char);
 
+int	sshkey_ind_alg(const char **name, int loc);
+
+int	 sshkeyalg_from_blob(const u_char *blob, size_t blen, struct sshkey ** keyp, char **pkalgp);
+
 int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **);
 int	 sshkey_fromb(struct sshbuf *, struct sshkey **);
 int	 sshkey_froms(struct sshbuf *, struct sshkey **);
diff -ruN openssh-7.5p1/ssh-keyscan.0 openssh-7.5p1+x509-10.2/ssh-keyscan.0
--- openssh-7.5p1/ssh-keyscan.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keyscan.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,20 +1,20 @@
-SSH-KEYSCAN(1)              General Commands Manual             SSH-KEYSCAN(1)
+SSH-KEYSCAN(1)            BSD General Commands Manual           SSH-KEYSCAN(1)
 
 NAME
-     ssh-keyscan M-bM-^@M-^S gather ssh public keys
+     ssh-keyscan -- Gather secure shell public keys
 
 SYNOPSIS
-     ssh-keyscan [-46cHv] [-f file] [-p port] [-T timeout] [-t type]
+     ssh-keyscan [-46Hv] [-f file] [-p port] [-T timeout] [-t type]
                  [host | addrlist namelist] ...
 
 DESCRIPTION
-     ssh-keyscan is a utility for gathering the public ssh host keys of a
-     number of hosts.  It was designed to aid in building and verifying
+     ssh-keyscan is a utility for gathering the public ssh host keys of a num-
+     ber of hosts.  It was designed to aid in building and verifying
      ssh_known_hosts files.  ssh-keyscan provides a minimal interface suitable
      for use by shell and perl scripts.
 
-     ssh-keyscan uses non-blocking socket I/O to contact as many hosts as
-     possible in parallel, so it is very efficient.  The keys from a domain of
+     ssh-keyscan uses non-blocking socket I/O to contact as many hosts as pos-
+     sible in parallel, so it is very efficient.  The keys from a domain of
      1,000 hosts can be collected in tens of seconds, even when some of those
      hosts are down or do not run ssh.  For scanning, one does not need login
      access to the machines that are being scanned, nor does the scanning
@@ -26,16 +26,15 @@
 
      -6      Forces ssh-keyscan to use IPv6 addresses only.
 
-     -c      Request certificates from target hosts instead of plain keys.
-
      -f file
-             Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line.
-             If - is supplied instead of a filename, ssh-keyscan will read
-             hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from the standard input.
+             Read hosts or ``addrlist namelist'' pairs from file, one per
+             line.  If - is supplied instead of a filename, ssh-keyscan will
+             read hosts or ``addrlist namelist'' pairs from the standard
+             input.
 
      -H      Hash all hostnames and addresses in the output.  Hashed names may
-             be used normally by ssh and sshd, but they do not reveal
-             identifying information should the file's contents be disclosed.
+             be used normally by ssh and sshd, but they do not reveal identi-
+             fying information should the file's contents be disclosed.
 
      -p port
              Port to connect to on the remote host.
@@ -49,21 +48,25 @@
 
      -t type
              Specifies the type of the key to fetch from the scanned hosts.
-             The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^],
-             M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2.  Multiple
-             values may be specified by separating them with commas.  The
-             default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys.
+             The possible values are ``rsa1'' for protocol version 1 and
+             ``x509v3-ecdsa-sha2-nistp256'', ``x509v3-ecdsa-sha2-nistp384'',
+             ``x509v3-ecdsa-sha2-nistp521'', ``x509v3-ssh-rsa'',
+             ``x509v3-ssh-dss'', ``x509v3-sign-rsa'', ``x509v3-sign-dss'',
+             ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'',
+             ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', ``ssh-rsa'', or
+             ``ssh-dss'' for protocol version 2.  Multiple values may be spec-
+             ified by separating them with commas.  The default are keys for
+             protocol version 2.
 
      -v      Verbose mode.  Causes ssh-keyscan to print debugging messages
              about its progress.
 
 SECURITY
-     If an ssh_known_hosts file is constructed using ssh-keyscan without
-     verifying the keys, users will be vulnerable to man in the middle
-     attacks.  On the other hand, if the security model allows such a risk,
-     ssh-keyscan can help in the detection of tampered keyfiles or man in the
-     middle attacks which have begun after the ssh_known_hosts file was
-     created.
+     If an ssh_known_hosts file is constructed using ssh-keyscan without veri-
+     fying the keys, users will be vulnerable to man in the middle attacks.
+     On the other hand, if the security model allows such a risk, ssh-keyscan
+     can help in the detection of tampered keyfiles or man in the middle
+     attacks which have begun after the ssh_known_hosts file was created.
 
 FILES
      Input format:
@@ -78,8 +81,16 @@
 
      host-or-namelist keytype base64-encoded-key
 
-     Where keytype is either M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^],
-     M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or M-bM-^@M-^\ssh-rsaM-bM-^@M-^].
+     Where keytype is either ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'',
+     ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', ``ssh-dss'' or ``ssh-rsa''.
+
+     Output format for rsa and dsa keys with X.509 certificates:
+
+     host-or-namelist keytype distinguished-name
+
+     Where keytype is either ``x509v3-sign-rsa''
+     ``x509v3-ecdsa-sha2-nistp256'' ``x509v3-ecdsa-sha2-nistp384''
+     ``x509v3-ecdsa-sha2-nistp521'' or ``x509v3-sign-dss''.
 
      /etc/ssh/ssh_known_hosts
 
@@ -91,7 +102,7 @@
      Find all hosts from the file ssh_hosts which have new or different keys
      from those in the sorted file ssh_known_hosts:
 
-     $ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \
+     $ ssh-keyscan -t x509v3-sign-rsa,x509v3-sign-dss,rsa,dsa,x509v3-ecdsa-sha2-nistp256,x509v3-ecdsa-sha2-nistp384,x509v3-ecdsa-sha2-nistp521,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521 -f ssh_hosts | \
              sort -u - ssh_known_hosts | diff ssh_known_hosts -
 
 SEE ALSO
@@ -100,7 +111,7 @@
 AUTHORS
      David Mazieres <dm@lcs.mit.edu> wrote the initial version, and Wayne
      Davison <wayned@users.sourceforge.net> added support for protocol version
-     2.
+     2.  Roumen Petrov contributed support for X.509 certificates.
 
 BUGS
      It generates "Connection closed by remote host" messages on the consoles
@@ -108,4 +119,4 @@
      This is because it opens a connection to the ssh port, reads the public
      key, and drops the connection as soon as it gets the key.
 
-OpenBSD 6.0                    November 8, 2015                    OpenBSD 6.0
+BSD                            November 8, 2015                            BSD
diff -ruN openssh-7.5p1/ssh-keyscan.1 openssh-7.5p1+x509-10.2/ssh-keyscan.1
--- openssh-7.5p1/ssh-keyscan.1	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keyscan.1	2017-05-20 21:07:00.000000000 +0300
@@ -6,16 +6,47 @@
 .\" permitted provided that due credit is given to the author and the
 .\" OpenBSD project by leaving this copyright notice intact.
 .\"
+.\" X.509 certificates support,
+.\" Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .Dd $Mdocdate: November 8 2015 $
 .Dt SSH-KEYSCAN 1
 .Os
 .Sh NAME
 .Nm ssh-keyscan
-.Nd gather ssh public keys
+.Nd Gather secure shell public keys
 .Sh SYNOPSIS
 .Nm ssh-keyscan
 .Bk -words
-.Op Fl 46cHv
+.Op Fl 46Hv
 .Op Fl f Ar file
 .Op Fl p Ar port
 .Op Fl T Ar timeout
@@ -54,8 +85,6 @@
 Forces
 .Nm
 to use IPv6 addresses only.
-.It Fl c
-Request certificates from target hosts instead of plain keys.
 .It Fl f Ar file
 Read hosts or
 .Dq addrlist namelist
@@ -92,19 +121,23 @@
 The possible values are
 .Dq rsa1
 for protocol version 1 and
-.Dq dsa ,
-.Dq ecdsa ,
-.Dq ed25519 ,
+.Dq x509v3-ecdsa-sha2-nistp256 ,
+.Dq x509v3-ecdsa-sha2-nistp384 ,
+.Dq x509v3-ecdsa-sha2-nistp521 ,
+.Dq x509v3-ssh-rsa ,
+.Dq x509v3-ssh-dss ,
+.Dq x509v3-sign-rsa ,
+.Dq x509v3-sign-dss ,
+.Dq ecdsa-sha2-nistp256 ,
+.Dq ecdsa-sha2-nistp384 ,
+.Dq ecdsa-sha2-nistp521 ,
+.Dq ssh-ed25519 ,
+.Dq ssh-rsa ,
 or
-.Dq rsa
+.Dq ssh-dss
 for protocol version 2.
 Multiple values may be specified by separating them with commas.
-The default is to fetch
-.Dq rsa ,
-.Dq ecdsa ,
-and
-.Dq ed25519
-keys.
+The default are keys for protocol version 2.
 .It Fl v
 Verbose mode.
 Causes
@@ -148,6 +181,21 @@
 or
 .Dq ssh-rsa .
 .Pp
+.Pa Output format for rsa and dsa keys with X.509 certificates:
+.Bd -literal
+host-or-namelist keytype distinguished-name
+.Ed
+.Pp
+Where
+.Pa keytype
+is either
+.Dq x509v3-sign-rsa
+.Dq x509v3-ecdsa-sha2-nistp256
+.Dq x509v3-ecdsa-sha2-nistp384
+.Dq x509v3-ecdsa-sha2-nistp521
+or
+.Dq x509v3-sign-dss .
+.Pp
 .Pa /etc/ssh/ssh_known_hosts
 .Sh EXAMPLES
 Print the rsa host key for machine
@@ -161,7 +209,7 @@
 which have new or different keys from those in the sorted file
 .Pa ssh_known_hosts :
 .Bd -literal
-$ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \e
+$ ssh-keyscan -t x509v3-sign-rsa,x509v3-sign-dss,rsa,dsa,x509v3-ecdsa-sha2-nistp256,x509v3-ecdsa-sha2-nistp384,x509v3-ecdsa-sha2-nistp521,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521 -f ssh_hosts | \e
 	sort -u - ssh_known_hosts | diff ssh_known_hosts -
 .Ed
 .Sh SEE ALSO
@@ -173,6 +221,7 @@
 wrote the initial version, and
 .An Wayne Davison Aq Mt wayned@users.sourceforge.net
 added support for protocol version 2.
+Roumen Petrov contributed support for X.509 certificates.
 .Sh BUGS
 It generates "Connection closed by remote host" messages on the consoles
 of all the machines it scans if the server is older than version 2.9.
diff -ruN openssh-7.5p1/ssh-keyscan.c openssh-7.5p1+x509-10.2/ssh-keyscan.c
--- openssh-7.5p1/ssh-keyscan.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keyscan.c	2017-05-20 21:07:01.000000000 +0300
@@ -5,6 +5,29 @@
  * Modification and redistribution in source and binary forms is
  * permitted provided that due credit is given to the author and the
  * OpenBSD project by leaving this copyright notice intact.
+ *
+ * X.509 certificates support,
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
@@ -20,6 +43,7 @@
 #include <arpa/inet.h>
 
 #include <openssl/bn.h>
+#include "evp-compat.h"
 
 #include <netdb.h>
 #include <errno.h>
@@ -35,6 +59,8 @@
 #include "ssh1.h"
 #include "sshbuf.h"
 #include "sshkey.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "cipher.h"
 #include "kex.h"
 #include "compat.h"
@@ -54,14 +80,7 @@
 
 int ssh_port = SSH_DEFAULT_PORT;
 
-#define KT_RSA1		1
-#define KT_DSA		2
-#define KT_RSA		4
-#define KT_ECDSA	8
-#define KT_ED25519	16
-
-int get_cert = 0;
-int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519;
+char* get_keynames = NULL;
 
 int hash_hosts = 0;		/* Hash hostname on output */
 
@@ -94,7 +113,7 @@
 	int c_plen;		/* Packet length field for ssh packet */
 	int c_len;		/* Total bytes which must be read. */
 	int c_off;		/* Length of data read so far. */
-	int c_keytype;		/* Only one of KT_RSA1, KT_DSA, or KT_RSA */
+	const char *c_keyname;
 	sig_atomic_t c_done;	/* SSH2 done */
 	char *c_namebase;	/* Address to free for c_name and c_namelist */
 	char *c_name;		/* Hostname of connection for errors */
@@ -177,7 +196,7 @@
  * null token for two adjacent separators, so we may have to loop.
  */
 static char *
-strnnsep(char **stringp, char *delim)
+strnnsep(char **stringp, const char *delim)
 {
 	char *tok;
 
@@ -195,6 +214,7 @@
 	static struct sshbuf *msg;
 	int r;
 	u_char type;
+	BIGNUM *n = NULL, *e = NULL;
 
 	if (rsa == NULL) {
 		if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
@@ -213,6 +233,7 @@
 		sshbuf_reset(msg);
 		return NULL;
 	}
+	RSA_get0_key(rsa->rsa, (const BIGNUM**)&n, (const BIGNUM**)&e, NULL);
 	if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
 	    /* server key */
 	    (r = sshbuf_get_u32(msg, NULL)) != 0 ||
@@ -220,8 +241,8 @@
 	    (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
 	    /* host key */
 	    (r = sshbuf_get_u32(msg, NULL)) != 0 ||
-	    (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
-	    (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
+	    (r = sshbuf_get_bignum1(msg, e)) != 0 ||
+	    (r = sshbuf_get_bignum1(msg, n)) != 0) {
  buf_err:
 		error("%s: buffer error: %s", __func__, ssh_err(r));
 		sshbuf_reset(msg);
@@ -268,32 +289,7 @@
 	int r;
 
 	enable_compat20();
-	switch (c->c_keytype) {
-	case KT_DSA:
-		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
-		    "ssh-dss-cert-v01@openssh.com" : "ssh-dss";
-		break;
-	case KT_RSA:
-		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
-		    "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa";
-		break;
-	case KT_ED25519:
-		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
-		    "ssh-ed25519-cert-v01@openssh.com" : "ssh-ed25519";
-		break;
-	case KT_ECDSA:
-		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
-		    "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
-		    "ecdsa-sha2-nistp384-cert-v01@openssh.com,"
-		    "ecdsa-sha2-nistp521-cert-v01@openssh.com" :
-		    "ecdsa-sha2-nistp256,"
-		    "ecdsa-sha2-nistp384,"
-		    "ecdsa-sha2-nistp521";
-		break;
-	default:
-		fatal("unknown key type %d", c->c_keytype);
-		break;
-	}
+	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = (char*)c->c_keyname;
 	if ((r = kex_setup(c->c_ssh, myproposal)) != 0) {
 		free(c->c_ssh);
 		fprintf(stderr, "kex_setup: %s\n", ssh_err(r));
@@ -321,7 +317,7 @@
 }
 
 static void
-keyprint_one(const char *host, struct sshkey *key)
+keyprint_one(const char *host, con *c, struct sshkey *key)
 {
 	char *hostport;
 	const char *known_host, *hashed;
@@ -331,9 +327,13 @@
 	if (hash_hosts && (hashed = host_hash(host, NULL, 0)) == NULL)
 		fatal("host_hash failed");
 	known_host = hash_hosts ? hashed : hostport;
-	if (!get_cert)
-		fprintf(stdout, "%s ", known_host);
+	fprintf(stdout, "%s ", known_host);
+	if (key_is_x509(key)) {
+		/* key_write prints x509 certificate in blob format :-( */
+		Xkey_write_subject(c->c_keyname, key, stdout);
+	} else {
 	sshkey_write(key, stdout);
+	}
 	fputs("\n", stdout);
 	free(hostport);
 }
@@ -346,13 +346,13 @@
 
 	if (key == NULL)
 		return;
-	if (get_cert || (!hash_hosts && ssh_port == SSH_DEFAULT_PORT)) {
-		keyprint_one(hosts, key);
+	if (!hash_hosts && ssh_port == SSH_DEFAULT_PORT) {
+		keyprint_one(hosts, c, key);
 		return;
 	}
 	ohosts = hosts = xstrdup(hosts);
 	while ((host = strsep(&hosts, ",")) != NULL)
-		keyprint_one(host, key);
+		keyprint_one(host, c, key);
 	free(ohosts);
 }
 
@@ -392,10 +392,15 @@
 }
 
 static int
-conalloc(char *iname, char *oname, int keytype)
+conalloc(char *iname, char *oname, const char *keyname)
 {
 	char *namebase, *name, *namelist;
 	int s;
+	int k_type;
+
+	k_type = key_type_from_name((char*)keyname);
+	if (k_type == KEY_UNSPEC)
+		return (-1);
 
 	namebase = namelist = xstrdup(iname);
 
@@ -412,7 +417,7 @@
 	if (fdcon[s].c_status)
 		fatal("conalloc: attempt to reuse fdno %d", s);
 
-	debug3("%s: oname %s kt %d", __func__, oname, keytype);
+	debug3("%s: oname %s keyname %s", __func__, oname, keyname);
 	fdcon[s].c_fd = s;
 	fdcon[s].c_status = CS_CON;
 	fdcon[s].c_namebase = namebase;
@@ -422,7 +427,13 @@
 	fdcon[s].c_data = (char *) &fdcon[s].c_plen;
 	fdcon[s].c_len = 4;
 	fdcon[s].c_off = 0;
-	fdcon[s].c_keytype = keytype;
+{
+	Key *k = key_new(k_type);
+	if (key_type_plain(k->type) == KEY_ECDSA)
+		k->ecdsa_nid = key_ecdsa_nid_from_name((char*)keyname);
+	fdcon[s].c_keyname = keyname;
+	key_free(k);
+}
 	gettimeofday(&fdcon[s].c_tv, NULL);
 	fdcon[s].c_tv.tv_sec += timeout;
 	TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
@@ -442,7 +453,7 @@
 	if (fdcon[s].c_status == CS_KEYS)
 		free(fdcon[s].c_data);
 	fdcon[s].c_status = CS_UNUSED;
-	fdcon[s].c_keytype = 0;
+	fdcon[s].c_keyname = NULL;
 	if (fdcon[s].c_ssh) {
 		ssh_packet_close(fdcon[s].c_ssh);
 		free(fdcon[s].c_ssh);
@@ -468,7 +479,7 @@
 	con *c = &fdcon[s];
 	int ret;
 
-	ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype);
+	ret = conalloc(c->c_namelist, c->c_output_name, c->c_keyname);
 	confree(s);
 	return (ret);
 }
@@ -481,6 +492,7 @@
 	char remote_version[sizeof buf];
 	size_t bufsiz;
 	con *c = &fdcon[s];
+	int rsa1key;
 
 	for (;;) {
 		memset(buf, '\0', sizeof(buf));
@@ -521,10 +533,11 @@
 	ssh_set_app_data(c->c_ssh, c);	/* back link */
 	if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
 	    &remote_major, &remote_minor, remote_version) == 3)
-		c->c_ssh->compat = compat_datafellows(remote_version);
+		SSH_XCOMPATIBILITY(c->c_ssh, remote_version)
 	else
-		c->c_ssh->compat = 0;
-	if (c->c_keytype != KT_RSA1) {
+		SSH_XCOMPATIBILITY(c->c_ssh, NULL);
+	rsa1key = (strcmp(c->c_keyname, "rsa1") == 0);
+	if (!rsa1key) {
 		if (!ssh2_capable(remote_major, remote_minor)) {
 			debug("%s doesn't support ssh2", c->c_name);
 			confree(s);
@@ -535,10 +548,10 @@
 		confree(s);
 		return;
 	}
-	fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf));
+	fprintf(stderr, "# %s:%d (%s) %s\n", c->c_name, ssh_port, fdcon[s].c_keyname, chop(buf));
 	n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
-	    c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
-	    c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
+	    rsa1key ? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
+	    rsa1key ? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
 	if (n < 0 || (size_t)n >= sizeof(buf)) {
 		error("snprintf: buffer too small");
 		confree(s);
@@ -549,7 +562,7 @@
 		confree(s);
 		return;
 	}
-	if (c->c_keytype != KT_RSA1) {
+	if (!rsa1key) {
 		keygrab_ssh2(c);
 		confree(s);
 		return;
@@ -655,16 +668,18 @@
 do_host(char *host)
 {
 	char *name = strnnsep(&host, " \t\n");
-	int j;
+	const char *keyname;
 
 	if (name == NULL)
 		return;
-	for (j = KT_RSA1; j <= KT_ED25519; j *= 2) {
-		if (get_keytypes & j) {
-			while (ncon >= MAXCON)
-				conloop();
-			conalloc(name, *host ? host : name, j);
-		}
+	for (
+	    keyname = strtok(get_keynames, ",");
+	    keyname != NULL;
+	    keyname = strtok(NULL, ",")
+	) {
+		while (ncon >= MAXCON)
+			conloop();
+		conalloc(name, *host ? host : name, keyname);
 	}
 }
 
@@ -712,14 +727,28 @@
 	if (argc <= 1)
 		usage();
 
-	while ((opt = getopt(argc, argv, "cHv46p:T:t:f:")) != -1) {
+	fill_default_xkalg();
+	get_keynames = xstrdup(
+		 /* list all protocol v2 keys by default */
+		"x509v3-ecdsa-sha2-nistp256," /*RFC6187 ecdsa*/
+		"x509v3-ecdsa-sha2-nistp384," /*RFC6187 ecdsa*/
+		"x509v3-ecdsa-sha2-nistp521," /*RFC6187 ecdsa*/
+		"x509v3-ssh-rsa," /*RFC6187 rsa*/
+		"x509v3-ssh-dss," /*RFC6187 dsa*/
+		"x509v3-sign-rsa,"
+		"x509v3-sign-dss,"
+		"ecdsa-sha2-nistp256,"
+		"ecdsa-sha2-nistp384,"
+		"ecdsa-sha2-nistp521,"
+		"ssh-ed25519,"
+		"ssh-rsa,"
+		"ssh-dss"
+	);
+	while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) {
 		switch (opt) {
 		case 'H':
 			hash_hosts = 1;
 			break;
-		case 'c':
-			get_cert = 1;
-			break;
 		case 'p':
 			ssh_port = a2port(optarg);
 			if (ssh_port <= 0) {
@@ -750,33 +779,12 @@
 			argv[fopt_count++] = optarg;
 			break;
 		case 't':
-			get_keytypes = 0;
+			get_keynames = xstrdup(optarg);
 			tname = strtok(optarg, ",");
 			while (tname) {
 				int type = sshkey_type_from_name(tname);
-
-				switch (type) {
-#ifdef WITH_SSH1
-				case KEY_RSA1:
-					get_keytypes |= KT_RSA1;
-					break;
-#endif
-				case KEY_DSA:
-					get_keytypes |= KT_DSA;
-					break;
-				case KEY_ECDSA:
-					get_keytypes |= KT_ECDSA;
-					break;
-				case KEY_RSA:
-					get_keytypes |= KT_RSA;
-					break;
-				case KEY_ED25519:
-					get_keytypes |= KT_ED25519;
-					break;
-				case KEY_UNSPEC:
-				default:
-					fatal("Unknown key type \"%s\"", tname);
-				}
+				if (type == KEY_UNSPEC)
+					fatal("unknown key type %s", tname);
 				tname = strtok(NULL, ",");
 			}
 			break;
diff -ruN openssh-7.5p1/ssh-keysign.0 openssh-7.5p1+x509-10.2/ssh-keysign.0
--- openssh-7.5p1/ssh-keysign.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keysign.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SSH-KEYSIGN(8)              System Manager's Manual             SSH-KEYSIGN(8)
+SSH-KEYSIGN(8)            BSD System Manager's Manual           SSH-KEYSIGN(8)
 
 NAME
-     ssh-keysign M-bM-^@M-^S ssh helper program for host-based authentication
+     ssh-keysign -- ssh helper program for host-based authentication
 
 SYNOPSIS
      ssh-keysign
@@ -12,11 +12,11 @@
 
      ssh-keysign is disabled by default and can only be enabled in the global
      client configuration file /etc/ssh/ssh_config by setting EnableSSHKeysign
-     to M-bM-^@M-^\yesM-bM-^@M-^].
+     to ``yes''.
 
      ssh-keysign is not intended to be invoked by the user, but from ssh(1).
-     See ssh(1) and sshd(8) for more information about host-based
-     authentication.
+     See ssh(1) and sshd(8) for more information about host-based authentica-
+     tion.
 
 FILES
      /etc/ssh/ssh_config
@@ -32,13 +32,18 @@
              are readable only by root, ssh-keysign must be set-uid root if
              host-based authentication is used.
 
+             Host key for protocol version 2 may contain X.509 certificate
+             that match private key.  For x509v3-ecdsa-sha2-* public key algo-
+             rithms, file with ECDSA key may contain extra X.509 certificates
+             used to build chain of certificates leading to a trusted certifi-
+             cate authority.
+
      /etc/ssh/ssh_host_dsa_key-cert.pub
      /etc/ssh/ssh_host_ecdsa_key-cert.pub
      /etc/ssh/ssh_host_ed25519_key-cert.pub
      /etc/ssh/ssh_host_rsa_key-cert.pub
-             If these files exist they are assumed to contain public
-             certificate information corresponding with the private keys
-             above.
+             If these files exist they are assumed to contain public certifi-
+             cate information corresponding with the private keys above.
 
 SEE ALSO
      ssh(1), ssh-keygen(1), ssh_config(5), sshd(8)
@@ -49,4 +54,4 @@
 AUTHORS
      Markus Friedl <markus@openbsd.org>
 
-OpenBSD 6.0                    February 17, 2016                   OpenBSD 6.0
+BSD                           September 18, 2016                           BSD
diff -ruN openssh-7.5p1/ssh-keysign.8 openssh-7.5p1+x509-10.2/ssh-keysign.8
--- openssh-7.5p1/ssh-keysign.8	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keysign.8	2017-05-20 21:07:00.000000000 +0300
@@ -1,6 +1,7 @@
 .\" $OpenBSD: ssh-keysign.8,v 1.15 2016/02/17 07:38:19 jmc Exp $
 .\"
 .\" Copyright (c) 2002 Markus Friedl.  All rights reserved.
+.\" Copyright (c) 2002-2016 Roumen Petrov.  All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -22,7 +23,15 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: February 17 2016 $
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
+.Dd $Mdocdate: September 18 2016 $
 .Dt SSH-KEYSIGN 8
 .Os
 .Sh NAME
@@ -73,6 +82,13 @@
 .Nm
 must be set-uid root if host-based authentication is used.
 .Pp
+Host key for protocol version 2 may contain
+X.509 certificate that match private key.
+For x509v3-ecdsa-sha2-* public key algorithms, file
+with ECDSA key may contain extra X.509 certificates
+used to build chain of certificates
+leading to a trusted certificate authority.
+.Pp
 .It Pa /etc/ssh/ssh_host_dsa_key-cert.pub
 .It Pa /etc/ssh/ssh_host_ecdsa_key-cert.pub
 .It Pa /etc/ssh/ssh_host_ed25519_key-cert.pub
diff -ruN openssh-7.5p1/ssh-keysign.c openssh-7.5p1+x509-10.2/ssh-keysign.c
--- openssh-7.5p1/ssh-keysign.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-keysign.c	2017-05-20 21:07:01.000000000 +0300
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
++ * X509 certificate support,
++ * Copyright (c) 2011-2017 Roumen Petrov.  All rights reserved.
++ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -40,11 +43,14 @@
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
+#include "openbsd-compat/openssl-compat.h"
 #endif
 
 #include "xmalloc.h"
 #include "log.h"
-#include "sshkey.h"
+#include "compat.h"
+#include "ssh-x509.h"
+#include "ssh-xkalg.h"
 #include "ssh.h"
 #include "ssh2.h"
 #include "misc.h"
@@ -55,7 +61,6 @@
 #include "pathnames.h"
 #include "readconf.h"
 #include "uidswap.h"
-#include "sshkey.h"
 #include "ssherr.h"
 
 struct ssh *active_state = NULL; /* XXX needed for linking */
@@ -67,6 +72,57 @@
 
 extern char *__progname;
 
+/* used in ssh-x509.c */
+extern STACK_OF(X509)* (*pssh_x509store_build_certchain)(X509 *cert, STACK_OF(X509) *untrusted);
+
+/* minimize OCSP dependencies */
+#ifdef SSH_OCSP_ENABLED
+
+#if 1	/* used in readconf.c */
+
+void
+ssh_set_validator(const VAOptions *_va) {
+	(void)_va;
+	return;
+}
+
+int
+ssh_get_default_vatype(void) {
+	return(SSHVA_NONE);
+}
+
+int
+ssh_get_vatype_s(const char* type) {
+	(void)type;
+	return(-1);
+}
+
+const char*
+ssh_get_vatype_i(int id) {
+	(void)id;
+	return(NULL);
+}
+
+#endif	/* end of used in readconf.c */
+#endif /*def SSH_OCSP_ENABLED*/
+
+
+#if 1	/* used in x509store.c */
+int
+ssh_ocsp_validate(X509 *cert, X509_STORE *x509store) {
+	(void)cert;
+	(void)x509store;
+	return(-1);
+}
+
+X509_LOOKUP_METHOD* X509_LOOKUP_ldap(void);
+X509_LOOKUP_METHOD*
+X509_LOOKUP_ldap(void) {
+	return(NULL);
+}
+#endif	/* end of used in x509store.c */
+
+
 static int
 valid_request(struct passwd *pw, char *host, struct sshkey **ret,
     u_char *data, size_t datalen)
@@ -123,7 +179,7 @@
 	pktype = sshkey_type_from_name(pkalg);
 	if (pktype == KEY_UNSPEC)
 		fail++;
-	else if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
+	else if ((r = Xkey_from_blob(pkalg, pkblob, blen, &key)) != 0) {
 		error("%s: bad key blob: %s", __func__, ssh_err(r));
 		fail++;
 	} else if (key->type != pktype)
@@ -183,6 +239,7 @@
 #endif
 
 	ssh_malloc_init();	/* must be called before any mallocs */
+	__progname = ssh_get_progname(argv[0]);
 	if (pledge("stdio rpath getpw dns id", NULL) != 0)
 		fatal("%s: pledge: %s", __progname, strerror(errno));
 
@@ -193,6 +250,18 @@
 	if (fd > 2)
 		close(fd);
 
+	ssh_OpenSSL_startup();
+	fill_default_xkalg();
+{
+	X509StoreOptions ca;
+
+	X509StoreOptions_init(&ca);
+	X509StoreOptions_system_defaults(&ca);
+	ssh_x509store_addlocations(&ca);
+	X509StoreOptions_reset(&ca);
+}
+	pssh_x509store_build_certchain = ssh_x509store_build_certchain;
+
 	i = 0;
 	/* XXX This really needs to read sshd_config for the paths */
 	key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
@@ -229,7 +298,6 @@
 		fatal("could not open any host key");
 
 #ifdef WITH_OPENSSL
-	OpenSSL_add_all_algorithms();
 	arc4random_buf(rnd, sizeof(rnd));
 	RAND_seed(rnd, sizeof(rnd));
 #endif
@@ -292,9 +360,13 @@
 		    sshkey_type(key), fp ? fp : "");
 	}
 
-	if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, NULL, 0))
-	    != 0)
-		fatal("sshkey_sign failed: %s", ssh_err(r));
+{	ssh_compat ctx_compat = { 0, 0 }; /* TODO-Xkey_sign compat */
+	ssh_sign_ctx ctx = { NULL, keys[i], &ctx_compat };
+
+	r = Xkey_sign(&ctx, &signature, &slen, data, dlen);
+	if (r != 0)
+		fatal("Xkey_sign failed: %s", ssh_err(r));
+}
 	free(data);
 
 	/* send reply */
diff -ruN openssh-7.5p1/sshlogin.c openssh-7.5p1+x509-10.2/sshlogin.c
--- openssh-7.5p1/sshlogin.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/sshlogin.c	2017-05-20 21:07:01.000000000 +0300
@@ -55,6 +55,7 @@
 #include <unistd.h>
 #include <limits.h>
 
+#include "sshlogin.h"
 #include "loginrec.h"
 #include "log.h"
 #include "buffer.h"
diff -ruN openssh-7.5p1/ssh-ocsp.c openssh-7.5p1+x509-10.2/ssh-ocsp.c
--- openssh-7.5p1/ssh-ocsp.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-ocsp.c	2016-08-26 21:18:51.692923466 +0300
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (c) 2004-2007,2011 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "x509store.h"
+#ifndef SSH_OCSP_ENABLED
+#  include "error: OCSP is disabled"
+#endif
+
+#if 1
+#  /* not yet fully implemented */
+#  define SSH_WITH_SSLOCSP
+#endif
+
+#include <string.h>
+
+#include "xmalloc.h"
+#include "log.h"
+#include <openssl/pem.h>
+#include <openssl/ocsp.h>
+#ifdef SSH_WITH_SSLOCSP
+#  include <openssl/ssl.h>
+#endif
+/* "bye, bye xfree()" ;) */
+#define xfree free
+
+#if defined(sk_OPENSSL_STRING_new_null) || defined(HAVE_SK_OPENSSL_STRING_NEW_NULL)
+/*
+ * STACK_OF(OPENSSL_STRING) is defined for openssl version >= 1.0
+ * (OPENSSL_VERSION_NUMBER >= 0x10000000L).
+ * NOTE: We will test for definition of sk_OPENSSL_STRING_new_null
+ * instead openssl version number! As in OpenSSL 1.1 stack functions
+ * are inlined we must use configure check.
+ */
+#define ssh_sk_OPENSSL_STRING		STACK_OF(OPENSSL_STRING)
+
+static void OPENSSL_STRING_xfree(OPENSSL_STRING p) {
+/* xfree warnings for OpenSSL 1+:
+.../ssh-ocsp.c: In function 'ssh_ocsp_validate2':
+.../ssh-ocsp.c:845: warning: pointer type mismatch in conditional expression
+.../ssh-ocsp.c:845: warning: ISO C forbids conversion of object pointer to function pointer type
+*/
+  xfree(p);
+}
+
+#else /* !def sk_OPENSSL_STRING_new_null */
+
+#ifdef sk_STRING_new_null
+/*some OpenSSL 1.0 pre and release candidate */
+# define ssh_sk_OPENSSL_STRING		STACK_OF(STRING)
+# define sk_OPENSSL_STRING_new_null	sk_STRING_new_null
+# define sk_OPENSSL_STRING_push		sk_STRING_push
+# define sk_OPENSSL_STRING_num		sk_STRING_num
+# define sk_OPENSSL_STRING_value	sk_STRING_value
+# define sk_OPENSSL_STRING_pop_free	sk_STRING_pop_free
+
+static void OPENSSL_STRING_xfree(STRING p) {
+  xfree(p);
+}
+
+#else /* !def sk_STRING_new_null */
+
+# define ssh_sk_OPENSSL_STRING		STACK
+# define sk_OPENSSL_STRING_new_null	sk_new_null
+# define sk_OPENSSL_STRING_push		sk_push
+# define sk_OPENSSL_STRING_num		sk_num
+# define sk_OPENSSL_STRING_value	sk_value
+# define sk_OPENSSL_STRING_pop_free	sk_pop_free
+
+#define OPENSSL_STRING_xfree		xfree
+
+#endif
+
+#endif
+
+static VAOptions va = { SSHVA_NONE, NULL, NULL };
+
+typedef struct va_type_map_s va_type_map;
+struct va_type_map_s {
+	int id;
+	const char* code;
+};
+
+static va_type_map sshva_type_map[] = {
+	{ SSHVA_NONE     , "none"     },
+	{ SSHVA_OCSP_CERT, "ocspcert" },
+	{ SSHVA_OCSP_SPEC, "ocspspec" },
+};
+
+
+int
+ssh_get_default_vatype(void) {
+	return(SSHVA_NONE);
+}
+
+
+int
+ssh_get_vatype_s(const char* type) {
+	int k, n;
+
+	if (type == NULL) return(-1);
+
+	n = sizeof(sshva_type_map) / sizeof(sshva_type_map[0]);
+	for (k = 0; k < n; k++) {
+		va_type_map *p = sshva_type_map + k;
+		if (strcasecmp(type, p->code) == 0) return(p->id);
+	}
+
+	return(-1);
+}
+
+
+const char*
+ssh_get_vatype_i(int id) {
+	int k, n;
+
+	n = sizeof(sshva_type_map) / sizeof(sshva_type_map[0]);
+	for (k = 0; k < n; k++) {
+		va_type_map *p = sshva_type_map + k;
+		if (id == p->id) return(p->code);
+	}
+
+	return("UNKNOWN");
+}
+
+
+static void
+ssh_set_vatype(int type) {
+	switch (type) {
+	case SSHVA_NONE:
+	case SSHVA_OCSP_CERT:
+	case SSHVA_OCSP_SPEC:
+		va.type = type;
+		break;
+	default:
+		fatal("ssh_set_vatype: invalid type %d", type);
+		break;
+	}
+}
+
+
+void
+ssh_set_validator(const VAOptions *_va) {
+	if (va.certificate_file != NULL) {
+		xfree((void*)va.certificate_file);
+		va.certificate_file = NULL;
+	}
+	if (va.responder_url != NULL) {
+		xfree((void*)va.responder_url);
+		va.responder_url = NULL;
+	}
+	if (_va == NULL) {
+		debug("ssh_set_validator: NULL options - set vatype to none");
+		ssh_set_vatype(SSHVA_NONE);
+		return;
+	}
+
+	ssh_set_vatype(_va->type); /*fatal on error*/
+	if (_va->certificate_file != NULL) {
+		switch(va.type) {
+		case SSHVA_NONE:
+		case SSHVA_OCSP_CERT:
+			debug("ssh_set_validator: ignore certificate file");
+			break;
+		case SSHVA_OCSP_SPEC:
+			va.certificate_file = xstrdup(_va->certificate_file); /*fatal on error*/
+			break;
+		}
+	}
+	switch(va.type) {
+	case SSHVA_NONE:
+	case SSHVA_OCSP_CERT:
+		debug("ssh_set_validator: ignore responder url");
+		break;
+	case SSHVA_OCSP_SPEC:
+		if (_va->responder_url == NULL) {
+			fatal("ssh_set_validator: responder url is mandatory");
+		}
+		va.responder_url = xstrdup(_va->responder_url); /*fatal on error*/
+		break;
+	}
+}
+
+
+static void
+openssl_error(const char *ssh_method, const char *openssl_method) {
+	char buf[512];
+
+	openssl_errormsg(buf, sizeof(buf));
+	error("%.128s: %.128s fail with errormsg='%.*s'"
+		, ssh_method
+		, openssl_method
+		, (int) sizeof(buf), buf);
+}
+
+
+static char*
+ssh_ASN1_GENERALIZEDTIME_2_string(ASN1_GENERALIZEDTIME *asn1_time) {
+	BIO    *bio;
+	int     k;
+	char   *p = NULL;
+
+	if (asn1_time == NULL) {
+		error("ssh_ASN1_GENERALIZEDTIME_2_string: asn1_time is NULL");
+		return(NULL);
+	}
+
+	bio = BIO_new(BIO_s_mem());
+	if (bio == NULL) {
+		error("ssh_ASN1_GENERALIZEDTIME_2_string: BIO_new fail");
+		return(NULL);
+	}
+
+	ASN1_GENERALIZEDTIME_print(bio, asn1_time);
+	(void)BIO_flush(bio);
+
+	k = BIO_pending(bio);
+	p = xmalloc(k + 1); /*fatal on error*/
+	k = BIO_read(bio, p, k);
+	p[k] = '\0';
+	BIO_free_all(bio);
+	return(p);
+}
+
+
+static STACK_OF(X509)*
+ssh_load_x509certs(const char *certs_file, const char* certs_descrip) {
+	STACK_OF(X509) *ret_certs = NULL;
+	BIO *fbio = NULL;
+
+	if (certs_file == NULL) {
+		error("ssh_load_x509certs: file is NULL");
+		goto exit;
+	}
+
+	ret_certs = sk_X509_new_null();
+	if (ret_certs == NULL) {
+		error("ssh_load_x509certs: sk_X509_new_null fail");
+		goto exit;
+	}
+
+	fbio = BIO_new(BIO_s_file());
+	if (fbio == NULL) {
+		error("ssh_load_x509certs: BIO_new fail");
+		goto exit;
+	}
+
+	if (BIO_read_filename(fbio, certs_file) <= 0) {
+		openssl_error("ssh_load_x509certs", "BIO_read_filename");
+		logit("ssh_load_x509certs:"
+			" description/filename='%.512s'/'%.512s'"
+			, certs_descrip
+			, certs_file);
+		goto exit;
+	}
+
+	{
+		int k;
+		STACK_OF(X509_INFO) *data;
+
+		data = PEM_X509_INFO_read_bio(fbio, NULL, NULL, NULL);
+		if (data == NULL) {
+			error("ssh_load_x509certs: no data.");
+			goto exit;
+		}
+
+		for (k = 0; k < sk_X509_INFO_num(data); k++) {
+			X509_INFO *xi = sk_X509_INFO_value(data, k);
+			if (xi->x509) {
+				sk_X509_push(ret_certs, xi->x509);
+				xi->x509 = NULL;
+			}
+		}
+		sk_X509_INFO_pop_free(data, X509_INFO_free);
+	}
+
+exit:
+	if (fbio != NULL) BIO_free_all(fbio);
+	if (ret_certs != NULL) {
+		debug3("ssh_load_x509certs: return %d certs", (int)sk_X509_num(ret_certs));
+	} else {
+		debug("ssh_load_x509certs: return NULL");
+	}
+	return(ret_certs);
+}
+
+
+static int/*bool*/
+ssh_ocspreq_addcert(
+	X509 *cert,
+	X509_STORE* x509store,
+	OCSP_REQUEST *req,
+	STACK_OF(OCSP_CERTID) *ids,
+	ssh_sk_OPENSSL_STRING *subjs
+) {
+	X509        *issuer = NULL;
+	OCSP_CERTID *id = NULL;
+	char        *subj = NULL;
+
+	if (cert == NULL) {
+		error("ssh_ocspreq_addcert: cert is NULL");
+		return(0);
+	}
+	if (x509store == NULL) {
+		error("ssh_ocspreq_addcert: x509store is NULL");
+		return(0);
+	}
+	if (req == NULL) {
+		error("ssh_ocspreq_addcert: req is NULL");
+		return(0);
+	}
+	if (ids == NULL) {
+		error("ssh_ocspreq_addcert: ids is NULL");
+		return(0);
+	}
+	if (subjs == NULL) {
+		error("ssh_ocspreq_addcert: subjs is NULL");
+		return(0);
+	}
+
+	issuer = ssh_x509store_get_cert_by_subject(x509store, X509_get_issuer_name(cert));
+	if (issuer == NULL) {
+		error("ssh_ocspreq_addcert: cannot found issuer certificate");
+		return(0);
+	}
+
+	id = OCSP_cert_to_id(NULL, cert, issuer);
+	if (id == NULL) {
+		error("ssh_ocspreq_addcert: OCSP_cert_to_id fail");
+		return(0);
+	}
+
+	if (!OCSP_request_add0_id(req, id)) {
+		error("ssh_ocspreq_addcert: OCSP_request_add0_id fail");
+		return(0);
+	}
+	if (!sk_OCSP_CERTID_push(ids, id)) {
+		error("ssh_ocspreq_addcert: sk_OCSP_CERTID_push fail");
+		return(0);
+	}
+	subj = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/
+	if (!sk_OPENSSL_STRING_push(subjs, subj)) {
+		error("ssh_ocspreq_addcert: sk_push(..., subj) fail");
+		return(0);
+	}
+
+	return(1);
+}
+
+
+struct ssh_ocsp_conn_s {
+	const char     *url;
+
+#ifdef SSH_WITH_SSLOCSP
+	int             use_ssl;
+#endif
+	/*pointers inside data buffer*/
+	/*const*/ char *host;
+	const char     *port;
+	const char     *path;
+
+	/*data buffer to hold all connection info*/
+	char           *data;
+};
+
+typedef struct ssh_ocsp_conn_s ssh_ocsp_conn;
+
+
+static void
+ssh_ocsp_conn_free(ssh_ocsp_conn **pconn) {
+	ssh_ocsp_conn *conn = *pconn;
+
+	if (conn == NULL) return;
+	*pconn = NULL;
+
+	/* we don't need to clean items */
+	if (conn->path != NULL) xfree((void*)conn->path);
+	if (conn->data != NULL) xfree(conn->data);
+	if (conn->url  != NULL) xfree((void*)conn->url );
+	xfree(conn);
+}
+
+
+static int/*bool*/
+ssh_ocsp_set_protocol(ssh_ocsp_conn *conn, const char *protocol) {
+	if (strcmp(protocol, "http") == 0) {
+#ifdef SSH_WITH_SSLOCSP
+		conn->use_ssl = 0;
+#endif
+		return(1);
+	}
+
+#ifdef SSH_WITH_SSLOCSP
+	if (strcmp(protocol, "https") == 0) {
+		conn->use_ssl = 1;
+		return(1);
+	}
+#endif
+
+#ifdef SSH_WITH_SSLOCSP
+	conn->use_ssl = -1;
+#endif
+	return(0);
+}
+
+
+static ssh_ocsp_conn*
+ssh_ocsp_conn_new(const char *url) {
+	ssh_ocsp_conn *conn = NULL;
+	char *p = NULL;
+	char *q = NULL;
+
+	if (url == NULL) {
+		error("ssh_ocsp_conn_new: url is NULL");
+		return(NULL);
+	}
+
+	conn = xmalloc(sizeof(*conn)); /*fatal on error*/
+	memset(conn, 0, sizeof(*conn));
+
+	conn->url = xstrdup(url); /*fatal on error*/
+	conn->data = xstrdup(url); /*fatal on error*/
+
+	/* chech for protocol */
+	p = conn->data;
+	q = strchr(p, ':');
+	if (q == NULL) goto error;
+	*q = '\x0';
+
+	if (!ssh_ocsp_set_protocol(conn, p)) {
+		error("ssh_ocsp_conn_new:"
+			" unsupported protocol '%.16s'"
+			, p);
+		goto error;
+	}
+
+	p = q;
+	if (*++p != '/') { /*this symbol is inside data */
+		error("ssh_ocsp_conn_new: expected first slash,"
+			" got char with code %d"
+			, (int)*p);
+		goto error;
+	}
+	if (*++p != '/') { /*this symbol is inside data */
+		error("ssh_ocsp_conn_new: expected second slash,"
+			" got char with code %d"
+			, (int)*p);
+		goto error;
+	}
+
+	/* chech for host and port */
+	if (*++p == '\x0') {
+		error("ssh_ocsp_conn_new: missing host in url '%.512s'", url);
+		goto error;
+	}
+	conn->host = p;
+	q = strchr(p, '/');
+	if (q != NULL) {
+		if (q[1] != '\x0') conn->path = xstrdup(q); /*fatal on error*/
+		*q = '\x0';
+		/* now p(conn->host) point only to host{:port} */
+	}
+	/*else q is NULL !!!*/
+
+	/* chech for port */
+	p = strrchr(conn->host, ':');
+	if (p != NULL) {
+		*p = '\x0';
+		if (*++p != '\x0') conn->port = p;
+	}
+	if (conn->port == NULL) {
+#ifdef SSH_WITH_SSLOCSP
+		conn->port = conn->use_ssl ? "443" : "80";
+#else
+		conn->port = "80";
+#endif
+	}
+
+exit:
+	return(conn);
+error:
+	ssh_ocsp_conn_free(&conn);
+	goto exit;
+}
+
+
+static OCSP_RESPONSE*
+ssh_ocsp_get_response(const ssh_ocsp_conn *conn, OCSP_REQUEST *req) {
+	OCSP_RESPONSE *resp = NULL;
+	BIO           *bio_conn = NULL;
+#ifdef SSH_WITH_SSLOCSP
+	SSL_CTX       *ctx = NULL;
+#endif
+
+	if (conn == NULL) {
+		error("ssh_ocsp_get_response: conn is NULL");
+		return(NULL);
+	}
+	if (req == NULL) {
+		error("ssh_ocsp_get_response: req is NULL");
+		return(NULL);
+	}
+
+#ifndef OPENSSL_NO_SOCK
+	bio_conn = BIO_new_connect(conn->host);
+	if (bio_conn == NULL) {
+		openssl_error("ssh_ocsp_get_response", "BIO_new_connect");
+		goto exit;
+	}
+#else
+	error("ssh_ocsp_get_response: sockets are not supported in OpenSSL");
+	goto exit;
+#endif
+	if (conn->port != NULL) {
+		BIO_set_conn_port(bio_conn, conn->port);
+	}
+
+#ifdef SSH_WITH_SSLOCSP
+	if (conn->use_ssl == 1) {
+		BIO *bio_sslconn;
+		/* NOTE since 18 Mar 2012 OpenSSL use only v23 method */
+		ctx = SSL_CTX_new(SSLv23_client_method());
+		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+		bio_sslconn = BIO_new_ssl(ctx, 1);
+		bio_conn = BIO_push(bio_sslconn, bio_conn);
+	}
+#endif /*def SSH_WITH_SSLOCSP*/
+
+	if (BIO_do_connect(bio_conn) <= 0) {
+		openssl_error("ssh_ocsp_get_response", "BIO_do_connect");
+		goto exit;
+	}
+
+	/*
+	 * OCSP_sendreq_bio accept null as path argument but if path
+	 * is null http request will contain <NULL> what is incorrect.
+	 */
+	resp = OCSP_sendreq_bio(bio_conn, (char*)(conn->path ? conn->path : "/") , req);
+	if (resp == NULL) {
+		openssl_error("ssh_ocsp_get_response", "OCSP_sendreq_bio");
+	}
+
+exit:
+	if (bio_conn != NULL) BIO_free_all(bio_conn);
+#ifdef SSH_WITH_SSLOCSP
+	if (ctx      != NULL) SSL_CTX_free(ctx);
+#endif
+
+	return(resp);
+}
+
+
+static OCSP_BASICRESP*
+ssh_ocsp_get_basicresp(
+	OCSP_REQUEST	*req,
+	OCSP_RESPONSE	*resp,
+	STACK_OF(X509)	*vacrts,
+	X509_STORE	*x509store
+) {
+	OCSP_BASICRESP *br = NULL;
+	unsigned long basic_verify_flags = 0/*NO:OCSP_NOEXPLICIT*/;
+	int	flag;
+
+	if (req == NULL) {
+		error("ssh_ocsp_get_basicresp: req is NULL");
+		return(NULL);
+	}
+	if (resp == NULL) {
+		error("ssh_ocsp_get_basicresp: resp is NULL");
+		return(NULL);
+	}
+	if (x509store == NULL) {
+		error("ssh_ocsp_get_basicresp: x509store is NULL");
+		return(NULL);
+	}
+
+	br = OCSP_response_get1_basic(resp);
+	if (br == NULL) {
+		openssl_error("ssh_ocsp_get_basicresp", "OCSP_response_get1_basic");
+		return(NULL);
+	}
+
+	flag = OCSP_check_nonce(req, br);
+	if (flag <= 0) {
+		if (flag == -1) {
+			logit("ssh_ocsp_get_basicresp: WARNING - no nonce in response");
+		} else {
+			openssl_error("ssh_ocsp_get_basicresp", "OCSP_check_nonce");
+			goto error;
+		}
+	}
+
+#ifdef SSHOCSPTEST
+{
+int k;
+logit("ssh_ocsp_get_basicresp: VA certs num=%d", sk_X509_num(vacrts));
+for (k = 0; k < sk_X509_num(vacrts); k++) {
+	char *buf;
+	X509 *x = sk_X509_value(vacrts, k);
+	buf = ssh_X509_NAME_oneline(X509_get_subject_name(x)); /*fatal on error*/
+	logit("ssh_ocsp_get_basicresp: VA[%d] subject='%s'", k, buf);
+	xfree(buf);
+}
+}
+#endif /*def SSHOCSPTEST*/
+
+/*
+ * RFC2560:
+ * ...
+ * All definitive response messages SHALL be digitally signed. The key
+ * used to sign the response MUST belong to one of the following:
+ *
+ * -- the CA who issued the certificate in question
+ * -- a Trusted Responder whose public key is trusted by the requester
+ * -- a CA Designated Responder (Authorized Responder) who holds a
+ *    specially marked certificate issued directly by the CA, indicating
+ *    that the responder may issue OCSP responses for that CA
+ * ...
+ *
+ * TODO: to check OpenSSL implementation
+ */
+	if ((vacrts == NULL) || (sk_X509_num(vacrts) <= 0)) {
+		flag = -1;
+	} else {
+		/*
+		 * With flag OCSP_TRUSTOTHER:
+		 * - we never get error 'without missing ocspsigning
+		 *   usage' for VA certificate !!!
+		 * Without flag OCSP_TRUSTOTHER:
+		 * - we can get OCSP_basic_verify error "root ca not trusted"
+		 */
+#if 0
+		flag = OCSP_basic_verify(br, vacrts, x509store, basic_verify_flags | OCSP_TRUSTOTHER);
+#else
+		flag = OCSP_basic_verify(br, vacrts, x509store, basic_verify_flags);
+#endif
+	}
+	if (flag < 0) {
+		flag = OCSP_basic_verify(br, NULL, x509store, basic_verify_flags);
+	}
+	if (flag <= 0) {
+		openssl_error("ssh_ocsp_get_basicresp", "OCSP_basic_verify");
+		logit("ssh_ocsp_get_basicresp: flag=%d", flag);
+		goto error;
+	}
+
+	debug3("ssh_ocsp_get_basicresp: OK");
+	return(br);
+
+error:
+	debug3("ssh_ocsp_get_basicresp: FAIL");
+	if (br != NULL) OCSP_BASICRESP_free(br);
+	return(NULL);
+}
+
+
+/*
+ * Method return value:
+ *  1 - all cert.-s are good
+ * -1 - error or at least one cert. with status unknow
+ *  0 - otherwise, i.e. at least one cert. is revoked and rest are good
+ */
+static int
+ssh_ocsp_check_validity(
+	OCSP_REQUEST *req,
+	OCSP_BASICRESP *br,
+	STACK_OF(OCSP_CERTID) *ids,
+	ssh_sk_OPENSSL_STRING *subjs
+) {
+	int ret = 1;
+	/* Maximum leeway in validity period: default 5 minutes */
+	const long nsec = (5 * 60);
+	const long maxage = -1;
+
+	int k;
+	int status, reason;
+	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+	if (req == NULL) {
+		error("ssh_ocsp_check_validity: req is NULL");
+		return(-1);
+	}
+	if (br == NULL) {
+		error("ssh_ocsp_check_validity: br is NULL");
+		return(-1);
+	}
+	if (sk_OCSP_CERTID_num(ids) <= 0) {
+		error("ssh_ocsp_check_validity:"
+			" number of ids is %d"
+			, sk_OCSP_CERTID_num(ids));
+		return(-1);
+	}
+	if (sk_OPENSSL_STRING_num(subjs) <= 0) {
+		error("ssh_ocsp_check_validity:"
+			" number of subjs is %d"
+			, sk_OPENSSL_STRING_num(subjs));
+		return(-1);
+	}
+	if (sk_OCSP_CERTID_num(ids) != sk_OPENSSL_STRING_num(subjs)) {
+		error("ssh_ocsp_check_validity:"
+			" ids(%d) != subjs(%d)"
+			, sk_OCSP_CERTID_num(ids)
+			, sk_OPENSSL_STRING_num(subjs));
+		return(-1);
+	}
+
+	for (k = 0; k < sk_OCSP_CERTID_num(ids); k++) {
+		OCSP_CERTID *id = sk_OCSP_CERTID_value(ids, k);
+
+		if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+			char *subject = sk_OPENSSL_STRING_value(subjs, k);
+			debug3("ssh_ocsp_check_validity: cert[%d]='%s'", k, subject);
+		}
+
+		if (!OCSP_resp_find_status(
+			br, id, &status, &reason,
+			&rev, &thisupd, &nextupd)
+		) {
+			ret = -1;
+			error("ssh_ocsp_check_validity: cannot found status");
+			break;
+		}
+
+		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
+			char ebuf[512];
+			ret = -1;
+			logit("ssh_ocsp_check_validity: "
+				" WARNING-invalid status time."
+				" OCSP_check_validity fail with errormsg='%.512s'"
+				, openssl_errormsg(ebuf, sizeof(ebuf)));
+			break;
+		}
+		debug("ssh_ocsp_check_validity: status=%.32s", OCSP_cert_status_str(status));
+		if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+			char *p = ssh_ASN1_GENERALIZEDTIME_2_string(thisupd);
+			debug3("ssh_ocsp_check_validity: This Update=%.128s", p);
+			xfree(p);
+			if (nextupd != NULL) {
+				p = ssh_ASN1_GENERALIZEDTIME_2_string(nextupd);
+				debug3("ssh_ocsp_check_validity: Next Update=%.128s", p);
+				xfree(p);
+			}
+		}
+
+		if (status == V_OCSP_CERTSTATUS_GOOD) continue;
+
+		if (status != V_OCSP_CERTSTATUS_REVOKED) {
+			ret = -1;
+			error("ssh_ocsp_check_validity: unknow certificate status");
+			break;
+		}
+
+		ret = 0;
+		if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+			char *p = ssh_ASN1_GENERALIZEDTIME_2_string(rev);
+			debug3("ssh_ocsp_check_validity: Revocation Time=%.128s", p);
+			xfree(p);
+			if (reason != -1) {
+				debug3("ssh_ocsp_check_validity:"
+					" Revocation Reason='%.128s'"
+					, OCSP_crl_reason_str(reason));
+			}
+		}
+		break;
+	}
+	debug3("ssh_ocsp_check_validity: return %d", ret);
+	return(ret);
+}
+
+
+static int
+ssh_ocsp_validate2(
+	X509 *cert,
+	X509_STORE *x509store,
+	const ssh_ocsp_conn *ocsp
+) {
+	int ret = -1;
+	int add_nonce = 0;
+
+	STACK_OF(X509)        *vacrts = NULL;
+	OCSP_REQUEST          *req = OCSP_REQUEST_new();
+	STACK_OF(OCSP_CERTID) *ids = sk_OCSP_CERTID_new_null();
+	ssh_sk_OPENSSL_STRING *subjs = sk_OPENSSL_STRING_new_null();
+	OCSP_RESPONSE         *resp = NULL;
+	OCSP_BASICRESP        *br = NULL;
+
+	if ((va.type == SSHVA_OCSP_SPEC) &&
+	    (va.certificate_file != NULL)) {
+		vacrts = ssh_load_x509certs(va.certificate_file, "'OCSP Responder' trusted certificates");
+		if (vacrts == NULL) goto exit;
+		debug("ssh_ocsp_validate2: VA certs num=%d", sk_X509_num(vacrts));
+	}
+
+	if (!ssh_ocspreq_addcert(cert, x509store, req, ids, subjs)) {
+		goto exit;
+	}
+
+	if (req && add_nonce) {
+		OCSP_request_add1_nonce(req, NULL, -1);
+	}
+
+	resp = ssh_ocsp_get_response(ocsp, req);
+	if (resp == NULL) goto exit;
+
+	{ /*check OCSP response status*/
+		int flag = OCSP_response_status(resp);
+		if (flag != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+			error("ssh_ocsp_validate2:"
+				" responder error=%d(%.256s)"
+				, flag
+				, OCSP_response_status_str((long/*???*/)flag));
+			goto exit;
+		}
+	}
+
+	br = ssh_ocsp_get_basicresp(req, resp, vacrts, x509store);
+	if (br == NULL) goto exit;
+
+	ret = ssh_ocsp_check_validity(req, br, ids, subjs);
+
+exit:
+	if (br     != NULL)	OCSP_BASICRESP_free(br);
+	if (resp   != NULL)	OCSP_RESPONSE_free(resp);
+	if (subjs  != NULL)	sk_OPENSSL_STRING_pop_free(subjs, OPENSSL_STRING_xfree);
+	if (ids    != NULL)	sk_OCSP_CERTID_free(ids);
+	if (req    != NULL)	OCSP_REQUEST_free(req);
+	if (vacrts != NULL)	sk_X509_pop_free(vacrts, X509_free);
+
+	return(ret);
+}
+
+
+static AUTHORITY_INFO_ACCESS*
+ssh_aia_get(X509_EXTENSION *ext) {
+	X509V3_EXT_METHOD *method = NULL;
+	void *ext_str = NULL;
+	const unsigned char *p;
+	int len;
+
+	if (ext == NULL) {
+		error("ssh_aia_get: ext is NULL");
+		return(NULL);
+	}
+
+	method = (X509V3_EXT_METHOD*) X509V3_EXT_get(ext);
+	if (method == NULL) {
+		debug("ssh_aia_get: cannot get method");
+		return(NULL);
+	}
+
+{
+	ASN1_OCTET_STRING *ext_val = X509_EXTENSION_get_data(ext);
+	ssh_ASN1_STRING_get0_data(ext_val, &p, &len);
+}
+
+	if (method->it) {
+		ext_str = ASN1_item_d2i(NULL, &p, len, ASN1_ITEM_ptr(method->it));
+	} else {
+		ext_str = method->d2i(NULL, &p, len);
+	}
+	if (ext_str == NULL) {
+		debug("ssh_aia_get: null ext_str!");
+		return(NULL);
+	}
+
+	return((AUTHORITY_INFO_ACCESS*)ext_str);
+}
+
+
+static void
+ssh_aia_free(X509_EXTENSION *ext, AUTHORITY_INFO_ACCESS* aia) {
+	X509V3_EXT_METHOD *method = NULL;
+
+	if (ext == NULL) {
+		error("ssh_aia_free: ext is NULL");
+		return;
+	}
+
+	method = (X509V3_EXT_METHOD*) X509V3_EXT_get(ext);
+	if (method == NULL) return;
+
+	if (method->it) {
+		ASN1_item_free((void*)aia, ASN1_ITEM_ptr(method->it));
+	} else {
+		method->ext_free(aia);
+	}
+}
+
+
+static int
+ssh_aiaocsp_validate(
+	X509 *cert,
+	X509_STORE *x509store,
+	AUTHORITY_INFO_ACCESS *aia,
+	int *has_ocsp_url
+) {
+	int ret = -1;
+	int k;
+	if (has_ocsp_url == NULL) {
+		fatal("ssh_aiaocsp_validate: has_ocsp_url is NULL");
+		return(-1); /*;-)*/
+	}
+
+	*has_ocsp_url = 0;
+	for (k = 0; k < sk_ACCESS_DESCRIPTION_num(aia); k++) {
+		ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(aia, k);
+		GENERAL_NAME *gn;
+		ASN1_IA5STRING *uri;
+		ssh_ocsp_conn *conn;
+
+		if (OBJ_obj2nid(ad->method) != NID_ad_OCSP) continue;
+
+		gn = ad->location;
+#if 0
+{
+BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE);
+if (bio != NULL) {
+	BIO_puts(bio, "gn->type:");
+	switch (gn->type) {
+	case GEN_OTHERNAME : BIO_puts(bio, "GEN_OTHERNAME"); break;
+	case GEN_EMAIL     : BIO_puts(bio, "GEN_EMAIL"    ); break;
+	case GEN_DNS       : BIO_puts(bio, "GEN_DNS"      ); break;
+	case GEN_X400      : BIO_puts(bio, "GEN_X400"     ); break;
+	case GEN_DIRNAME   : BIO_puts(bio, "GEN_DIRNAME"  ); break;
+	case GEN_EDIPARTY  : BIO_puts(bio, "GEN_EDIPARTY" ); break;
+	case GEN_URI       : BIO_puts(bio, "GEN_URI"      ); break;
+	case GEN_IPADD     : BIO_puts(bio, "GEN_IPADD"    ); break;
+	case GEN_RID       : BIO_puts(bio, "GEN_RID"      ); break;
+	default            : BIO_puts(bio, "[unsupported]"); break;
+	}
+	BIO_puts(bio, "\n");
+	BIO_free(bio);
+}
+}
+#endif
+		if (gn->type != GEN_URI) continue;
+
+		uri = gn->d.uniformResourceIdentifier;
+		*has_ocsp_url = 1;
+
+		conn = ssh_ocsp_conn_new((const char*)uri->data);
+		if (conn == NULL) {
+			debug("ssh_aiaocsp_validate: cannot create ocsp connection");
+			continue;
+		}
+		ret = ssh_ocsp_validate2(cert, x509store, conn);
+		ssh_ocsp_conn_free(&conn);
+
+		if (ret >= 0) break;
+	}
+
+	return(*has_ocsp_url ? ret : 1);
+}
+
+
+static int
+ssh_ocsp_validate4cert(X509 *cert, X509_STORE *x509store) {
+	int found = 0;
+	int ret = -1;
+	int loc = -1;
+
+	if (cert == NULL) return(0);
+
+	for (	loc = X509_get_ext_by_NID(cert, NID_info_access, loc);
+		loc >= 0;
+		loc = X509_get_ext_by_NID(cert, NID_info_access, loc)
+	) {
+		X509_EXTENSION	*xe;
+
+		xe = X509_get_ext(cert, loc);
+		if (xe == NULL) {
+			debug("ssh_ocsp_validate4cert: cannot get x509 extension");
+			continue;
+		}
+
+		{/*validate from AIA*/
+			AUTHORITY_INFO_ACCESS	*aia = ssh_aia_get(xe);
+			if (aia == NULL) continue;
+
+			ret = ssh_aiaocsp_validate(cert, x509store, aia, &found);
+
+			ssh_aia_free(xe, aia);
+		}
+
+		if (ret >= 0) break;
+	}
+
+	if (found) {
+		debug3("ssh_ocsp_validate4cert: validation result=%d", ret);
+	} else {
+		debug3("ssh_ocsp_validate4cert: no OCSP 'Service Locator' URL");
+	}
+	return(found ? ret : 1);
+}
+
+
+int
+ssh_ocsp_validate(X509 *cert, X509_STORE *x509store) {
+	int ret = -1;
+	ssh_ocsp_conn	*conn = NULL;
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		char *buf = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/
+		debug3("ssh_ocsp_validate: for '%s'", buf);
+		xfree(buf);
+	}
+
+	switch (va.type) {
+	default:
+		/*when something is missing*/
+		fatal("ssh_ocsp_validate: invalid validator type %d", va.type);
+		break; /*;-)*/
+	case SSHVA_NONE:
+		debug3("ssh_ocsp_validate: none");
+		ret = 1;
+		break;
+	case SSHVA_OCSP_CERT:
+		ret = ssh_ocsp_validate4cert(cert, x509store);
+		break;
+	case SSHVA_OCSP_SPEC:
+		conn = ssh_ocsp_conn_new(va.responder_url);
+		if (conn != NULL) {
+			ret = ssh_ocsp_validate2(cert, x509store, conn);
+			ssh_ocsp_conn_free(&conn);
+		}
+		break;
+	}
+
+	return(ret);
+}
diff -ruN openssh-7.5p1/ssh-pkcs11.c openssh-7.5p1+x509-10.2/ssh-pkcs11.c
--- openssh-7.5p1/ssh-pkcs11.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-pkcs11.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,9 @@
 /* $OpenBSD: ssh-pkcs11.c,v 1.23 2016/10/28 03:33:52 djm Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Kenneth Robinette.  All rights reserved.
+ * Copyright (c) 2013 Andrew Cooke.  All rights reserved.
+ * Copyright (c) 2016 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +22,11 @@
 
 #ifdef ENABLE_PKCS11
 
+#ifndef HAVE_RSA_PKCS1_OPENSSL
+# undef RSA_PKCS1_OpenSSL
+# define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
+#endif
+
 #include <sys/types.h>
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -32,6 +40,7 @@
 #include "openbsd-compat/sys-queue.h"
 
 #include <openssl/x509.h>
+#include "evp-compat.h"
 
 #define CRYPTOKI_COMPAT
 #include "pkcs11.h"
@@ -42,6 +51,14 @@
 #include "ssh-pkcs11.h"
 #include "xmalloc.h"
 
+/* Define if you want yo use legacy rsa key code */
+#undef USE_LEGACY_PKCS11_RSAKEY
+
+#ifndef USE_LEGACY_PKCS11_RSAKEY
+#include "ssh-x509.h"
+#endif
+
+
 struct pkcs11_slotinfo {
 	CK_TOKEN_INFO		token;
 	CK_SESSION_HANDLE	session;
@@ -63,15 +80,76 @@
 
 TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
 
+
+/*
+ * Constants used when creating the context extra data
+ */
+static int ssh_pkcs11_rsa_ctx_index = -1;
+static int ssh_pkcs11_dsa_ctx_index = -1;
+#ifdef OPENSSL_HAS_ECC
+static int ssh_pkcs11_ec_ctx_index = -1;
+#endif /*def OPENSSL_HAS_ECC*/
+
 struct pkcs11_key {
 	struct pkcs11_provider	*provider;
 	CK_ULONG		slotidx;
-	int			(*orig_finish)(RSA *rsa);
-	RSA_METHOD		rsa_method;
 	char			*keyid;
 	int			keyid_len;
 };
 
+static void pkcs11_provider_unref(struct pkcs11_provider *p);
+
+static void
+pkcs11_key_free(struct pkcs11_key *k11) {
+	if (k11 == NULL) return;
+
+	if (k11->provider)
+		pkcs11_provider_unref(k11->provider);
+	free(k11->keyid);
+	free(k11);
+}
+
+static void
+CRYPTO_EX_pkcs11_key_free(
+    void *parent, void *ptr, CRYPTO_EX_DATA *ad, long argl, void *argp
+) {
+	(void)parent;
+	pkcs11_key_free(ptr);
+	(void)ad;
+	(void)argl;
+	(void)argp;
+}
+
+static void
+CRYPTO_EX_pkcs11_rsa_free(
+    void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+    int idx, long argl, void *argp
+) {
+	if (idx == ssh_pkcs11_rsa_ctx_index)
+		CRYPTO_EX_pkcs11_key_free(parent, ptr, ad, argl, argp);
+}
+
+static void
+CRYPTO_EX_pkcs11_dsa_free(
+    void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+    int idx, long argl, void *argp
+) {
+	if (idx == ssh_pkcs11_dsa_ctx_index)
+		CRYPTO_EX_pkcs11_key_free(parent, ptr, ad, argl, argp);
+}
+
+#ifdef OPENSSL_HAS_ECC
+static void
+CRYPTO_EX_pkcs11_ec_free(
+    void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+    int idx, long argl, void *argp
+) {
+	if (idx == ssh_pkcs11_ec_ctx_index)
+		CRYPTO_EX_pkcs11_key_free(parent, ptr, ad, argl, argp);
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
 int pkcs11_interactive = 0;
 
 int
@@ -95,7 +173,7 @@
 	CK_ULONG i;
 
 	debug("pkcs11_provider_finalize: %p refcount %d valid %d",
-	    p, p->refcount, p->valid);
+	    (void*)p, p->refcount, p->valid);
 	if (!p->valid)
 		return;
 	for (i = 0; i < p->nslots; i++) {
@@ -118,10 +196,10 @@
 static void
 pkcs11_provider_unref(struct pkcs11_provider *p)
 {
-	debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount);
+	debug("pkcs11_provider_unref: %p refcount %d", (void*)p, p->refcount);
 	if (--p->refcount <= 0) {
 		if (p->valid)
-			error("pkcs11_provider_unref: %p still valid", p);
+			error("pkcs11_provider_unref: %p still valid", (void*)p);
 		free(p->slotlist);
 		free(p->slotinfo);
 		free(p);
@@ -148,7 +226,7 @@
 	struct pkcs11_provider *p;
 
 	TAILQ_FOREACH(p, &pkcs11_providers, next) {
-		debug("check %p %s", p, p->name);
+		debug("check %p %s", (void*)p, p->name);
 		if (!strcmp(provider_id, p->name))
 			return (p);
 	}
@@ -175,19 +253,44 @@
 pkcs11_rsa_finish(RSA *rsa)
 {
 	struct pkcs11_key	*k11;
-	int rv = -1;
 
-	if ((k11 = RSA_get_app_data(rsa)) != NULL) {
-		if (k11->orig_finish)
-			rv = k11->orig_finish(rsa);
-		if (k11->provider)
-			pkcs11_provider_unref(k11->provider);
-		free(k11->keyid);
-		free(k11);
-	}
-	return (rv);
+	k11 = RSA_get_ex_data(rsa, ssh_pkcs11_rsa_ctx_index);
+	RSA_set_ex_data(rsa, ssh_pkcs11_rsa_ctx_index, NULL);
+	pkcs11_key_free(k11);
+	return (1);
 }
 
+/* openssl callback for freeing an DSA key */
+static int
+pkcs11_dsa_finish(DSA *dsa)
+{
+	struct pkcs11_key	*k11;
+
+	k11 = DSA_get_ex_data(dsa, ssh_pkcs11_dsa_ctx_index);
+	DSA_set_ex_data(dsa, ssh_pkcs11_dsa_ctx_index, NULL);
+	pkcs11_key_free(k11);
+	return (1);
+}
+
+#ifdef OPENSSL_HAS_ECC
+/* openssl callback for freeing an EC key */
+static void
+pkcs11_ec_finish(EC_KEY *ec)
+{
+	struct pkcs11_key	*k11;
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+	k11 = EC_KEY_get_ex_data(ec, ssh_pkcs11_ec_ctx_index);
+	EC_KEY_set_ex_data(ec, ssh_pkcs11_ec_ctx_index, NULL);
+#else
+	k11 = ECDSA_get_ex_data(ec, ssh_pkcs11_ec_ctx_index);
+	ECDSA_set_ex_data(ec, ssh_pkcs11_ec_ctx_index, NULL);
+#endif
+	pkcs11_key_free(k11);
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
 /* find a single 'obj' for given attributes */
 static int
 pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr,
@@ -240,15 +343,17 @@
 	char			*pin = NULL, prompt[1024];
 	int			rval = -1;
 
+	(void)padding;
 	key_filter[0].pValue = &private_key_class;
 	key_filter[2].pValue = &true_val;
 
-	if ((k11 = RSA_get_app_data(rsa)) == NULL) {
-		error("RSA_get_app_data failed for rsa %p", rsa);
+	k11 = RSA_get_ex_data(rsa, ssh_pkcs11_rsa_ctx_index);
+	if (k11 == NULL) {
+		error("RSA_get_ex_data failed for rsa %p", (void*)rsa);
 		return (-1);
 	}
 	if (!k11->provider || !k11->provider->valid) {
-		error("no pkcs11 (valid) provider for rsa %p", rsa);
+		error("no pkcs11 (valid) provider for rsa %p", (void*)rsa);
 		return (-1);
 	}
 	f = k11->provider->function_list;
@@ -305,16 +410,54 @@
 pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
     int padding)
 {
+	(void)flen;
+	(void)from;
+	(void)to;
+	(void)rsa;
+	(void)padding;
 	return (-1);
 }
 
+static RSA_METHOD *ssh_pkcs11_rsa_method = NULL;
+
 /* redirect private key operations for rsa key to pkcs11 token */
 static int
 pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
     CK_ATTRIBUTE *keyid_attrib, RSA *rsa)
 {
 	struct pkcs11_key	*k11;
-	const RSA_METHOD	*def = RSA_get_default_method();
+
+	/* ensure RSA context index */
+	if (ssh_pkcs11_rsa_ctx_index < 0)
+		ssh_pkcs11_rsa_ctx_index = RSA_get_ex_new_index(0, NULL, NULL, NULL, CRYPTO_EX_pkcs11_rsa_free);
+	if (ssh_pkcs11_rsa_ctx_index < 0) {
+		return (-1);
+	}
+
+	if (ssh_pkcs11_rsa_method == NULL) {
+		const RSA_METHOD *def = RSA_PKCS1_OpenSSL();
+
+		ssh_pkcs11_rsa_method = RSA_meth_new("SSH PKCS#11 RSA method",
+		#ifdef RSA_FLAG_FIPS_METHOD
+			RSA_FLAG_FIPS_METHOD |
+		#endif
+			0);
+		if (ssh_pkcs11_rsa_method == NULL)
+			return (-1);
+
+		if (!RSA_meth_set_priv_enc(ssh_pkcs11_rsa_method, pkcs11_rsa_private_encrypt)
+		||  !RSA_meth_set_priv_dec(ssh_pkcs11_rsa_method, pkcs11_rsa_private_decrypt)
+		||  !RSA_meth_set_finish(ssh_pkcs11_rsa_method, pkcs11_rsa_finish)
+		)
+			goto err;
+
+		if (!RSA_meth_set_pub_enc(ssh_pkcs11_rsa_method, RSA_meth_get_pub_enc(def))
+		||  !RSA_meth_set_pub_dec(ssh_pkcs11_rsa_method, RSA_meth_get_pub_dec(def))
+		||  !RSA_meth_set_mod_exp(ssh_pkcs11_rsa_method, RSA_meth_get_mod_exp(def))
+		||  !RSA_meth_set_bn_mod_exp(ssh_pkcs11_rsa_method, RSA_meth_get_bn_mod_exp(def))
+		)
+			goto err;
+	}
 
 	k11 = xcalloc(1, sizeof(*k11));
 	k11->provider = provider;
@@ -326,17 +469,405 @@
 		k11->keyid = xmalloc(k11->keyid_len);
 		memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
 	}
-	k11->orig_finish = def->finish;
-	memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
-	k11->rsa_method.name = "pkcs11";
-	k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
-	k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
-	k11->rsa_method.finish = pkcs11_rsa_finish;
-	RSA_set_method(rsa, &k11->rsa_method);
-	RSA_set_app_data(rsa, k11);
+	RSA_set_method(rsa, ssh_pkcs11_rsa_method);
+	RSA_set_ex_data(rsa, ssh_pkcs11_rsa_ctx_index, k11);
 	return (0);
+
+err:
+	RSA_meth_free(ssh_pkcs11_rsa_method);
+	ssh_pkcs11_rsa_method = NULL;
+	return (-1);
+}
+
+static DSA_SIG*
+parse_DSA_SIG(char *buf, CK_ULONG blen) {
+	DSA_SIG *sig;
+	BIGNUM *ps, *pr;
+	int  k = blen >> 1;
+
+	pr = BN_bin2bn(buf    , k, NULL);
+	ps = BN_bin2bn(buf + k, k, NULL);
+	if ((pr == NULL) || (ps == NULL)) goto parse_err;
+
+	sig = DSA_SIG_new();
+	if (sig == NULL) goto parse_err;
+
+	if (DSA_SIG_set0(sig, pr, ps))
+		return (sig);
+
+/*error*/
+	DSA_SIG_free(sig);
+parse_err:
+	BN_free(pr);
+	BN_free(ps);
+	return (NULL);
+}
+
+/* redirect private key operations for dsa key to pkcs11 token */
+static DSA_SIG*
+pkcs11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+	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_DSA, NULL_PTR, 0
+	};
+	CK_ATTRIBUTE		key_filter[] = {
+		{CKA_CLASS, NULL, sizeof(private_key_class) },
+		{CKA_ID, NULL, 0},
+		{CKA_SIGN, NULL, sizeof(true_val) }
+	};
+	char			*pin, prompt[1024];
+	DSA_SIG			*sig = NULL;
+
+	debug3("pkcs11_dsa_do_sign");
+
+	/* some compilers complain about non-constant initializer so we
+	   use NULL in CK_ATTRIBUTE above and set the values here */
+	key_filter[0].pValue = &private_key_class;
+	key_filter[2].pValue = &true_val;
+
+	k11 = DSA_get_ex_data(dsa, ssh_pkcs11_dsa_ctx_index);
+	if (k11 == NULL) {
+		error("DSA_get_ex_data failed for dsa %p", (void*)dsa);
+		return NULL;
+	}
+	if (!k11->provider || !k11->provider->valid) {
+		error("no pkcs11 (valid) provider for dsa %p", (void*)dsa);
+		return NULL;
+	}
+	f = k11->provider->function_list;
+	si = &k11->provider->slotinfo[k11->slotidx];
+	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
+		if (!pkcs11_interactive) {
+			error("need pin");
+			return (NULL);
+		}
+		snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
+		    si->token.label);
+		pin = read_passphrase(prompt, RP_ALLOW_EOF);
+		if (pin == NULL)
+			return (NULL);	/* bail out */
+		if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin)))
+		    != CKR_OK) {
+			free(pin);
+			error("C_Login failed: %lu", rv);
+			return (NULL);
+		}
+		free(pin);
+		si->logged_in = 1;
+	}
+	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 {
+		char rs[(2*SHA_DIGEST_LENGTH)];
+		tlen = (2*SHA_DIGEST_LENGTH);
+		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dlen, rs, &tlen);
+		if (rv == CKR_OK) {
+			sig = parse_DSA_SIG(rs, tlen);
+		}
+		else
+			error("C_Sign failed: %lu", rv);
+	}
+	return (sig);
 }
 
+
+static DSA_METHOD *ssh_pkcs11_dsa_method = NULL;
+
+
+static int
+pkcs11_dsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
+    CK_ATTRIBUTE *keyid_attrib, DSA *dsa)
+{
+	struct pkcs11_key	*k11;
+
+	/* ensure DSA context index */
+	if (ssh_pkcs11_dsa_ctx_index < 0)
+		ssh_pkcs11_dsa_ctx_index = DSA_get_ex_new_index(0, NULL, NULL, NULL, CRYPTO_EX_pkcs11_dsa_free);
+	if (ssh_pkcs11_dsa_ctx_index < 0) {
+		return (-1);
+	}
+
+	if (ssh_pkcs11_dsa_method == NULL) {
+		const DSA_METHOD *def = DSA_OpenSSL();
+
+		ssh_pkcs11_dsa_method = DSA_meth_new("SSH PKCS#11 DSA method",
+		#ifdef DSA_FLAG_FIPS_METHOD
+			DSA_FLAG_FIPS_METHOD |
+		#endif
+			0);
+		if (ssh_pkcs11_dsa_method == NULL)
+			return (-1);
+
+		if (!DSA_meth_set_sign(ssh_pkcs11_dsa_method, pkcs11_dsa_do_sign)
+		||  !DSA_meth_set_finish(ssh_pkcs11_dsa_method, pkcs11_dsa_finish)
+		)
+			goto err;
+
+		if (!DSA_meth_set_verify(ssh_pkcs11_dsa_method, DSA_meth_get_verify(def))
+		||  !DSA_meth_set_mod_exp(ssh_pkcs11_dsa_method, DSA_meth_get_mod_exp(def))
+		||  !DSA_meth_set_bn_mod_exp(ssh_pkcs11_dsa_method, DSA_meth_get_bn_mod_exp(def))
+		)
+			goto err;
+	}
+
+	k11 = xcalloc(1, sizeof(*k11));
+	k11->provider = provider;
+	provider->refcount++;	/* provider referenced by DSA 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);
+	}
+	DSA_set_method(dsa, ssh_pkcs11_dsa_method);
+	DSA_set_ex_data(dsa, ssh_pkcs11_dsa_ctx_index, k11);
+	return (0);
+
+err:
+	DSA_meth_free(ssh_pkcs11_dsa_method);
+	ssh_pkcs11_dsa_method = NULL;
+	return (-1);
+}
+
+
+#ifdef OPENSSL_HAS_ECC
+static ECDSA_SIG*
+parse_ECDSA_SIG(char *buf, CK_ULONG blen) {
+	ECDSA_SIG *sig;
+	BIGNUM *ps, *pr;
+	int  k = blen >> 1;
+
+	pr = BN_bin2bn(buf    , k, NULL);
+	ps = BN_bin2bn(buf + k, k, NULL);
+	if ((pr == NULL) || (ps == NULL)) goto parse_err;
+
+	sig = ECDSA_SIG_new();
+	if (sig == NULL) goto parse_err;
+
+	if (ECDSA_SIG_set0(sig, pr, ps))
+		return (sig);
+
+/*error*/
+	ECDSA_SIG_free(sig);
+parse_err:
+	BN_free(pr);
+	BN_free(ps);
+	return (NULL);
+}
+
+
+/* redirect private key operations for ec key to pkcs11 token */
+static ECDSA_SIG*
+pkcs11_ecdsa_do_sign(
+	const unsigned char *dgst, int dlen,
+	const BIGNUM *inv, const BIGNUM *rp,
+	EC_KEY *ec
+) {
+	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) }
+	};
+	char			*pin, prompt[1024];
+	ECDSA_SIG		*sig = NULL;
+
+	debug3("pkcs11_ecdsa_do_sign");
+
+	(void)inv;
+	(void)rp;
+
+	/* some compilers complain about non-constant initializer so we
+	   use NULL in CK_ATTRIBUTE above and set the values here */
+	key_filter[0].pValue = &private_key_class;
+	key_filter[2].pValue = &true_val;
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+	k11 = EC_KEY_get_ex_data(ec, ssh_pkcs11_ec_ctx_index);
+#else
+	k11 = ECDSA_get_ex_data(ec, ssh_pkcs11_ec_ctx_index);
+#endif
+	if (k11 == NULL) {
+	#ifdef HAVE_EC_KEY_METHOD_NEW
+		error("EC_KEY_get_ex_data failed for ec %p", (void*)ec);
+	#else
+		error("ECDSA_get_ex_data failed for ec %p", (void*)ec);
+	#endif
+		return NULL;
+	}
+	if (!k11->provider || !k11->provider->valid) {
+		error("no pkcs11 (valid) provider for ec %p", (void*)ec);
+		return NULL;
+	}
+	f = k11->provider->function_list;
+	si = &k11->provider->slotinfo[k11->slotidx];
+	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
+		if (!pkcs11_interactive) {
+			error("need pin");
+			return (NULL);
+		}
+		snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
+		    si->token.label);
+		pin = read_passphrase(prompt, RP_ALLOW_EOF);
+		if (pin == NULL)
+			return (NULL);	/* bail out */
+		if ((rv = f->C_Login(si->session, CKU_USER, pin, strlen(pin)))
+		    != CKR_OK) {
+			free(pin);
+			error("C_Login failed: %lu", rv);
+			return (NULL);
+		}
+		free(pin);
+		si->logged_in = 1;
+	}
+	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 {
+		char rs[(1024>>2)/*> 2*[521/8]=2*66 */];
+
+		tlen = sizeof(rs);
+		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dlen, rs, &tlen);
+		if (rv == CKR_OK) {
+			sig = parse_ECDSA_SIG(rs, tlen);
+		}
+		else
+			error("C_Sign failed: %lu", rv);
+	}
+	return (sig);
+}
+
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static int
+pkcs11_ecdsa_sign(int type,
+	const unsigned char *dgst, int dlen,
+	unsigned char *sig, unsigned int *siglen,
+	const BIGNUM *inv, const BIGNUM *rp,
+	EC_KEY *ec
+) {
+	ECDSA_SIG *s;
+
+	debug3("pkcs11_ecdsa_sign");
+	(void)type;
+
+	s = pkcs11_ecdsa_do_sign(dgst, dlen, inv, rp, ec);
+	if (s == NULL) {
+		*siglen = 0;
+		return (0);
+	}
+
+	*siglen = i2d_ECDSA_SIG(s, &sig);
+
+	ECDSA_SIG_free(s);
+	return (1);
+}
+#endif /*def HAVE_EC_KEY_METHOD_NEW*/
+
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static EC_KEY_METHOD *pkcs11_ec_method = NULL;
+#else
+static ECDSA_METHOD  *pkcs11_ec_method = NULL;
+#endif
+
+
+static int
+pkcs11_ec_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
+    CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec)
+{
+	struct pkcs11_key	*k11;
+
+	/* ensure EC context index */
+	if (ssh_pkcs11_ec_ctx_index < 0)
+	#ifdef HAVE_EC_KEY_METHOD_NEW
+		ssh_pkcs11_ec_ctx_index = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, CRYPTO_EX_pkcs11_ec_free);
+	#else
+		ssh_pkcs11_ec_ctx_index = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, CRYPTO_EX_pkcs11_ec_free);
+	#endif
+	if (ssh_pkcs11_ec_ctx_index < 0) {
+		return (-1);
+	}
+
+	if (pkcs11_ec_method == NULL) {
+	#ifdef HAVE_EC_KEY_METHOD_NEW
+		pkcs11_ec_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
+
+		EC_KEY_METHOD_set_init(pkcs11_ec_method,
+		    NULL /* int (*init)(...) */,
+		    pkcs11_ec_finish,
+		    NULL /* int (*copy)(...) */,
+		    NULL /* int (*set_group)(...) */,
+		    NULL /* int (*set_private)(...) */,
+		    NULL /* int (*set_public)(...) */
+		);
+
+		EC_KEY_METHOD_set_sign(pkcs11_ec_method,
+		    pkcs11_ecdsa_sign,
+		    NULL /* *sign_setup */,
+		    pkcs11_ecdsa_do_sign
+		);
+	#else
+		pkcs11_ec_method = ECDSA_METHOD_new(ECDSA_OpenSSL());
+
+		ECDSA_METHOD_set_sign(pkcs11_ec_method,
+		    pkcs11_ecdsa_do_sign
+		);
+	#endif
+	}
+
+	k11 = xcalloc(1, sizeof(*k11));
+	k11->provider = provider;
+	provider->refcount++;	/* provider referenced by EC 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);
+	}
+#ifdef HAVE_EC_KEY_METHOD_NEW
+	EC_KEY_set_method(ec, pkcs11_ec_method);
+	EC_KEY_set_ex_data(ec, ssh_pkcs11_ec_ctx_index, k11);
+#else
+	ECDSA_set_method(ec, pkcs11_ec_method);
+	ECDSA_set_ex_data(ec, ssh_pkcs11_ec_ctx_index, k11);
+#endif
+	return (0);
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
 /* remove trailing spaces */
 static void
 rmspace(u_char *buf, size_t len)
@@ -397,7 +928,7 @@
  * keysp points to an (possibly empty) array with *nkeys keys.
  */
 static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG,
-    CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *)
+    CK_ATTRIBUTE [], int, CK_ATTRIBUTE [3], struct sshkey ***, int *)
 	__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE))));
 
 static int
@@ -409,8 +940,15 @@
 	CK_ATTRIBUTE		pubkey_filter[] = {
 		{ CKA_CLASS, NULL, sizeof(pubkey_class) }
 	};
+#ifndef USE_LEGACY_PKCS11_RSAKEY
+	/* Find objects with cert class and X.509 cert type. */
+	CK_CERTIFICATE_TYPE	type = CKC_X_509;
+#endif
 	CK_ATTRIBUTE		cert_filter[] = {
 		{ CKA_CLASS, NULL, sizeof(cert_class) }
+#ifndef USE_LEGACY_PKCS11_RSAKEY
+	,	{ CKA_CERTIFICATE_TYPE, NULL, sizeof(type) }
+#endif
 	};
 	CK_ATTRIBUTE		pubkey_attribs[] = {
 		{ CKA_ID, NULL, 0 },
@@ -422,17 +960,30 @@
 		{ CKA_SUBJECT, NULL, 0 },
 		{ CKA_VALUE, NULL, 0 }
 	};
+	/* some compilers complain about non-constant initializer so we
+	   use NULL in CK_ATTRIBUTE above and set the value here */
 	pubkey_filter[0].pValue = &pubkey_class;
 	cert_filter[0].pValue = &cert_class;
+#ifndef USE_LEGACY_PKCS11_RSAKEY
+	cert_filter[1].pValue = &type;
+#endif
 
-	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs,
+#ifdef USE_LEGACY_PKCS11_RSAKEY
+	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, 1, pubkey_attribs,
 	    keysp, nkeys) < 0 ||
-	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs,
-	    keysp, nkeys) < 0)
+#else
+	(void)pubkey_filter;
+	(void)pubkey_attribs;
+	if (
+#endif
+	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, sizeof(cert_filter)/sizeof(*cert_filter),
+	    cert_attribs, keysp, nkeys) < 0)
 		return (-1);
 	return (0);
 }
 
+
+#ifdef USE_LEGACY_PKCS11_RSAKEY
 static int
 pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
 {
@@ -443,16 +994,19 @@
 			return (1);
 	return (0);
 }
+#endif /*def USE_LEGACY_PKCS11_RSAKEY*/
 
 static int
 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
-    CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
+    CK_ATTRIBUTE filter[], int filter_size, CK_ATTRIBUTE attribs[3],
     struct sshkey ***keysp, int *nkeys)
 {
 	struct sshkey		*key;
+#ifdef USE_LEGACY_PKCS11_RSAKEY
 	RSA			*rsa;
 	X509 			*x509;
 	EVP_PKEY		*evp;
+#endif
 	int			i;
 	const u_char		*cp;
 	CK_RV			rv;
@@ -464,7 +1018,7 @@
 	f = p->function_list;
 	session = p->slotinfo[slotidx].session;
 	/* setup a filter the looks for public keys */
-	if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) {
+	if ((rv = f->C_FindObjectsInit(session, filter, filter_size)) != CKR_OK) {
 		error("C_FindObjectsInit failed: %lu", rv);
 		return (-1);
 	}
@@ -477,7 +1031,7 @@
 		if ((rv = f->C_FindObjects(session, &obj, 1, &nfound)) != CKR_OK
 		    || nfound == 0)
 			break;
-		/* found a key, so figure out size of the attributes */
+		/* found a object, so figure out size of the attributes */
 		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
 		    != CKR_OK) {
 			error("C_GetAttributeValue failed: %lu", rv);
@@ -504,10 +1058,13 @@
 		 * retrieve ID, modulus and public exponent of RSA key,
 		 * or ID, subject and value for certificates.
 		 */
+#ifdef USE_LEGACY_PKCS11_RSAKEY
 		rsa = NULL;
+#endif
 		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
 		    != CKR_OK) {
 			error("C_GetAttributeValue failed: %lu", rv);
+#ifdef USE_LEGACY_PKCS11_RSAKEY
 		} else if (attribs[1].type == CKA_MODULUS ) {
 			if ((rsa = RSA_new()) == NULL) {
 				error("RSA_new failed");
@@ -553,6 +1110,44 @@
 			}
 		} else if (rsa) {
 			RSA_free(rsa);
+#else /* ndef USE_LEGACY_PKCS11_RSAKEY */
+		} else {
+			int rv_wrap;
+			(void)cp;
+			key = x509key_from_blob(attribs[2].pValue, attribs[2].ulValueLen);
+			if (key == NULL) {
+				/* x509key_from_blob return NULL if key type is not
+				 * supported and if can not extract X.509 certificate
+				 */
+				debug3("%s: x509key_from_blob fail", __func__);
+				continue;
+			}
+
+			switch(X509KEY_BASETYPE(key)) {
+			case KEY_RSA:
+				rv_wrap = pkcs11_rsa_wrap(p, slotidx, &attribs[0], key->rsa);
+				break;
+			case KEY_DSA:
+				rv_wrap = pkcs11_dsa_wrap(p, slotidx, &attribs[0], key->dsa);
+				break;
+#ifdef OPENSSL_HAS_ECC
+			case KEY_ECDSA:
+				rv_wrap = pkcs11_ec_wrap(p, slotidx, &attribs[0], key->ecdsa);
+				break;
+#endif /*def OPENSSL_HAS_ECC*/
+			default:
+				rv_wrap = -1;
+			}
+
+			if (rv_wrap == 0) {
+				key->flags |= KEY_FLAG_EXT;
+				/* expand key array and add key */
+				*keysp = xreallocarray(*keysp, *nkeys + 1, sizeof(Key *));
+				(*keysp)[*nkeys] = key;
+				*nkeys = *nkeys + 1;
+				debug("have %d keys", *nkeys);
+			}
+#endif /* ndef USE_LEGACY_PKCS11_RSAKEY */
 		}
 		for (i = 0; i < 3; i++)
 			free(attribs[i].pValue);
diff -ruN openssh-7.5p1/ssh-pkcs11-client.c openssh-7.5p1+x509-10.2/ssh-pkcs11-client.c
--- openssh-7.5p1/ssh-pkcs11-client.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-pkcs11-client.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,7 @@
 /* $OpenBSD: ssh-pkcs11-client.c,v 1.6 2015/12/11 00:20:04 mmcc Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2016 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +20,11 @@
 
 #ifdef ENABLE_PKCS11
 
+#ifndef HAVE_RSA_PKCS1_OPENSSL
+# undef RSA_PKCS1_OpenSSL
+# define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
+#endif
+
 #include <sys/types.h>
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -31,6 +37,7 @@
 #include <errno.h>
 
 #include <openssl/rsa.h>
+#include "evp-compat.h"
 
 #include "pathnames.h"
 #include "xmalloc.h"
@@ -93,6 +100,7 @@
 int
 pkcs11_init(int interactive)
 {
+	(void)interactive;
 	return (0);
 }
 
@@ -139,18 +147,160 @@
 	return (ret);
 }
 
+#ifdef OPENSSL_HAS_ECC
+static ECDSA_SIG*
+pkcs11_ecdsa_do_sign(
+	const unsigned char *dgst, int dlen,
+	const BIGNUM *inv, const BIGNUM *rp,
+	EC_KEY *ec
+) {
+	ECDSA_SIG* ret = NULL;
+	Key key;
+	Buffer msg;
+
+	(void)inv;
+	(void)rp;
+
+	key.type = KEY_ECDSA;
+	key.ecdsa = ec;
+	key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ec);
+{
+	u_char *blob;
+	u_int blen;
+
+	if (key_to_blob(&key, &blob, &blen) == 0)
+		goto done;
+
+	buffer_init(&msg);
+	buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
+	buffer_put_string(&msg, blob, blen);
+	buffer_put_string(&msg, dgst, dlen);
+	buffer_put_int(&msg, 0);
+	free(blob);
+}
+	send_msg(&msg);
+
+	buffer_clear(&msg);
+
+	if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) {
+		u_char *signature;
+		u_int slen = 0;
+
+		signature = buffer_get_string(&msg, &slen);
+		if (signature == NULL) {
+			buffer_free(&msg);
+			goto done;
+		}
+
+		{	/* decode ECDSA signature */
+			const unsigned char *p = signature;
+			ret = d2i_ECDSA_SIG(NULL, &p, slen);
+		}
+		free(signature);
+	}
+	buffer_free(&msg);
+
+done:
+	return (ret);
+}
+
+#ifdef HAVE_EC_KEY_METHOD_NEW
+static int
+pkcs11_ecdsa_sign(int type,
+	const unsigned char *dgst, int dlen,
+	unsigned char *sig, unsigned int *siglen,
+	const BIGNUM *inv, const BIGNUM *rp,
+	EC_KEY *ec
+) {
+	ECDSA_SIG *s;
+
+	debug3("pkcs11_ecdsa_sign");
+	(void)type;
+
+	s = pkcs11_ecdsa_do_sign(dgst, dlen, inv, rp, ec);
+	if (s == NULL) {
+		*siglen = 0;
+		return (0);
+	}
+
+	*siglen = i2d_ECDSA_SIG(s, &sig);
+
+	ECDSA_SIG_free(s);
+	return (1);
+}
+#endif /*def HAVE_EC_KEY_METHOD_NEW*/
+#endif /*def OPENSSL_HAS_ECC*/
+
 /* redirect the 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 = NULL;
+
+	if (helper_rsa == NULL) {
+		helper_rsa = RSA_meth_dup(RSA_PKCS1_OpenSSL());
+		if (helper_rsa == NULL)
+			return (-1);
+
+		if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper")
+		||  !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt)
+		) {
+			RSA_meth_free(helper_rsa);
+			helper_rsa = NULL;
+			return (-1);
+		}
+	}
+
+	if (!RSA_set_method(rsa, helper_rsa))
+		return (-1);
+	return (0);
+}
+
+#ifdef OPENSSL_HAS_ECC
+static int
+wrap_ec_key(EC_KEY *ec)
 {
-	static RSA_METHOD helper_rsa;
+#ifdef HAVE_EC_KEY_METHOD_NEW
+	static EC_KEY_METHOD *helper_ec = NULL;
+
+	if (helper_ec == NULL) {
+		helper_ec = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
+		if (helper_ec == NULL)
+			return (-1);
+
+		EC_KEY_METHOD_set_sign(helper_ec,
+		    pkcs11_ecdsa_sign,
+		    NULL /* *sign_setup */,
+		    pkcs11_ecdsa_do_sign);
+	}
+	EC_KEY_set_method(ec, helper_ec);
+#else
+	static ECDSA_METHOD *helper_ec = NULL;
+
+	if (helper_ec == NULL) {
+		helper_ec = ECDSA_METHOD_new(ECDSA_OpenSSL());
+		if (helper_ec == NULL)
+			return (-1);
 
-	memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
-	helper_rsa.name = "ssh-pkcs11-helper";
-	helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
-	RSA_set_method(rsa, &helper_rsa);
+		ECDSA_METHOD_set_sign(helper_ec,
+		    pkcs11_ecdsa_do_sign);
+	}
+	ECDSA_set_method(ec, helper_ec);
+#endif
 	return (0);
 }
+#endif /*def OPENSSL_HAS_ECC*/
+
+static int
+wrap_key(Key *key) {
+	switch(X509KEY_BASETYPE(key)) {
+	case KEY_RSA: return (wrap_rsa_key(key->rsa));
+#ifdef OPENSSL_HAS_ECC
+	case KEY_ECDSA: return (wrap_ec_key(key->ecdsa));
+#endif
+	default:      return (-1);
+	}
+}
 
 static int
 pkcs11_start_helper(void)
@@ -209,7 +359,10 @@
 			blob = buffer_get_string(&msg, &blen);
 			free(buffer_get_string(&msg, NULL));
 			k = key_from_blob(blob, blen);
-			wrap_key(k->rsa);
+			if (wrap_key(k) < 0) {
+				key_free(k);
+				k = NULL;
+			}
 			(*keysp)[i] = k;
 			free(blob);
 		}
diff -ruN openssh-7.5p1/ssh-pkcs11-helper.0 openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.0
--- openssh-7.5p1/ssh-pkcs11-helper.0	2017-03-20 11:52:56.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.0	2017-05-20 21:07:00.000000000 +0300
@@ -1,7 +1,7 @@
-SSH-PKCS11-HELPER(8)        System Manager's Manual       SSH-PKCS11-HELPER(8)
+SSH-PKCS11-HELPER(8)      BSD System Manager's Manual     SSH-PKCS11-HELPER(8)
 
 NAME
-     ssh-pkcs11-helper M-bM-^@M-^S ssh-agent helper program for PKCS#11 support
+     ssh-pkcs11-helper -- ssh-agent helper program for PKCS#11 support
 
 SYNOPSIS
      ssh-pkcs11-helper
@@ -22,4 +22,4 @@
 AUTHORS
      Markus Friedl <markus@openbsd.org>
 
-OpenBSD 6.0                      July 16, 2013                     OpenBSD 6.0
+BSD                              July 16, 2013                             BSD
diff -ruN openssh-7.5p1/ssh-pkcs11-helper.8 openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.8
--- openssh-7.5p1/ssh-pkcs11-helper.8	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.8	2017-05-20 21:07:00.000000000 +0300
@@ -1,4 +1,3 @@
-.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.4 2013/07/16 00:07:52 schwarze Exp $
 .\"
 .\" Copyright (c) 2010 Markus Friedl.  All rights reserved.
 .\"
@@ -14,6 +13,14 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
+.\" Implement .Dd with the Mdocdate RCS keyword
+.rn Dd xD
+.de Dd
+.ie \\$1$Mdocdate: \{\
+.	xD \\$2 \\$3, \\$4
+.\}
+.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
 .Dd $Mdocdate: July 16 2013 $
 .Dt SSH-PKCS11-HELPER 8
 .Os
diff -ruN openssh-7.5p1/ssh-pkcs11-helper.c openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.c
--- openssh-7.5p1/ssh-pkcs11-helper.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-pkcs11-helper.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,8 @@
 /* $OpenBSD: ssh-pkcs11-helper.c,v 1.12 2016/02/15 09:47:49 dtucker Exp $ */
 /*
  * Copyright (c) 2010 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2011 Kenneth Robinette.  All rights reserved.
+ * Copyright (c) 2016 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -93,8 +95,8 @@
 	struct pkcs11_keyinfo *ki;
 
 	TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
-		debug("check %p %s", ki, ki->providername);
-		if (key_equal(k, ki->key))
+		debug("check %p %s", (void*)ki, ki->providername);
+		if (key_equal_public(k, ki->key))
 			return (ki->key);
 	}
 	return (NULL);
@@ -164,6 +166,50 @@
 	buffer_free(&msg);
 }
 
+static int
+process_key_sign(
+	u_int dlen, u_char *data,
+	Key *key,
+	u_char **signature, u_int *slen
+) {
+	int ret;
+
+	switch(X509KEY_BASETYPE(key)) {
+	case KEY_RSA: {
+		ret = RSA_size(key->rsa);
+		*signature = xmalloc(ret);
+
+		ret = RSA_private_encrypt(dlen, data, *signature, key->rsa, RSA_PKCS1_PADDING);
+		if (ret != -1) {
+			*slen = ret;
+			ret = 0;
+		}
+		} break;
+#ifdef OPENSSL_HAS_ECC
+	case KEY_ECDSA: {
+		ECDSA_SIG *sig = NULL;
+
+		sig = ECDSA_do_sign(data, dlen, key->ecdsa);
+		if (sig == NULL) return (-1);
+
+		/* encode ECDSA signature */
+		ret = i2d_ECDSA_SIG(sig, signature);
+		if (ret > 0) {
+			*slen = ret;
+			ret = 0;
+		} else
+			ret = -1;
+		ECDSA_SIG_free(sig);
+		} break;
+#endif /*def OPENSSL_HAS_ECC*/
+	default:
+		ret = -1;
+		break;
+	}
+
+	return (ret);
+}
+
 static void
 process_sign(void)
 {
@@ -180,15 +226,7 @@
 	if ((key = key_from_blob(blob, blen)) != NULL) {
 		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;
-			}
+			ok = process_key_sign(dlen, data, found, &signature, &slen);
 #endif /* WITH_OPENSSL */
 		}
 		key_free(key);
@@ -280,6 +318,7 @@
 
 	extern char *__progname;
 
+	(void)argc;
 	ssh_malloc_init();	/* must be called before any mallocs */
 	TAILQ_INIT(&pkcs11_keylist);
 	pkcs11_init(0);
@@ -368,6 +407,7 @@
 {
 	extern char *__progname;
 
+	(void)argc;
 	__progname = ssh_get_progname(argv[0]);
 	log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0);
 	fatal("PKCS#11 support disabled at compile time");
diff -ruN openssh-7.5p1/ssh-rsa.c openssh-7.5p1+x509-10.2/ssh-rsa.c
--- openssh-7.5p1/ssh-rsa.c	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-rsa.c	2017-05-20 21:07:01.000000000 +0300
@@ -1,6 +1,8 @@
 /* $OpenBSD: ssh-rsa.c,v 1.60 2016/09/12 23:39:34 djm Exp $ */
 /*
  * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2011 Dr. Stephen Henson.  All rights reserved.
+ * Copyright (c) 2011-2017 Roumen Petrov.  All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -33,8 +35,21 @@
 #define SSHKEY_INTERNAL
 #include "sshkey.h"
 #include "digest.h"
+#include "evp-compat.h"
+#include "xmalloc.h"
+#include "log.h"
+
+/*NOTE: Do not define USE_LEGACY_RSA_... if build
+  is with FIPS capable OpenSSL */
+/* Define if you want yo use legacy sign code */
+#undef USE_LEGACY_RSA_SIGN
+/* Define if you want yo use legacy verify code */
+#undef USE_LEGACY_RSA_VERIFY
 
+
+#ifdef USE_LEGACY_RSA_VERIFY
 static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
+#endif
 
 static const char *
 rsa_hash_alg_ident(int hash_alg)
@@ -42,10 +57,12 @@
 	switch (hash_alg) {
 	case SSH_DIGEST_SHA1:
 		return "ssh-rsa";
+#ifdef HAVE_EVP_SHA256
 	case SSH_DIGEST_SHA256:
 		return "rsa-sha2-256";
 	case SSH_DIGEST_SHA512:
 		return "rsa-sha2-512";
+#endif /*def HAVE_EVP_SHA256*/
 	}
 	return NULL;
 }
@@ -56,10 +73,12 @@
 	if (strcmp(ident, "ssh-rsa") == 0 ||
 	    strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0)
 		return SSH_DIGEST_SHA1;
+#ifdef HAVE_EVP_SHA256
 	if (strcmp(ident, "rsa-sha2-256") == 0)
 		return SSH_DIGEST_SHA256;
 	if (strcmp(ident, "rsa-sha2-512") == 0)
 		return SSH_DIGEST_SHA512;
+#endif /*def HAVE_EVP_SHA256*/
 	return -1;
 }
 
@@ -83,9 +102,13 @@
 ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen, const char *alg_ident)
 {
-	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
+#ifdef USE_LEGACY_RSA_SIGN
+	u_char digest[SSH_DIGEST_MAX_LENGTH];
+	u_int dlen;
+#endif
+	u_char *sig = NULL;
 	size_t slen;
-	u_int dlen, len;
+	u_int len;
 	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *b = NULL;
 
@@ -98,16 +121,23 @@
 		hash_alg = SSH_DIGEST_SHA1;
 	else
 		hash_alg = rsa_hash_alg_from_ident(alg_ident);
+	debug3("%s  hash_alg=%d/%s", __func__, hash_alg, rsa_hash_alg_ident(hash_alg));
 	if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
-	    sshkey_type_plain(key->type) != KEY_RSA ||
-	    BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+	    sshkey_type_plain(key->type) != KEY_RSA)
+		return SSH_ERR_INVALID_ARGUMENT;
+{
+	const BIGNUM *n = NULL;
+	RSA_get0_key(key->rsa, &n, NULL, NULL);
+	if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 		return SSH_ERR_INVALID_ARGUMENT;
+}
 	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);
+#ifdef USE_LEGACY_RSA_SIGN
 	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
 		return SSH_ERR_INTERNAL_ERROR;
 	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
@@ -123,6 +153,91 @@
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
 		goto out;
 	}
+#else /*ndef USE_LEGACY_RSA_SIGN*/
+{
+	const EVP_MD *evp_md;
+	EVP_PKEY *pkey = NULL;
+	int ok = -1;
+
+	sig = NULL;
+
+	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
+		error("%s: EVP_get_digestbynid %d failed", __func__, nid);
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+		goto out;
+	}
+
+	pkey = EVP_PKEY_new();
+	if (pkey == NULL) {
+		error("%s: out of memory", __func__);
+		goto done;
+	}
+
+	EVP_PKEY_set1_RSA(pkey, key->rsa);
+
+	slen = EVP_PKEY_size(pkey);
+	sig = xmalloc(slen);	/*fatal on error*/
+
+{
+	EVP_MD_CTX *md;
+
+	md = EVP_MD_CTX_new();
+	if (md == NULL) {
+		ok = -1;
+		error("%s: out of memory", __func__);
+		goto clean;
+	}
+
+	ok = EVP_SignInit_ex(md, evp_md, NULL);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_SignInit_ex fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ok = EVP_SignUpdate(md, data, datalen);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_SignUpdate fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ok = EVP_SignFinal(md, sig, &len, pkey);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: SignFinal fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+clean:
+	EVP_MD_CTX_free(md);
+}
+
+done:
+	if (pkey != NULL) EVP_PKEY_free(pkey);
+
+	if (ok <= 0) {
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+		goto out;
+	}
+}
+#endif /*ndef USE_LEGACY_RSA_SIGN*/
+
 	if (len < slen) {
 		size_t diff = slen - len;
 		memmove(sig + diff, sig, len);
@@ -151,7 +266,9 @@
 		*lenp = len;
 	ret = 0;
  out:
+#ifdef USE_LEGACY_RSA_SIGN
 	explicit_bzero(digest, sizeof(digest));
+#endif
 	if (sig != NULL) {
 		explicit_bzero(sig, slen);
 		free(sig);
@@ -166,15 +283,24 @@
 {
 	char *ktype = NULL;
 	int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
-	size_t len, diff, modlen, dlen;
+	size_t len, diff, modlen;
 	struct sshbuf *b = NULL;
-	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
+	u_char *osigblob, *sigblob = NULL;
+#ifdef USE_LEGACY_RSA_VERIFY
+	size_t dlen;
+	u_char digest[SSH_DIGEST_MAX_LENGTH];
+#endif
 
 	if (key == NULL || key->rsa == NULL ||
 	    sshkey_type_plain(key->type) != KEY_RSA ||
-	    BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE ||
 	    sig == NULL || siglen == 0)
 		return SSH_ERR_INVALID_ARGUMENT;
+{
+	const BIGNUM *n = NULL;
+	RSA_get0_key(key->rsa, &n, NULL, NULL);
+	if (BN_num_bits(n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+		return SSH_ERR_INVALID_ARGUMENT;
+}
 
 	if ((b = sshbuf_from(sig, siglen)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
@@ -186,6 +312,7 @@
 		ret = SSH_ERR_KEY_TYPE_MISMATCH;
 		goto out;
 	}
+	debug3("%s  hash_alg=%d/%s", __func__, hash_alg, rsa_hash_alg_ident(hash_alg));
 	if (sshbuf_get_string(b, &sigblob, &len) != 0) {
 		ret = SSH_ERR_INVALID_FORMAT;
 		goto out;
@@ -211,6 +338,7 @@
 		explicit_bzero(sigblob, diff);
 		len = modlen;
 	}
+#ifdef USE_LEGACY_RSA_VERIFY
 	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
 		ret = SSH_ERR_INTERNAL_ERROR;
 		goto out;
@@ -221,6 +349,90 @@
 
 	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
 	    key->rsa);
+#else /*ndef USE_LEGACY_RSA_VERIFY*/
+{
+	int nid;
+	const EVP_MD *evp_md;
+	EVP_PKEY *pkey;
+	int ok = -1;
+
+	nid = rsa_hash_alg_nid(hash_alg);
+	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
+		error("%s: EVP_get_digestbynid %d failed", __func__, nid);
+		free(sigblob);
+		return -1;
+	}
+
+	ok = -1;
+	pkey = EVP_PKEY_new();
+	if (pkey == NULL) {
+		error("%s: out of memory", __func__);
+		goto done;
+	}
+
+	EVP_PKEY_set1_RSA(pkey, key->rsa);
+
+{
+	EVP_MD_CTX *md;
+
+	md = EVP_MD_CTX_new();
+	if (md == NULL) {
+		ok = -1;
+		error("%s: out of memory", __func__);
+		goto clean;
+	}
+
+	ok = EVP_VerifyInit(md, evp_md);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyInit fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ok = EVP_VerifyUpdate(md, data, datalen);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyUpdate fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+	ok = EVP_VerifyFinal(md, sigblob, len, pkey);
+	if (ok <= 0) {
+#ifdef TRACE_EVP_ERROR
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyFinal fail with errormsg='%.*s'"
+		, __func__
+		, (int)sizeof(ebuf), ebuf);
+#endif
+		goto clean;
+	}
+
+clean:
+	EVP_MD_CTX_free(md);
+}
+
+done:
+	if (pkey != NULL) EVP_PKEY_free(pkey);
+
+	if (ok <= 0) {
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+		goto out;
+	} else
+		ret = SSH_ERR_SUCCESS;
+}
+#endif /*ndef USE_LEGACY_RSA_VERIFY*/
+
  out:
 	if (sigblob != NULL) {
 		explicit_bzero(sigblob, len);
@@ -228,10 +440,13 @@
 	}
 	free(ktype);
 	sshbuf_free(b);
+#ifdef USE_LEGACY_RSA_VERIFY
 	explicit_bzero(digest, sizeof(digest));
+#endif
 	return ret;
 }
 
+#ifdef USE_LEGACY_RSA_VERIFY
 /*
  * See:
  * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
@@ -353,4 +568,6 @@
 	}
 	return ret;
 }
+#endif /*def USE_LEGACY_RSA_VERIFY*/
+
 #endif /* WITH_OPENSSL */
diff -ruN openssh-7.5p1/ssh-x509.c openssh-7.5p1+x509-10.2/ssh-x509.c
--- openssh-7.5p1/ssh-x509.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-x509.c	2017-05-20 20:45:28.000000000 +0300
@@ -0,0 +1,2511 @@
+/*
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ssh-x509.h"
+#include <ctype.h>
+#include <string.h>
+
+#include "ssh-xkalg.h"
+#include "x509store.h"
+#include <openssl/pem.h>
+#include "evp-compat.h"
+#include "compat.h"
+#include "xmalloc.h"
+#include "ssherr.h"
+#include "uuencode.h"
+#include "log.h"
+
+#ifndef ISSPACE
+#  define ISSPACE(ch) (isspace((int)(unsigned char)(ch)))
+#endif
+
+/* pointer to x509store function to minimize build dependencies */
+int (*pssh_x509store_verify_cert)(X509 *_cert, STACK_OF(X509) *_chain) = NULL;
+STACK_OF(X509)* (*pssh_x509store_build_certchain)(X509 *cert, STACK_OF(X509) *untrusted) = NULL;
+
+
+static int x509key_to_blob2(const char *pkalg, const Key *key, Buffer *b);
+
+
+/* Temporary solution, see key.h */
+#define TO_X509_KEY_TYPE(key)	SET_X509_KEY_TYPE(key, key->type)
+
+static inline void
+SET_X509_KEY_TYPE(Key *key, int k_type) {
+	switch (k_type) {
+	case KEY_RSA	: key->type = KEY_X509_RSA	; break;
+	case KEY_ECDSA	: key->type = KEY_X509_ECDSA	; break;
+	case KEY_DSA	: key->type = KEY_X509_DSA	; break;
+	default		: /* avoid compiler warnings */	  break;
+	}
+}
+
+
+struct ssh_x509_st {
+	X509           *cert;  /* key certificate */
+	STACK_OF(X509) *chain; /* reserved for future use */
+};
+
+
+SSH_X509*
+SSH_X509_new() {
+	SSH_X509 *xd;
+
+	xd = xmalloc(sizeof(SSH_X509)); /*fatal on error*/
+	xd->cert = NULL;
+	xd->chain = NULL;
+
+	return(xd);
+}
+
+
+static inline void
+SSH_X509_free_data(SSH_X509* xd) {
+	if (xd->cert != NULL) {
+		X509_free(xd->cert);
+		xd->cert = NULL;
+	}
+
+	if (xd->chain != NULL) {
+		sk_X509_pop_free(xd->chain, X509_free);
+		xd->chain = NULL;
+	}
+}
+
+
+void
+SSH_X509_free(SSH_X509* xd) {
+	if (xd == NULL) return;
+
+	SSH_X509_free_data(xd);
+	free(xd);
+}
+
+
+X509*
+SSH_X509_get_cert(SSH_X509 *xd) {
+	return((xd != NULL) ? xd->cert : NULL);
+}
+
+
+int
+ssh_X509_NAME_print(BIO* bio, X509_NAME *xn) {
+	static u_long print_flags =	((XN_FLAG_ONELINE & \
+					  ~ASN1_STRFLGS_ESC_MSB & \
+					  ~XN_FLAG_SPC_EQ & \
+					  ~XN_FLAG_SEP_MASK) | \
+					 XN_FLAG_SEP_COMMA_PLUS);
+
+	if (xn == NULL) return(-1);
+
+	X509_NAME_print_ex(bio, xn, 0, print_flags);
+	(void)BIO_flush(bio);
+
+	return(BIO_pending(bio));
+}
+
+
+char*
+ssh_X509_NAME_oneline(X509_NAME *xn) {
+	char *buf = NULL;
+	int size;
+	BIO* mbio = NULL;
+
+	if (xn == NULL) return(NULL);
+
+	mbio = BIO_new(BIO_s_mem());
+	if (mbio == NULL) return(buf);
+
+	size = ssh_X509_NAME_print(mbio, xn);
+	if (size <= 0) {
+		error("ssh_X509_NAME_oneline: no data in buffer");
+		goto done;
+	}
+
+	buf = xmalloc(size + 1); /*fatal on error*/
+
+	/* we should request one byte more !?!? */
+	if (size != BIO_gets(mbio, buf, size + 1)) {
+		error("ssh_X509_NAME_oneline: cannot get data from buffer");
+		goto done;
+	}
+	buf[size] = '\0';
+
+done:
+	/* This call will walk the chain freeing all the BIOs */
+	BIO_free_all(mbio);
+
+	return(buf);
+}
+
+
+static inline int
+ssh_x509_support_plain_type(int k_type) {
+	return (
+	    (k_type == KEY_RSA) ||
+#ifdef OPENSSL_HAS_ECC
+	    (k_type == KEY_ECDSA) ||
+#endif
+	    (k_type == KEY_DSA)
+	) ? 1 : 0;
+}
+
+
+int/*bool*/
+key_is_x509(const Key *k) {
+	if (k == NULL) return(0);
+
+	if ( (k->type == KEY_X509_RSA) ||
+#ifdef OPENSSL_HAS_ECC
+	     (k->type == KEY_X509_ECDSA) ||
+#endif
+	     (k->type == KEY_X509_DSA) ) {
+		return(1);
+	}
+
+	return(0);
+}
+
+
+static const char*
+x509key_find_subject(const char* s) {
+	static const char *keywords[] = {
+		"subject",
+		"distinguished name",
+		"distinguished-name",
+		"distinguished_name",
+		"distinguishedname",
+		"dn",
+		NULL
+	};
+	const char **q, *p;
+	size_t len;
+
+	if (s == NULL) {
+		error("x509key_find_subject: no input data");
+		return(NULL);
+	}
+	for (; *s && ISSPACE(*s); s++)
+	{/*skip space*/}
+
+	for (q=keywords; *q; q++) {
+		len = strlen(*q);
+		if (strncasecmp(s, *q, len) != 0) continue;
+
+		for (p = s + len; *p && ISSPACE(*p); p++)
+		{/*skip space*/}
+		if (!*p) {
+			error("x509key_find_subject: no data after keyword");
+			return(NULL);
+		}
+		if (*p == ':' || *p == '=') {
+			for (p++; *p && ISSPACE(*p); p++)
+			{/*skip space*/}
+			if (!*p) {
+				error("x509key_find_subject: no data after separator");
+				return(NULL);
+			}
+		}
+		if (*p == '/' || *p == ',') {
+			/*skip leading [Relative]DistinguishedName elements separator*/
+			for (p++; *p && ISSPACE(*p); p++)
+			{/*skip space*/}
+			if (!*p) {
+				error("x509key_find_subject: no data");
+				return(NULL);
+			}
+		}
+		return(p);
+	}
+	return(NULL);
+}
+
+
+static unsigned long
+ssh_hctol(u_char ch) {
+/* '0'-'9' = 0x30 - 0x39 (ascii) */
+/* 'A'-'F' = 0x41 - 0x46 (ascii) */
+/* 'a'-'f' = 0x61 - 0x66 (ascii) */
+/* should work for EBCDIC */
+	if (('0' <= ch) && (ch <= '9')) {
+		return((long)(ch - '0'));
+	}
+	if (('A' <= ch) && (ch <= 'F')) {
+		return((long)(ch - ('A' - 10)));
+	}
+	if (('a' <= ch) && (ch <= 'f')) {
+		return((long)(ch - ('a' - 10)));
+	}
+
+	return(-1);
+}
+
+
+static unsigned long
+ssh_hatol(const u_char *str, size_t maxsize) {
+	int k;
+	long v, ret = 0;
+
+	for(k = maxsize; k > 0; k--, str++) {
+		v = ssh_hctol(*str);
+		if (v < 0) return(-1);
+		ret = (ret << 4) + v;
+	}
+	return(ret);
+}
+
+
+static int
+get_escsymbol(const u_char* str, size_t len, u_long *value) {
+	const char ch = *str;
+	long v;
+
+	if (len < 1) {
+		error("get_escsymbol:"
+		" missing characters in escape sequence");
+		return(-1);
+	}
+
+	/*escape formats:
+		"{\\}\\W%08lX"
+		"{\\}\\U%04lX"
+		"{\\}\\%02X"
+		"{\\}\\x%02X" - X509_NAME_oneline format
+	*/
+	if (ch == '\\') {
+		if (value) *value = ch;
+		return(1);
+	}
+	if (ch == 'W') {
+		if (len < 9) {
+			error("get_escsymbol:"
+			" to short 32-bit escape sequence");
+			return(-1);
+		}
+		v = ssh_hatol(++str, 8);
+		if (v < 0) {
+			error("get_escsymbol:"
+			" invalid character in 32-bit hex sequence");
+			 return(-1);
+		}
+		if (value) *value = v;
+		return(9);
+	}
+	if (ch == 'U') {
+		if (len < 5) {
+			error("get_escsymbol:"
+			" to short 16-bit escape sequence");
+			return(-1);
+		}
+		v = ssh_hatol(++str, 4);
+		if (v < 0) {
+			error("get_escsymbol:"
+			" invalid character in 16-bit hex sequence");
+			 return(-1);
+		}
+		if (value) *value = v;
+		return(5);
+	}
+#if 0
+/*
+The code bellow isn't correct. Let 'O' is not 8-bit string(as example
+BMPString) then "X509_NAME_oneline" will output "\x00O"(!).
+The X509_NAME_oneline output format will left unsupported, i.e.:
+Unsupported:
+$ openssl x509 -in cert_file -subject -noout
+Supported:
+  v0.9.7+
+$ openssl x509 -in cert_file -subject -noout -nameopt oneline[,<more_name_options>]
+  v0.9.6
+$ openssl x509 -in cert_file -subject -noout -nameopt oneline [-nameopt <other_name_option>]
+*/
+	if ((ch == 'x') || (ch == 'X')) {
+		if (len < 3) {
+			error("get_escsymbol:"
+			" to short 8-bit hex sequence");
+			return(-1);
+		}
+		v = ssh_hatol(++str, 2);
+		if (v < 0) {
+			error("get_escsymbol:"
+			" invalid character in 8-bit hex sequence");
+			 return(-1);
+		}
+		if (value) *value = v;
+		return(3);
+	}
+#endif
+	v = ssh_hctol(*str);
+	if (v < 0) {
+		/*a character is escaped ?*/
+		if (*str > 127) { /*ASCII comparision !*/
+			/* there is no reason symbol above 127
+                           to be escaped in this way */
+			error("get_escsymbol:"
+			" non-ascii character in escape sequence");
+			return(-1);
+		}
+		if (value) *value = *str;
+		return(1);
+	}
+
+	/*two hex numbers*/
+	{
+		long vlo;
+		if (len < 2) {
+			error("get_escsymbol:"
+			" to short 8-bit escape sequence");
+			return(-1);
+		}
+		vlo = ssh_hctol(*++str);
+		if (vlo < 0) {
+			error("get_escsymbol:"
+			" invalid character in 8-bit hex sequence");
+			 return(-1);
+		}
+		v = (v << 4) + vlo;
+	}
+	if (value) *value = v;
+	return(2);
+}
+
+
+static int/*bool*/
+ssh_X509_NAME_add_entry_by_NID(X509_NAME* name, int nid, const u_char* str, size_t len) {
+/* default maxsizes:
+  C: 2
+  L, ST: 128
+  O, OU, CN: 64
+  emailAddress: 128
+*/
+	u_char  buf[129*6+1]; /*enough for 128 UTF-8 symbols*/
+	int     ret = 0;
+	int     type = MBSTRING_ASC;
+	u_long  ch;
+	u_char *p;
+	const u_char *q;
+	size_t  k;
+
+	/*this is internal method and we don't check validity of some arguments*/
+
+	p = buf;
+	q = str;
+	k = sizeof(buf);
+
+	while ((len > 0) && (k > 0)) {
+		int ch_utf8 = 1;
+		if (*q == '\0') {
+			error("ssh_X509_NAME_add_entry_by_NID:"
+			" unsupported zero(NIL) symbol in name");
+			return(0);
+		}
+		if (*q == '\\') {
+			len--;
+			if (len <= 0) {
+				error("ssh_X509_NAME_add_entry_by_NID:"
+				" escape sequence without data");
+				return(0);
+			}
+
+			ret = get_escsymbol(++q, len, &ch);
+			if (ret < 0) return(0);
+			if (ret == 2) {
+				/*escaped two hex numbers*/
+				ch_utf8 = 0;
+			}
+		} else {
+			ret = UTF8_getc(q, len, &ch);
+			if(ret < 0) {
+				error("ssh_X509_NAME_add_entry_by_NID:"
+				" cannot get next symbol(%.32s)"
+				, q);
+				return(0);
+			}
+		}
+		len -= ret;
+		q += ret;
+
+		if (ch_utf8) {
+			/* UTF8_putc return negative if buffer is too short */
+			ret = UTF8_putc(p, k, ch);
+			if (ret < 0) {
+				error("ssh_X509_NAME_add_entry_by_NID:"
+				" UTF8_putc fail for symbol %ld", ch);
+				return(0);
+			}
+		} else {
+			*p = (u_char)ch;
+			ret = 1;
+		}
+		k -= ret;
+		p += ret;
+	}
+	if (len > 0) {
+		error("ssh_X509_NAME_add_entry_by_NID:"
+		" too long data");
+		return(0);
+	}
+	*p = '\0';
+
+	for (p = buf; *p; p++) {
+		if (*p > 127) {
+			type = MBSTRING_UTF8;
+			break;
+		}
+	}
+	k = strlen((char*)buf);
+
+#if 0
+	debug3("ssh_X509_NAME_add_entry_by_NID:"
+		" type=%s, k=%d"
+		, ((type == MBSTRING_ASC) ? "ASCII" : "UTF-8")
+		, (int)k
+	);
+#endif
+
+	/* this method will fail if string exceed max size limit for nid */
+	ret = X509_NAME_add_entry_by_NID(name, nid, type, buf, (int)k, -1, 0);
+	if (!ret) {
+		char ebuf[1024];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("ssh_X509_NAME_add_entry_by_NID: X509_NAME_add_entry_by_NID"
+		" fail with errormsg='%.*s'"
+		" for nid=%d/%.32s"
+		" and data='%.512s'"
+		, (int)sizeof(ebuf), ebuf
+		, nid, OBJ_nid2ln(nid)
+		, str);
+	}
+	return(ret);
+}
+
+
+static int/*bool*/
+x509key_str2X509NAME(const char* _str, X509_NAME *_name) {
+	int   ret = 1;
+	char *str = NULL;
+	char *p, *q, *token;
+	int   has_more = 0;
+
+	str = xmalloc(strlen(_str) + 1); /*fatal on error*/
+	strcpy(str, _str);
+
+	p = (char*)str;
+	while (*p) {
+		int nid;
+		for (; *p && ISSPACE(*p); p++)
+		{/*skip space*/}
+		if (!*p) break;
+
+		/* get shortest token */
+		{
+			char *tokenA = strchr(p, ',');
+			char *tokenB = strchr(p, '/');
+
+			if (tokenA == NULL) {
+				token = tokenB;
+			} else if (tokenB == NULL) {
+				token = tokenA;
+			} else {
+				token = (tokenA < tokenB) ? tokenA : tokenB;
+			}
+		}
+		if (token) {
+			has_more = 1;
+			*token = 0;
+		} else {
+			has_more = 0;
+			token = p + strlen(p);
+		}
+		q = strchr(p, '=');
+		if (!q) {
+			error("x509key_str2X509NAME: cannot parse '%.200s' ...", p);
+			ret = 0;
+			break;
+		}
+		{
+			char *s = q;
+			for(--s; ISSPACE(*s) && (s > p); s--)
+			{/*skip trailing space*/}
+			*++s = 0;
+		}
+		nid = OBJ_txt2nid(p);
+#ifdef SSH_OPENSSL_DN_WITHOUT_EMAIL
+		if (nid == NID_undef) {
+			/* work around for OpenSSL 0.9.7+ */
+			if (strcasecmp(p, "Email") == 0) {
+				nid = OBJ_txt2nid("emailAddress");
+			}
+		}
+#endif /* def SSH_OPENSSL_DN_WITHOUT_EMAIL */
+		if (nid == NID_undef) {
+			error("x509key_str2X509NAME: cannot get nid from string '%.200s'", p);
+			ret = 0;
+			break;
+		}
+
+		p = q + 1;
+		if (!*p) {
+			error("x509key_str2X509NAME: no data");
+			ret = 0;
+			break;
+		}
+
+		for (; *p && ISSPACE(*p); p++)
+		{/*skip space*/}
+		for (q = token - 1; (q >= p) && ISSPACE(*q); q--)
+		{/*skip unexpected \n, etc. from end*/}
+		*++q = 0;
+
+		ret = ssh_X509_NAME_add_entry_by_NID(_name, nid, (u_char*)p, (size_t)(q - p));
+		if (!ret) {
+			break;
+		}
+
+		p = token;
+		if (has_more) p++;
+	}
+
+	free(str);
+	debug3("x509key_str2X509NAME: return %d", ret);
+	return(ret);
+}
+
+
+static Key*
+x509key_from_subject(int _keytype, const char* _cp) {
+	const char *subject;
+	Key        *key;
+	X509       *x;
+
+	if (_keytype != KEY_X509_RSA &&
+	    _keytype != KEY_X509_ECDSA &&
+	    _keytype != KEY_X509_DSA) {
+		debug3("x509key_from_subject: %d is not x509 key type", _keytype);
+		return(NULL);
+	}
+	debug3("x509key_from_subject(%d, [%.1024s]) called",
+		_keytype, (_cp ? _cp : ""));
+	subject = x509key_find_subject(_cp);
+	if (subject == NULL)
+		return(NULL);
+
+	debug3("x509key_from_subject: subject=[%.1024s]", subject);
+	key = key_new(KEY_UNSPEC);
+	if (key == NULL) {
+		error("x509key_from_subject: out of memory");
+		return(NULL);
+	}
+
+	x = X509_new();
+	if (x == NULL) {
+		error("%s: out of memory X509_new()", __func__);
+		goto err;
+	}
+
+
+	{	/*set distinguished name*/
+		X509_NAME  *xn = X509_get_subject_name(x);
+
+		if (xn == NULL) {
+			error("%s: X.509 certificate without subject", __func__);
+			goto err;
+		}
+
+		if (!x509key_str2X509NAME(subject, xn)) {
+			error("%s: x509key_str2X509NAME fail", __func__);
+			goto err;
+		}
+	}
+
+	key->type = _keytype;
+	if (!ssh_x509_set_cert(key, x)) {
+		error("%s: ssh_x509_set_cert fail", __func__);
+		goto err;
+	}
+	goto done;
+
+err:
+	if (x != NULL)
+		X509_free(x);
+	if (key != NULL) {
+		key_free(key);
+		key = NULL;
+	}
+
+done:
+	debug3("x509key_from_subject: return %p", (void*)key);
+	return(key);
+}
+
+
+Key*
+X509key_from_subject(const char *pkalg, const char *cp, char **ep) {
+	Key *ret;
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return NULL;
+
+	ret = x509key_from_subject(p->type, cp);
+}
+
+	if (ret != NULL && ep != NULL) {
+		/* NOTE line with subject lack comment part */
+		*ep = (char*)cp + strlen(cp);
+	}
+
+	return(ret);
+}
+
+
+static Key*
+x509_to_key(X509 *x509) {
+	Key      *key = NULL;
+	EVP_PKEY *env_pkey;
+
+	env_pkey = X509_get_pubkey(x509);
+	if (env_pkey == NULL) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("x509_to_key: X509_get_pubkey fail %.*s",
+			(int)sizeof(ebuf), ebuf);
+		return(NULL);
+	}
+	/*else*/
+	debug3("x509_to_key: X509_get_pubkey done!");
+
+	switch (EVP_PKEY_id(env_pkey)) {
+	case EVP_PKEY_RSA:
+		key = key_new(KEY_UNSPEC);
+		key->rsa = EVP_PKEY_get1_RSA(env_pkey);
+		key->type = KEY_RSA;
+		(void)ssh_x509_set_cert(key, x509);
+#ifdef DEBUG_PK
+		RSA_print_fp(stderr, key->rsa, 8);
+#endif
+		break;
+
+	case EVP_PKEY_DSA:
+		key = key_new(KEY_UNSPEC);
+		key->dsa = EVP_PKEY_get1_DSA(env_pkey);
+		key->type = KEY_DSA;
+		(void)ssh_x509_set_cert(key, x509);
+#ifdef DEBUG_PK
+		DSA_print_fp(stderr, key->dsa, 8);
+#endif
+		break;
+
+#ifdef OPENSSL_HAS_ECC
+	case EVP_PKEY_EC: {
+		const EC_POINT *q = NULL;
+
+		key = key_new(KEY_UNSPEC);
+		key->ecdsa = EVP_PKEY_get1_EC_KEY(env_pkey);
+		key->type = KEY_ECDSA;
+		key->ecdsa_nid = key_ecdsa_key_to_nid(key->ecdsa);
+		if (key->ecdsa_nid < 0) {
+			error("%s: unsupported elliptic curve", __func__);
+			goto err;
+		}
+		q = EC_KEY_get0_public_key(key->ecdsa);
+		if (q == NULL) {
+			error("%s: cannot get public ec key ", __func__);
+			goto err;
+		}
+		if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) < 0) {
+			debug3("%s: cannot validate public ec key ", __func__);
+			goto err;
+		}
+		(void)ssh_x509_set_cert(key, x509);
+#ifdef DEBUG_PK
+		key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
+#endif
+		} break;
+#endif /*def OPENSSL_HAS_ECC*/
+
+	default:
+		error("%s: unsupported EVP_PKEY type %d", __func__, EVP_PKEY_id(env_pkey));
+	}
+
+	EVP_PKEY_free(env_pkey);
+	return(key);
+
+err:
+	EVP_PKEY_free(env_pkey);
+	key_free(key);
+	return(NULL);
+}
+
+
+static X509*
+x509_from_blob(const u_char *blob, int blen, int check_pending) {
+	X509* x509 = NULL;
+	BIO *mbio;
+
+	if (blob == NULL) return(NULL);
+	if (blen <= 0) return(NULL);
+
+	/* convert blob data to BIO certificate data */
+	mbio = BIO_new_mem_buf((void*)blob, blen);
+	if (mbio == NULL) return(NULL);
+
+	/* read X509 certificate from BIO data */
+	x509 = d2i_X509_bio(mbio, NULL);
+	if (x509 == NULL) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		debug3("%s: read X509 from BIO fail %.*s", __func__,
+			(int)sizeof(ebuf), ebuf);
+	}
+
+	if (check_pending) {
+		size_t k;
+
+		k = BIO_ctrl_pending(mbio);
+		if (k > 0)
+			error("%s: remaining bytes in X.509 blob %d", __func__,
+				(int) k);
+	}
+
+	/* This call will walk the chain freeing all the BIOs */
+	BIO_free_all(mbio);
+
+	return(x509);
+}
+
+
+Key*
+x509key_from_blob(const u_char *blob, int blen) {
+	Key* key = NULL;
+	X509* x509 = NULL;
+
+	x509 = x509_from_blob(blob, blen, 0);
+	if (x509 == NULL) {
+		/* print only debug info !!!
+		 * This method is used in place where we can only check incomming data.
+		 * If data contain x506 certificate blob we will return a key otherwise NULL.
+		 */
+		debug3("%s: no X.509 certificate data", __func__);
+	} else {
+		key = x509_to_key(x509);
+		if (key == NULL)
+			X509_free(x509);
+	}
+
+	return(key);
+}
+
+
+static int
+X509key_from_buf2_common(struct sshbuf *b, struct sshkey **keyp, char **pkalgp) {
+	int r;
+	u_int nc, no, k;
+	char  *pkalg = NULL;
+	struct sshkey *key = NULL;
+
+if ((SSHX_RFC6187_MISSING_KEY_IDENTIFIER & xcompat) == 0) {
+	/* RFC6187: string  "algorithm-identifier" */
+	r = sshbuf_get_cstring(b, &pkalg, NULL);
+	if (r != 0) return SSH_ERR_INVALID_FORMAT;
+}
+
+	/* RFC6187: uint32  certificate-count */
+	r = sshbuf_get_u32(b, &nc);
+	if (r != 0) goto err;
+	debug3("%s: certificate-count: %u", __func__, nc);
+
+	if (nc > 100) {
+		error("%s: the number of X.509 certificates"
+		    " exceed limit(%d > 100)", __func__, nc);
+		r = SSH_ERR_INVALID_FORMAT;
+		goto err;
+	}
+	if (nc < 1) {
+		error("%s: at least one X.509 certificate"
+		    " must present", __func__);
+		r = SSH_ERR_INVALID_FORMAT;
+		goto err;
+	}
+
+{	/* RFC6187: string  certificate[1..certificate-count] */
+	const u_char *xs;
+	size_t        xlen;
+
+	X509 *x;
+	STACK_OF(X509) *pchain;
+
+	r = sshbuf_get_string_direct(b, &xs, &xlen);
+	if (r != 0) goto err;
+
+	x = x509_from_blob(xs, xlen, 1);
+	if (x == NULL) {
+		r = SSH_ERR_INVALID_FORMAT;
+		goto err;
+	}
+	debug3("%s: certificate[0]=%p", __func__, (void*)x);
+
+	key = x509_to_key(x);
+	if (key == NULL) {
+		X509_free(x);
+		r = SSH_ERR_INVALID_FORMAT;
+		goto err;
+	}
+
+{	SSH_X509 *xd = key->x509_data;
+
+	if (xd == NULL) {
+		r = SSH_ERR_ALLOC_FAIL;
+		goto err;
+	}
+
+	pchain = sk_X509_new_null();
+	if (pchain == NULL) {
+		error("X509key_from_buf2_common: out of memory (chain)");
+		r = SSH_ERR_ALLOC_FAIL;
+		goto err;
+	}
+	xd->chain = pchain;
+}
+
+	for (k = 1; k < nc; k++) {
+		r = sshbuf_get_string_direct(b, &xs, &xlen);
+		if (r != 0) goto err;
+
+		x = x509_from_blob(xs, xlen, 1);
+		debug3("%s: certificate[%d]=%p", __func__, k, (void*)x);
+		if (x == NULL) {
+			r = SSH_ERR_INVALID_FORMAT;
+			goto err;
+		}
+
+		sk_X509_insert(pchain, x, -1 /*last*/);
+	}
+}
+
+	/* RFC6187: uint32  ocsp-response-count */
+	r = sshbuf_get_u32(b, &no);
+	if (r != 0) goto err;
+	debug3("%s: ocsp-response-count: %u", __func__, nc);
+
+	/* The number of OCSP responses MUST NOT exceed the number of certificates. */
+	if (no > nc) {
+		error("%s: the number of OCSP responses(%d)"
+		    " exceed the number of certificates(%d)",
+		      __func__, no, nc);
+		r = SSH_ERR_INVALID_FORMAT;
+		goto err;
+	}
+
+	/* RFC6187: string  ocsp-response[0..ocsp-response-count] */
+	for (k = 0; k < no; k++) {
+		const u_char *os;
+		r = sshbuf_get_string_direct(b, &os, NULL);
+		if (r != 0) goto err;
+
+		/* nop */
+	}
+
+{	size_t l = sshbuf_len(b);
+	if (l > 0) {
+		error("%s: remaining bytes in key blob %zu", __func__, l);
+		r = SSH_ERR_INVALID_FORMAT;
+	}
+}
+
+err:
+	if (r != 0) {
+		sshkey_free(key);
+		free(pkalg);
+	} else {
+		if (keyp != NULL)
+			*keyp = key;
+		if (pkalgp != NULL) {
+			/* compatibility: if key identifier is missing */
+			if (pkalg == NULL)
+				pkalg = xstrdup(sshkey_ssh_name(key));
+			*pkalgp = pkalg;
+		}
+	}
+	return r;
+}
+
+
+static Key*
+x509key_from_blob2(const char *pkalg, const u_char *blob, int blen) {
+	Key   *key = NULL;
+	char  *xpkalg = NULL;
+
+	int r;
+	struct sshbuf *b;
+
+	b = sshbuf_new();
+	if (b == NULL) goto err;
+
+	r = sshbuf_put(b, blob, blen);
+	if (r != 0) goto err;
+
+	r = X509key_from_buf2_common(b, &key, &xpkalg);
+	if (r != 0) goto err;
+
+	if (strcmp(pkalg, xpkalg) != 0) {
+		error("%s: public-key algorithm mismatch:"
+		    " expected %.100s extracted %.100s",
+		    __func__, pkalg, xpkalg);
+		goto err;
+	}
+
+done:
+	free(xpkalg);
+	sshbuf_free(b);
+	return key;
+
+err:
+	sshkey_free(key);
+	key = NULL;
+	goto done;
+}
+
+
+static int
+x509key_check(const char* method, const Key *key) {
+	SSH_X509 *xd;
+
+	if (key == NULL)
+		{ error("%.50s: no key", method); return(0); }
+
+	if (!key_is_x509(key))
+		{ error("%.50s: cannot handle key type %d", method, key->type); return(0); }
+
+	xd = key->x509_data;
+	if (xd == NULL)
+		{ error("%.50s: no X.509 identity", method); return(0); }
+
+	if (xd->cert == NULL)
+		{ error("%.50s: no X.509 certificate", method); return(0); }
+
+	return(1);
+}
+
+
+static int
+sshbuf_put_x509_f(
+	struct sshbuf *b, X509 *x,
+	int (*f)(struct sshbuf *, const void *, size_t)
+) {
+	void   *p;
+	int     l, k;
+	int     r;
+
+	l = i2d_X509(x, NULL);
+	p = xmalloc(l); /*fatal on error*/
+	{
+		u_char *q = p;
+		k = i2d_X509(x, &q);
+	}
+
+	if (l == k)
+		r = f(b, p, l);
+	else
+		r = SSH_ERR_ALLOC_FAIL;
+
+	free(p);
+
+	return(r);
+}
+
+
+static inline int
+sshbuf_put_x509(struct sshbuf *b, X509 *x) {
+	return sshbuf_put_x509_f(b, x, sshbuf_put_string);
+}
+
+
+static inline int
+sshbuf_append_x509(struct sshbuf *b, X509 *x) {
+	return sshbuf_put_x509_f(b, x, sshbuf_put);
+}
+
+
+int
+X509key_encode_identity(const char *pkalg, const struct sshkey *key, struct sshbuf *b) {
+	int RFC6187_format;
+	int ret;
+
+	if (!key_is_x509(key))
+		return SSH_ERR_SUCCESS;
+
+{	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return SSH_ERR_SUCCESS;
+
+	RFC6187_format = p->chain;
+}
+
+	if (RFC6187_format) {
+		struct sshbuf *d;
+
+		d = sshbuf_new();
+		if (d == NULL)
+			return SSH_ERR_ALLOC_FAIL;
+
+		ret = x509key_to_blob2(pkalg, key, d);
+		if (ret != SSH_ERR_SUCCESS)
+			debug3("%s: x509key_to_blob2 fail" , __func__);
+
+		if (ret == SSH_ERR_SUCCESS)
+			ret = sshbuf_put_stringb(b, d);
+
+		buffer_free(d);
+	} else {
+		ret = sshbuf_put_x509(b, key->x509_data->cert);
+	}
+
+	return ret;
+}
+
+
+int
+X509key_decode_identity(const char *pkalg, struct sshbuf *b, struct sshkey *k) {
+	int RFC6187_format;
+	struct sshkey *tkey = NULL;
+	int ret;
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return SSH_ERR_SUCCESS;
+
+	RFC6187_format = p->chain;
+}
+
+{	/* fetch X.509 key */
+	size_t slen;
+	u_char *blob = NULL;
+	u_int blen;
+
+	ret = sshbuf_get_string(b, &blob, &slen);
+	if (ret != SSH_ERR_SUCCESS)
+		goto end_key;
+
+	blen = (u_int)slen;
+	if ((size_t)blen != slen) {
+		ret = SSH_ERR_INVALID_FORMAT;
+		goto end_key;
+	}
+
+	tkey = RFC6187_format
+		? x509key_from_blob2(pkalg, blob, blen)
+		: x509key_from_blob(blob, blen);
+	ret = tkey ? SSH_ERR_SUCCESS : SSH_ERR_INVALID_FORMAT;
+end_key:
+	free(blob);
+}
+
+	if (ret != SSH_ERR_SUCCESS)
+		return ret;
+
+	SSH_X509_free(k->x509_data);
+	k->x509_data = tkey->x509_data;
+	tkey->x509_data = NULL;
+
+	key_free(tkey);
+
+	return ret;
+}
+
+
+void
+x509key_move_identity(Key *from, Key *to) {
+	/* Temporary controls for key types based on enumerate.
+	 *
+	 * Caller is responsible to perform all controlls before to call this
+	 * method. For instance public key of X.509 certificate has to match
+	 * plain public key.
+	 * NOTE X.509 certificate may contain only distinguished name!
+	 */
+	if (!x509key_check("move_identity", from)) return;
+
+	SSH_X509_free(to->x509_data);
+	to->x509_data = from->x509_data;
+	from->x509_data = NULL;
+}
+
+
+void
+x509key_copy_identity(const Key *from, Key *to) {
+	X509 *x;
+	SSH_X509 *xd;
+	STACK_OF(X509) *chain;
+	STACK_OF(X509) *pchain;
+	int n;
+
+	if (!key_is_x509(from)) return;
+
+	if (!x509key_check("copy_identity", from))
+		fatal("x509key_copy_identity: no X.509 identity");
+
+	xd = to->x509_data;
+	if (xd)
+		SSH_X509_free_data(xd);
+	else {
+		xd = SSH_X509_new(); /*fatal on error*/
+		to->x509_data = xd;
+	}
+
+	x = X509_dup(from->x509_data->cert);
+	if (x == NULL)
+		fatal("x509key_copy_identity: X509_dup failed");
+	xd->cert = x;
+
+	/* legacy keys does not use chain */
+	chain = from->x509_data->chain;
+	if (chain == NULL)
+		return;
+
+	pchain = sk_X509_new_null();
+	if (pchain == NULL)
+		fatal("x509key_copy_identity: sk_X509_new_null failed");
+	xd->chain = pchain;
+
+	for (n = 0; n < sk_X509_num(chain); n++) {
+		x = sk_X509_value(chain, n);
+		x = X509_dup(x);
+		if (x == NULL)
+			fatal("x509key_copy_identity: X509_dup failed");
+		sk_X509_insert(pchain, x, -1 /*last*/);
+	}
+}
+
+
+void
+x509key_demote(const Key *k, Key *pk) {
+	x509key_copy_identity(k, pk);
+}
+
+
+static inline int
+x509key_to_blob(const Key *key, Buffer *b) {
+	int r;
+	r = sshbuf_append_x509(b, key->x509_data->cert);
+	return(r == 0);
+}
+
+
+static int
+x509key_to_blob2(const char *pkalg, const Key *key, struct sshbuf *b) {
+	STACK_OF(X509) *chain;
+	int   r;
+	u_int n;
+
+	if (!x509key_check("x509key_to_blob2", key)) return(0);
+
+	/* RFC6187 key format */
+	chain = key->x509_data->chain;
+	if (chain == NULL) {
+		/* NOTE Historic key algorithm use only one X.509
+		 * certificate. Empty chain is protocol error for
+		 * keys in RFC6187 format, but we accept them.
+		 */
+		verbose("%s: X.509 certificate chain is not set."
+		    " Some server may refuse key.", __func__);
+	}
+
+	/* NOTE: sk_num returns -1 if argument is null */
+	n = chain ? sk_X509_num(chain) : 0;
+
+if ((SSHX_RFC6187_MISSING_KEY_IDENTIFIER & xcompat) == 0) {
+	/* string  "algorithm-identifier" */
+	r = sshbuf_put_cstring(b, pkalg);
+	if (r != 0) goto end;
+}
+
+	/* uint32  certificate-count */
+	r = sshbuf_put_u32(b, 1 + n);
+	if (r != 0) goto end;
+
+{	/* string  certificate[1..certificate-count] */
+	X509  *x;
+	u_int  i;
+
+	x = key->x509_data->cert;
+	r = sshbuf_put_x509(b, x);
+	if (r != 0) goto end;
+	for (i = 0; i < n; i++) {
+		x = sk_X509_value(chain, i);
+		r = sshbuf_put_x509(b, x);
+		if (r != 0) goto end;
+	}
+}
+
+	/* uint32  ocsp-response-count */
+	r = sshbuf_put_u32(b, 0);
+	if (r != 0) goto end;
+
+	/* string  ocsp-response[0..ocsp-response-count] */
+	/* nop */
+
+end:
+	return r;
+}
+
+
+char*
+x509key_subject(const Key *key) {
+	X509_NAME *dn;
+
+	if (!x509key_check("x509key_subject", key)) return(NULL);
+
+	/* match format used in Xkey_write_subject */
+	dn = X509_get_subject_name(key->x509_data->cert);
+	return(ssh_X509_NAME_oneline(dn)); /*fatal on error*/
+}
+
+
+int
+x509key_write(const Key *key, FILE *f) {
+	int    ret = 0;
+	Buffer b;
+	char  *uu;
+	int    k;
+	size_t n;
+
+	if (!x509key_check("x509key_write_blob", key)) return(ret);
+
+	buffer_init(&b);
+	if (sshbuf_append_x509(&b, key->x509_data->cert) != 0)
+		return(ret);
+
+	k = buffer_len(&b);
+	n = (size_t)(k << 1);
+	if (n < (size_t)k) goto done;	/* overflow */
+
+	uu = xmalloc(n); /*fatal on error*/
+	/* uuencode return int */
+	k = uuencode(buffer_ptr(&b), k, uu, n);
+	ret = k > 0;
+	if (ret) {
+		/* write ssh "blob" key */
+		const char *ktype = key_ssh_name(key);
+		n = strlen(ktype);
+		ret = ( fwrite(ktype, 1, n, f) == n ) &&
+		      ( fwrite(" ", 1, 1, f) == 1 ) &&
+		      ( fwrite(uu, 1, k, f) ==  (size_t)k );
+	}
+	free(uu);
+
+done:
+	buffer_free(&b);
+	return(ret);
+}
+
+
+int
+Xkey_write_subject(const char *pkalg, const struct sshkey *key, FILE *f) {
+	BIO  *out;
+
+	if (!x509key_check("Xkey_write_subject", key)) return(0);
+
+	if (pkalg == NULL) pkalg = key_ssh_name(key);
+
+	out = BIO_new_fp(f, BIO_NOCLOSE);
+	if (out == NULL) return(0);
+#ifdef VMS
+	{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		out = BIO_push(tmpbio, out);
+	}
+#endif
+
+	BIO_puts(out, pkalg);
+	BIO_puts(out, " Subject:");
+	ssh_X509_NAME_print(out, X509_get_subject_name(key->x509_data->cert));
+
+	BIO_free_all(out);
+	return(1);
+}
+
+
+static int
+x509key_load_certs_bio(Key *key, BIO *bio) {
+	int ret = 0;
+	STACK_OF(X509) *chain;
+
+	chain = sk_X509_new_null();
+	if (chain == NULL) {
+		fatal("x509key_load_certs_bio: out of memory");
+		return(-1); /*unreachable code*/
+	}
+
+	do {
+		X509 *x = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+		if (x == NULL) break;
+
+		sk_X509_insert(chain, x, -1 /*last*/);
+	} while (1);
+
+{	/* clear OpenSSL "error buffer" */
+	char ebuf[64];
+	(void) openssl_errormsg(ebuf, sizeof(ebuf));
+}
+
+	key->x509_data->chain = chain;
+
+	x509key_build_chain(key);
+
+	ret = sk_X509_num(chain);
+
+	return(ret);
+}
+
+
+void
+x509key_parse_cert(Key *key, EVP_PKEY *pk, BIO *bio) {
+	X509 *x;
+	SSH_X509 *xd;
+
+	if (key == NULL) return;
+
+	if (!ssh_x509_support_plain_type(key->type))
+		return;
+
+	debug("read X.509 certificate begin");
+	x = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+	if (x == NULL) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		debug3("%s: PEM_read_X509 fail %.*s", __func__,
+			(int)sizeof(ebuf), ebuf);
+		return;
+	}
+
+	if (!X509_check_private_key(x, pk)) {
+		fatal("X.509 certificate don't match private key");
+		/*unreachable code*/
+	}
+
+	xd = key->x509_data = SSH_X509_new(); /*fatal on error*/
+	xd->cert = x;
+
+	TO_X509_KEY_TYPE(key);
+
+	(void)x509key_load_certs_bio(key, bio);
+
+	debug("read X.509 certificate done: type %.40s", key_type(key));
+	return;
+}
+
+
+void
+x509key_load_certs(const char *pkalg, Key *key, const char *filename) {
+	size_t len;
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return;
+
+	/* return if public key algorithm is not in RFC6187 format */
+	if (!p->chain)
+		return;
+}
+
+	len = strlen(filename);
+	if ((len > 9) &&
+	    (strcmp (filename + len - 9,"-cert.pub") == 0)
+	)	return;
+	if ((len > 4) &&
+	    (strcmp (filename + len - 4,".pub") != 0)
+	)	return;
+
+{	/* Remove .pub suffix and try to extract certificates from
+	 * "private" key file. Note that for pkcs11 module we may
+	 * have only "public" part.
+	 */
+	char file[PATH_MAX];
+
+	if (strlcpy(file, filename, sizeof(file)) < len) {
+		fatal("x509key_load_certs: length of filename exceed PATH_MAX");
+		return; /*unreachable code*/
+	}
+	file[len - 4] = '\0';
+
+{	BIO *bio = BIO_new_file(file, "r");
+	if (bio != NULL) {
+		(void)x509key_load_certs_bio(key, bio);
+		BIO_free_all(bio);
+	}
+}
+}
+
+	return;
+}
+
+
+void
+x509key_build_chain(Key *key) {
+	SSH_X509 *x509_data;
+	STACK_OF(X509)* chain;
+
+	if (pssh_x509store_build_certchain == NULL) return;
+
+	x509_data = key->x509_data;
+	if (x509_data == NULL) return;
+
+	chain = (*pssh_x509store_build_certchain)(x509_data->cert, x509_data->chain);
+	if (chain == NULL) return;
+
+	sk_X509_pop_free(x509_data->chain, X509_free);
+	x509_data->chain = chain;
+}
+
+
+static int
+x509key_write_bio_cert(BIO *out, X509 *x509) {
+	int  ret = 0;
+
+	BIO_puts(out, "issuer= ");
+	ssh_X509_NAME_print(out, X509_get_issuer_name(x509));
+	BIO_puts(out, "\n");
+
+	BIO_puts(out, "subject= ");
+	ssh_X509_NAME_print(out, X509_get_subject_name(x509));
+	BIO_puts(out, "\n");
+
+	{
+		const char *alstr = (const char*)X509_alias_get0(x509, NULL);
+		if (alstr == NULL) alstr = "<No Alias>";
+		BIO_puts(out, alstr);
+		BIO_puts(out, "\n");
+	}
+
+	ret = PEM_write_bio_X509(out, x509);
+	if (!ret) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: PEM_write_bio_X509 fail %.*s",
+			__func__, (int)sizeof(ebuf), ebuf);
+	}
+
+	return(ret);
+}
+
+
+int/*bool*/
+x509key_write_identity_bio_pem(
+	BIO *bio,
+	const Key *key
+) {
+	int flag = 0;
+	X509 *x;
+	STACK_OF(X509) *chain;
+	int k;
+
+	if (!x509key_check("save_identity_pem", key)) return(0);
+
+	x = key->x509_data->cert;
+	flag = x509key_write_bio_cert(bio, x);
+	if (!flag)
+		goto done;
+
+	chain = key->x509_data->chain;
+	if (chain == NULL)
+		goto done;
+
+	for (k = 0; k < sk_X509_num(chain); k++) {
+		x = sk_X509_value(chain, k);
+		flag = x509key_write_bio_cert(bio, x);
+		if (!flag)
+			goto done;
+	}
+
+done:
+	return(flag);
+}
+
+
+#ifndef OPENSSH_KEYS_USE_BIO
+int/*bool*/
+x509key_save_identity_pem(FILE *fp, const Key *key) {
+	int  flag;
+	BIO *out;
+
+	out = BIO_new_fp(fp, BIO_NOCLOSE);
+	if (out == NULL) return(0);
+
+#ifdef VMS
+	{
+		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		if (tmpbio == NULL) {
+			BIO_free_all(out);
+			return(0);
+		}
+		out = BIO_push(tmpbio, out);
+	}
+#endif
+	flag = x509key_write_identity_bio_pem(bio, key);
+
+	BIO_free_all(out);
+
+	return(flag);
+}
+#endif /*ndef OPENSSH_KEYS_USE_BIO*/
+
+
+/*
+ * We can check only by Subject (Distinguished Name):
+ *   - sshd receive from client only x509 certificate !!!
+ *   - sshadd -d ... send only x509 certificate !!!
+ *   - otherwise Key might contain private key
+ */
+int
+ssh_x509_equal(const Key *a, const Key *b) {
+	X509 *xa;
+	X509 *xb;
+
+	if (!x509key_check("ssh_x509_equal", a)) return(1);
+	if (!x509key_check("ssh_x509_equal", b)) return(-1);
+
+	xa = a->x509_data->cert;
+	xb = b->x509_data->cert;
+#if 1
+/*
+ * We must use own method to compare two X509_NAMEs instead of OpenSSL
+ * function[s]! See notes before body of "ssh_X509_NAME_cmp()".
+ */
+	{
+		X509_NAME *nameA = X509_get_subject_name(xa);
+		X509_NAME *nameB = X509_get_subject_name(xb);
+		return(ssh_X509_NAME_cmp(nameA, nameB));
+	}
+#else
+	return(X509_subject_name_cmp(xa, xb));
+#endif
+}
+
+
+int
+ssh_x509key_type(const char *name) {
+	const SSHX509KeyAlgs *p;
+	int k;
+
+	if (name == NULL) {
+		fatal("ssh_x509key_type: name is NULL");
+		return(KEY_UNSPEC); /*unreachable code*/
+	}
+
+	k = ssh_xkalg_nameind(name, &p, -1);
+	return((k >= 0) ? p->type : KEY_UNSPEC);
+}
+
+
+const char*
+ssh_x509key_name(const Key *k) {
+	const SSHX509KeyAlgs *p;
+	int n;
+
+	if (k == NULL) {
+		fatal("ssh_x509key_name: key is NULL");
+		return(NULL); /*unreachable code*/
+	}
+	if (!key_is_x509(k)) return(NULL);
+
+	n = ssh_xkalg_typeind(k->type, k->ecdsa_nid, &p, -1);
+	if (n >= 0) return(p->name);
+
+	return(NULL);
+}
+
+
+int
+ssh_x509key_verify_cert(const Key *k) {
+	int ret = -1;
+	SSH_X509 *xd;
+
+	if (!x509key_check("verify_cert", k)) goto done;
+
+	xd = k->x509_data;
+
+	if (pssh_x509store_verify_cert != NULL) {
+		ret = pssh_x509store_verify_cert(xd->cert, xd->chain);
+	} else {
+		error("%s: pssh_x509store_verify_cert is NULL", __func__);
+	}
+
+done:
+	return(ret);
+}
+
+
+static int
+ssh_x509_EVP_PKEY_sign(
+	EVP_PKEY *privkey, const ssh_x509_md *dgst,
+	u_char *sigret, u_int *siglen,
+	const u_char *data, u_int datalen
+) {
+	int         ret = 1;
+	EVP_MD_CTX *ctx;
+
+	ctx = EVP_MD_CTX_new();
+	if (ctx == NULL) {
+		ret = -1;
+		error("ssh_x509_EVP_PKEY_sign: out of memory");
+	}
+
+	if (ret > 0) {
+		ret = EVP_SignInit_ex(ctx, dgst->evp, NULL);
+		if (ret <= 0) {
+			char ebuf[1024];
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			error("ssh_x509_EVP_PKEY_sign: EVP_SignInit_ex"
+			" fail with errormsg='%.*s'"
+			, (int)sizeof(ebuf), ebuf);
+		}
+	}
+	if (ret > 0) {
+		ret = EVP_SignUpdate(ctx, data, datalen);
+		if (ret <= 0) {
+			char ebuf[1024];
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			error("ssh_x509_EVP_PKEY_sign: EVP_SignUpdate"
+			" fail with errormsg='%.*s'"
+			, (int)sizeof(ebuf), ebuf);
+		}
+	}
+	if (ret > 0) {
+		ret = dgst->SignFinal(ctx, sigret, siglen, privkey);
+		debug3("ssh_x509_EVP_PKEY_sign: keylen=%d, siglen=%u",
+		       EVP_PKEY_size(privkey), *siglen);
+		if (ret <= 0) {
+			char ebuf[1024];
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			error("ssh_x509_EVP_PKEY_sign: digest failed: %.*s"
+			, (int)sizeof(ebuf), ebuf);
+		}
+	}
+
+	EVP_MD_CTX_free(ctx);
+
+	return(ret);
+}
+
+
+static int
+ssh_x509_sign(ssh_sign_ctx *ctx,
+	u_char **sigp, size_t *lenp, const u_char *data, size_t datalen
+) {
+	int r;
+	const struct sshkey *key;
+	const SSHX509KeyAlgs *xkalg = NULL;
+	int  keylen = 0;
+	u_char *sigret = NULL;
+	u_int  siglen;
+
+	key = ctx->key;
+
+	debug3("ssh_x509_sign: key alg/type/name: %s/%s/%s",
+	    ctx->alg, key_type(key), key_ssh_name(key));
+	debug3("ssh_x509_sign: compatibility: { 0x%08x, 0x%08x }",
+	    ctx->compat->datafellows, ctx->compat->xcompat);
+
+	if (ssh_xkalg_nameind(ctx->alg, &xkalg, -1) < 0) {
+		error("ssh_x509_sign: cannot handle algorithm"
+		    " '%s' for key type %d[, curve %d]",
+		    ctx->alg, key->type, key->ecdsa_nid);
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+{	/* compute signature */
+	EVP_PKEY *privkey = EVP_PKEY_new();
+	int res = -1;
+
+	if (privkey == NULL) {
+		error("ssh_x509_sign: out of memory - EVP_PKEY_new");
+		r = SSH_ERR_ALLOC_FAIL;
+		goto done;
+	}
+	r = SSH_ERR_SUCCESS;
+
+	if (key->rsa)
+		res = EVP_PKEY_set1_RSA(privkey, key->rsa);
+	else if (key->dsa)
+		res = EVP_PKEY_set1_DSA(privkey, key->dsa);
+#ifdef OPENSSL_HAS_ECC
+	else if (key->ecdsa)
+		res = EVP_PKEY_set1_EC_KEY(privkey, key->ecdsa);
+#endif
+	else {
+		error("ssh_x509_sign: missing private key");
+		r = SSH_ERR_INVALID_ARGUMENT;
+		goto end_sign_pkey;
+	}
+
+	if (res <= 0) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("ssh_x509_sign: EVP_PKEY_set1_XXX: fail %.*s",
+			(int)sizeof(ebuf), ebuf);
+		r = SSH_ERR_LIBCRYPTO_ERROR;
+		goto end_sign_pkey;
+	}
+
+	keylen = EVP_PKEY_size(privkey);
+	if (keylen <= 0) {
+		error("ssh_x509_sign: cannot get key size");
+		r = SSH_ERR_LIBCRYPTO_ERROR;
+		goto end_sign_pkey;
+	}
+
+	/* NOTE:
+	 * allocate extra size as signature like this for ecdsa
+	 * keys contain bytes with size of encoded items
+	 */
+	sigret = xmalloc(keylen+20/*?*/); /*fatal on error*/
+
+	debug3("ssh_x509_sign: alg=%.50s, md=%.30s", xkalg->name, xkalg->dgst.name);
+
+{	u_int len = datalen;
+
+	if ((size_t)len != datalen) {
+		r = SSH_ERR_INVALID_FORMAT;
+		goto end_sign_pkey;
+	}
+{	ssh_x509_md dgst;
+	ssh_xkalg_dgst_compat(&dgst, &xkalg->dgst, ctx->compat);
+
+	res = ssh_x509_EVP_PKEY_sign(privkey, &dgst, sigret, &siglen, data, len);
+}
+	if (res <= 0)
+		r = SSH_ERR_LIBCRYPTO_ERROR;
+}
+
+end_sign_pkey:
+	EVP_PKEY_free(privkey);
+}
+	if (r != SSH_ERR_SUCCESS) goto done;
+
+{	/* create ssh signature blob */
+	struct sshbuf *buf;
+	const char *signame;
+
+	buf = sshbuf_new();
+	if (buf == NULL) {
+		error("ssh_x509_sign: out of memory - sshbuf_new");
+		r = SSH_ERR_ALLOC_FAIL;
+		goto done;
+	}
+
+	signame = X509PUBALG_SIGNAME(xkalg);
+	debug3("ssh_x509_sign: signame=%.50s", signame);
+
+	r = sshbuf_put_cstring(buf, signame);
+	if (r != 0) goto end_sign_blob;
+
+	r = sshbuf_put_string(buf, sigret, siglen);
+	if (r != 0) goto end_sign_blob;
+
+{	size_t len = sshbuf_len(buf);
+	if (sigp != NULL) {
+		*sigp = xmalloc(len); /*fatal on error*/
+		memcpy(*sigp, sshbuf_ptr(buf), len);
+	}
+	if (lenp != NULL)
+		*lenp = len;
+}
+
+end_sign_blob:
+	sshbuf_free(buf);
+}
+
+done:
+	if (sigret != NULL) {
+		memset(sigret, 's', keylen+20);
+		free(sigret);
+	}
+
+	debug3("ssh_x509_sign: return %d", r);
+	return r;
+}
+
+
+static int
+ssh_xkalg_verify(
+	const SSHX509KeyAlgs *xkalg, EVP_PKEY* pubkey,
+	u_char *sigblob, u_int len, const u_char *data, u_int datalen
+) {
+	int ret;
+	EVP_MD_CTX *ctx;
+
+	ctx = EVP_MD_CTX_new();
+	if (ctx == NULL) {
+		error("ssh_xkalg_verify: out of memory");
+		return -1;
+	}
+
+	ret = EVP_VerifyInit(ctx, xkalg->dgst.evp);
+	if (ret <= 0) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyInit fail with errormsg='%.*s'"
+		    , __func__, (int)sizeof(ebuf), ebuf);
+		goto done;
+	}
+
+	ret = EVP_VerifyUpdate(ctx, data, datalen);
+	if (ret <= 0) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: EVP_VerifyUpdate fail with errormsg='%.*s'"
+		    , __func__, (int)sizeof(ebuf), ebuf);
+		goto done;
+	}
+
+	ret = xkalg->dgst.VerifyFinal(ctx, sigblob, len, pubkey);
+
+done:
+	EVP_MD_CTX_free(ctx);
+	return ret;
+}
+
+
+static int
+ssh_x509_verify(
+	ssh_sign_ctx *ctx,
+	const u_char *sig, size_t siglen,
+	const u_char *data, size_t dlen
+) {
+	int r = SSH_ERR_INTERNAL_ERROR;
+	const struct sshkey *key;
+	const SSHX509KeyAlgs *xkalg;
+	int loc;
+	EVP_PKEY* pubkey;
+	u_char *sigblob = NULL;
+	u_int len = 0;
+	u_int datalen;
+
+	key = ctx->key;
+	debug3("ssh_x509_verify:  key alg/type/name: %s/%s/%s",
+	    ctx->alg, key_type(key), key_ssh_name(key));
+	debug3("ssh_x509_verify: compatibility: { 0x%08x, 0x%08x }",
+	    ctx->compat->datafellows, ctx->compat->xcompat);
+
+	loc = ssh_xkalg_nameind(ctx->alg, &xkalg, -1);
+	if (loc < 0) {
+		error("ssh_x509_verify: cannot handle algorithm"
+		    " '%s' for key type %d[, curve %d]",
+		    ctx->alg, key->type, key->ecdsa_nid);
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+	pubkey = X509_get_pubkey(key->x509_data->cert);
+	if (pubkey == NULL) {
+		error("ssh_x509_verify: no 'X509 Public Key'");
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+	if (dlen > INT_MAX)
+		return SSH_ERR_INVALID_ARGUMENT;
+	datalen = dlen;
+
+	/* process signature */
+{	struct sshbuf *buf;
+
+	buf = sshbuf_new();
+	if (buf == NULL) {
+		error("ssh_x509_verify: out of memory - sshbuf_new");
+		return SSH_ERR_ALLOC_FAIL;
+	}
+
+	r = sshbuf_put(buf, sig, siglen);
+	if (r != 0) goto end_sign_blob;
+
+	/* check signature name */
+{	u_char *sigformat;
+
+	r = sshbuf_get_string(buf, &sigformat, NULL);
+	if (r != 0) goto end_sign_blob;
+
+	debug3("ssh_x509_verify: signature name = %.40s", sigformat);
+	if (!ssh_is_x509signame(sigformat)) {
+		error("ssh_x509_verify: cannot handle signature name %.40s", sigformat);
+		r = SSH_ERR_INVALID_FORMAT;
+	}
+	free(sigformat);
+}
+	if (r != 0) goto end_sign_blob;
+
+	/* extract signature blob */
+{	size_t lenblob = 0;
+
+	r = sshbuf_get_string(buf, &sigblob, &lenblob);
+	if (r != 0) goto end_sign_blob;
+
+	if (lenblob > INT_MAX) {
+		r = SSH_ERR_SIGNATURE_INVALID;
+		len = INT_MAX;
+		goto end_sign_blob;
+	}
+	len = lenblob;
+}
+
+	/* check consistency */
+{	size_t rlen = sshbuf_len(buf);
+	if (rlen != 0) {
+		error("ssh_x509_verify: remaining bytes in signature %zu", rlen);
+		r = SSH_ERR_INVALID_FORMAT;
+	}
+}
+
+end_sign_blob:
+	sshbuf_free(buf);
+}
+	if (r != 0) goto done;
+
+	 /* verify signed data */
+{	int ret;
+	for (; loc >= 0; loc = ssh_xkalg_nameind(ctx->alg, &xkalg, loc)) {
+		debug3("ssh_x509_verify: md=%.30s, loc=%d", xkalg->dgst.name, loc);
+
+		ret = ssh_xkalg_verify(xkalg, pubkey, sigblob, len, data, datalen);
+		if (ret > 0) break;
+	}
+	if (ret <= 0) {
+		debug3("ssh_x509_verify: failed for all digests");
+		r = SSH_ERR_SIGNATURE_INVALID;
+	}
+}
+
+done:
+	if (sigblob) {
+		memset(sigblob, 's', len);
+		free(sigblob);
+		sigblob = NULL;
+	}
+	EVP_PKEY_free(pubkey);
+
+	if (r == 0) {
+		int ret;
+		ret = ssh_x509key_verify_cert(key);
+		if (ret <= 0)
+			r = SSH_ERR_KEY_CERT_INVALID;
+	}
+
+	debug3("ssh_x509_verify: return %d", r);
+	return r;
+}
+
+
+int
+Xkey_sign(ssh_sign_ctx *ctx,
+	  u_char **sigp, size_t *lenp,
+	  const u_char *data, size_t datalen
+) {
+	if (ctx->alg == NULL)
+		ctx->alg = sshkey_ssh_name(ctx->key);
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(ctx->alg, &p, -1) < 0)
+		return sshkey_sign(ctx->key, sigp, lenp,
+		    data, datalen, ctx->alg, ctx->compat->datafellows);
+}
+
+	return ssh_x509_sign(ctx, sigp, lenp, data, datalen);
+}
+
+
+static inline void
+log_ssh_err(const char *func, int r) {
+	if (r == SSH_ERR_INTERNAL_ERROR || r == SSH_ERR_ALLOC_FAIL)
+		fatal("%s: %s", func, ssh_err(r));
+	else
+		error("%s: %s", func, ssh_err(r));
+}
+
+
+int
+xkey_sign(ssh_sign_ctx *ctx, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) {
+	int r;
+	u_char *sig;
+	size_t siglen;
+
+	if (sigp != NULL) *sigp = NULL;
+	if (lenp != NULL) *lenp = 0;
+
+	r = Xkey_sign(ctx, &sig, &siglen, data, datalen);
+	if (r != 0) {
+		log_ssh_err(__func__, r);
+		return -1;
+	}
+	if (siglen > INT_MAX)
+		fatal("%s: giant len %zu", __func__, siglen);
+
+	if (sigp != NULL) *sigp = sig;
+	if (lenp != NULL) *lenp = siglen;
+
+	return 0;
+}
+
+
+int
+Xkey_verify(ssh_sign_ctx *ctx,
+	    const u_char *sig, size_t siglen,
+	    const u_char *data, size_t dlen
+) {
+	if (ctx->alg == NULL)
+		ctx->alg = sshkey_ssh_name(ctx->key);
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(ctx->alg, &p, -1) < 0)
+		return sshkey_verify(ctx->key, sig, siglen,
+		     data, dlen, ctx->compat->datafellows);
+}
+
+	return ssh_x509_verify(ctx, sig, siglen, data, dlen);
+}
+
+
+int
+xkey_verify(ssh_sign_ctx *ctx, const u_char *sig, u_int siglen, const u_char *data, u_int dlen) {
+	int r;
+
+	/* sizeof (u_int) <= sizeof(size_t) */
+	r = Xkey_verify(ctx, sig, siglen, data, dlen);
+	if (r == SSH_ERR_SUCCESS) return 1;
+
+	return (r == SSH_ERR_SIGNATURE_INVALID) ? 0 : -1;
+}
+
+
+u_int
+ssh_x509_key_size(const Key *key) {
+	EVP_PKEY *pkey;
+	int k = 0;
+
+	if (!x509key_check("key_size", key)) goto done;
+
+	pkey = X509_get_pubkey(key->x509_data->cert);
+	if (pkey == NULL) goto done;
+
+	/* NOTE BN_num_bits returns int! */
+	switch(EVP_PKEY_id(pkey)) {
+	case EVP_PKEY_RSA: {
+		RSA *rsa;
+		const BIGNUM *n;
+
+		rsa = EVP_PKEY_get0_RSA(pkey);
+		RSA_get0_key(rsa, &n, NULL, NULL);
+		k = BN_num_bits(n);
+		} break;
+	case EVP_PKEY_DSA: {
+		DSA *dsa;
+		const BIGNUM *p;
+
+		dsa = EVP_PKEY_get0_DSA(pkey);
+		DSA_get0_pqg(dsa, &p, NULL, NULL);
+		k = BN_num_bits(p);
+		} break;
+#ifdef OPENSSL_HAS_ECC
+	case EVP_PKEY_EC: {
+		int     ecdsa_nid;
+		{
+			EC_KEY *ecdsa = EVP_PKEY_get0_EC_KEY(pkey);
+			ecdsa_nid = key_ecdsa_key_to_nid(ecdsa);
+		}
+		k = key_curve_nid_to_bits(ecdsa_nid);
+		} break;
+#endif
+	default:
+		fatal("ssh_x509_key_size: unknow EVP_PKEY type %d", EVP_PKEY_id(pkey));
+		/*unreachable code*/
+	}
+	EVP_PKEY_free(pkey);
+done:
+	return((u_int) k);
+}
+
+
+int/*bool*/
+ssh_x509_set_cert(Key *key, X509 *x509) {
+	int ret = 0;
+	SSH_X509 *xd;
+
+	if (key == NULL) {
+		fatal("%s: key is NULL", __func__);
+		goto done; /*unreachable code*/
+	}
+
+{	int k_type = key_type_plain(key->type);
+	if (!ssh_x509_support_plain_type(k_type)) {
+		fatal("%s: unsupported key type %d", __func__, key->type);
+		goto done; /*unreachable code*/
+	}
+}
+
+	xd = key->x509_data;
+	if (xd != NULL) {
+		if (xd->cert != NULL) {
+			fatal("%s: X.509 certificate is alreasy set", __func__);
+			goto done; /*unreachable code*/
+		}
+	} else
+		xd = key->x509_data = SSH_X509_new(); /*fatal on error*/
+
+	/* NOTE caller is responsible to ensure that X.509 certificate
+	 * match private key
+	 */
+	xd->cert = x509;
+
+	TO_X509_KEY_TYPE(key);
+
+	ret = 1;
+done:
+	return(ret);
+}
+
+
+int
+ssh_x509_cmp_cert(const Key *key1, const Key *key2) {
+	/* only dns.c call this function so skip checks ...
+	if (!x509key_check("cmp_cert", key1)) return(-1);
+	if (!x509key_check("cmp_cert", key2)) return(1);
+	*/
+	return(X509_cmp(key1->x509_data->cert, key2->x509_data->cert));
+}
+
+
+int
+Xkey_from_blob(const char *pkalg, const u_char *blob, size_t blen, struct sshkey **keyp) {
+	int klen = (int)blen;
+	int RFC6187_format;
+
+	if (pkalg == NULL) {
+		error("%s: pkalg is NULL", __func__);
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+	debug3("%s() pkalg='%s', blen=%zu", __func__, pkalg, blen);
+
+	if ((size_t)klen != blen)
+		return SSH_ERR_INVALID_ARGUMENT;
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return sshkey_from_blob(blob, blen, keyp);
+
+	RFC6187_format = p->chain;
+}
+
+{	struct sshkey *key = RFC6187_format
+		? x509key_from_blob2(pkalg, blob, klen)
+		: x509key_from_blob(blob, klen);
+
+	if (key == NULL)
+		return SSH_ERR_INVALID_FORMAT;
+
+	if (keyp != NULL)
+		*keyp = key;
+}
+	return SSH_ERR_SUCCESS;
+}
+
+
+Key*
+xkey_from_blob(const char *pkalg, const u_char *blob, u_int blen) {
+	Key* key;
+	int r;
+
+	r = Xkey_from_blob(pkalg, blob, (size_t) blen, &key);
+
+	return (r == SSH_ERR_SUCCESS) ? key : NULL;
+}
+
+
+int
+Xkey_to_blob(const char *pkalg, const struct sshkey *key, u_char **blobp, size_t *lenp) {
+	int RFC6187_format;
+
+	if (pkalg == NULL)
+		return SSH_ERR_INVALID_ARGUMENT;
+	if (key == NULL) {
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return sshkey_to_blob(key, blobp, lenp);
+
+	RFC6187_format = p->chain;
+}
+
+{
+	struct sshbuf *b;
+	size_t len;
+
+	b = sshbuf_new();
+	if (b == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+
+	if (RFC6187_format) {
+		int ret;
+		ret = x509key_to_blob2(pkalg, key, b);
+		if (ret != SSH_ERR_SUCCESS)
+			return ret;
+	} else {
+		if (!x509key_to_blob(key, b))
+			return SSH_ERR_INTERNAL_ERROR;
+	}
+
+	len = sshbuf_len(b);
+	if (lenp != NULL)
+		*lenp = len;
+	if (blobp != NULL) {
+		*blobp = xmalloc(len);
+		memcpy(*blobp, sshbuf_ptr(b), len);
+	}
+
+	sshbuf_free(b);
+
+	return SSH_ERR_SUCCESS;
+}
+}
+
+
+int
+xkey_to_blob(const char *pkalg, const Key *key, u_char **blobp, u_int *lenp) {
+	size_t len;
+
+	if (Xkey_to_blob(pkalg, key, blobp, &len) != SSH_ERR_SUCCESS)
+		return 0;
+
+	/*cast from size_t to u_int is save*/
+	if (lenp != NULL)
+		*lenp = len;
+
+	return len;
+}
+
+
+int
+X509key_to_buf(const struct sshkey *key, struct sshbuf *b) {
+	SSH_X509 *xd;
+	X509 *x;
+	int r;
+
+	/*ensure that caller check for non-null X.509 key argument*/
+
+	xd = key->x509_data;
+	if (xd == NULL)
+		return SSH_ERR_INVALID_FORMAT;
+
+	if (xd->cert == NULL)
+		return SSH_ERR_INVALID_FORMAT;
+
+	x = xd->cert;
+	r = sshbuf_append_x509(b, x);
+	if (r != 0) goto end;
+
+#if 0 /* incorrect */
+{	STACK_OF(X509) *chain = key->x509_data->chain;
+	int n;
+
+	if (chain == NULL) return SSH_ERR_SUCCESS;
+
+	/* append certificates from chain */
+	for (n = 0; n < sk_X509_num(chain); n++) {
+		x = sk_X509_value(chain, n);
+		r = sshbuf_append_x509(b, x);
+		if (r != 0) goto end;
+	}
+}
+#endif
+end:
+	return(r);
+}
+
+
+int
+X509key_from_buf(struct sshbuf *b, struct sshkey **keyp) {
+	struct sshkey* key = NULL;
+	BIO *mbio;
+	X509* x;
+
+{
+	const u_char *blob = sshbuf_ptr(b);
+	/* ssh buffer is limited to SSHBUF_SIZE_MAX(0x08000000) < int(0x7FFFFFFF) */
+	int           blen = sshbuf_len(b);
+	mbio = BIO_new_mem_buf((void*)blob, blen);
+	if (mbio == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+}
+	x = d2i_X509_bio(mbio, NULL);
+	if (x == NULL)
+		return SSH_ERR_INVALID_FORMAT;
+
+{	/* rewind buffer */
+	size_t l = i2d_X509(x, NULL);
+	sshbuf_consume(b, l);
+}
+
+	key = x509_to_key(x);
+	if (key == NULL) {
+		X509_free(x);
+		return SSH_ERR_ALLOC_FAIL;
+	}
+
+	if (BIO_pending(mbio) > 0) {
+#if 0 /* incorrect */
+		STACK_OF(X509) *chain;
+
+		chain = sk_X509_new_null();
+		if (chain == NULL) {
+			sshkey_free(key);
+			return SSH_ERR_ALLOC_FAIL;
+		}
+
+		for (
+		    x = d2i_X509_bio(mbio, NULL);
+		    x != NULL;
+		    x = d2i_X509_bio(mbio, NULL)
+		) {
+		{	/* rewind buffer */
+			size_t l = i2d_X509(x, NULL);
+			sshbuf_consume(b, l);
+		}
+			sk_X509_insert(chain, x, -1 /*last*/);
+		}
+		key->x509_data->chain = chain;
+#else
+		debug3("%s() remaining bytes %d", __func__, BIO_pending(mbio));
+#endif
+	}
+
+	if (keyp == NULL)
+		sshkey_free(key);
+	else
+		*keyp = key;
+	return SSH_ERR_SUCCESS;
+}
+
+
+int
+Xkey_puts(const char *pkalg, const struct sshkey *key, struct sshbuf *b) {
+	int r;
+	int RFC6187_format;
+
+	if (pkalg == NULL)
+		return SSH_ERR_INVALID_ARGUMENT;
+	if (key == NULL) {
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return sshkey_puts(key, b);
+
+	RFC6187_format = p->chain;
+}
+
+	if (RFC6187_format) {
+		struct sshbuf *d = sshbuf_new();
+		if (d == NULL) return SSH_ERR_ALLOC_FAIL;
+
+		r = x509key_to_blob2(pkalg, key, d);
+		if (r != SSH_ERR_SUCCESS)
+			debug3("%s: x509key_to_blob2 fail" , __func__);
+		else
+			r = sshbuf_put_stringb(b, d);
+
+		buffer_free(d);
+	} else
+		r = sshbuf_put_x509(b, key->x509_data->cert);
+
+	return r;
+}
+
+
+int
+Xkey_putb(const char *pkalg, const struct sshkey *key, struct sshbuf *b) {
+	int r;
+	int RFC6187_format;
+
+	if (pkalg == NULL)
+		return SSH_ERR_INVALID_ARGUMENT;
+	if (key == NULL) {
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+{	/* check if public algorithm is with X.509 certificates */
+	const SSHX509KeyAlgs *p;
+
+	if (ssh_xkalg_nameind(pkalg, &p, -1) < 0)
+		return sshkey_putb(key, b);
+
+	RFC6187_format = p->chain;
+}
+
+	if (RFC6187_format)
+		r = x509key_to_blob2(pkalg, key, b);
+	else
+		r = sshbuf_append_x509(b, key->x509_data->cert);
+
+	return r;
+}
+
+
+int
+parse_key_from_blob(
+	const u_char *blob, size_t blen,
+	struct sshkey **keyp, char **pkalgp
+) {
+	int r;
+
+{	struct sshbuf *b = sshbuf_from(blob, blen);
+
+	if (b == NULL) return SSH_ERR_ALLOC_FAIL;
+
+	r = X509key_from_buf2_common(b, keyp, pkalgp);
+
+	sshbuf_free(b);
+	if (r == SSH_ERR_SUCCESS) return r;
+}
+
+	r = sshkeyalg_from_blob(blob, blen, keyp, pkalgp);
+
+	return r;
+}
diff -ruN openssh-7.5p1/ssh-x509.h openssh-7.5p1+x509-10.2/ssh-x509.h
--- openssh-7.5p1/ssh-x509.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-x509.h	2017-03-23 20:27:54.000000000 +0200
@@ -0,0 +1,119 @@
+#ifndef SSH_X509_H
+#define SSH_X509_H
+/*
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include "key.h"
+#include "buffer.h"
+
+
+/*
+ * Method return a key(x509) only with "Subject"("Distinguished Name") !
+ */
+Key*	X509key_from_subject(const char *pkalg, const char *cp, char **ep);
+
+
+/* draft-ietf-secsh-transport-12.txt */
+Key*	x509key_from_blob(const u_char *blob, int blen);
+
+int	X509key_to_buf(const struct sshkey *key, struct sshbuf *b);
+int	X509key_from_buf(struct sshbuf *b, struct sshkey **keyp);
+
+int	X509key_encode_identity(const char *pkalg, const struct sshkey *key, struct sshbuf *b);
+int	X509key_decode_identity(const char *pkalg, struct sshbuf *b, struct sshkey *k);
+
+void	x509key_move_identity(Key *from, Key *to);
+void	x509key_copy_identity(const Key *from, Key *to);
+void	x509key_demote(const Key *k, Key *pk);
+
+char*	x509key_subject(const Key *key);
+
+/*
+ * Method write base 64 encoded X.509 identity of key.
+ */
+int	x509key_write(const Key *key, FILE *f);
+/*
+ * Method write subject of key X.509 certificate.
+ */
+int	Xkey_write_subject(const char *pkalg, const struct sshkey *key, FILE *f);
+
+/*
+ * The patched configure script define OPENSSH_KEYS_USE_BIO
+ * depending from OpenSSH version
+ */
+
+void	x509key_parse_cert(Key *key, EVP_PKEY *pk, BIO *bio);
+void	x509key_load_certs(const char *pkalg, Key *key, const char *filename);
+void	x509key_build_chain(Key *key);
+
+int/*bool*/	x509key_write_identity_bio_pem(BIO *bio, const Key *key);
+#ifndef OPENSSH_KEYS_USE_BIO
+int/*bool*/	x509key_save_identity_pem(FILE *fp, const Key *key);
+#endif
+
+int	ssh_x509_equal(const Key *a, const Key *b);
+
+int		ssh_x509key_type(const char *name);
+const char*	ssh_x509key_name(const Key *k);
+int		ssh_x509key_verify_cert(const Key *k);
+
+u_int	ssh_x509_key_size(const Key *key);
+
+int/*bool*/	ssh_x509_set_cert(Key *key, X509 *x509);
+int		ssh_x509_cmp_cert(const Key *key1, const Key *key2);
+
+
+/* extended key format support */
+int	Xkey_from_blob(const char *pkalg, const u_char *blob, size_t blen, struct sshkey **keyp);
+Key	*xkey_from_blob(const char *pkalg, const u_char *blob, u_int blen);
+
+int	Xkey_to_blob(const char *pkalg, const struct sshkey *key, u_char **blobp, size_t *lenp);
+int	xkey_to_blob(const char *pkalg, const Key *key, u_char **blobp, u_int *lenp);
+
+int	Xkey_puts(const char *pkalg, const struct sshkey *key, struct sshbuf *b);
+int	Xkey_putb(const char *pkalg, const struct sshkey *key, struct sshbuf *b);
+
+int	parse_key_from_blob(const u_char *blob, size_t blen,
+	    struct sshkey **keyp, char **pkalgp);
+
+
+struct ssh_signature_context_st {
+	const char	*alg;		/* public key algorith name (optional) */
+	struct sshkey	*key;		/* signing key */
+	ssh_compat	*compat;	/* ssh compatibilities */
+};
+
+int	Xkey_sign(ssh_sign_ctx *ctx, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen);
+int	xkey_sign(ssh_sign_ctx *ctx, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen);
+
+int	Xkey_verify(ssh_sign_ctx *ctx, const u_char *sig, size_t siglen, const u_char *data, size_t dlen);
+int	xkey_verify(ssh_sign_ctx *ctx, const u_char *sig, u_int siglen, const u_char *data, u_int dlen);
+
+
+/* backward compatibility */
+int	 key_is_x509(const Key *);
+#define KEY_FLAG_EXT	SSHKEY_FLAG_EXT
+
+#endif /* SSH_X509_H */
diff -ruN openssh-7.5p1/ssh-xkalg.c openssh-7.5p1+x509-10.2/ssh-xkalg.c
--- openssh-7.5p1/ssh-xkalg.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-xkalg.c	2017-03-30 21:33:33.000000000 +0300
@@ -0,0 +1,903 @@
+/*
+ * Copyright (c) 2005-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ssh-xkalg.h"
+#include <string.h>
+#include <openssl/sha.h>
+
+#include "log.h"
+#include "key.h"
+#include "match.h"
+#include "myproposal.h"
+#include "xmalloc.h"
+#include "evp-compat.h"
+#include "compat.h"
+
+
+#define SHARAW_DIGEST_LENGTH (2*SHA_DIGEST_LENGTH)
+
+
+#ifdef OPENSSL_NO_DSA
+#  error "OPENSSL_NO_DSA"
+#endif
+#ifdef OPENSSL_NO_SHA
+#  error "OPENSSL_NO_SHA"
+#endif
+
+
+static int
+DSS1RAW_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey) {
+	int ret;
+	unsigned char buf[20+2*(SHA_DIGEST_LENGTH)];
+	unsigned int  len;
+
+	ret = EVP_SignFinal(ctx, buf, &len, pkey);
+	if (ret <= 0) goto done;
+
+	ret = -1;
+{
+	DSA_SIG *sig;
+
+{	/* decode DSA signature */
+	const unsigned char *psig = buf;
+	sig = d2i_DSA_SIG(NULL, &psig, (long)len);
+}
+
+	*siglen = SHARAW_DIGEST_LENGTH;
+	if (sig != NULL) {
+		const BIGNUM *ps, *pr;
+		u_int rlen, slen;
+
+		DSA_SIG_get0(sig, &pr, &ps);
+
+		rlen = BN_num_bytes(pr);
+		slen = BN_num_bytes(ps);
+
+		if (rlen > SHA_DIGEST_LENGTH || slen > SHA_DIGEST_LENGTH) {
+			error("%s: bad sig size %u %u", __func__, rlen, slen);
+			goto done;
+		}
+
+		explicit_bzero(sigret, SHARAW_DIGEST_LENGTH);
+		BN_bn2bin(pr, sigret + SHARAW_DIGEST_LENGTH - SHA_DIGEST_LENGTH - rlen);
+		BN_bn2bin(ps, sigret + SHARAW_DIGEST_LENGTH - slen);
+
+		ret = 1;
+	}
+	DSA_SIG_free(sig);
+}
+done:
+	return(ret);
+}
+
+
+static int
+DSS1RAW_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) {
+	int ret = -1;
+	unsigned char *buf = NULL;
+	int len;
+
+	if (siglen != SHARAW_DIGEST_LENGTH) return(ret);
+
+{	BIGNUM *ps, *pr;
+	DSA_SIG *sig;
+
+	pr = BN_bin2bn(sigbuf                  , SHA_DIGEST_LENGTH, NULL);
+	ps = BN_bin2bn(sigbuf+SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH, NULL);
+	if ((pr == NULL) || (ps == NULL)) goto parse_err;
+
+	sig = DSA_SIG_new();
+	if (sig == NULL) goto parse_err;
+
+	if (DSA_SIG_set0(sig, pr, ps))
+		goto encode;
+
+	DSA_SIG_free(sig);
+parse_err:
+	BN_free(pr);
+	BN_free(ps);
+	return(ret);
+
+
+encode:
+	len = i2d_DSA_SIG(sig, NULL);
+	if (len <= 0) goto done;
+
+	buf = xmalloc(len);  /*fatal on error*/
+
+{	/* encode DSA signature */
+	unsigned char *pbuf = buf;
+	len = i2d_DSA_SIG(sig, &pbuf);
+}
+
+	DSA_SIG_free(sig);
+
+	if (len <= 0) goto done;
+}
+
+	ret = EVP_VerifyFinal(ctx, buf, len, pkey);
+
+done:
+	if (buf != NULL) {
+		explicit_bzero(buf, len);
+		free(buf);
+	}
+	return(ret);
+}
+
+
+#ifdef OPENSSL_HAS_ECC
+static int
+SSH_ECDSA_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey) {
+	ECDSA_SIG *sig;
+	unsigned int len;
+
+{	int ret;
+	unsigned char buf[20+2*(SHA512_DIGEST_LENGTH)];
+
+	ret = EVP_SignFinal(ctx, buf, &len, pkey);
+	if (ret <= 0) return(ret);
+
+{	/* decode ECDSA signature */
+	const unsigned char *psig = buf;
+	sig = d2i_ECDSA_SIG(NULL, &psig, (long)len);
+}
+
+	if (sig == NULL) return(-1);
+}
+
+/* encode ECDSA r&s into SecSH signature blob */
+{	int r;
+	struct sshbuf *buf = NULL;
+	const BIGNUM *pr, *ps;
+
+	buf = sshbuf_new();
+	if (buf == NULL) goto encode_err;
+
+	ECDSA_SIG_get0(sig, &pr, &ps);
+
+	r = sshbuf_put_bignum2(buf, pr);
+	if (r != 0) goto encode_err;
+
+	r = sshbuf_put_bignum2(buf, ps);
+	if (r != 0) goto encode_err;
+
+	len = sshbuf_len(buf);
+	if ((size_t)len != sshbuf_len(buf)) goto encode_err;
+
+	memcpy(sigret, sshbuf_ptr(buf), len);
+	*siglen = len;
+	return(1);
+
+encode_err:
+	sshbuf_free(buf);
+	ECDSA_SIG_free(sig);
+	return(-1);
+}
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
+#ifdef OPENSSL_HAS_ECC
+static int
+SSH_ECDSA_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigblob, unsigned int siglen, EVP_PKEY *pkey) {
+	ECDSA_SIG *sig;
+
+	if ((SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE & xcompat) != 0)
+		return EVP_VerifyFinal(ctx, sigblob, siglen, pkey);
+
+/* decode ECDSA r&s from SecSH signature blob */
+{	int r;
+	struct sshbuf *buf;
+	const unsigned char *bnbuf;
+	size_t bnlen;
+	BIGNUM *pr = NULL, *ps = NULL;
+
+	buf = sshbuf_from(sigblob, (size_t) siglen);
+	if (buf == NULL) return(-1);
+
+	/* extract mpint r */
+	r = sshbuf_get_bignum2_bytes_direct(buf, &bnbuf, &bnlen);
+	if (r != 0) goto parse_err;
+
+	pr = BN_bin2bn(bnbuf, bnlen, NULL);
+	if (pr == NULL) goto parse_err;
+
+	/* extract mpint s */
+	r = sshbuf_get_bignum2_bytes_direct(buf, &bnbuf, &bnlen);
+	if (r != 0) goto parse_err;
+
+	ps = BN_bin2bn(bnbuf, bnlen, NULL);
+	if (ps == NULL) goto parse_err;
+
+	sig = ECDSA_SIG_new();
+	if (sig == NULL) goto parse_err;
+
+	if (ECDSA_SIG_set0(sig, pr, ps))
+		goto process;
+
+	ECDSA_SIG_free(sig);
+
+parse_err:
+	BN_free(ps);
+	BN_free(pr);
+	sshbuf_free(buf);
+	return(-1);
+}
+
+process:
+{	int len;
+	unsigned char *buf;
+	int ret = -1;
+
+	len = i2d_ECDSA_SIG(sig, NULL);
+	if (len <= 0) {
+		ECDSA_SIG_free(sig);
+		return(-1);
+	}
+
+	buf = xmalloc(len);  /*fatal on error*/
+
+{	/* encode ECDSA signature */
+	unsigned char *pbuf = buf;
+	len = i2d_ECDSA_SIG(sig, &pbuf);
+}
+
+	if (len > 0)
+		ret = EVP_VerifyFinal(ctx, buf, len, pkey);
+
+	if (buf != NULL) {
+		explicit_bzero(buf, len);
+		free(buf);
+	}
+
+	ECDSA_SIG_free(sig);
+
+	return(ret);
+}
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
+void
+ssh_xkalg_dgst_compat(ssh_x509_md *dest, const ssh_x509_md *src, ssh_compat *compat) {
+	dest->name = src->name;
+	dest->evp = src->evp;
+
+#ifdef OPENSSL_HAS_ECC
+	if (check_compat_x509(compat, SSHX_RFC6187_ASN1_OPAQUE_ECDSA_SIGNATURE)) {
+		if (src->SignFinal == SSH_ECDSA_SignFinal) {
+			dest->SignFinal = EVP_SignFinal;
+			dest->VerifyFinal = EVP_VerifyFinal;
+			return;
+		}
+	}
+#else
+	(void)compat;
+#endif /*ndef OPENSSL_HAS_ECC*/
+
+	dest->SignFinal = src->SignFinal;
+	dest->VerifyFinal = src->VerifyFinal;
+}
+
+
+/* SSH X509 public key algorithms*/
+static int x509keyalgs_initialized = 0;
+static SSHX509KeyAlgs x509keyalgs[20];
+
+
+static void
+initialize_xkalg(void) {
+	SSHX509KeyAlgs *p = x509keyalgs;
+	int k;
+
+	if (x509keyalgs_initialized) return;
+
+#ifdef TRACE_XKALG
+logit("TRACE_XKALG initialize_xkalg:");
+#endif
+	k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+	for (; k > 0; k--, p++) {
+		p->type = KEY_UNSPEC;
+		p->name = NULL;
+		p->dgst.name = NULL;
+		p->dgst.evp = NULL;
+		p->dgst.SignFinal = EVP_SignFinal;
+		p->dgst.VerifyFinal = EVP_VerifyFinal;
+		p->signame = NULL;
+		p->basetype = KEY_UNSPEC;
+		p->subtype = -1;
+		p->chain = 0;
+	}
+	x509keyalgs_initialized = 1;
+}
+
+
+static void
+add_default_xkalg(void) {
+#ifdef TRACE_XKALG
+logit("TRACE_XKALG add_default_xkalg:");
+#endif
+
+	/* EC public key algorithm: */
+	/* - RFC6187: ssh opaque signature */
+# ifdef OPENSSL_HAS_NISTP256
+	if (ssh_add_x509key_alg("x509v3-ecdsa-sha2-nistp256,ssh-sha256,ecdsa-sha2-nistp256") < 0)
+		fatal("ssh_init_xkalg: oops");
+# endif
+# ifdef OPENSSL_HAS_NISTP384
+	if (ssh_add_x509key_alg("x509v3-ecdsa-sha2-nistp384,ssh-sha384,ecdsa-sha2-nistp384") < 0)
+		fatal("ssh_init_xkalg: oops");
+# endif
+# ifdef OPENSSL_HAS_NISTP521
+	if (ssh_add_x509key_alg("x509v3-ecdsa-sha2-nistp521,ssh-sha512,ecdsa-sha2-nistp521") < 0)
+		fatal("ssh_init_xkalg: oops");
+# endif
+
+	/* RSA public key algorithm: */
+	/* - draft-ietf-secsh-transport-NN.txt where NN <= 12
+	 * does not define explicitly signature format.
+	 * - starting from version 7.1 first is rsa-sha1
+	 */
+	if (ssh_add_x509key_alg("x509v3-sign-rsa,rsa-sha1") < 0)
+		fatal("ssh_init_xkalg: oops");
+#ifdef OPENSSL_FIPS
+	if(!FIPS_mode())
+#endif
+	if (ssh_add_x509key_alg("x509v3-sign-rsa,rsa-md5") < 0)
+		fatal("ssh_init_xkalg: oops");
+	/* - RFC6187 */
+	if (ssh_add_x509key_alg("x509v3-ssh-rsa,rsa-sha1,ssh-rsa") < 0)
+		fatal("ssh_init_xkalg: oops");
+
+	/* DSA public key algorithm: */
+	/* - default is compatible with draft-ietf-secsh-transport-NN.txt
+	 * where NN <= 12
+	 */
+	if (ssh_add_x509key_alg("x509v3-sign-dss,dss-asn1") < 0)
+		fatal("ssh_init_xkalg: oops");
+	/* - some non OpenSSH implementations incompatible with
+	 * draft-ietf-secsh-transport-NN.txt where NN <= 12
+	 */
+	if (ssh_add_x509key_alg("x509v3-sign-dss,dss-raw") < 0)
+		fatal("ssh_init_xkalg: oops");
+	/* - RFC6187 */
+	if (ssh_add_x509key_alg("x509v3-ssh-dss,dss-raw,ssh-dss") < 0)
+		fatal("ssh_init_xkalg: oops");
+}
+
+
+void
+fill_default_xkalg(void) {
+	SSHX509KeyAlgs *p = x509keyalgs;
+
+#ifdef TRACE_XKALG
+logit("TRACE_XKALG fill_default_xkalg:");
+#endif
+	initialize_xkalg();
+	if (p[0].name == NULL) add_default_xkalg();
+}
+
+
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+
+/* work-arounds for limited EVP digests in OpenSSL 0.9.8+ ...
+ * (missing ecdsa support)
+ */
+
+#if defined(OPENSSL_HAS_NISTP256) || defined(OPENSSL_HAS_NISTP384) || defined(OPENSSL_HAS_NISTP521)
+static inline void
+ssh_EVP_MD_ecdsa_init(EVP_MD *t, const EVP_MD *s) {
+    memcpy(t, s, sizeof(*t));
+    t->sign = (evp_sign_method*)ECDSA_sign;
+    t->verify = (evp_verify_method*)ECDSA_verify;
+    t->required_pkey_type[0] = EVP_PKEY_EC;
+    t->required_pkey_type[1] = 0;
+}
+#endif
+
+
+#ifdef OPENSSL_HAS_NISTP256
+/* Test for NID_X9_62_prime256v1(nistp256) includes test for EVP_sha256 */
+EVP_MD ecdsa_sha256_md = { NID_undef };
+
+static const EVP_MD*
+ssh_ecdsa_EVP_sha256(void) {
+    if (ecdsa_sha256_md.type == NID_undef)
+	ssh_EVP_MD_ecdsa_init(&ecdsa_sha256_md, EVP_sha256());
+    return &ecdsa_sha256_md;
+}
+#endif
+
+#ifdef OPENSSL_HAS_NISTP384
+/* Test for NID_secp384r1(nistp384) includes test for EVP_sha384 */
+EVP_MD ecdsa_sha384_md = { NID_undef };
+
+static const EVP_MD*
+ssh_ecdsa_EVP_sha384(void) {
+    if (ecdsa_sha384_md.type == NID_undef)
+	ssh_EVP_MD_ecdsa_init(&ecdsa_sha384_md, EVP_sha384());
+    return &ecdsa_sha384_md;
+}
+#endif
+
+#ifdef OPENSSL_HAS_NISTP521
+/* Test for NID_secp521r1(nistp521) includes test for EVP_sha512 */
+EVP_MD ecdsa_sha512_md = { NID_undef };
+
+static const EVP_MD*
+ssh_ecdsa_EVP_sha512(void) {
+    if (ecdsa_sha512_md.type == NID_undef)
+	ssh_EVP_MD_ecdsa_init(&ecdsa_sha512_md, EVP_sha512());
+    return &ecdsa_sha512_md;
+}
+#endif
+
+#else
+
+#ifdef OPENSSL_HAS_NISTP256
+static inline const EVP_MD* ssh_ecdsa_EVP_sha256(void) { return EVP_sha256(); }
+#endif
+#ifdef OPENSSL_HAS_NISTP384
+static inline const EVP_MD* ssh_ecdsa_EVP_sha384(void) { return EVP_sha384(); }
+#endif
+#ifdef OPENSSL_HAS_NISTP521
+static inline const EVP_MD* ssh_ecdsa_EVP_sha512(void) { return EVP_sha512(); }
+#endif
+
+#endif /*OPENSSL_VERSION_NUMBER < 0x10000000L*/
+
+
+#ifdef OPENSSL_HAS_ECC
+static inline void
+wrap_digest_ecdsa(SSHX509KeyAlgs* p) {
+	p->dgst.SignFinal = SSH_ECDSA_SignFinal;
+	p->dgst.VerifyFinal = SSH_ECDSA_VerifyFinal;
+}
+#endif /*def OPENSSL_HAS_ECC*/
+
+
+static int
+ssh_x509key_alg_digest(SSHX509KeyAlgs* p, const char *dgstname) {
+	const EVP_MD* md = NULL;
+
+	if (dgstname == NULL) {
+		fatal("ssh_get_md: dgstname is NULL");
+		return(-1); /*unreachable code*/
+	}
+
+	if (strcasecmp("rsa-sha1", dgstname) == 0) { md = EVP_sha1(); goto done; }
+	if (strcasecmp("rsa-md5" , dgstname) == 0) { md = EVP_md5(); goto done; }
+
+#ifdef OPENSSL_HAS_NISTP256
+	if (strcasecmp("ssh-sha256"  , dgstname) == 0) {
+		md = ssh_ecdsa_EVP_sha256();
+		wrap_digest_ecdsa(p);
+		goto done;
+	}
+	if (strcasecmp("sha256"  , dgstname) == 0) { md = ssh_ecdsa_EVP_sha256(); goto done; }
+#endif
+#ifdef OPENSSL_HAS_NISTP384
+	if (strcasecmp("ssh-sha384"  , dgstname) == 0) {
+		md = ssh_ecdsa_EVP_sha384();
+		wrap_digest_ecdsa(p);
+		goto done;
+	}
+	if (strcasecmp("sha384"  , dgstname) == 0) { md = ssh_ecdsa_EVP_sha384(); goto done; }
+#endif
+#ifdef OPENSSL_HAS_NISTP521
+	if (strcasecmp("ssh-sha512"  , dgstname) == 0) {
+		md = ssh_ecdsa_EVP_sha512();
+		wrap_digest_ecdsa(p);
+		goto done;
+	}
+	if (strcasecmp("sha512"  , dgstname) == 0) { md = ssh_ecdsa_EVP_sha512(); goto done; }
+#endif
+
+	if (strcasecmp("dss-asn1", dgstname) == 0) { md = EVP_dss1(); goto done; }
+	if (strcasecmp("dss-raw" , dgstname) == 0) {
+		md = EVP_dss1();
+		p->dgst.SignFinal = DSS1RAW_SignFinal;
+		p->dgst.VerifyFinal = DSS1RAW_VerifyFinal;
+		goto done;
+	}
+
+	return(-1);
+
+done:
+	p->dgst.name = dgstname;
+	p->dgst.evp = md;
+
+	return(0);
+}
+
+
+int
+ssh_add_x509key_alg(const char *data) {
+	char *name, *mdname, *signame;
+	SSHX509KeyAlgs* p;
+	int nid = -1;
+
+	if (data == NULL) {
+		error("ssh_add_x509pubkey_alg: data is NULL");
+		return(-1);
+	}
+
+	name = xstrdup(data); /*fatal on error*/
+
+	mdname = strchr(name, ',');
+	if (mdname == NULL) {
+		error("ssh_add_x509pubkey_alg: cannot parse digest");
+		goto err;
+	}
+	*mdname++ = '\0';
+
+	signame = strchr(mdname, ',');
+	if (signame != NULL) *signame++ = '\0';
+
+	initialize_xkalg();
+	p = x509keyalgs;
+	{
+		int k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+
+		for (; k > 0; k--, p++) {
+			if (p->name == NULL) break;
+		}
+		if (k <= 0) {
+			error("ssh_add_x509pubkey_alg: insufficient slots");
+			goto err;
+		}
+	}
+
+	if (strncmp(name, "x509v3-ecdsa-sha2-", 18) == 0) {
+		const char *ec_name = name + 18;
+
+		nid = key_curve_name_to_nid(ec_name);
+		if (nid < 0) {
+			fatal("ssh_add_x509pubkey_alg: unsupported curve %s", ec_name);
+		}
+
+		p->type = KEY_X509_ECDSA;
+		p->basetype = KEY_ECDSA;
+		p->chain = 1;
+	} else
+	if (strncmp(name, "x509v3-ssh-rsa", 14) == 0) {
+		p->type = KEY_X509_RSA;
+		p->basetype = KEY_RSA;
+		p->chain = 1;
+	} else
+	if (strncmp(name, "x509v3-sign-rsa", 15) == 0) {
+		p->type = KEY_X509_RSA;
+		p->basetype = KEY_RSA;
+		p->chain = 0;
+	} else
+	if (strncmp(name, "x509v3-ssh-dss", 14) == 0) {
+		p->type = KEY_X509_DSA;
+		p->basetype = KEY_DSA;
+		p->chain = 1;
+	} else
+	if (strncmp(name, "x509v3-sign-dss", 15) == 0) {
+		p->type = KEY_X509_DSA;
+		p->basetype = KEY_DSA;
+		p->chain = 0;
+	} else
+	{
+		error("ssh_add_x509pubkey_alg: "
+			"unsupported public key algorithm '%s'", name);
+		goto err;
+	}
+
+	if (ssh_x509key_alg_digest(p, mdname) < 0) {
+		error("ssh_add_x509pubkey_alg: unsupported digest %.50s", mdname);
+		goto err;
+	}
+
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode()) {
+		if ((EVP_MD_flags(p->dgst.evp) & EVP_MD_FLAG_FIPS) == 0) {
+			error("ssh_add_x509pubkey_alg: "
+				"%s in not enabled in FIPS mode ", mdname);
+			goto err;
+		}
+	}
+#endif
+	p->name = name;
+	p->signame = signame;
+	p->subtype = nid;
+
+	return (1);
+
+err:
+	free((void*)name);
+	return (-1);
+}
+
+
+int/*bool*/
+ssh_is_x509signame(const char *signame) {
+	SSHX509KeyAlgs *xkalg;
+	int k;
+
+	if (signame == NULL) {
+		fatal("ssh_is_x509signame: signame is NULL");
+		return(0); /*unreachable code*/
+	}
+
+	initialize_xkalg();
+	xkalg = x509keyalgs;
+	k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+
+	for (; k > 0; k--, xkalg++) {
+		if (xkalg->name == NULL) return(0);
+		if (strcmp(signame, X509PUBALG_SIGNAME(xkalg)) == 0) return(1);
+	}
+	return(0);
+}
+
+
+int
+ssh_xkalg_nameind(const char *name, const SSHX509KeyAlgs **q, int loc) {
+	int k, n;
+	const SSHX509KeyAlgs *p;
+
+	if (name == NULL) return (-1);
+
+	initialize_xkalg();
+	k = (loc < 0) ? 0 : (loc + 1);
+	n = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+	if (k < n) p = &x509keyalgs[k];
+
+	for (; k < n; k++, p++) {
+		if (p->name == NULL) return(-1);
+		if (strcmp(p->name, name) == 0) {
+			if (q) *q = p;
+			return(k);
+		}
+	}
+	return(-1);
+}
+
+
+int
+ssh_xkalg_typeind(int type, int subtype, const SSHX509KeyAlgs **q, int loc) {
+	int k, n;
+	const SSHX509KeyAlgs *p;
+
+	initialize_xkalg();
+	k = (loc < 0) ? 0 : (loc + 1);
+	n = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+	if (k < n) p = &x509keyalgs[k];
+
+	type = key_type_plain(type);
+	for (; k < n; k++, p++) {
+		if (p->name == NULL) break;
+		if (type != p->basetype) continue;
+
+		if ((subtype > 0) && (subtype != p->subtype))
+			continue;
+
+		if (q) *q = p;
+		return(k);
+	}
+	return(-1);
+}
+
+
+int
+ssh_xkalg_ind(const SSHX509KeyAlgs **q, int loc) {
+	int k, n;
+
+	initialize_xkalg();
+	k = (loc < 0) ? 0 : (loc + 1);
+	n = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]);
+
+	if (k < n) {
+		const SSHX509KeyAlgs *p;
+
+		p = &x509keyalgs[k];
+		if (p->name != NULL) {
+			if (q) *q = p;
+			return(k);
+		}
+	}
+	return(-1);
+}
+
+
+static void
+ssh_xkalg_list(int type, Buffer *b, const char *sep) {
+	const SSHX509KeyAlgs *xkalg;
+	int loc;
+	int seplen;
+
+	if (b == NULL) {
+		error("ssh_xkalg_list: buffer is NULL");
+		return;
+	}
+
+/*
+IMPORTANT NOTE:
+  For every unique "key name" we MUST define unique "key type"
+otherwise cannot distinguish them !
+As example structure Kex contain integer attribute "kex_type"
+and kex use method "load_host_key" to find hostkey. When client
+request hostkey algorithms (comma separated list with names)
+server should be able to find first hostkey that match one of them.
+Note to "load_host_key" is assigned method "get_hostkey_by_type"
+defined in "sshd.c".
+*/
+
+	if (sep == NULL) sep = ",";
+	seplen = strlen(sep);
+
+	for (
+	    loc = ssh_xkalg_typeind(type, -1, &xkalg, -1);
+	    loc >= 0;
+	    loc = ssh_xkalg_typeind(type, -1, &xkalg, loc)
+	) {
+		const char *p;
+		int dupl, k;
+
+		/* exclude duplicate names */
+		p = xkalg->name;
+		dupl = 0;
+		for (
+		    k = ssh_xkalg_typeind(type, -1, &xkalg, -1);
+		    (k >= 0) && (k < loc);
+		    k = ssh_xkalg_typeind(type, -1, &xkalg, k)
+		) {
+			if (strcmp(p, xkalg->name) == 0) {
+				dupl = 1;
+				break;
+			}
+		}
+		if (dupl) continue;
+
+		if (buffer_len(b) > 0) buffer_append(b, sep, seplen);
+		buffer_append(b, p, strlen(p));
+	}
+}
+
+
+void
+ssh_xkalg_listall(Buffer *b, const char *sep) {
+	ssh_xkalg_list(KEY_ECDSA, b, sep);
+	ssh_xkalg_list(KEY_RSA, b, sep);
+	ssh_xkalg_list(KEY_DSA, b, sep);
+}
+
+
+char*
+default_publickey_algorithms(void) {
+	Buffer b;
+	char *p;
+
+	/* NOTE: fatal on error in buffer allocation or xstrdup */
+	buffer_init(&b);
+
+	ssh_xkalg_listall(&b, ",");
+
+	p = KEX_DEFAULT_PK_ALG;
+	if (buffer_len(&b) > 0) buffer_append(&b, ",", 1);
+	buffer_append(&b, p, strlen(p));
+
+	/* With OpenSSH 7.0 ssh-dss is not listed in KEX_DEFAULT_PK_ALG */
+	p = "ssh-dss";
+	buffer_append(&b, ",", 1);
+	buffer_append(&b, p, strlen(p));
+
+	buffer_append(&b, "\0", 1);
+
+	p = xstrdup(buffer_ptr(&b));
+
+	buffer_free(&b);
+
+	return p;
+}
+
+
+char*
+ssh_get_allnames(char sep, int sigflag, const char* pattern) {
+	const char **list = NULL;;
+	int loc;
+	size_t k, n = 0, len = 0;
+
+	if (pattern == NULL) pattern= "*";
+
+{	const SSHX509KeyAlgs *xkalg;
+	for (
+	    loc = ssh_xkalg_ind(&xkalg, -1);
+	    loc >= 0;
+	    loc = ssh_xkalg_ind(&xkalg, loc)
+	) {
+		const char *p;
+
+		if (match_pattern_list(xkalg->name, pattern, 0) != 1)
+			continue;
+
+		p = sigflag ? X509PUBALG_SIGNAME(xkalg) : xkalg->name;
+		for (k = 0; k < n; k++) {
+			if (strcmp(p, list[k]) == 0) {
+				p = NULL;
+				break;
+			}
+		}
+		if (p == NULL) continue;
+
+		k = n++;
+		list = realloc(list, n * sizeof(char*));
+		if (list == NULL)
+			fatal("ssh_get_all_pkalg: realloc fail for xkalg");
+		list[k] = p;
+		len += 1 + strlen(p);
+	}
+}
+{	const char *name;
+	for (
+	    loc = sshkey_ind_alg(&name, -1);
+	    loc >= 0;
+	    loc = sshkey_ind_alg(&name, loc)
+	) {
+		const char *p;
+
+		if (match_pattern_list(name, pattern, 0) != 1)
+			continue;
+
+		p = name;
+		for (k = 0; k < n; k++) {
+			if (strcmp(p, list[k]) == 0) {
+				p = NULL;
+				break;
+			}
+		}
+		if (p == NULL) continue;
+
+		k = n++;
+		list = realloc(list, n * sizeof(char*));
+		if (list == NULL)
+			fatal("ssh_get_all_pkalg: realloc fail for alg");
+		list[k] = p;
+		len += 1 + strlen(p);
+	}
+}
+{	char *s = NULL, *p;
+
+	if (n > 0) {
+		s = p = malloc(len);
+		if (s == NULL)
+			fatal("ssh_get_all_pkalg: out of memory");
+	}
+	for (k = 0; k < n; k++) {
+		size_t l = strlen(list[k]);
+		memmove(p, list[k], l);
+		p += l;
+		*p++ = sep;
+	}
+	if (n > 0)
+		*(--p) = '\0';
+
+	free(list);
+	return s;
+}
+}
diff -ruN openssh-7.5p1/ssh-xkalg.h openssh-7.5p1+x509-10.2/ssh-xkalg.h
--- openssh-7.5p1/ssh-xkalg.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/ssh-xkalg.h	2017-03-23 20:27:54.000000000 +0200
@@ -0,0 +1,75 @@
+#ifndef SSH_XKALG_H
+#define SSH_XKALG_H
+/*
+ * Copyright (c) 2005-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "includes.h"
+#include <openssl/evp.h>
+#include "buffer.h"
+
+
+typedef int	(*fEVP_SignFinal)(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey);
+typedef int	(*fEVP_VerifyFinal)(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey);
+
+struct ssh_x509_md_st {
+	const char       *name;
+	const EVP_MD     *evp;
+	fEVP_SignFinal    SignFinal;
+	fEVP_VerifyFinal  VerifyFinal;
+};
+typedef struct ssh_x509_md_st ssh_x509_md;
+
+void	ssh_xkalg_dgst_compat(ssh_x509_md *dest, const ssh_x509_md *src, ssh_compat *compat);
+
+typedef struct {
+	int           type;
+	const char   *name;
+	ssh_x509_md   dgst;
+	const char   *signame;
+	int           basetype;
+	int           chain;
+	int           subtype; /* curve nid for EC keys */
+}	SSHX509KeyAlgs;
+#define X509PUBALG_SIGNAME(p)	(p->signame ? p->signame : p->name)
+
+
+void	fill_default_xkalg(void);
+	/* format "name,dgst_name[,sig_name]" */
+int	ssh_add_x509key_alg(const char *data);
+
+
+int/*bool*/	ssh_is_x509signame(const char *signame);
+
+int	ssh_xkalg_nameind(const char *name, const SSHX509KeyAlgs **q, int loc);
+int	ssh_xkalg_typeind(int type, int subtype, const SSHX509KeyAlgs **q, int loc);
+int	ssh_xkalg_ind(const SSHX509KeyAlgs **q, int loc);
+
+void	ssh_xkalg_listall(Buffer *b, const char *sep);
+
+char*	default_publickey_algorithms(void);
+
+char*	ssh_get_allnames(char sep, int sigflag, const char* pattern);
+
+#endif /* SSH_XKALG_H */
diff -ruN openssh-7.5p1/tests/CA/1-cre_cadb.sh openssh-7.5p1+x509-10.2/tests/CA/1-cre_cadb.sh
--- openssh-7.5p1/tests/CA/1-cre_cadb.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/1-cre_cadb.sh	2016-08-02 09:04:34.000000000 +0300
@@ -0,0 +1,443 @@
+#! /bin/sh
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create a new certificate authority config and database.
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/1-cre_cadb.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+if test yes = "$SSH_DN_FORCE_UTF8"; then
+  string_mask=utf8only
+else
+  string_mask=default
+fi
+
+# ===
+# args:
+#   $1 - type
+echo_CA_common_options () {
+cat <<EOF
+certs           = \$dir/crt             # Where the issued certs are kept
+crl_dir         = \$dir/crl             # Where the issued crl are kept
+database        = \$dir/index-$1.txt       # database index file.
+new_certs_dir   = \$dir/newcerts        # default place for new certs.
+serial          = \$dir/serial          # The current serial number
+
+#x509_extensions = usr_cert            # The default extentions to add to the cert
+default_days    = $SSH_CACERTDAYS                   # how long to certify for
+default_crl_days= $SSH_CACRLDAYS                   # how long before next CRL
+policy          = policy_match
+
+# print options (internal use)
+#name_opt        = oneline,-space_eq,-esc_msb # print UTF-8
+#name_opt        = utf8,sep_comma_plus
+cert_opt        = compatible
+
+EOF
+}
+
+
+# ===
+# args:
+#   none
+echo_CA_ocsp_options () {
+if test "x$SSH_OCSP" = "xyes"; then
+cat << EOF
+
+# OCSP Validator(Responder) URI
+# Since OpenSSL OCSP responder support only one issuer certificate
+# we should setup for the test cases many responders - each certificate
+# type with responder on different port.
+EOF
+  printf "authorityInfoAccess = "
+(
+  port=${SSH_VA_BASEPORT}
+  for DIGEST in ${RSA_DIGEST_LIST}; do
+    printf "OCSP;URI:http://${SSHD_LISTENADDRESS}:${port},"
+    port=`expr ${port} + 1`
+  done
+    printf "OCSP;URI:http://${SSHD_LISTENADDRESS}:${port}"
+)
+  printf "\n"
+fi
+}
+
+
+# ===
+cre_config () {
+cat << EOF > "$1"
+# Where everything is kept:
+dir = $SSH_CAROOT
+
+[ ca ]
+#md5 is not allowed in FIPSmode
+#default_ca              = ca_test_rsa_md5
+default_ca              = ca_test_rsa_sha1
+
+
+# For the CA policy
+[ policy_match ]
+countryName             = match
+stateOrProvinceName     = match
+organizationName        = match
+organizationalUnitName  = optional
+commonName              = supplied
+emailAddress            = optional
+
+[ ca_policy_match ]
+countryName             = match
+stateOrProvinceName     = match
+localityName            = match
+organizationName        = match
+organizationalUnitName  = optional
+commonName              = supplied
+emailAddress            = optional
+
+
+[ req ]
+default_bits            = 1024
+distinguished_name      = req_distinguished_name
+attributes              = req_attributes
+#prompt                  = no
+#string_mask             = MASK: <unsigned long> | nombstr | pkix | utf8only | default(=0xFFFFFFFFL)
+string_mask             = $string_mask
+#utf8                    = yes
+
+# The extensions to add to a certificate request:
+#???req_extensions          = usr_cert
+
+
+[ req_distinguished_name ]
+countryName                     = Country Name (2 letter code)
+countryName_default             = $SSH_DN_C
+countryName_min                 = 2
+countryName_max                 = 2
+
+stateOrProvinceName             = State or Province Name (full name)
+stateOrProvinceName_default     = $SSH_DN_ST
+
+localityName                    = Locality Name (eg, city)
+localityName_default            = $SSH_DN_L
+
+0.organizationName              = Organization Name (eg, company)
+0.organizationName_default      = $SSH_DN_O
+
+0.organizationalUnitName          = Organizational Unit1 Name (eg, section1 - optional)
+0.organizationalUnitName_default  = ${SSH_DN_OU}-1
+
+1.organizationalUnitName          = Organizational Unit2 Name (eg, section2 - optional)
+1.organizationalUnitName_default  = ${SSH_DN_OU}-2
+
+2.organizationalUnitName          = Organizational Unit3 Name (eg, section3 - optional)
+2.organizationalUnitName_default  = ${SSH_DN_OU}-3
+
+commonName                      = Common Name (eg, YOUR name)
+commonName_min                  = 2
+commonName_max                  = 64
+
+emailAddress                    = Email Address (optional)
+emailAddress_max                = 40
+emailAddress_default            = $SSH_DN_EM
+
+
+[ req_attributes ]
+challengePassword               = A challenge password
+challengePassword_min           = 4
+challengePassword_max           = 20
+
+
+[ ca_root_cert ]
+# PKIX recommendation.
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+
+# As we generate test CA we could comment next line.
+basicConstraints=CA:true
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test CA Root Certificate"
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# Since we verify CRL signatures cRLSign must present
+keyUsage = keyCertSign, cRLSign
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid:always,issuer:always
+
+
+[ ca_cert ]
+# PKIX recommendation.
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+
+# As we generate test CA we could comment next line.
+basicConstraints=CA:true
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test CA Certificate"
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# Since we verify CRL signatures cRLSign must present
+keyUsage = keyCertSign, cRLSign
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid:always,issuer:always
+
+# To test CRL presence this extension should exist
+crlDistributionPoints = URI:attribute_only_exist
+EOF
+
+
+# X.509 extensions: SSH client certificates
+cat << EOF >> "$1"
+
+
+[ usr_cert ]
+# These extensions are added when 'ca' signs a request.
+basicConstraints                = CA:false
+nsCertType                      = client, email
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test Client Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid,issuer:always
+EOF
+
+echo_CA_ocsp_options >> "$1"
+
+
+# X.509 extensions: SSH server certificates
+cat << EOF >> "$1"
+
+
+[ srv_cert ]
+# These extensions are added when 'ca' signs a request.
+basicConstraints                = CA:false
+
+# To test hostbased authentication we need
+# following certificate purposes:
+nsCertType                      = server,client
+# Normal for server certificate is:
+#nsCertType                      = server
+# but in last case me must disable check of certificate purposes
+# in sshd_config otherwise hostbased fail.
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test Server Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid,issuer:always
+
+# Some SSH clients require server certificate to contain
+# correct alternate name of type DNS (FQDN)
+subjectAltName = DNS:localhost
+EOF
+
+echo_CA_ocsp_options >> "$1"
+
+
+# X.509 extensions: SSH self-signed certificates
+cat << EOF >> "$1"
+
+
+[ self_cert ]
+# These extensions are added when 'ca' signs a request.
+basicConstraints                = CA:false
+nsCertType                      = client, email
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test Client Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid,issuer:always
+EOF
+
+echo_CA_ocsp_options >> "$1"
+
+
+# X.509 extensions: OCSP Validator certificates
+if test "x$SSH_OCSP" = "xyes"; then
+cat << EOF >> "$1"
+
+
+[ ocsp_cert ]
+# These extensions are added when 'ca' signs a request.
+basicConstraints                = CA:false
+
+# Normal for validator certificate is:
+nsCertType                      = objsign
+
+# This is typical in keyUsage for a validator certificate.
+keyUsage = nonRepudiation, digitalSignature
+
+# This should present for a validator certificate.
+extendedKeyUsage = OCSPSigning
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Test OCSP Responder Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid,issuer:always
+EOF
+fi
+
+
+cat << EOF >> "$1"
+
+
+[ ca_test_root ]
+certs           = \$dir/crt             # Where the issued certs are kept
+crl_dir         = \$dir/crl             # Where the issued crl are kept
+database        = \$dir/index-root.txt  # database index file.
+new_certs_dir   = \$dir/newcerts        # default place for new certs.
+serial          = \$dir/serial          # The current serial number
+
+#x509_extensions = usr_cert            # The default extentions to add to the cert
+default_days    = $SSH_CACERTDAYS                   # how long to certify for
+default_crl_days= $SSH_CACRLDAYS                   # how long before next CRL
+policy          = ca_policy_match
+
+# print options (internal use)
+#name_opt        = oneline,-space_eq,-esc_msb # print UTF-8
+#name_opt        = utf8,sep_comma_plus
+cert_opt        = compatible
+
+
+# which md to use:
+default_md      = sha1
+
+# The private key (!)
+private_key     = "${SSH_CAKEYDIR}/${CAKEY_PREFIX}-root0.key"
+
+#The CA certificate (!)
+certificate     = "${SSH_CACERTDIR}/${CAKEY_PREFIX}-root0.crt.pem"
+EOF
+
+
+for DIGEST in ${RSA_DIGEST_LIST}; do
+( cat << EOF
+
+
+[ ca_test_rsa_$DIGEST ]
+EOF
+  echo_CA_common_options "rsa_${DIGEST}"
+  cat << EOF
+# which md to use:
+default_md      = ${DIGEST}
+
+# The private key (!)
+private_key     = "${SSH_CAKEYDIR}/${CAKEY_PREFIX}-rsa.key"
+
+#The CA certificate  (!)
+certificate     = "${SSH_CACERTDIR}/${CAKEY_PREFIX}-rsa_${DIGEST}.crt.pem"
+EOF
+) >> "$1"
+done
+
+( cat << EOF
+
+
+[ ca_test_dsa ]
+EOF
+  echo_CA_common_options "dsa"
+  cat << EOF
+# which md to use:
+default_md      = sha1
+
+# The private key (!)
+private_key     = "${SSH_CAKEYDIR}/${CAKEY_PREFIX}-dsa.key"
+
+#The CA certificate  (!)
+certificate     = "${SSH_CACERTDIR}/${CAKEY_PREFIX}-dsa.crt.pem"
+EOF
+) >> "$1"
+}
+
+
+# ===
+cre_db () {
+(
+  var="${SSH_CAROOT}"
+
+  if test ! -d "$var"; then
+    mkdir -p "$var" || exit $?
+  else
+    count=`getNextDirName "${var}"` || exit $?
+    if test -d "${var}"; then
+      printf '%s' "saving old directoty as ${attn}${var}.${warn}${count}${norm} ... "
+      mv "${var}" "${var}.${count}"; show_status $? || exit $?
+    fi
+  fi
+
+  mkdir -p "$var" &&
+  mkdir "$var/crt" &&
+  mkdir "$var/crl" ||
+  exit $?
+
+  create_empty_file "$var/index-root.txt" || exit $?
+
+  for type in ${SSH_SIGN_TYPES}; do
+    create_empty_file "$var/index-${type}.txt" || exit $?
+  done
+
+  mkdir "$var/newcerts" &&
+  echo '200402160906000001' > "$var/serial"
+)
+}
+
+
+# ===
+
+cre_config "${TMPDIR}/${CACONFIG}" &&
+cre_db &&
+update_file "${TMPDIR}/${CACONFIG}" "${SSH_CACFGFILE}"; retval=$?
+
+show_status $retval "${extd}Creating${norm} ${warn}TEST${norm} ${attn}Certificate Authority Database${norm}"
diff -ruN openssh-7.5p1/tests/CA/2-cre_cakeys.sh openssh-7.5p1+x509-10.2/tests/CA/2-cre_cakeys.sh
--- openssh-7.5p1/tests/CA/2-cre_cakeys.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/2-cre_cakeys.sh	2016-01-14 23:47:28.159117647 +0200
@@ -0,0 +1,409 @@
+#! /bin/sh
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create "Test Certificate Authority" private keys and certificates.
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/2-cre_cakeys.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+
+CA_LOG="$CWD/ca-2.log"
+create_empty_file .delmy &&
+update_file .delmy "$CA_LOG" > /dev/null || exit $?
+
+
+# ===
+echo_SSH_CA_DN () {
+cat <<EOF
+$SSH_DN_C
+$SSH_DN_ST
+$SSH_DN_L
+$SSH_DN_O
+$SSH_DN_OU
+$SSH_DN_OU $1 keys
+.
+SSH TestCA $1 key
+.
+.
+EOF
+}
+
+
+# ===
+echo_SSH_CAROOT_DN () {
+cat <<EOF
+$SSH_DN_C
+$SSH_DN_ST
+$SSH_DN_L
+$SSH_DN_O
+$SSH_DN_OU
+$SSH_DN_OU level $1
+.
+SSH TestCA level $1
+.
+EOF
+}
+
+
+# ===
+#args:
+#  $1 - X.509 file in pem format
+format_trusted_x509() {
+(
+  X509CMD="$OPENSSL x509 -inform PEM $OPENSSL_NAMEOPT"
+
+  $X509CMD -in "$1" -fingerprint -noout || exit $?
+  echo PEM data:
+  $X509CMD -in "$1" -trustout           || exit $?
+  echo Certificate Ingredients:
+  $X509CMD -in "$1" -text -noout        || exit $?
+
+  exit 0
+)
+}
+
+
+# ===
+#args:
+#  $1 - existing X.509 file in pem format
+#  $2 - name of X.509 file to store in pretty pem format
+move_as_trusted_x509() {
+  printf '%s' "creating file ${attn}$2${norm}"
+  format_trusted_x509 "$1" > "$2"
+  show_status $? || return $?
+
+  rm -f "$1"
+  return 0
+}
+
+
+# ===
+#args:
+#  $1 - rsa keyfile
+gen_rsa_key () {
+( umask 077
+  RSA_OPT=
+  if test -n "$random_seed_files" ; then
+    RSA_OPT="$RSA_OPT -rand $random_seed_files"
+  fi
+
+  rm -f "$1" 2>/dev/null
+
+  if $openssl_nopkcs8_keys; then
+    rm -f "$1"-trad 2>/dev/null
+    $OPENSSL genrsa $RSA_OPT \
+      -out "$1"-trad 1024 \
+      2>> "$CA_LOG" &&
+    $OPENSSL pkcs8 -topk8 \
+      -in "$1"-trad \
+      -out "$1" -passout pass:$KEY_PASS \
+      -v1 PBE-SHA1-3DES \
+      2>> "$CA_LOG" &&
+    rm "$1"-trad
+  else
+    RSA_OPT="$RSA_OPT -des3"
+    $OPENSSL genrsa $RSA_OPT \
+      -passout pass:$KEY_PASS \
+      -out "$1" 1024 \
+      2>> "$CA_LOG"
+  fi
+)
+}
+
+
+# ===
+cre_root () {
+  gen_rsa_key "$TMPDIR/$CAKEY_PREFIX"-root0.key \
+  ; show_status $? "generating ${extd}TEST ROOT CA${norm} ${attn}rsa${norm} private key" \
+  || return $?
+
+  echo_SSH_CAROOT_DN "0" | \
+  $OPENSSL req \
+    -new -x509 \
+    -config "$SSH_CACFGFILE" \
+    $SSH_DN_UTF8_FLAG \
+    -days $SSH_CACERTDAYS \
+    -passin pass:${KEY_PASS} \
+    -key "$TMPDIR/${CAKEY_PREFIX}-root0.key" \
+    -sha1 \
+    -out "$TMPDIR/${CAKEY_PREFIX}-root0.crt" \
+    -extensions ca_root_cert \
+    2>> "$CA_LOG" \
+  ; show_status $? "generating ${extd}TEST CA${norm} ${attn}root${norm} certificate" \
+  || return $?
+
+  F="$CAKEY_PREFIX"-root0.key
+  update_file "$TMPDIR/$F" "$SSH_CAKEYDIR/$F"
+
+  F="$CAKEY_PREFIX"-root0.crt
+  move_as_trusted_x509 "$TMPDIR/$F" "$SSH_CACERTDIR/$F".pem
+}
+
+
+# ===
+gen_rsa () {
+  gen_rsa_key "$TMPDIR/$CAKEY_PREFIX"-rsa.key \
+  ; show_status $? "generating ${extd}TEST CA${norm} ${attn}rsa${norm} private key"
+}
+
+
+# ===
+#args:
+#  $1 - dsa keyfile
+#  $2 - dsa parameter file
+gen_dsa_key () {
+( umask 077
+  DSA_OPT=
+  if test -n "$random_seed_files"; then
+    DSA_OPT="$DSA_OPT -rand $random_seed_files"
+  fi
+
+  rm -f "$1" 2>/dev/null
+
+  if $openssl_nopkcs8_keys; then
+    rm -f "$1"-trad 2>/dev/null &&
+    $OPENSSL gendsa $DSA_OPT \
+      -out "$1"-trad \
+      "$2" \
+      2>> "$CA_LOG" &&
+    $OPENSSL pkcs8 -topk8 \
+      -in "$1"-trad \
+      -out "$1" -passout pass:$KEY_PASS \
+      -v1 PBE-SHA1-3DES \
+      2>> "$CA_LOG" &&
+    rm "$1"-trad
+  else
+    DSA_OPT="$DSA_OPT -des3"
+    $OPENSSL gendsa $DSA_OPT \
+      -passout pass:$KEY_PASS \
+      -out "$1" \
+      "$2" \
+      2>> "$CA_LOG"
+  fi
+)
+}
+
+
+# ===
+gen_dsa () {
+  DSA_OPT=
+  if test -n "$random_seed_files" ; then
+    DSA_OPT="$DSA_OPT -rand $random_seed_files"
+  fi
+
+( umask 077
+  rm -f "$TMPDIR/$CAKEY_PREFIX-dsa.prm" 2>/dev/null
+  $OPENSSL dsaparam $DSA_OPT \
+    -out "$TMPDIR/$CAKEY_PREFIX"-dsa.prm 1024\
+    2>> "$CA_LOG";\
+  show_status $? "generating ${extd}DSA parameter file${norm}"
+) || return $?
+
+  gen_dsa_key \
+    "$TMPDIR/$CAKEY_PREFIX"-dsa.key \
+    "$TMPDIR/$CAKEY_PREFIX"-dsa.prm \
+  ; show_status $? "generating ${extd}TEST CA${norm} ${attn}dsa${norm} private key"
+}
+
+
+# ===
+cre_crt () {
+for type in $SSH_SIGN_TYPES; do
+  rm -f "$TMPDIR/$CAKEY_PREFIX"-${type}.crt 2>/dev/null
+
+  case $type in
+      *rsa*) keyfile="$TMPDIR/$CAKEY_PREFIX"-rsa.key;;
+      *dsa*) keyfile="$TMPDIR/$CAKEY_PREFIX"-dsa.key;;
+      *) return 99;;
+  esac
+
+  echo_SSH_CA_DN "$type" |
+  $OPENSSL req \
+    -new \
+    -config "$SSH_CACFGFILE" \
+    $SSH_DN_UTF8_FLAG \
+    -key "$keyfile" \
+    -passin pass:$KEY_PASS \
+    -out "$TMPDIR/${CAKEY_PREFIX}-${type}".csr \
+    2>> "$CA_LOG" \
+  ; show_status $? "generating ${extd}TEST CA${norm} ${attn}${type}${norm} request" \
+  || return $?
+
+  $OPENSSL ca \
+    -config "$SSH_CACFGFILE" \
+    -batch \
+    -in "$TMPDIR/${CAKEY_PREFIX}-${type}".csr \
+    -name "ca_test_root" \
+    -passin pass:$KEY_PASS \
+    -out "$TMPDIR/${CAKEY_PREFIX}-${type}".crt \
+    -extensions ca_cert \
+    2>> "$CA_LOG" \
+  ; show_status $? "generating ${extd}TEST CA${norm} ${attn}${type}${norm} certificate" || \
+  { retval=$?
+    printf '%s' "${warn}"
+    grep 'ERROR:' "$CA_LOG"
+    printf '%s' "${norm}"
+    rm -f "$TMPDIR/${CAKEY_PREFIX}-${type}".csr
+    rm -f "$TMPDIR/${CAKEY_PREFIX}-${type}".crt
+    return $retval
+  }
+
+  sync
+  $OPENSSL verify \
+    -CAfile "$SSH_CACERTDIR/$CAKEY_PREFIX"-root0.crt.pem \
+    "$TMPDIR/${CAKEY_PREFIX}-${type}".crt \
+  ; retval=$?
+  # exit code always is 0 :(
+
+  rm -f "$TMPDIR/${CAKEY_PREFIX}-${type}".csr
+
+  test $retval -ne 0 && return $retval
+done
+  return 0
+}
+
+
+# ===
+crt2bundle () {
+(
+  val="$1"
+  test -z "$val" && { echo ${warn}missing DN${norm} >&2; return 1; }
+
+  echo
+  echo $val
+  echo $val | sed -e 's/./=/g'
+  cat "$2"
+)
+}
+
+
+# ===
+cre_dirs () {
+  for D in \
+    "$SSH_CAROOT" \
+    "$SSH_CAKEYDIR" \
+    "$SSH_CACERTDIR" \
+  ; do
+    if test ! -d "$D"; then
+      mkdir -p "$D" || return $?
+    fi
+  done
+  chmod 700 "$SSH_CAKEYDIR"
+}
+
+
+install () {
+(
+  update_file "$TMPDIR/${CAKEY_PREFIX}-dsa.prm" "$SSH_CAROOT/${CAKEY_PREFIX}-dsa.prm" || exit $?
+
+  for type in rsa dsa; do
+    F="${CAKEY_PREFIX}-${type}.key"
+    update_file "${TMPDIR}/${F}" "${SSH_CAKEYDIR}/${F}"
+  done
+
+  for type in ${SSH_SIGN_TYPES}; do
+    F="${CAKEY_PREFIX}-${type}.crt"
+    move_as_trusted_x509 "${TMPDIR}/${F}" "${SSH_CACERTDIR}/${F}.pem" || exit $?
+  done
+
+  create_empty_file "${TMPDIR}/${CACERTFILE}" &&
+  for level in 0; do
+    F="$SSH_CACERTDIR/$CAKEY_PREFIX"-root${level}.crt.pem
+    crt2bundle "$SSH_DN_O level $level" "$F" >> "$TMPDIR/$CACERTFILE" || exit $?
+  done
+  for type in ${SSH_SIGN_TYPES}; do
+    F="${SSH_CACERTDIR}/${CAKEY_PREFIX}-${type}.crt.pem"
+    crt2bundle "${SSH_DN_O}-${type}" "${F}" >> "${TMPDIR}/${CACERTFILE}" || exit $?
+  done
+
+  update_file "${TMPDIR}/${CACERTFILE}" "${SSH_CAROOT}/${CACERTFILE}"
+)
+}
+
+
+# ===
+cre_hash_link () {
+(
+#option -noout problem:
+#exit code from .../openssl ... -noout ... is sometime nonzero !!!
+#might only by .../openssl x509 ... -noout ... exit code is zero
+#sample:
+#a) exit code is one - INCORRECT
+#  .../openssl crl -in a_crl_file  -hash -noout
+#b) exit code is zero - correct
+#  .../openssl crl -in a_crl_file  -hash -out /dev/null
+#
+#work around might is to use -out /dev/null :-/
+  HASH=`$OPENSSL x509 -in "$1" -noout -hash` || exit $?
+  NAME=`getNextFreeName ${HASH}.`            || exit $?
+
+  echo "creating link ${attn}${NAME}${norm} to ${attn}$1${norm}"
+  rm -f "${NAME}" &&
+  ln -s "$1" "${NAME}" || exit $?
+  #link might never fail ;-(
+  test -h "${NAME}"
+)
+}
+
+
+cre_hashs () {
+#(!) openssl script "c_rehash" is missing in some installations :-(
+#  c_rehash "${SSH_CACERTDIR}"
+(
+  cd "${SSH_CACERTDIR}" || exit $?
+
+  for F in [0-9a-f]*.[0-9]; do
+    # we must use test -L, but on ?-OSes ... :-(
+    if test -h "$F"; then
+      rm -f "$F" || exit $?
+    fi
+  done
+
+  for level in 0; do
+    cre_hash_link "${CAKEY_PREFIX}-root${level}.crt.pem" || exit $?
+  done
+
+  for type in ${SSH_SIGN_TYPES}; do
+    cre_hash_link "${CAKEY_PREFIX}-${type}.crt.pem" || exit $?
+  done
+
+  exit 0
+)
+}
+
+
+# ===
+
+cre_dirs &&
+cre_root &&
+gen_rsa &&
+gen_dsa &&
+cre_crt &&
+install &&
+cre_hashs; retval=$?
+
+show_status $retval "${extd}Creating${norm} ${warn}TEST${norm} ${attn}Certificate Authority${norm}"
+echo "${warn}password for all private keys is ${attn}${KEY_PASS}${norm}"
+exit $retval
diff -ruN openssh-7.5p1/tests/CA/2-cre_key.sh openssh-7.5p1+x509-10.2/tests/CA/2-cre_key.sh
--- openssh-7.5p1/tests/CA/2-cre_key.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/2-cre_key.sh	2011-12-29 02:00:00.000000000 +0200
@@ -0,0 +1,33 @@
+#! /bin/sh
+# Copyright (c) 2011 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create "Test Certificate Authority" private keys and certificates.
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/2-cre_key.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+test -z "$TEST_SSH_SSHKEYGEN" && { echo "${warn}Please define ${attn}TEST_SSH_SSHKEYGEN${norm}"; exit 1; }
+
+$TEST_SSH_SSHKEYGEN ${1+"$@"}
diff -ruN openssh-7.5p1/tests/CA/3-cre_certs.sh openssh-7.5p1+x509-10.2/tests/CA/3-cre_certs.sh
--- openssh-7.5p1/tests/CA/3-cre_certs.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/3-cre_certs.sh	2017-05-20 20:45:28.000000000 +0300
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create test certificate(s).
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/3-cre_certs.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+usage () {
+  cat <<EOF
+usage: $0 <options>
+  -f[ile]	[ssh]key_file_name
+  -t[ype]	certificate type: client, server, ocsp(if enabled)
+  -n[ame]	"base" common name
+EOF
+  exit 1
+}
+
+test "x$TEST_SSH_SSHKEYGEN" = "x" && { echo "Please define TEST_SSH_SSHKEYGEN"; exit 1; }
+test -z "$1" && usage
+
+
+SSH_SELFCERT=no
+
+while test -n "$1"; do
+  case $1 in
+    -f|\
+    -file)
+      shift
+      if test -z "$1"; then
+        usage
+      fi
+      if test -n "${SSH_BASE_KEY}"; then
+        usage
+      fi
+      SSH_BASE_KEY="$1"
+      shift
+      ;;
+
+    -t|\
+    -type)
+      shift
+      if test -z "$1"; then
+        usage
+      fi
+      if test -n "$SSH_CERT_TYPE"; then
+        usage
+      fi
+      SSH_CERT_TYPE="$1"
+      shift
+      case $SSH_CERT_TYPE in
+        client)
+          SSH_X509V3_EXTENSIONS="usr_cert"
+          ;;
+        server)
+          SSH_X509V3_EXTENSIONS="srv_cert"
+          ;;
+        self)
+          SSH_SELFCERT=yes
+          SSH_X509V3_EXTENSIONS=self_cert
+          ;;
+        ocsp)
+          if test "x$SSH_OCSP" = "xyes"; then
+            SSH_X509V3_EXTENSIONS="ocsp_cert"
+          else
+            echo "${warn}unsupported type${norm}"
+            usage
+          fi
+          ;;
+        *)
+          echo "${warn}wrong type${norm}"
+          usage
+          ;;
+      esac
+      ;;
+
+    -n|\
+    -name)
+      shift
+      if test -z "$1"; then
+        usage
+      fi
+      if test -n "${SSH_BASE_DN_CN}"; then
+        usage
+      fi
+      SSH_BASE_DN_CN="$1"
+      shift
+      ;;
+
+    *)
+      usage
+      ;;
+  esac
+done
+
+test -z "${SSH_BASE_KEY}" && usage
+test ! -r "${SSH_BASE_KEY}" && { error_file_not_readable; exit 1; }
+test -z "${SSH_BASE_DN_CN}" && usage
+test -z "${SSH_CERT_TYPE}" && usage
+
+
+CA_LOG="$CWD/ca-3.$SSH_BASE_KEY.$SSH_X509V3_EXTENSIONS.log"
+create_empty_file .delmy &&
+update_file .delmy "$CA_LOG" > /dev/null || exit $?
+
+
+# ===
+cre_csr () {
+  echo "=== create a new CSR ===" >> "$CA_LOG"
+  (
+    if test "$SSH_X509V3_EXTENSIONS" != "usr_cert"; then
+      SSH_DN_EM="."
+    fi
+
+    cat <<EOF
+$SSH_DN_C
+$SSH_DN_ST
+$SSH_DN_L
+$SSH_DN_O
+${SSH_DN_OU}-2
+${SSH_DN_OU}-1
+${SSH_DN_OU}-3
+$SSH_BASE_DN_CN(${type}${subtype})
+$SSH_DN_EM
+.
+EOF
+  ) |
+  $OPENSSL req \
+    -new \
+    -config "${SSH_CACFGFILE}" \
+    $SSH_DN_UTF8_FLAG \
+    -key "${SSH_BASE_KEY}" \
+    -passin pass:"" \
+    -out "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.csr" \
+    2>> "$CA_LOG" \
+  ; show_status $? "- ${extd}CSR${norm}"
+}
+
+
+# ===
+cre_crt () {
+  echo "=== create a new CRT ===" >> "$CA_LOG"
+  $OPENSSL ca \
+    -config "${SSH_CACFGFILE}" \
+    -batch \
+    -in "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.csr" \
+    -name "ca_test_$type" \
+    -passin pass:$KEY_PASS \
+    -out "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.crt" \
+    -extensions ${SSH_X509V3_EXTENSIONS} \
+    2>> "$CA_LOG" \
+  ; show_status $? "- ${extd}CRT${norm}" ||
+  { retval=$?
+    printf '%s' "${warn}"
+    grep 'ERROR:' "$CA_LOG"
+    printf '%s' "${norm}"
+    return $retval
+  }
+
+  sync
+  $OPENSSL verify \
+    -CAfile "$SSH_CAROOT/$CACERTFILE" \
+    "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.crt" &&
+  rm -f "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.csr" ||
+    return $?
+
+  # openssl verify exit always with zero :(
+
+  printf '%s' '- ' &&
+  update_file \
+    "$TMPDIR/$SSH_X509V3_EXTENSIONS-$type$subtype.crt" \
+    "$SSH_BASE_KEY-$type$subtype.crt" ||
+    return $?
+
+  # openssl ca command does not support name option
+  F="$SSH_BASE_KEY-$type$subtype.crt"
+  mv "$F" t-"$F" &&
+  $OPENSSL x509 \
+    -in t-"$F" \
+    -text $OPENSSL_NAMEOPT \
+    > "$F" &&
+  rm t-"$F"
+}
+
+
+# ===
+cre_self () {
+  echo "=== create a new self-CRT ===" >> "$CA_LOG"
+  (
+    cat <<EOF
+$SSH_DN_C
+$SSH_DN_ST
+$SSH_DN_L
+$SSH_DN_O
+${SSH_DN_OU}-2
+${SSH_DN_OU}-1
+${SSH_DN_OU}-3
+$SSH_BASE_DN_CN(${type}-self)
+$SSH_DN_EM
+.
+EOF
+  ) |
+  $OPENSSL req \
+    -new -x509 \
+    -config "$SSH_CACFGFILE" \
+    $SSH_DN_UTF8_FLAG \
+    -key "$SSH_BASE_KEY" \
+    -days $SSH_CACERTDAYS \
+    -passin pass:"" \
+    -out "$TMPDIR/${SSH_X509V3_EXTENSIONS}-${type}".crt \
+    -extensions $SSH_X509V3_EXTENSIONS \
+    2>> "$CA_LOG" \
+  ; show_status $? "- ${extd}self-CRT${norm}" \
+  || return $?
+
+  update_file \
+    "$TMPDIR/${SSH_X509V3_EXTENSIONS}-${type}".crt \
+    "${SSH_BASE_KEY}-${type}".crt
+}
+
+
+# ===
+cre_ssh_crt () {
+  printf '%s' "- ${extd}PKIX-SSH certificate${norm}"
+  ( cat "$SSH_BASE_KEY"
+
+    $OPENSSL x509 \
+     -in "$SSH_BASE_KEY-$type$subtype.crt" \
+     -subject -issuer -alias $OPENSSL_NAMEOPT
+  ) > "$SSH_BASE_KEY-$type$subtype" &&
+  chmod 600 "$SSH_BASE_KEY-$type$subtype" \
+  ; show_status $?
+}
+
+
+cre_ssh_pubkey () {
+  printf '%s' "- ${extd}PKIX-SSH public key${norm}"
+  "$TEST_SSH_SSHKEYGEN" -y -f "${SSH_BASE_KEY}-${type}${subtype}" \
+    > "${SSH_BASE_KEY}-${type}${subtype}.pub" \
+  ; show_status $?
+}
+
+
+cre_p12 () {
+  P12_OPT=
+  if test -n "$OPENSSL_FIPS"; then
+    P12_OPT="$P12_OPT -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES"
+  fi
+  printf '%s' "- ${extd}PKCS #12${norm} file"
+  ( cat "$SSH_BASE_KEY-$type$subtype"
+    cat "$SSH_CACERTDIR/$CAKEY_PREFIX-$type".crt.pem
+  ) | \
+  $OPENSSL pkcs12 $P12_OPT \
+    -passin pass: \
+    -passout pass: \
+    -out "$SSH_BASE_KEY-$type$subtype".p12 \
+    -export \
+  ; show_status $?
+}
+
+
+revoke_crt () {
+  echo "=== revoke a CRT ===" >> "$CA_LOG"
+  printf '%s' "- ${extd}revoke${norm} certificate"
+  $OPENSSL ca \
+    -config "${SSH_CACFGFILE}" \
+    -name "ca_test_$type" \
+    -passin pass:$KEY_PASS \
+    -revoke "${SSH_BASE_KEY}-${type}${subtype}.crt" \
+    2>> "$CA_LOG" \
+  ; show_status $?
+}
+
+
+# ===
+cre_all2 () {
+  echo
+  printf '%s\n' "creating ${extd}${SSH_X509V3_EXTENSIONS}${norm} for ${extd}${SSH_BASE_DN_CN}${norm}(${attn}${type}${norm}${warn}${subtype}${norm}) ..."
+
+  if test "$SSH_SELFCERT" = "yes"; then
+    cre_self
+  else
+    cre_csr &&
+    cre_crt
+  fi || return $?
+
+  test "$SSH_X509V3_EXTENSIONS" = "ocsp_cert" && return 0
+
+  cre_ssh_crt &&
+  cre_ssh_pubkey &&
+  cre_p12
+}
+
+
+# ===
+cre_all () {
+(
+  subtype=""
+  for type in ${SSH_SIGN_TYPES}; do
+    cre_all2 || exit $?
+  done
+
+  if test "$SSH_X509V3_EXTENSIONS" = "srv_cert" || \
+     test "$SSH_SELFCERT" = "yes" \
+  ; then
+    create_empty_file $SSH_BASE_KEY.certstamp
+    exit $?
+  fi
+
+  subtype="-revoked"
+  for type in ${SSH_SIGN_TYPES}; do
+    cre_all2 &&
+    revoke_crt || exit $?
+  done
+
+  create_empty_file $SSH_BASE_KEY.certstamp
+)
+}
+
+# ===
+
+cre_all; retval=$?
+
+echo
+show_status $retval "${extd}Creating${norm} ${attn}${SSH_BASE_DN_CN}${norm} group of ${warn}test${norm} certificates"
diff -ruN openssh-7.5p1/tests/CA/4-cre_crls.sh openssh-7.5p1+x509-10.2/tests/CA/4-cre_crls.sh
--- openssh-7.5p1/tests/CA/4-cre_crls.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/4-cre_crls.sh	2015-03-28 18:58:48.441378338 +0200
@@ -0,0 +1,125 @@
+#! /bin/sh
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create "Test Certificate Authority" CRLs.
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/4-cre_crls.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+
+CA_LOG="$CWD/ca-4.log"
+create_empty_file .delmy &&
+update_file .delmy "$CA_LOG" > /dev/null || exit $?
+
+
+# ===
+cre_crlfile() {
+(
+  type="$1"
+
+  cd "${SSH_CACRLDIR}" || exit $?
+
+  FILE="${CAKEY_PREFIX}-${type}.crl.pem"
+
+  printf '%s' "- ${attn}${type}${norm} certificates"
+  ${OPENSSL} ca \
+    -config "${SSH_CACFGFILE}" \
+    -name "ca_test_$type" \
+    -passin pass:${KEY_PASS} \
+    -gencrl \
+    -out "${FILE}" \
+    2>> "$CA_LOG" \
+  ; show_status $? || exit $?
+
+  HASH=`$OPENSSL crl -out /dev/null -in "$FILE" -hash 2>> "$CA_LOG"` || exit $?
+
+  NAME=`getNextFreeName "${HASH}.r"` || exit $?
+
+  ln -s "${FILE}" "${NAME}"
+  #link might never fail :-(
+  test -h "${NAME}"
+)
+}
+
+
+# ===
+cre_crlindir () {
+  echo "=== create a new CRL ===" >> "$CA_LOG"
+  rm -f "${SSH_CACRLDIR}"/* 2>/dev/null
+
+  printf '%s\n' "creating ${extd}CA CRL file${norm} for ..."
+  for type in ${SSH_SIGN_TYPES}; do
+    cre_crlfile "${type}" || return $?
+  done
+
+  return 0
+}
+
+
+# ===
+cre_CAcrlfile () {
+(
+  crlfile="$SSH_CAROOT/$CACRLFILE"
+
+  # NOTE -nameopt is without effect over -text
+  # As work-around file will contain in addition
+  # issuer name.
+
+  create_empty_file "$crlfile"-t &&
+  for type in $SSH_SIGN_TYPES; do
+    (
+      if test -n "$OPENSSL_NAMEOPT"; then
+        $OPENSSL crl $OPENSSL_NAMEOPT \
+        -in "$SSH_CACRLDIR/$CAKEY_PREFIX-$type.crl.pem" \
+        -issuer -noout \
+        2>> "$CA_LOG" &&
+        echo "============================================================"
+      fi &&
+      $OPENSSL crl \
+      -in "$SSH_CACRLDIR/$CAKEY_PREFIX-$type.crl.pem" \
+      -text \
+      2>> "$CA_LOG" \
+      && echo && echo
+    ) >> "$crlfile"-t || exit $?
+  done
+
+  mv "$crlfile"-t "$crlfile"
+)
+}
+
+
+# ===
+cre_all () {
+  cre_crlindir || return $?
+
+  printf '%s' "creating ${extd}CA CRL ${attn}common${norm} ${extd}file${norm} ..."
+  cre_CAcrlfile; show_status $?
+}
+
+
+# ===
+cre_all; retval=$?
+
+show_status $retval "${extd}Creating${norm} ${warn}TEST${norm} ${attn}Certificate Authority${norm} CRL files"
diff -ruN openssh-7.5p1/tests/CA/5-cre_ldap.sh openssh-7.5p1+x509-10.2/tests/CA/5-cre_ldap.sh
--- openssh-7.5p1/tests/CA/5-cre_ldap.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/5-cre_ldap.sh	2016-02-28 21:01:05.000000000 +0200
@@ -0,0 +1,143 @@
+#! /bin/sh
+# Copyright (c) 2004-2007,2011 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Create LDAP files.
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/5-cre_ldap.sh$//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+
+if test ! -d ldap/data; then
+  mkdir -p ldap/data || exit $?
+fi
+
+
+# ===
+cre_base_ldif() {
+(
+  cat <<EOF
+dn: ${SSH_LDAP_DC}
+changetype: add
+objectClass: dcObject
+objectClass: organization
+dc: example
+o: Example Corporation
+description: The Example Corporation
+
+dn: cn=Manager,${SSH_LDAP_DC}
+changetype: add
+objectClass: inetOrgPerson
+cn: Manager
+sn: Manager
+title: the world's most famous manager
+mail: manager@example.com
+uid: manager
+
+
+# The organization 'SSH Test Team':
+# "O=${SSH_DN_O},${SSH_LDAP_DC}"
+dn:`utf8base64 "O=${SSH_DN_O},${SSH_LDAP_DC}"`
+changetype: add
+objectclass: organization
+o:`utf8base64 "${SSH_DN_O}"`
+st: ${SSH_DN_ST}
+
+
+# The 'SSH Testers' organizational units:
+# "OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"
+dn:`utf8base64 "OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"`
+changetype: add
+objectclass: organizationalUnit
+ou:`utf8base64 "${SSH_DN_OU}"`
+l:`utf8base64 "${SSH_DN_L}"`
+st: ${SSH_DN_ST}
+EOF
+
+
+  for level in 0; do
+    cat <<EOF
+
+# "OU=${SSH_DN_OU} level ${level},OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"
+dn:`utf8base64 "OU=${SSH_DN_OU} level ${level},OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"`
+changetype: add
+objectclass: organizationalUnit
+ou:`utf8base64 "$SSH_DN_OU level ${level}"`
+l:`utf8base64 "${SSH_DN_L}"`
+st: ${SSH_DN_ST}
+EOF
+  done
+
+
+  for type in ${SSH_SIGN_TYPES}; do
+    cat <<EOF
+
+# "OU=${SSH_DN_OU} $type keys,OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"
+dn:`utf8base64 "OU=${SSH_DN_OU} $type keys,OU=${SSH_DN_OU},O=${SSH_DN_O},${SSH_LDAP_DC}"`
+changetype: add
+objectclass: organizationalUnit
+ou:`utf8base64 "$SSH_DN_OU $type keys"`
+l:`utf8base64 "${SSH_DN_L}"`
+st: ${SSH_DN_ST}
+EOF
+  done
+) > ldap/base.ldif
+}
+
+
+# ===
+cre_slapdconf () {
+(
+  cat <<EOF
+#required schemas
+include		$LDAP_SYSCONFDIR/schema/core.schema
+include		$LDAP_SYSCONFDIR/schema/cosine.schema
+include		$LDAP_SYSCONFDIR/schema/inetorgperson.schema
+
+#features
+allow bind_v2
+#disallow bind_simple ;-)
+
+# dbms backend settings should be same file !
+# this is required for openldap version 2.3.32(but not for <= 2.3.20,2.2.x,2.1.x)
+##dbms
+#database	$SSH_LDAP_DB
+#suffix		"$SSH_LDAP_DC"
+#rootdn		"cn=Manager,$SSH_LDAP_DC"
+#rootpw		secret
+#
+#index	objectClass	eq
+EOF
+) > ldap/slapd.conf.tmpl
+
+}
+
+
+# ===
+
+cre_base_ldif &&
+cre_slapdconf &&
+: ; retval=$?
+
+show_status $retval "${extd}Creating${norm} ${warn}LDAP${norm} ${attn}files${norm}"
diff -ruN openssh-7.5p1/tests/CA/config openssh-7.5p1+x509-10.2/tests/CA/config
--- openssh-7.5p1/tests/CA/config	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/config	2016-12-19 17:16:42.126651925 +0200
@@ -0,0 +1,271 @@
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: SSH X.509 tests configuration.
+#
+
+
+# === setup from build environment:
+. ./env
+
+# === main variables:
+# on some system (with pam?, AIX?, when port is below 1024, etc.) we
+# might use sudo command to start sshd when current user isn`t root or
+# to run tests as root.
+# Prefered user for tests is NOT root :-) !
+SUDO=${SUDO-}
+# uncomment to override enviroment
+#SUDO=sudo
+
+
+#Old BSD shells, including the Ultrix `sh', don't accept the colon
+#for any shell substitution, and complain and die.
+##TMPDIR="${TMPDIR:-/tmp}"
+
+if test -n "$TMPDIR"; then
+  if test ! -d "$TMPDIR"; then
+    echo "error: $TMPDIR is not directory"
+    exit 1
+  fi
+  if test ! -w "$TMPDIR"; then
+    echo "error: $TMPDIR is not writable"
+    exit 1
+  fi
+else
+  for D in /tmp /var/tmp /usr/tmp; do
+    test -d $D || continue
+    test -w $D || continue
+    TMPDIR=$D
+    break
+  done
+  if test -z "$TMPDIR"; then
+    echo "error: cannot set TMPDIR"
+    exit 1
+  fi
+fi
+
+
+if test -z "$SSH_X509TESTS"; then
+SSH_X509TESTS="\
+ blob_auth
+ dn_auth_file
+ dn_auth_path
+ agent
+ crl
+ self
+ alg
+ hostalg
+ algfmt
+ ocsp
+ by_ldap
+"
+fi
+
+
+# === openssl:
+
+if test -z "${OPENSSL}"; then
+  OPENSSL=`which openssl 2>/dev/null`
+  if test -z "${OPENSSL}"; then
+    echo "error:cannot find openssl is your path !" >&2
+    exit 1
+  fi
+fi
+
+#NOTE: environment variable OPENSSL_FIPS is used as test flag
+# in regression tests
+if test yes = $OPENSSL_FIPS_MODE; then
+  :
+else
+  # unset OPENSSL_FIPS for non-FIPS build, to avoid mis-use
+  # of flag in regression tests
+  unset OPENSSL_FIPS || :
+fi
+
+printf "OpenSSL command: ${attn}%s${norm}\n" "$OPENSSL"
+openssl_version=`$OPENSSL version` || exit $?
+test -z "$openssl_version" && { echo "error: cannot determine OpenSSL version" >&2; exit 1; }
+printf "        version: ${attn}%s${norm}\n" "$openssl_version"
+
+
+openssl_nopkcs8_keys=false
+if test -n "$OPENSSL_FIPS"; then
+  #NOTE
+  # - 1.0.0* and 1.1+ does not support FIPS build
+  # - Usualy in FIPS mode keys are in PKCS8 format by default
+  # - Only OpenSSL 1.0.1* before 1.0.1d does not create keys in PKCS8 format
+  # - Do conversion only for 1.0.1* branch
+  case $openssl_version in
+    1.0.1*)
+      openssl_nopkcs8_keys=:
+      ;;
+  esac
+fi
+
+# Uncoment and modify next if you would like to load(seed) file(s)
+# into the random number generator.
+# Note that some openssl forks fail to process -rand option!
+#random_seed_files=/etc/random-seed
+
+
+# These are the known patent issues with OpenSSL:
+# name   #         expires
+# mdc2:  4,908,861 13/03/2007 - enabled in OpenSSL 1.x branches from 2009-08-12
+# idea:  5,214,703 25/05/2010
+# rc5:   5,724,428 03/03/2015
+#
+# Note the MD2 hash algorithm is considered as weak (2009) and
+# most vendors disable it in openssl. Also from 2009-07-08
+# OpenSSL team disable md2 by default in 0.9.8 and 1.x branches.
+# This is reason md2 to be removed from list starting with
+# "X.509 certificate support version 6.3".
+
+# With support for EC certificates we will limit RSA
+# tests to sha1 only. Comment next line to restore.
+RSA_DIGEST_LIST=${RSA_DIGEST_LIST-sha1}
+
+if test -z "${RSA_DIGEST_LIST}"; then
+  for DIGEST in sha1 md5 mdc2 md4 rmd160; do
+    if "${OPENSSL}" dgst -${DIGEST} "${OPENSSL}" >/dev/null 2>&1; then
+      RSA_DIGEST_LIST="${RSA_DIGEST_LIST} ${DIGEST}"
+    fi
+  done
+fi
+if test -z "${RSA_DIGEST_LIST}"; then
+  echo "RSA_DIGEST_LIST is empty" >&2
+  exit 1
+fi
+echo "RSA digest list: ${RSA_DIGEST_LIST}"
+
+
+SSH_SIGN_TYPES=""
+for DIGEST in ${RSA_DIGEST_LIST}; do
+  SSH_SIGN_TYPES="${SSH_SIGN_TYPES} rsa_${DIGEST}"
+done
+  SSH_SIGN_TYPES="${SSH_SIGN_TYPES} dsa"
+
+
+# === server section:
+
+if test -z "${SSHD_PORT}"; then
+  SSHD_PORT=20022
+fi
+
+SSHD_LISTENADDRESS=127.0.0.1
+#SSHD_LISTENADDRESS=::1
+
+#"yes" or "no"
+SSHSERVER_USEPRIVILEGESEPARATION="yes"
+#SSHSERVER_USEPRIVILEGESEPARATION="no"
+
+SSHSERVER_SYSLOGFACILITY=AUTH
+SSHSERVER_LOGLEVEL=FATAL
+#SSHSERVER_SYSLOGFACILITY=LOCAL3
+#SSHSERVER_LOGLEVEL=DEBUG3
+
+
+# === certificates:
+
+KEY_PASS="change_it"
+CAKEY_PREFIX="catest"
+
+SSH_CAROOT="`pwd`/ca-test"
+SSH_CAKEYDIR="${SSH_CAROOT}/keys"
+
+CACERTFILE="catest-bundle.crt"
+CACRLFILE="catest-bundle.crl"
+
+SSH_CACERTDIR="${SSH_CAROOT}/crt"
+SSH_CACRLDIR="${SSH_CAROOT}/crl"
+
+CACONFIG="catest.config"
+SSH_CACFGFILE="${SSH_CAROOT}/${CACONFIG}"
+
+SSH_CACERTDAYS=60
+SSH_CACRLDAYS=60
+
+SSH_DN_C="XX"
+SSH_DN_ST="World"
+SSH_DN_L="Somewhere"
+SSH_DN_O="SSH Test Team"
+SSH_DN_OU="SSH Testers"
+SSH_DN_EM="email@not.set"
+
+SSH_DN_UTF8_FLAG='-utf8'
+# '-utf8' flag is added in OpenSSL 0.9.7
+case $openssl_version in
+  *0.9.6*)
+    SSH_DN_UTF8_FLAG=
+    ;;
+  *);;
+esac
+if test -n "$SSH_DN_UTF8_FLAG"; then
+  SSH_DN_SUF=" cyrillic-АБВ-Яабв-я greek-ΑΒΓ-Ωαβγ-ω"
+  SSH_DN_L="$SSH_DN_L$SSH_DN_SUF"
+  SSH_DN_O="$SSH_DN_O$SSH_DN_SUF"
+  SSH_DN_OU="$SSH_DN_OU$SSH_DN_SUF"
+
+  OPENSSL_NAMEOPT="-nameopt utf8,sep_comma_plus" #ok
+  #OPENSSL_NAMEOPT="-nameopt esc_2253,esc_ctrl,esc_msb,utf8,dump_nostr,dump_der,use_quote,sep_comma_plus_space,sname" #fail - esc_msb should be removed
+  #OPENSSL_NAMEOPT="-nameopt esc_2253,esc_ctrl,utf8,dump_nostr,dump_der,use_quote,sep_comma_plus_space,sname" #ok
+  #OPENSSL_NAMEOPT="-nameopt esc_2253,esc_ctrl,-esc_msb,utf8,dump_nostr,dump_der,use_quote,sep_comma_plus_space,sname" #ok
+  #OPENSSL_NAMEOPT="-nameopt esc_2253,esc_ctrl,esc_msb,utf8,dump_nostr,dump_der,use_quote,sep_comma_plus_space,sname,-esc_msb" #ok
+  #OPENSSL_NAMEOPT="-nameopt oneline,-esc_msb,-space_eq" #ok
+  #OPENSSL_NAMEOPT="-nameopt oneline,-esc_msb" #now ok (spaces around '=')
+else
+  OPENSSL_NAMEOPT=
+fi
+
+# OpenSSL control type distiguished item type with string_mask
+# option in [req] section from configuration file.
+# By default option is set to
+# - nombstr (0.9.7x and 0.9.8x)
+# - utf8only (1.0+)
+SSH_DN_FORCE_UTF8=${SSH_DN_FORCE_UTF8-no}
+case $openssl_version in
+  *0.9.6*)
+    # not supported so override enviroment settings
+    SSH_DN_FORCE_UTF8=no
+    ;;
+esac
+
+# === OCSP:
+# OpenSSL OCSP test responders listen on BASE, BASE+1, ...
+# Set the default base port if is not set by environment.
+SSH_VA_BASEPORT=${SSH_VA_BASEPORT-20080}
+
+# OpenSSL OCSP responder don't use SO_REUSEADDR :-(, so ocsp tests
+# must wait socket to close.
+# Set the default timeout if is not set by environment.
+SSH_OPENSSL_OCSP_TMOUT=${SSH_OPENSSL_OCSP_TMOUT-60}
+
+# === LDAP:
+SSH_LDAP_DB=bdb
+# "hdb" backend since openldap 2.2+
+#SSH_LDAP_DB=hdb
+# openldap 2.4+ deprecate "ldbm" backend
+#SSH_LDAP_DB=ldbm
+SSH_LDAP_DC="dc=example,dc=com"
+
+# LDAP test server listen on specified port.
+# Set the default ldap port if is not set by environment.
+LDAPD_PORT=${LDAPD_PORT-20389}
+
+LDAPD_URL="ldap://${SSHD_LISTENADDRESS}:${LDAPD_PORT}"
diff -ruN openssh-7.5p1/tests/CA/env.in openssh-7.5p1+x509-10.2/tests/CA/env.in
--- openssh-7.5p1/tests/CA/env.in	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/env.in	2016-02-28 21:01:05.000000000 +0200
@@ -0,0 +1,8 @@
+# LDAP environment:
+@LDAP_ON@LDAP_SYSCONFDIR="@LDAP_SYSCONFDIR@"
+@LDAP_ON@LDAP_LIBEXECDIR="@LDAP_LIBEXECDIR@"
+@LDAP_ON@LDAP_BINDIR="@LDAP_BINDIR@"
+@LDAP_ON@LDAPADD="@LDAPADD@"
+
+# FIPS capable openssl
+OPENSSL_FIPS_MODE=@OPENSSL_FIPS_MODE@
diff -ruN openssh-7.5p1/tests/CA/functions openssh-7.5p1+x509-10.2/tests/CA/functions
--- openssh-7.5p1/tests/CA/functions	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/functions	2016-08-02 09:04:34.000000000 +0300
@@ -0,0 +1,281 @@
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Usefull functions.
+#
+
+
+# ===
+#
+# define colors and more for echo commands
+#
+#    \033          ascii ESCape
+#    \033[<NUM>G   move to column <NUM> (linux console, xterm, not vt100)
+#    \033[<NUM>C   move <NUM> columns forward but only upto last column
+#    \033[<NUM>D   move <NUM> columns backward but only upto first column
+#    \033[<NUM>A   move <NUM> rows up
+#    \033[<NUM>B   move <NUM> rows down
+#    \033[1m       switch bold on
+#    \033[31m      switch red on
+#    \033[32m      switch green on
+#    \033[33m      switch yellow on
+#    \033[m        switch color/bold off
+#    \017          exit alternate mode (xterm, vt100, linux console)
+#    \033[10m      exit alternate mode (linux console)
+#    \015          carriage return (without newline)
+#
+
+# get terminal settings in a portable way
+# NOTE: stty size is not portable
+if test -z "$LINES" -o -z "$COLUMNS" ; then
+  eval `stty size 2>/dev/null | (read L C; echo LINES=$L COLUMNS=$C)`
+fi
+test -z "$LINES"  && LINES=`tput lines`
+test -z "$COLUMNS"&& COLUMNS=`tput cols`
+# set defaults
+test -z "$LINES"  && LINES=24
+test -z "$COLUMNS"&& COLUMNS=80
+export LINES COLUMNS
+
+if test "${TERM}" != "dumb" ; then
+         esc=`printf '\033'`
+        extd="${esc}[1m"
+        warn="${esc}[1;31m"
+        done="${esc}[1;32m"
+        attn="${esc}[1;34m"
+        norm=`printf '%s\017' "${esc}[m"`
+        stat=`printf '\015%s' "${esc}[${COLUMNS}C${esc}[10D"`
+
+     msg_done="${stat}${done}done${norm}"
+   msg_failed="${stat}${warn}failed${norm}"
+
+else
+         esc=""
+        extd=""
+        warn=""
+        done=""
+        attn=""
+        norm=""
+        stat=""
+
+     msg_done="..done"
+   msg_failed="..failed"
+
+fi
+
+
+# ===
+error_file_not_found () {
+  echo "${warn}file ${attn}${1}${warn} not found${norm}"
+  return 1
+}
+
+
+# ===
+error_file_not_readable () {
+  echo "${warn}file ${attn}${1}${warn} not found or not readable${norm}"
+  return 1
+}
+
+
+# ===
+error_dir_not_found () {
+  echo "${warn}directory ${attn}${1}${warn} not found${norm}"
+  return 1
+}
+
+
+# ===
+printSeparator() {
+  echo "======================================================================="
+}
+
+
+# ===
+show_status () {
+  if test -n "$2"; then
+    printf '%s' "$2"
+  fi
+  if test $1 -eq 0; then
+    echo "$msg_done"
+  else
+    echo "$msg_failed"
+  fi
+  return $1
+}
+
+
+# ===
+getNextFreeName() {
+  var="$1"
+  limit="$2"
+
+  if test -z "${limit}"; then
+    limit=10
+  fi
+
+  count=0
+  while true; do
+    test ! -f "${var}${count}" && break
+    count=`expr ${count} + 1`
+    if test ${count} -ge ${limit}; then
+      echo "getNextFreeName: ${warn}limit reached${norm} for file ${attn}${var}${norm}" >&2
+
+      echo ""
+      return 33
+    fi
+  done
+
+  echo "${var}${count}"
+  return 0
+}
+
+
+# ===
+getNextDirName() {
+  var="$1"
+  count=0
+  while true; do
+    test ! -d "${var}.${count}" && break
+    count=`expr ${count} + 1`
+  done
+  if test ${count} -ge 10; then
+    echo "${warn}please remove ${attn}${var}${warn} backup directories !${norm}" >&2
+    return 33
+  fi
+  echo $count
+  return 0
+}
+
+
+# ===
+create_empty_file () {
+  > "$1"
+}
+
+
+# ===
+update_file () {
+  var_new="$1"
+  var_old="$2"
+
+  if test ! -f "${var_old}"; then
+    printf '%s' "creating file ${attn}${var_old}${norm}"
+    mv "${var_new}" "${var_old}"; show_status $?
+    return $?
+  fi
+  test -r "${var_new}" || { error_file_not_readable "${var_new}"; return 1; }
+
+  if diff "${var_old}" "${var_new}" >/dev/null 2>&1; then
+    echo "no changes in ${attn}${var_old}${norm}"
+    rm -f "${var_new}"
+    return 0
+  fi
+
+  backup=`getNextFreeName "${var_old}."` || return $?
+  printf '%s' "saving old file as ${attn}${backup}${norm}"
+  cp -p "${var_old}" "${backup}"; show_status $? || return $?
+
+  printf '%s' "updating file ${attn}${var_old}${norm}"
+  if test ! -w "${var_old}"; then
+    chmod u+w "${var_old}"
+    not_writable="yes"
+  fi
+  cat "${var_new}" > "${var_old}"; show_status $? || return $?
+  if test "$not_writable" = "yes"; then
+    chmod u-w "${var_old}"
+  fi
+  rm -f "${var_new}"
+  return 0
+}
+
+
+# ===
+getSSHkeyType () {
+  identity_file="$1"
+  if test ! -r "$identity_file"; then
+    error_file_not_readable "${identity_file}" >&2; return $?
+  fi
+
+  sshkeytype="unspec"
+  retval=0
+
+  sshkeytype=`"${TEST_SSH_SSHKEYGEN}" -f "${identity_file}" -y 2>/dev/null`; retval=$?
+  if test $retval -ne 0 ; then
+    echo "${warn}command${norm} ${TEST_SSH_SSHKEYGEN} ${warn}fail${norm}" >&2
+    return $retval
+  fi
+  echo "${sshkeytype}" | cut -d ' ' -f 1
+  return 0
+}
+
+
+# ===
+getSubject () {
+  identity_file="$1"
+#rest of arguments passed to openssl
+
+  if test ! -r "$identity_file"; then
+    error_file_not_readable "${identity_file}" >&2
+    return 1
+  fi
+  shift
+
+  retval=0
+
+#SHELL bug or ?: when we assign command result to "local xxx=..." retval is always zero :-/ !!!
+#unix sh don't like local :-)
+#  local subject=`"${OPENSSL}" x509 -noout -subject -in "${identity_file}" $*`; retval=$?
+#
+  subject=`"$OPENSSL" x509 -noout -subject $OPENSSL_NAMEOPT -in "$identity_file" $* 2>/dev/null`; retval=$?
+  if test $retval -ne 0 ; then
+    echo "${warn}cannot get certificate subject${norm}" >&2
+    return $retval
+  fi
+
+#on some ksh versions output is broken if utf8 string contain parenthesis.
+#ksh 2007-03-28 fail. good versions are 2010-06-21 and 2011-02-08.
+  echo "$subject" | cut -d '=' -f 2-
+}
+
+
+#===
+creX509AuthorizedKeysFile () {
+  identity_file="$1"
+
+  sshkeytype=`getSSHkeyType "${identity_file}"` || return $?
+  subject=`getSubject "${identity_file}"` || return $?
+  echo "${sshkeytype} subject ${subject}" > "${AUTHORIZEDKEYSFILE}"
+}
+
+
+# ===
+utf8base64() {
+  if test -n "${SSH_DN_UTF8_FLAG}"; then
+    printf ':'
+    printf "$1" | ${OPENSSL} enc -a -e | xargs printf ' %s\n'
+  else
+    printf " $1"
+  fi
+}
+
+
+# ===
+FUNCTIONS_INCLUDED="yes"
diff -ruN openssh-7.5p1/tests/CA/Makefile.in openssh-7.5p1+x509-10.2/tests/CA/Makefile.in
--- openssh-7.5p1/tests/CA/Makefile.in	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/Makefile.in	2016-08-02 09:04:34.000000000 +0300
@@ -0,0 +1,262 @@
+SHELL=@SHELL@
+srcdir=@srcdir@
+@OCSP_ON@SSH_OCSP=yes
+@OCSP_OFF@SSH_OCSP=no
+RSAKEYBITS=2048
+
+
+all:
+
+
+clean: ldap_clean
+	-rm -f testhostkey_*
+	-rm -f testid_*
+	-rm -f selfid_*
+	-rm -f testocsp_*
+	-rm -fr ca-test/
+	-rm -f ca-?.log
+	-rm -f ca-3.*.log
+	-rm -f va-*.log
+	-rm -f sshd_x509.log
+
+distclean: clean
+	-rm -f env
+	-rm -f Makefile
+
+# ===
+
+check-certs: ca_files hostkeys identities selfidentities ocsp_certs crl_files ldap_files
+	@echo
+	$(SHELL) $(srcdir)/ssh_x509tests.sh
+
+# ===
+ca_files: ca-test/catest.config ca-test/catest-bundle.crt
+
+#user is responsible to recreate X.509 tests files !!!
+#ca-test/catest.config: $(srcdir)/config
+ca-test/catest.config:
+	@echo
+	SSH_OCSP=$(SSH_OCSP) \
+	$(SHELL) $(srcdir)/1-cre_cadb.sh
+
+ca-test/catest-bundle.crt: ca-test/catest.config
+	@echo
+	$(SHELL) $(srcdir)/2-cre_cakeys.sh
+
+# ===
+#some versions of ksh fail to expand ${1+"$@"} if last argument is
+#empty string. so use ... -N "" -f $@ instead ... -f $@ -N ""
+
+
+hostkeys: testhostkey_rsa.certstamp testhostkey_dsa.certstamp
+
+testhostkey_rsa:
+	@echo
+	@echo "generating RSA 'hostkey'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t rsa -b $(RSAKEYBITS) -N "" -f $@
+
+testhostkey_rsa.certstamp: testhostkey_rsa ca-test/catest-bundle.crt
+	@echo
+	@echo "generating RSA server certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_rsa -t server -n "localhost RSA"
+
+testhostkey_dsa:
+	@echo
+	@echo "generating DSA 'hostkey'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t dsa -N "" -f $@
+
+testhostkey_dsa.certstamp: testhostkey_dsa ca-test/catest-bundle.crt
+	@echo
+	@echo "generating DSA server certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_dsa -t server -n "localhost DSA"
+
+@COMMENT_OUT_ECC256@hostkeys: testhostkey_eccnistp256.certstamp
+@COMMENT_OUT_ECC384@hostkeys: testhostkey_eccnistp384.certstamp
+@COMMENT_OUT_ECC521@hostkeys: testhostkey_eccnistp521.certstamp
+
+testhostkey_eccnistp256:
+	@echo
+	@echo "generating ECDSA(nistp256) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 256 -N "" -f $@
+
+testhostkey_eccnistp256.certstamp: testhostkey_eccnistp256 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp256) server certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_eccnistp256 -t server -n "localhost ECDSA(nistp256)"
+
+testhostkey_eccnistp384:
+	@echo
+	@echo "generating ECDSA(nistp384) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 384 -N "" -f $@
+
+testhostkey_eccnistp384.certstamp: testhostkey_eccnistp384 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp384) server certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_eccnistp384 -t server -n "localhost ECDSA(nistp384)"
+
+testhostkey_eccnistp521:
+	@echo
+	@echo "generating ECDSA(nistp521) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 521 -N "" -f $@
+
+testhostkey_eccnistp521.certstamp: testhostkey_eccnistp521 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp521) server certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_eccnistp521 -t server -n "localhost ECDSA(nistp521)"
+
+
+# ===
+identities: testid_rsa.certstamp testid_dsa.certstamp
+
+testid_rsa:
+	@echo
+	@echo "generating RSA 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t rsa -b $(RSAKEYBITS) -N "" -f $@
+
+testid_rsa.certstamp: testid_rsa ca-test/catest-bundle.crt
+	@echo
+	@echo "generating RSA client certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testid_rsa -t client -n "SSH RSA test certificate"
+
+testid_dsa:
+	@echo
+	@echo "generating DSA 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t dsa -N "" -f $@
+
+testid_dsa.certstamp: testid_dsa ca-test/catest-bundle.crt
+	@echo
+	@echo "generating DSA client certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testid_dsa -t client -n "SSH DSA test certificate"
+
+@COMMENT_OUT_ECC256@identities: testid_eccnistp256.certstamp
+@COMMENT_OUT_ECC384@identities: testid_eccnistp384.certstamp
+@COMMENT_OUT_ECC521@identities: testid_eccnistp521.certstamp
+
+testid_eccnistp256:
+	@echo
+	@echo "generating ECDSA(nistp256) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 256 -N "" -f $@
+
+testid_eccnistp256.certstamp: testid_eccnistp256 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp256) client certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testid_eccnistp256 -t client -n "SSH ECDSA(nistp256) test certificate"
+
+testid_eccnistp384:
+	@echo
+	@echo "generating ECDSA(nistp384) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 384 -N "" -f $@
+
+testid_eccnistp384.certstamp: testid_eccnistp384 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp384) client certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testid_eccnistp384 -t client -n "SSH ECDSA(nistp384) test certificate"
+
+testid_eccnistp521:
+	@echo
+	@echo "generating ECDSA(nistp521) 'Identity'"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 521 -N "" -f $@
+
+testid_eccnistp521.certstamp: testid_eccnistp521 ca-test/catest-bundle.crt
+	@echo
+	@echo "generating ECDSA(nistp521) client certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f testid_eccnistp521 -t client -n "SSH ECDSA(nistp521) test certificate"
+
+
+# ===
+selfidentities: selfid_rsa.certstamp selfid_dsa.certstamp
+
+selfid_rsa.certstamp: selfid_rsa
+	@echo
+	@echo "generating RSA client self-signed certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f selfid_rsa -t self -n "SSH RSA test self-signed certificate"
+
+selfid_rsa:
+	@echo
+	@echo "generating RSA 'Identity' for self-signed"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t rsa -b $(RSAKEYBITS) -N "" -f $@
+
+selfid_dsa.certstamp: selfid_dsa
+	@echo
+	@echo "generating DSA client self-signed certificates, keys, etc."
+	$(SHELL) $(srcdir)/3-cre_certs.sh -f selfid_dsa -t self -n "SSH DSA test self-signed certificate"
+
+selfid_dsa:
+	@echo
+	@echo "generating DSA 'Identity' for self-signed"
+	$(SHELL) $(srcdir)/2-cre_key.sh -t dsa -N "" -f $@
+
+
+# ===
+@OCSP_OFF@ocsp_certs:
+@OCSP_ON@ocsp_certs: testocsp_rsa.certstamp testocsp_dsa.certstamp
+
+@OCSP_ON@testocsp_rsa.certstamp: testocsp_rsa ca-test/catest-bundle.crt
+@OCSP_ON@	@echo; echo "generating RSA ocsp responder certificates."
+@OCSP_ON@	SSH_OCSP=$(SSH_OCSP) \
+@OCSP_ON@	$(SHELL) $(srcdir)/3-cre_certs.sh -f testocsp_rsa -t ocsp -n "validator RSA"
+
+@OCSP_ON@testocsp_rsa:
+@OCSP_ON@	@echo; echo "generating RSA 'ocspkey'"
+@OCSP_ON@	$(SHELL) $(srcdir)/2-cre_key.sh -t rsa -b $(RSAKEYBITS) -N "" -f $@
+
+@OCSP_ON@testocsp_dsa.certstamp: testocsp_dsa ca-test/catest-bundle.crt
+@OCSP_ON@	@echo; echo "generating DSA ocsp responder certificates."
+@OCSP_ON@	SSH_OCSP=$(SSH_OCSP) \
+@OCSP_ON@	$(SHELL) $(srcdir)/3-cre_certs.sh -f testocsp_dsa -t ocsp -n "validator DSA"
+
+@OCSP_ON@testocsp_dsa:
+@OCSP_ON@	@echo; echo "generating DSA 'ocspkey'"
+@OCSP_ON@	$(SHELL) $(srcdir)/2-cre_key.sh -t dsa -N "" -f $@
+
+@OCSP_ON@@COMMENT_OUT_ECC256@ocsp_certs: testocsp_eccnistp256.certstamp
+@OCSP_ON@@COMMENT_OUT_ECC384@ocsp_certs: testocsp_eccnistp384.certstamp
+@OCSP_ON@@COMMENT_OUT_ECC521@ocsp_certs: testocsp_eccnistp521.certstamp
+
+@OCSP_ON@testocsp_eccnistp256.certstamp: testocsp_eccnistp256 ca-test/catest-bundle.crt
+@OCSP_ON@	@echo; echo "generating RSA ocsp responder certificates."
+@OCSP_ON@	SSH_OCSP=$(SSH_OCSP) \
+@OCSP_ON@	$(SHELL) $(srcdir)/3-cre_certs.sh -f testocsp_eccnistp256 -t ocsp -n "validator ECDSA(nistp256)"
+
+@OCSP_ON@testocsp_eccnistp256:
+@OCSP_ON@	@echo; echo "generating ECDSA(nistp256) 'ocspkey'"
+@OCSP_ON@	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 256 -N "" -f $@
+
+@OCSP_ON@testocsp_eccnistp384.certstamp: testocsp_eccnistp384 ca-test/catest-bundle.crt
+@OCSP_ON@	@echo; echo "generating RSA ocsp responder certificates."
+@OCSP_ON@	SSH_OCSP=$(SSH_OCSP) \
+@OCSP_ON@	$(SHELL) $(srcdir)/3-cre_certs.sh -f testocsp_eccnistp384 -t ocsp -n "validator ECDSA(nistp384)"
+
+@OCSP_ON@testocsp_eccnistp384:
+@OCSP_ON@	@echo; echo "generating ECDSA(nistp384) 'ocspkey'"
+@OCSP_ON@	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 384 -N "" -f $@
+
+@OCSP_ON@testocsp_eccnistp521.certstamp: testocsp_eccnistp521 ca-test/catest-bundle.crt
+@OCSP_ON@	@echo; echo "generating RSA ocsp responder certificates."
+@OCSP_ON@	SSH_OCSP=$(SSH_OCSP) \
+@OCSP_ON@	$(SHELL) $(srcdir)/3-cre_certs.sh -f testocsp_eccnistp521 -t ocsp -n "validator ECDSA(nistp521)"
+
+@OCSP_ON@testocsp_eccnistp521:
+@OCSP_ON@	@echo; echo "generating ECDSA(nistp521) 'ocspkey'"
+@OCSP_ON@	$(SHELL) $(srcdir)/2-cre_key.sh -t ecdsa -b 521 -N "" -f $@
+
+
+# ===
+crl_files: ca-test/catest-bundle.crl
+
+ca-test/catest-bundle.crl: testid_rsa-rsa_sha1 testid_dsa-rsa_sha1
+	@echo
+	$(SHELL) $(srcdir)/4-cre_crls.sh
+
+# ===
+@LDAP_OFF@ldap_files:
+@LDAP_ON@ldap_files: ldap/slapd.conf.tmpl
+
+@LDAP_ON@ldap/slapd.conf.tmpl: env
+@LDAP_ON@	@echo
+@LDAP_ON@	$(SHELL) $(srcdir)/5-cre_ldap.sh
+
+@LDAP_OFF@ldap_clean:
+@LDAP_ON@ldap_clean:
+@LDAP_ON@	-rm -f ldap_setup.log
+@LDAP_ON@	-rm -fr ldap
diff -ruN openssh-7.5p1/tests/CA/shell.rc openssh-7.5p1+x509-10.2/tests/CA/shell.rc
--- openssh-7.5p1/tests/CA/shell.rc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/shell.rc	2012-05-17 00:50:00.000000000 +0300
@@ -0,0 +1,41 @@
+# Copyright (c) 2003-2006,2012 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Shell settings.
+#
+
+
+# Be more Bourne compatible (as autoconf do it)
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+  esac
+fi
diff -ruN openssh-7.5p1/tests/CA/ssh_x509tests.sh openssh-7.5p1+x509-10.2/tests/CA/ssh_x509tests.sh
--- openssh-7.5p1/tests/CA/ssh_x509tests.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/ssh_x509tests.sh	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,412 @@
+#! /bin/sh
+# Copyright (c) 2002-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client and server with x509 certificates.
+#
+
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/ssh_x509tests.sh//'`
+. "${SCRIPTDIR}shell.rc"
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+test "x$TEST_SSH_SSH"       = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSH${norm}"      ; exit 1; }
+test "x$TEST_SSH_SSHD"      = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHD${norm}"     ; exit 1; }
+test "x$TEST_SSH_SSHAGENT"  = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHAGENT${norm}" ; exit 1; }
+test "x$TEST_SSH_SSHADD"    = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHADD${norm}"   ; exit 1; }
+test "x$TEST_SSH_SSHKEYGEN" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHKEYGEN${norm}"; exit 1; }
+#TEST_SSH_SSHKEYSCAN
+#TEST_SSH_SFTP
+#TEST_SSH_SFTPSERVER
+
+cat <<EOF
+ssh commands:
+	ssh		$TEST_SSH_SSH
+	sshd		$TEST_SSH_SSHD
+	ssh-agent	$TEST_SSH_SSHAGENT
+	ssh-add		$TEST_SSH_SSHADD
+	ssh-keygen	$TEST_SSH_SSHKEYGEN
+EOF
+
+# prevent user environment influence
+unset SSH_AGENT_PID || :
+unset SSH_AUTH_SOCK || :
+
+# regression test files
+SSHD_LOG="${CWD}/sshd_x509.log"
+SSHD_PID="${CWD}/.sshd_x509.pid"
+SSHD_CFG="${CWD}/sshd_config-certTests"
+SSH_CFG="${CWD}/ssh_config-certTests"
+
+SSH_ERRLOG="${CWD}/.ssh_x509.err.log"
+SSH_REPLY="${CWD}/.ssh_x509.reply"
+SSH_EXTRA_OPTIONS=""
+
+
+TEST_SSH_CLIENTKEYS="\
+  testid_rsa
+  testid_dsa
+"
+
+SSH_ALGS_X509_RSA=
+SSH_ALGS_X509_DSA=
+# some vendor specific openssl libraries does not support nistp521
+SSH_EC_CURVES=
+SSH_EC_ALGS_PLAIN=
+SSH_ALGS_X509_EC=
+
+for a in `$TEST_SSH_SSH -Q key` ; do
+  case $a in
+  x509v3-*-rsa)
+    SSH_ALGS_X509_RSA="$SSH_ALGS_X509_RSA $a"
+    ;;
+  x509v3-*-dss)
+    SSH_ALGS_X509_DSA="$SSH_ALGS_X509_DSA $a"
+    ;;
+  x509v3-ecdsa-sha2-*)
+    curve=`echo $a | sed 's/x509v3-ecdsa-sha2-//'`
+    case $curve in
+    nistp256);;
+    nistp384);;
+    nistp521);;
+    *)
+      # makefile create keys only for curves above
+      echo "${warn}test does not support curve ${attn}${curve}${norm}" >&2
+      continue
+      ;;
+    esac
+    SSH_EC_CURVES="$SSH_EC_CURVES $curve"
+    TEST_SSH_CLIENTKEYS="$TEST_SSH_CLIENTKEYS testid_ecc$curve"
+    SSH_EC_ALGS_PLAIN="$SSH_EC_ALGS_PLAIN `echo $a | sed 's/x509v3-//'`"
+    SSH_ALGS_X509_EC="$SSH_ALGS_X509_EC $a"
+    ;;
+  esac
+done
+
+
+# OpenSSL OCSP limitation: only rsa keys for versions before 1.x
+TEST_OCSP_RESPKEYS="\
+  testocsp_rsa \
+  testocsp_dsa \
+"
+for curve in $SSH_EC_CURVES ; do
+    TEST_OCSP_RESPKEYS="$TEST_OCSP_RESPKEYS testocsp_ecc$curve"
+done
+
+# OCSP tests are slow as OpenSSL OCSP sample responder does not reuse
+# socked address. So each test has to wait timeout to expire ~ 60 sec.
+# Lets use only rsa for now.
+TEST_OCSP_RESPKEYS="testocsp_rsa"
+
+#TEST_SSHD_HOSTKEY="$CWD/testhostkey_rsa-rsa_sha1"
+TEST_SSHD_HOSTKEY="$CWD/testhostkey_rsa"
+
+
+USERDIR="${HOME}/.ssh"
+if test ! -d "${USERDIR}"; then
+  mkdir "${USERDIR}" || exit 1
+  chmod 700 "${USERDIR}" || exit 1
+fi
+
+AUTHORIZEDKEYSFILE="${USERDIR}/authorized_keys-certTests"
+USERKNOWNHOSTSFILE="${USERDIR}/known_hosts-certTests"
+
+
+# ===
+# remove unsupported tests
+
+cat > "$SSHD_CFG" <<EOF
+CACertificateFile /file/not/found
+CAldapURL ${LDAPD_URL}
+VAType none
+EOF
+
+"$TEST_SSH_SSHD" -t -f "${SSHD_CFG}" > "${SSHD_LOG}" 2>&1
+if grep 'Unsupported.*CAldapURL' "${SSHD_LOG}" > /dev/null; then
+  SSH_LDAP_ENABLED="no"
+else
+  SSH_LDAP_ENABLED="yes"
+fi
+if grep 'Unsupported.*VAType' "${SSHD_LOG}" > /dev/null; then
+  SSH_OCSP_ENABLED="no"
+else
+  SSH_OCSP_ENABLED="yes"
+fi
+
+echo SSH_LDAP_ENABLED=${SSH_LDAP_ENABLED}
+if test "x${SSH_LDAP_ENABLED}" = "xno"; then
+  SSH_X509TESTS=`echo "${SSH_X509TESTS}" | sed -e 's|by_ldap||g'`
+fi
+echo SSH_OCSP_ENABLED=${SSH_OCSP_ENABLED}
+if test "x${SSH_OCSP_ENABLED}" = "xno"; then
+  SSH_X509TESTS=`echo "${SSH_X509TESTS}" | sed -e 's|ocsp||g'`
+fi
+echo SSH_X509TESTS=$SSH_X509TESTS
+
+
+# ===
+runSSHdaemon() {
+  echo "=======================================================================" >> "${SSHD_LOG}"
+
+  if test -f "${SSHD_PID}"; then
+    echo "${warn}sshd pid file exist!${norm}" >&2
+  fi
+
+  #NOTES:
+  #- without -d option sshd run in daemon mode and this command always return 0 !!!
+  #- bug or ?: with option -e no log to stderr in daemon mode
+  $SUDO "$TEST_SSH_SSHD" -f "${SSHD_CFG}" \
+    -o PidFile="${SSHD_PID}" \
+    -o SyslogFacility="${SSHSERVER_SYSLOGFACILITY}" \
+    -o LogLevel="${SSHSERVER_LOGLEVEL}" \
+  >> "${SSHD_LOG}" 2>&1
+
+  sleep 3
+  if test ! -f "${SSHD_PID}"; then
+    printf "${warn}cannot start sshd:${norm} " >&2
+    error_file_not_readable "${SSHD_PID}"
+    return 33
+  fi
+}
+
+
+# ===
+killSSHdaemon() {
+(
+  $SUDO kill `$SUDO cat "$SSHD_PID" 2>/dev/null` > /dev/null 2>&1
+  K=0
+  while test $K -le 9; do
+    if test ! -f "${SSHD_PID}"; then
+      break
+    fi
+    sleep 1
+    K=`expr $K + 1`
+  done
+  rm -f "${SSHD_CFG}"
+  if test -f "${SSHD_PID}"; then
+    $SUDO kill -9 `$SUDO cat "$SSHD_PID" 2>/dev/null` > /dev/null 2>&1
+    sleep 1
+    $SUDO rm -f "${SSHD_PID}" > /dev/null 2>&1
+  fi
+  exit 0
+)
+}
+
+
+# ===
+testEND() {
+  ( echo
+    echo "*=- The END -=*"
+  ) >> "${SSHD_LOG}"
+
+  rm -f "${SSH_ERRLOG}"
+  rm -f "${SSH_REPLY}"
+  rm -f "${AUTHORIZEDKEYSFILE}"
+  rm -f "${USERKNOWNHOSTSFILE}"
+  rm -f "${SSH_CFG}"
+}
+
+testBREAK() {
+  ( echo
+    echo "*=- BREAK -=*"
+  ) >> "${SSHD_LOG}"
+  killSSHdaemon
+}
+
+trap testBREAK INT QUIT ABRT KILL TERM || exit 1
+trap testEND EXIT || exit 1
+
+
+# ===
+creTestSSHDcfgFile() {
+  cat > "${SSHD_CFG}" <<EOF
+Port ${SSHD_PORT}
+Protocol 2
+ListenAddress ${SSHD_LISTENADDRESS}
+AuthorizedKeysFile ${AUTHORIZEDKEYSFILE}
+ChallengeResponseAuthentication no
+HostbasedAuthentication no
+#!NO(linux):KerberosAuthentication no
+#!NO(linux):KerberosOrLocalPasswd no
+#!NO(OpenBSD):PAMAuthenticationViaKbdInt no
+StrictModes no
+PasswordAuthentication no
+PubkeyAuthentication yes
+#deprecated#RhostsAuthentication no
+RhostsRSAAuthentication no
+RSAAuthentication no
+
+UsePrivilegeSeparation ${SSHSERVER_USEPRIVILEGESEPARATION}
+
+HostKey ${TEST_SSHD_HOSTKEY}
+
+#AllowedCertPurpose sslclient
+EOF
+}
+
+creTestSSHcfgFile() {
+  cat > "${SSH_CFG}" <<EOF
+Host *
+Port ${SSHD_PORT}
+PreferredAuthentications publickey
+Protocol 2
+StrictHostKeyChecking yes
+UserKnownHostsFile ${USERKNOWNHOSTSFILE}
+
+#AllowedCertPurpose sslserver
+$TEST_CLIENT_CFG
+
+CACertificatePath /path/not/found/global
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+UserCACertificatePath /path/not/found/user
+UserCACertificateFile /file/not/found/user
+
+CARevocationPath  /crlpath/not/found/global
+CARevocationFile  /crlfile/not/found/global
+UserCARevocationPath  /crlpath/not/found/user
+UserCARevocationFile  /crlfile/not/found/user
+EOF
+}
+
+
+# ===
+#args:
+#  $1 - type
+#  $2 - identity_file or empty
+#  $3 - info
+#  $4 - request to fail flag
+#  $5 - optional error text to search for if fail
+runTest () {
+(
+  printf '%s' "  * ${extd}${1}${norm} ${3}"
+
+  msg="A X.509 CertIficaTe TeSt-${1}"
+
+  sshopts=""
+  #sshopts="${sshopts} -v -v -v"
+  test -n "$2" && sshopts="${sshopts} -i $2"
+  #assignment to variable "identity_file" crash ksh :-(
+  #identity_file="value_without_significance"
+
+  case $4 in
+    Y|y|Yes|yes|YES|1)
+      must_fail=1;;
+    *)
+      must_fail=0;;
+  esac
+  if test -n "$5"; then
+    must_fail_err_txt="$5"
+  else
+    must_fail_err_txt='Permission denied (publickey)'
+  fi
+
+  creTestSSHcfgFile || exit $?
+
+  "$TEST_SSH_SSH" -F "${SSH_CFG}" ${sshopts} \
+    ${SSH_EXTRA_OPTIONS} \
+    ${SSHD_LISTENADDRESS} "echo \"${msg}\"" \
+    2> "${SSH_ERRLOG}" > "${SSH_REPLY}"; retval=$?
+
+  if test "x$must_fail" = "x1"; then
+    if test $retval -ne 0; then
+      retval=0
+    else
+      retval=1
+    fi
+  fi
+
+  show_status $retval
+  if test $retval -ne 0; then
+    printf '%s' "${warn}"
+    cat "${SSH_ERRLOG}"; printf '%s' "${norm}"
+  else
+    if test "x$must_fail" = "x1"; then
+      if fgrep "$must_fail_err_txt" "$SSH_ERRLOG" > /dev/null; then
+        printf '%s' "${done}"
+      else
+        retval=33
+        printf '%s' "${warn}"
+      fi
+      cat "${SSH_ERRLOG}"; printf '%s' "${norm}"
+    else
+      if fgrep "$msg" "${SSH_REPLY}" > /dev/null; then
+        :
+      else
+        retval=33
+        printf '%s' "${warn}"
+        cat "${SSH_REPLY}"; printf '%s' "${norm}"
+      fi
+    fi
+  fi
+
+  exit $retval
+)
+}
+
+
+# ===
+do_all () {
+  create_empty_file "${AUTHORIZEDKEYSFILE}" &&
+  chmod 644 "${AUTHORIZEDKEYSFILE}" || return $?
+
+  create_empty_file "${SSHD_LOG}" || return $?
+
+  if test ! -f "${TEST_SSHD_HOSTKEY}.pub"; then
+    echo "${warn}Public host file ${attn}${TEST_SSHD_HOSTKEY}.pub${warn} not found !${norm}"
+    return 3
+  fi
+  ( printf '%s' "${SSHD_LISTENADDRESS} "
+    cat "${TEST_SSHD_HOSTKEY}.pub"
+  ) > "${USERKNOWNHOSTSFILE}" &&
+  chmod 644 "${USERKNOWNHOSTSFILE}" || return $?
+
+  # call the test scripts
+  for LTEST in ${SSH_X509TESTS}; do
+  (
+    echo
+    echo "using: ${attn}${SCRIPTDIR}test-${LTEST}.sh.inc${norm}"
+    . ${SCRIPTDIR}test-${LTEST}.sh.inc &&
+    do_test
+  ) || return $?
+  done
+
+  printSeparator
+  return 0
+}
+
+
+# ===
+echo
+printSeparator
+echo "${extd}Testing client and server with X.509 certificates:${norm}"
+printSeparator
+
+do_all; retval=$?
+
+echo
+printSeparator
+echo "${extd}Testing client and server with X.509 certificates finished.${norm}"
+show_status $retval "  ${extd}status${norm}:"
+printSeparator
+echo
+
+exit $retval
diff -ruN openssh-7.5p1/tests/CA/test-agent.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-agent.sh.inc
--- openssh-7.5p1/tests/CA/test-agent.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-agent.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,151 @@
+#
+# Copyright (c) 2002-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - add a key to agent;
+#  - list agent keys;
+#  - try to connect with key from agent;
+#  - remove the key from agent.
+#
+
+
+# ===
+#env. vars:
+#  SSH_CLIENTKEY
+#  type
+testAgent () {
+  identity_file="${SSH_CLIENTKEY}-${type}"
+  if test ! -r "${identity_file}"; then
+    error_file_not_readable "${identity_file}"; return $?
+  fi
+
+  (
+    sshkeytype=`getSSHkeyType "$identity_file"` || exit $?
+    subject=`getSubject "$identity_file"` || exit $?
+
+    echo "$sshkeytype Subject: $subject"
+  ) > "${AUTHORIZEDKEYSFILE}" || return $?
+
+(
+killAgent () {
+  "${TEST_SSH_SSHAGENT}" -k > /dev/null
+  sleep 1
+  exit $1
+}
+
+checkEmptyListResponse () {
+  case $1 in
+    1) return 0;;
+    0) killAgent 99;;
+    *) killAgent $1;;
+  esac
+  return 33
+}
+
+showAgentMsg() {
+  show_status $1 "$2"
+  if test $1 -ne 0; then
+    printf '%s' "${warn}"
+    cat "${SSH_ERRLOG}"
+    printf '%s' "${norm}"
+    if test $1 -ne 2; then
+      killAgent $1
+    fi
+    exit $1
+  fi
+
+  if test "x$3" != "x"; then
+    printf '%s' "${done}"
+    cat "$3"
+    printf '%s' "${norm}"
+  fi
+  return 0
+}
+
+  eval `"${TEST_SSH_SSHAGENT}"` > /dev/null
+
+  "${TEST_SSH_SSHADD}" -L >/dev/null; checkEmptyListResponse $?
+
+  "${TEST_SSH_SSHADD}" "${identity_file}" 2> "${SSH_ERRLOG}" > "${SSH_REPLY}"; \
+  showAgentMsg $? "  add identity ${extd}${SSH_CLIENTKEY}-${attn}${type}${norm} to agent ..."
+
+  "${TEST_SSH_SSHADD}" -L 2> "${SSH_ERRLOG}" > "${SSH_REPLY}"; \
+  retval=$?
+  if test $retval -ne 0; then
+    showAgentMsg ${retval}
+  else
+    printf "  ${done}-${norm} "
+    cat "$SSH_REPLY"
+  fi
+
+# TODO
+# Note the current script run ssh with -i option,
+# but ssh check existence of file and when file
+# don't exit it is excluded from list of identity
+# files. When the list is empty ssh will use
+# default file names. To avoid this we will
+# use /dev/null, until method runTest run ssh
+# with -i option
+#!!!    "use-only-key-from-agent" \
+  runTest "${type}" \
+    "/dev/null" \
+    "key from agent ..." ||
+  killAgent $?
+
+  "${TEST_SSH_SSHADD}" -d "${identity_file}".pub \
+    2> "${SSH_ERRLOG}" > "${SSH_REPLY}"; \
+  showAgentMsg $? "  remove identity ${extd}${SSH_CLIENTKEY}-${attn}${type}${norm} from agent ..."
+
+  "${TEST_SSH_SSHADD}" -L > /dev/null; checkEmptyListResponse $?
+
+  killAgent 0
+)
+}
+
+
+# ===
+
+do_test () {
+  retval=0
+  echo "* ${extd}against ${attn}CACertificateFile${norm} and x509 identity from ${attn}agent${norm}:"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+      printSeparator
+      echo "Begin test with base key_file ${attn}${SSH_CLIENTKEY}${norm} ..."
+
+      for type in ${SSH_SIGN_TYPES}; do
+        testAgent || exit $?
+      done
+    done
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-algfmt.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-algfmt.sh.inc
--- openssh-7.5p1/tests/CA/test-algfmt.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-algfmt.sh.inc	2017-03-25 14:36:00.783170550 +0200
@@ -0,0 +1,171 @@
+#
+# Copyright (c) 2011-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and optional x509 certificates;
+#  - "AuthorizedKeysFile" contain certificate BLOB.
+#  - server accept different publickey algorithms based on certificates.
+#  - client use different digest algorithms.
+#  - test is not applicable for ecdsa
+# Note that "Host-Based Authentication" we cannot test without to install.
+#
+
+
+# ===
+#env. vars:
+#  alg
+testAlgFmt () {
+  printSeparator
+
+# NOTE:
+# The default for certificates with RSA key is:
+# - draft-ietf-secsh-transport-NN.txt where NN <= 12:
+#   X509KeyAlgorithm x509v3-sign-rsa,rsa-md5
+#   X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1
+# - rfc6187:
+#   X509KeyAlgorithm x509v3-ssh-rsa,sha1,ssh-rsa
+# The default for certificates with DSA key is:
+# - draft-ietf-secsh-transport-NN.txt where NN <= 12:
+#   X509KeyAlgorithm x509v3-sign-dss,dss-asn1
+#   X509KeyAlgorithm x509v3-sign-dss,dss-raw
+# - rfc6187:
+#   X509KeyAlgorithm x509v3-ssh-dss,dss-raw,ssh-dss
+# Not applicable for x509v3-ecdsa-sha2-*
+
+  case $alg in
+    x509v3-sign-rsa*) fmt_list="rsa-sha1 rsa-md5";;
+    x509v3-sign-dss*) fmt_list="dss-raw dss-asn1";;
+    x509v3-ssh-rsa*)  fmt_list="rsa-sha1,ssh-rsa";;
+    x509v3-ssh-dss*)  fmt_list="dss-raw,ssh-dss";;
+  esac
+
+  for fmt_srv in $fmt_list; do
+    echo "  - server: only ${attn}${alg}${norm} algorithm with ${attn}${fmt_srv}${norm} digest"
+
+    creTestSSHDcfgFile
+(
+    cat <<EOF
+CACertificateFile $SSH_CAROOT/$CACERTFILE
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+
+PubkeyAlgorithms $alg
+X509KeyAlgorithm $alg,$fmt_srv
+EOF
+    # TODO public key file contain default X.509 algorithm!
+    # To read authorized keys we has to know other algorithms,
+    # so let describe all of them with fake signature.
+    case $alg in
+    x509v3-sign-rsa*) echo "X509KeyAlgorithm x509v3-ssh-rsa,rsa-sha1,fake-ssh-rsa"  ;;
+    x509v3-sign-dss*) echo "X509KeyAlgorithm x509v3-ssh-dss,dss-raw,fake-ssh-dss"   ;;
+    x509v3-ssh-rsa*)  echo "X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1,fake-sign-rsa";;
+    x509v3-ssh-dss*)  echo "X509KeyAlgorithm x509v3-sign-dss,dss-raw,fake-sign-dss" ;;
+    esac
+) >> "$SSHD_CFG"
+    case $fmt_srv in
+      *md5)
+        if test -n "$OPENSSL_FIPS"; then
+          if "$TEST_SSH_SSHD" -f "$SSHD_CFG" -t >> "$SSHD_LOG" 2>&1; then
+            echo "    server in ${attn}FIPS${norm} mode - accept ${attn}$fmt_srv${norm} digest!"
+            return 99
+          else
+            echo "    server in ${attn}FIPS${norm} mode - skipping ..."
+            continue
+          fi
+        fi
+        ;;
+    esac
+
+
+    runSSHdaemon || return $?
+    (
+      for SSH_CLIENTKEY in $TEST_SSH_CLIENTKEYS; do
+        case $SSH_CLIENTKEY in
+          *ecc*) continue;;
+          *rsa) keytype="rsa";;
+          *dsa) keytype="dsa";;
+          *)    echo "${warn}unknown client key type : $SSH_CLIENTKEY${norm}"
+                exit 1;;
+        esac
+        case $alg in
+          x509v3-*-rsa*) test "$keytype" = "rsa" || continue;;
+          x509v3-*-dss*) test "$keytype" = "dsa" || continue;;
+          *)                echo "${warn}unknown X.509 alg${norm}"
+                            exit 1;;
+        esac
+
+        for type in $SSH_SIGN_TYPES; do
+          identity_file="$SSH_CLIENTKEY-$type"
+          "$TEST_SSH_SSHKEYGEN" -f "$identity_file" -y 2>/dev/null > "$AUTHORIZEDKEYSFILE" || exit $?
+
+          for fmt_cln in $fmt_list; do
+            TEST_CLIENT_CFG="\
+X509KeyAlgorithm $alg,$fmt_cln
+"
+            if test $fmt_srv = $fmt_cln; then
+              must_fail=no
+              typemsg="$identity_file $fmt_cln"
+            else
+              must_fail=yes
+              typemsg="$identity_file $fmt_cln ${warn}!${norm}"
+            fi
+            must_fail_err_txt=
+
+            if test -n "$OPENSSL_FIPS"; then
+              case $fmt_cln in
+                *md5)
+                  typemsg="$identity_file $fmt_cln ${warn}FIPS mode!${norm}"
+                  must_fail_err_txt='rsa-md5 in not enabled in FIPS mode'
+                  ;;
+              esac
+            fi
+
+            runTest "$typemsg" \
+              "$identity_file" "" $must_fail $must_fail_err_txt || exit $?
+          done
+        done
+      done
+    ); retval=$?
+    killSSHdaemon
+
+    test $retval -ne 0 && break
+  done
+
+  return $retval
+}
+
+
+# ===
+
+do_test () {
+  retval=0
+  echo "* ${extd}against ${attn}CACertificateFile${norm} and different digest ${attn}algorithms${norm}:"
+
+  for alg in \
+    $SSH_ALGS_X509_RSA \
+    $SSH_ALGS_X509_DSA \
+  ; do
+    testAlgFmt; retval=$?
+    test $retval -ne 0 && break
+  done
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-alg.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-alg.sh.inc
--- openssh-7.5p1/tests/CA/test-alg.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-alg.sh.inc	2017-03-25 14:36:00.782170554 +0200
@@ -0,0 +1,280 @@
+#
+# Copyright (c) 2004-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and optional x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate BLOB.
+#  - 1) server accept different publickey algorithms.
+#  - 2) client use failback publickey algorithm.
+# Note that "Host-Based Authentication" we can not test without to install.
+#
+
+
+# ===
+#args:
+#  $1 - identity file
+fill_authorized () {
+  # fill with extra host-keys to simulate multiple key-types
+  cat testhostkey_*.pub > "$AUTHORIZEDKEYSFILE"
+
+  "$TEST_SSH_SSHKEYGEN" -f "$1" -y 2>/dev/null >> "$AUTHORIZEDKEYSFILE"
+}
+
+
+# ===
+#env. vars:
+#  alg
+testAlg1 () {
+  printSeparator
+  echo "  - only ${attn}${alg}${norm} algorithm"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+
+# avoid impact of rsa-sha2-* and x509v3-ssh-*
+AcceptedAlgorithms $alg
+PubkeyAlgorithms $alg
+EOF
+
+  runSSHdaemon || return $?
+  (
+
+    for SSH_CLIENTKEY in $TEST_SSH_CLIENTKEYS ; do
+
+      withcert=
+      expr $alg : 'x509v3-' >/dev/null && withcert=yes
+
+      # 'plain' key
+      must_fail=yes
+      if test -z "$withcert" ; then
+        case $SSH_CLIENTKEY in
+        *_rsa)  test $alg = ssh-rsa && must_fail=;;
+        *_dsa)  test $alg = ssh-dss && must_fail=;;
+        *_ecc*) curve=`echo $SSH_CLIENTKEY | sed 's/^.*_ecc//'`
+                test $alg = ecdsa-sha2-$curve && must_fail=;;
+        *)
+          echo "${warn}unknown 'plain' client key type${norm}"
+          exit 1;;
+        esac
+      fi
+
+      identity_file="${SSH_CLIENTKEY}"
+      fill_authorized "$identity_file" || exit $?
+
+      if test -n "$must_fail"; then
+        typemsg="${identity_file} ${warn}!${norm}"
+      else
+        typemsg="${identity_file}"
+      fi
+      runTest "${typemsg}" \
+        "${identity_file}" "" "$must_fail" || exit $?
+
+      # X.509 keys
+      for type in $SSH_SIGN_TYPES ; do
+
+        must_fail=yes
+        if test -n "$withcert" ; then
+          case $SSH_CLIENTKEY in
+          *_rsa*) expr $alg : 'x509v3-.*-rsa' >/dev/null && must_fail=;;
+          *_dsa*) expr $alg : 'x509v3-.*-dss' >/dev/null && must_fail=;;
+          *_ecc*) curve=`echo $SSH_CLIENTKEY | sed 's/^.*_ecc//'`
+                  test $alg = x509v3-ecdsa-sha2-$curve && must_fail=;;
+          *)
+            echo "${warn}unknown 'x.509' client key type${norm}"
+            exit 1;;
+          esac
+        fi
+
+        identity_file="${SSH_CLIENTKEY}-${type}"
+        fill_authorized "$identity_file" || exit $?
+
+        if test -n "$must_fail"; then
+          typemsg="${identity_file} ${warn}!${norm}"
+        else
+          typemsg="${identity_file}"
+        fi
+        runTest "${typemsg}" \
+          "${identity_file}" "" "$must_fail" || exit $?
+      done
+    done
+  ); retval=$?
+  killSSHdaemon
+
+  return $retval
+}
+
+
+# ===
+#env. vars:
+#  alg - only public key based
+testAlg2 () {
+  printSeparator
+  echo "  - client failback to ${attn}${alg}${norm} algorithm"
+
+  # list only public key algorithms for 'plain' keys
+  pkalg="ssh-rsa,ssh-dss"
+  if test -n "$SSH_EC_ALGS_PLAIN" ; then
+    for a in $SSH_EC_ALGS_PLAIN ; do
+      pkalg="$pkalg,$a"
+    done
+  fi
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile /file/not/found
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+PubkeyAlgorithms $pkalg
+EOF
+
+  runSSHdaemon || return $?
+  (
+    TEST_CLIENT_CFG="\
+PubkeyAlgorithms $alg
+"
+    for SSH_CLIENTKEY in $TEST_SSH_CLIENTKEYS; do
+      must_fail=
+      case $SSH_CLIENTKEY in
+      *_rsa)  test $alg = ssh-rsa || must_fail=yes;;
+      *_dsa)  test $alg = ssh-dss || must_fail=yes;;
+      *_ecc*) curve=`echo $SSH_CLIENTKEY | sed 's/^.*_ecc//'`
+              test $alg = ecdsa-sha2-$curve || must_fail=yes;;
+      *)
+        echo "${warn}unknown client key type${norm}"
+        exit 1;;
+      esac
+
+      identity_file="$SSH_CLIENTKEY"
+      fill_authorized "$identity_file" || exit $?
+
+      for type in $SSH_SIGN_TYPES; do
+        identity_file="$SSH_CLIENTKEY-$type"
+
+        if test -n "$must_fail"; then
+          typemsg="$identity_file ${warn}!${norm}"
+        else
+          typemsg="$identity_file"
+        fi
+
+        runTest "$typemsg" "$identity_file" "" "$must_fail" || exit $?
+      done
+    done
+  ); retval=$?
+  killSSHdaemon
+
+  return $retval
+}
+
+
+# ===
+#env. vars:
+#  alg
+testAlg3 () {
+  printSeparator
+  echo "  - only ${attn}X.509${norm} algorithms"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile $SSH_CAROOT/$CACERTFILE
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+
+PubkeyAlgorithms x509v3-*
+EOF
+
+  runSSHdaemon || return $?
+  (
+
+    for SSH_CLIENTKEY in $TEST_SSH_CLIENTKEYS ; do
+
+      for type in "" $SSH_SIGN_TYPES; do
+
+        if test -z "$type" ; then
+          identity_file="$SSH_CLIENTKEY"
+          withcert=
+          must_fail=yes
+          typemsg="$identity_file ${warn}!${norm} (plain key)"
+        else
+          identity_file="$SSH_CLIENTKEY-$type"
+          withcert=yes
+          must_fail=
+          typemsg="$identity_file"
+        fi
+
+        fill_authorized "$identity_file" || exit $?
+
+        runTest "$typemsg" \
+          "$identity_file" "" "$must_fail" || exit $?
+
+      done
+    done
+  ); retval=$?
+  killSSHdaemon
+
+  return $retval
+}
+
+
+# ===
+
+do_test () {
+  retval=0
+  echo "* ${extd}against ${attn}CACertificateFile${norm} and different publickey ${attn}algorithms${norm}:"
+
+  for alg in \
+    "ssh-rsa" \
+    "ssh-dss" \
+    $SSH_EC_ALGS_PLAIN \
+    $SSH_ALGS_X509_RSA \
+    $SSH_ALGS_X509_DSA \
+    $SSH_ALGS_X509_EC \
+  ; do
+
+    testAlg1; retval=$?
+    if test $retval -ne 0; then
+      return $retval
+    fi
+  done
+
+  for alg in \
+    "ssh-rsa" \
+    "ssh-dss" \
+    $SSH_EC_ALGS_PLAIN \
+  ; do
+    testAlg2; retval=$?
+    if test $retval -ne 0; then
+      return $retval
+    fi
+  done
+
+  testAlg3; retval=$?
+  if test $retval -ne 0; then
+    return $retval
+  fi
+
+  return 0
+}
diff -ruN openssh-7.5p1/tests/CA/test-blob_auth.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-blob_auth.sh.inc
--- openssh-7.5p1/tests/CA/test-blob_auth.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-blob_auth.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,114 @@
+#
+# Copyright (c) 2002-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain encoded either X.509 certificate
+#    or public key.
+#
+
+
+# ===
+#env. vars:
+#  SSH_CLIENTKEY
+#  type
+testX509autorization () {
+  identity_file="$SSH_CLIENTKEY-$type"
+  if test ! -r "$identity_file" ; then
+    error_file_not_readable "$identity_file"; return $?
+  fi
+
+  echo "  using identity file $identity_file"
+
+  "$TEST_SSH_SSHKEYGEN" -f "$identity_file" -y 2>/dev/null > "$AUTHORIZEDKEYSFILE" || return $?
+  runTest "$type" "$identity_file"\
+    "${extd}valid${norm}" || return $?
+
+  blob=`cat "$AUTHORIZEDKEYSFILE"`
+  echo $blob | cut -c 1-50 > "$AUTHORIZEDKEYSFILE"
+  runTest "$type" "$identity_file"\
+    "${warn}invalid${norm}" "Yes" || return $?
+}
+
+
+# ===
+#env. vars:
+#  SSH_CLIENTKEY
+#  type
+testPUBKEYautorization () {
+  base_identity_file="$SSH_CLIENTKEY"
+  if test ! -r "$base_identity_file" ; then
+    error_file_not_readable "$base_identity_file"; return $?
+  fi
+  identity_file="$base_identity_file-$type"
+  if test ! -r "$identity_file" ; then
+    error_file_not_readable "$identity_file"; return $?
+  fi
+
+  echo "  using $base_identity_file to autorize X.509/$type"
+
+  "$TEST_SSH_SSHKEYGEN" -f "$base_identity_file" -y 2>/dev/null > "$AUTHORIZEDKEYSFILE" || return $?
+  runTest "$type" "$identity_file"\
+    "${extd}valid${norm}" || return $?
+
+  blob=`cat "$AUTHORIZEDKEYSFILE"`
+  echo $blob | cut -c 1-50 > "$AUTHORIZEDKEYSFILE"
+  runTest "$type" "$identity_file"\
+    "${warn}invalid${norm}" "Yes" || return $?
+}
+
+
+# ===
+
+do_test () {
+  retval=0
+  echo "* ${extd}with ${attn}CACertificateFile${norm} and"
+  echo "* ${extd}autorization${norm} by encoded ${attn}public identity${norm}:"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile $SSH_CAROOT/$CACERTFILE
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    for SSH_CLIENTKEY in $TEST_SSH_CLIENTKEYS; do
+      printSeparator
+      echo "Begin tests with autorization by encoded ${attn}X.509${norm} certificate ..."
+
+      for type in $SSH_SIGN_TYPES; do
+        testX509autorization || exit $?
+      done
+
+      printSeparator
+      echo "Begin tests with autorization by encoded ${attn}public${norm} key ..."
+      for type in $SSH_SIGN_TYPES; do
+        testPUBKEYautorization || exit $?
+      done
+
+    done
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-by_ldap.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-by_ldap.sh.inc
--- openssh-7.5p1/tests/CA/test-by_ldap.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-by_ldap.sh.inc	2016-02-28 21:01:05.000000000 +0200
@@ -0,0 +1,292 @@
+#
+# Copyright (c) 2004-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate Subject;
+#  - authorization against:
+#    - LDAP, without CRL file and hash-dir
+#
+
+
+LDAP_SETUP_LOG="${CWD}/ldap_setup.log"
+LDAPD_PID="${CWD}/slapd.pid"
+LDAPD_ARGS="${CWD}/slapd.args"
+LDAPD_CFG="${CWD}/slapd.conf"
+
+
+# ===
+#args:
+#  $1 - info. message for valid cert.
+#  $2 - request valid cert. to fail flag
+#  $3 - info. message for revoked cert.
+#  $4 - request revoked cert. to fail flag
+test_all_keys () {
+  for type in ${SSH_SIGN_TYPES}; do
+    for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+      identity_file="${SSH_CLIENTKEY}-${type}"
+      creX509AuthorizedKeysFile "${identity_file}" &&
+      runTest "${identity_file}" \
+        "${identity_file}" "$1" "$2" || return $?
+
+      identity_file="${SSH_CLIENTKEY}-${type}-revoked"
+      creX509AuthorizedKeysFile "${identity_file}" &&
+      runTest "${identity_file}" \
+        "${identity_file}" "$3" "$4" || return $?
+    done
+  done
+  return 0
+}
+
+
+# ===
+creTestLDAPDcfgFile() {
+(
+  cat <<EOF
+include		$CWD/ldap/slapd.conf.tmpl
+
+# dbms backend settings must be in same file !
+# this is required for openldap version 2.3.32(but not for <= 2.3.20,2.2.x,2.1.x)
+database	$SSH_LDAP_DB
+suffix		"$SSH_LDAP_DC"
+rootdn		"cn=Manager,$SSH_LDAP_DC"
+rootpw		secret
+
+directory	$CWD/ldap/data
+index	objectClass	eq
+
+pidfile		$LDAPD_PID
+argsfile	$LDAPD_ARGS
+EOF
+) > ${LDAPD_CFG}
+}
+
+
+# ===
+creTestLDAPDCAldifFile() {
+(
+  for level in 0; do
+    N="$CAKEY_PREFIX"-root${level}.crt
+    if test ! -f "ldap/$N.der"; then
+      $OPENSSL x509 \
+        -in "$SSH_CACERTDIR/$N".pem \
+        -out ldap/"$N".der -outform DER \
+        || exit $?
+    fi
+  done
+
+  for type in ${SSH_SIGN_TYPES}; do
+    N="${CAKEY_PREFIX}-${type}.crt"
+    if test ! -f "ldap/${N}.der"; then
+      ${OPENSSL} x509 \
+        -in "${SSH_CACERTDIR}/${N}".pem \
+        -out "ldap/${N}.der" -outform DER \
+        || exit $?
+    fi
+
+    N="${CAKEY_PREFIX}-${type}.crl"
+    if test ! -f "ldap/${N}.der"; then
+      ${OPENSSL} crl \
+        -in "${SSH_CACRLDIR}/${N}".pem \
+        -out "ldap/${N}.der" -outform DER \
+        || exit $?
+    fi
+  done
+) || return $?
+
+(
+  for level in 0; do
+    cat <<EOF
+dn:`utf8base64 "CN=SSH TestCA level $level,OU=$SSH_DN_OU level $level,OU=$SSH_DN_OU,O=$SSH_DN_O,$SSH_LDAP_DC"`
+changetype: add
+objectClass: inetOrgPerson
+objectClass: pkiCA
+cACertificate;binary:< file://$CWD/ldap/catest-root$level.crt.der
+cn: SSH TestCA level 0
+sn: SSH TestCA level 0
+ou:`utf8base64 "$SSH_DN_OU level $level"`
+ou:`utf8base64 "$SSH_DN_OU"`
+o:`utf8base64 "$SSH_DN_O"`
+l:`utf8base64 "$SSH_DN_L"`
+st: $SSH_DN_ST
+
+EOF
+  done
+
+  for type in $SSH_SIGN_TYPES; do
+    cat <<EOF
+dn:`utf8base64 "CN=SSH TestCA $type key,OU=$SSH_DN_OU $type keys,OU=$SSH_DN_OU,O=$SSH_DN_O,$SSH_LDAP_DC"`
+changetype: add
+objectClass: inetOrgPerson
+objectClass: pkiCA
+cACertificate;binary:< file://$CWD/ldap/catest-$type.crt.der
+certificateRevocationList;binary:< file://$CWD/ldap/catest-$type.crl.der
+cn: SSH TestCA $type key
+sn: SSH TestCA $type key
+ou:`utf8base64 "$SSH_DN_OU $type keys"`
+ou:`utf8base64 "$SSH_DN_OU"`
+o:`utf8base64 "$SSH_DN_O"`
+l:`utf8base64 "$SSH_DN_L"`
+st: $SSH_DN_ST
+
+EOF
+  done
+) > ldap/ca.ldif
+}
+
+
+# ===
+runLDAPdaemon() {
+  if test -f "${LDAPD_PID}"; then
+    echo "${warn}slapd pid file exist!${norm}" >&2
+  fi
+
+  printf '  %s' "starting ${extd}LDAP${norm} server on ${attn}${LDAPD_URL}${norm}"
+  #for errors check syslog files(LOCAL4 facility)
+  $SUDO "${LDAP_LIBEXECDIR}/slapd" \
+    -f "${LDAPD_CFG}" \
+    -h "${LDAPD_URL}" \
+  > /dev/null 2>&1
+
+  sleep 2
+  K=0
+  while test $K -le 5; do
+    if test -f "${LDAPD_PID}"; then
+      break
+    fi
+    sleep 1
+    K=`expr $K + 1`
+  done
+
+  test -r "${LDAPD_PID}"; show_status $?
+  if test ! -r "${LDAPD_PID}"; then
+    printf "${warn}cannot start slapd:${norm} " >&2
+    error_file_not_readable "${LDAPD_PID}"
+    return 33
+  fi
+  return 0
+}
+
+
+killLDAPdaemon() {
+(
+  $SUDO kill `cat "${LDAPD_PID}" 2>/dev/null` > /dev/null 2>&1
+  K=0
+  while test $K -le 9; do
+    if test ! -f "${LDAPD_PID}"; then
+      break
+    fi
+    sleep 1
+    K=`expr $K + 1`
+  done
+  if test -f "${LDAPD_PID}"; then
+    $SUDO kill -9 `cat "${LDAPD_PID}" 2>/dev/null` > /dev/null 2>&1
+    sleep 1
+    $SUDO rm -f "${LDAPD_PID}" > /dev/null 2>&1
+    $SUDO rm -f "${LDAPD_ARGS}" > /dev/null 2>&1
+  fi
+  rm -f "${LDAPD_CFG}"
+  exit 0
+)
+}
+
+
+initLDAPdb() {
+  create_empty_file "${LDAP_SETUP_LOG}" || return $?
+
+  "${LDAPADD}" \
+    -x -w secret -D "cn=Manager,${SSH_LDAP_DC}" \
+    -H "${LDAPD_URL}" \
+    -f "${CWD}/ldap/base.ldif" \
+  >> "${LDAP_SETUP_LOG}" 2>&1 || return $?
+
+  "${LDAPADD}" \
+    -x -w secret -D "cn=Manager,${SSH_LDAP_DC}" \
+    -H "${LDAPD_URL}" \
+    -f "${CWD}/ldap/ca.ldif" \
+  >> "${LDAP_SETUP_LOG}" 2>&1 || return $?
+
+  return 0
+}
+
+
+# ===
+# $1 - LDAP version
+testLDAP() {
+  printSeparator
+  echo "Begin test with LDAP ${extd}version${norm} ${attn}$1${norm}"
+
+  creTestLDAPDcfgFile
+  creTestLDAPDCAldifFile
+  creTestSSHDcfgFile
+
+#openssh config parser limitation
+SSH_CONF_LDAP_DC=`echo ${SSH_LDAP_DC} | sed -e 's|=|%3D|g' -e 's|,|%2C|'`
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile /file/not/found
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+CAldapVersion $1
+CAldapURL ${LDAPD_URL}/${SSH_CONF_LDAP_DC}
+#TODO:MandatoryCRL yes
+EOF
+
+  runSSHdaemon || return $?
+  (
+    rm -f "${CWD}/ldap/data"/*
+    runLDAPdaemon
+    (
+      initLDAPdb || exit $?
+
+      test_all_keys "" "" "${warn}!${norm}" "Yes"
+    ); retval=$?
+    killLDAPdaemon
+    exit ${retval}
+  ); retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+LDAPtestBREAK() {
+  echo
+  killLDAPdaemon
+  testBREAK
+}
+
+trap LDAPtestBREAK INT QUIT ABRT KILL TERM || exit 1
+
+
+# ===
+
+do_test () {
+  if test "x${SSH_LDAP_ENABLED}" = "xno"; then
+    echo "* ${extd}LDAP${norm} is ${attn}disabled${norm}"
+    return 1
+  fi
+  echo "* ${extd}against ${attn}CALdapUrl${norm}:"
+
+  testLDAP 2 &&
+  testLDAP 3
+}
diff -ruN openssh-7.5p1/tests/CA/test-crl.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-crl.sh.inc
--- openssh-7.5p1/tests/CA/test-crl.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-crl.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,262 @@
+#
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate Subject;
+#  - authorization against:
+#    - without CRL file and hash-dir
+#    - only with CRL file(CARevocationFile)
+#    - only with CRL hash-dir(CARevocationPath)
+#    - only one CRL file in a hash-dir
+#
+
+
+# ===
+#args:
+#  $1 - info. message for valid cert.
+#  $2 - request valid cert. to fail flag
+#  $3 - info. message for revoked cert.
+#  $4 - request revoked cert. to fail flag
+test_all_keys () {
+  for type in ${SSH_SIGN_TYPES}; do
+    for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+      identity_file="${SSH_CLIENTKEY}-${type}"
+      creX509AuthorizedKeysFile "${identity_file}" &&
+      runTest "${identity_file}" \
+        "${identity_file}" "$1" "$2" || return $?
+
+      identity_file="${SSH_CLIENTKEY}-${type}-revoked"
+      creX509AuthorizedKeysFile "${identity_file}" &&
+      runTest "${identity_file}" \
+        "${identity_file}" "$3" "$4" || return $?
+    done
+  done
+  return 0
+}
+
+
+# ===
+test_nocrl () {
+  printSeparator
+  echo "Begin test ${extd}without${norm} CRL ${attn}file${norm} and ${attn}hash-dir${norm} ..."
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+    test_all_keys "" "" "" ""; retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+test_crlfile () {
+  printSeparator
+  echo "Begin test with CRL ${extd}file(${attn}CARevocationFile${norm}) ..."
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  ${SSH_CAROOT}/${CACRLFILE}
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+    test_all_keys "" "" "${warn}!${norm}" "Yes"; retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+test_crldir () {
+  printSeparator
+  echo "Begin test with CRL ${extd}hash-dir(${attn}CARevocationPath${norm}) ..."
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  ${SSH_CACRLDIR}
+EOF
+
+  runSSHdaemon || return $?
+    test_all_keys "" "" "${warn}!${norm}" "Yes"; retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+#env. vars:
+#  crltype - crl for signature type
+test_crlbytype () {
+  retval=0
+
+  echo "  - ${extd}with ${attn}${crltype}${norm} only in ${attn}CARevocationPath${norm} ..."
+
+  printf "  creating ${attn}${crltype}${norm} crlfile in hash dir"
+  #printf "${warn}"
+    rm -f "${CRL_TEST_DIR}"/* 2> /dev/null
+    FILE="${SSH_CACRLDIR}/${CAKEY_PREFIX}-${crltype}.crl.pem"
+    HASH=`${OPENSSL} crl -out /dev/null -in "${FILE}" -hash`; retval=$?
+    if test ${retval} -eq 0; then
+      hashfile="${CRL_TEST_DIR}/${HASH}.r0"
+      ln -s "${FILE}" "${hashfile}"
+      #link might never fail :-(
+      test -h "${hashfile}"; retval=$?
+    fi
+  #printf "${norm}"
+  show_status ${retval} || return $?
+
+  (
+    for type in ${SSH_SIGN_TYPES}; do
+      for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+        identity_file="${SSH_CLIENTKEY}-${type}-revoked"
+
+        creX509AuthorizedKeysFile "${identity_file}" || exit $?
+
+        if test "${type}" = "${crltype}"; then
+          runTest "${SSH_CLIENTKEY}-${warn}${type}-revoked${norm}" \
+            "${identity_file}" "" "Yes"
+        else
+          runTest "${identity_file}" \
+            "${identity_file}" "" ""
+        fi || exit $?
+      done
+    done
+    exit 0
+  ); retval=$?
+
+  if test ${retval} -eq 0; then
+    rm -f "${hashfile}"; retval=$?
+  else
+    rm -f "${hashfile}"
+  fi
+  return ${retval}
+}
+
+
+# ===
+test_onlyonecrl () {
+  retval=0
+  CRL_TEST_DIR="${SSH_CAROOT}/crl-test"
+
+  printSeparator
+  echo "Check ${extd}revoked${norm} with only ${attn}one CRL${norm} in ${attn}CARevocationPath${norm} ..."
+
+  mkdir -p "${CRL_TEST_DIR}" || return $?
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  ${CRL_TEST_DIR}
+EOF
+
+
+  runSSHdaemon &&
+  (
+    for crltype in ${SSH_SIGN_TYPES}; do
+      test_crlbytype || exit $?
+    done
+  ); retval=$?
+  killSSHdaemon
+
+  rm -f "${CRL_TEST_DIR}"/* 2> /dev/null
+  if test ${retval} -eq 0; then
+    rmdir "${CRL_TEST_DIR}"; retval=$?
+  else
+    rmdir "${CRL_TEST_DIR}"
+  fi
+  return ${retval}
+}
+
+
+# ===
+test_crlpresence_yes () {
+  printSeparator
+  echo "Begin test with mandatory ${extd}CRL presence ${attn}with${norm} CRL ..."
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  ${SSH_CAROOT}/${CACRLFILE}
+CARevocationPath  /crlpath/not/found
+MandatoryCRL yes
+EOF
+
+  runSSHdaemon || return $?
+    test_all_keys "" "" "${warn}!${norm}" "Yes"; retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+test_crlpresence_no () {
+  printSeparator
+  echo "Begin test with mandatory ${extd}CRL presence ${attn}without${norm} CRL ..."
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+MandatoryCRL yes
+EOF
+
+  runSSHdaemon || return $?
+    test_all_keys "${warn}!${norm}" "Yes" "${warn}!${norm}" "Yes"; retval=$?
+  killSSHdaemon
+
+  return ${retval}
+}
+
+
+# ===
+
+do_test () {
+  echo "* ${extd}against ${attn}CA CRL${norm} file and/or hash-dir:"
+
+  test_nocrl &&
+  test_crlfile &&
+  test_crldir &&
+  test_onlyonecrl &&
+  test_crlpresence_yes &&
+  test_crlpresence_no
+}
diff -ruN openssh-7.5p1/tests/CA/test-dn_auth_file.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-dn_auth_file.sh.inc
--- openssh-7.5p1/tests/CA/test-dn_auth_file.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-dn_auth_file.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate "Distinguished Name"/
+#    "Subject" in varios formats.
+#
+
+
+# ===
+#env. vars:
+#  SSH_CLIENTKEY
+#  type
+testDNautorizations1 () {
+  identity_file="${SSH_CLIENTKEY}-${type}"
+  if test ! -r "$identity_file"; then
+    error_file_not_readable "${identity_file}"; return $?
+  fi
+
+  sshkeytype=`getSSHkeyType "${identity_file}"` || return $?
+  subject=`getSubject "${identity_file}"` || return $?
+
+  for subtype in \
+    "Subject:" \
+    "SuBjecT=" \
+    "sUbjecT" \
+    "diStinguished name:" \
+    "distiNguished-nAme:" \
+    "distinguiShed_naMe:" \
+    "disTinguishednamE:" \
+    "dN:" \
+  ; do
+    echo "${sshkeytype} ${subtype} ${subject}" > "${AUTHORIZEDKEYSFILE}"
+    runTest "${type} ${subtype}" "${identity_file}" "" || return $?
+  done
+
+  subtype="subject"
+  subject=`getSubject "${identity_file}" -nameopt RFC2253 -nameopt -esc_msb` || return $?
+  echo "${sshkeytype} ${subtype} ${subject}" > "${AUTHORIZEDKEYSFILE}"
+  runTest "${type} ${subtype} in ${attn}RFC2253${norm} format" "${identity_file}" "" || return $?
+
+  echo "${sshkeytype} ${subtype} ${subject}" | sed -e 's/,/\//'> "${AUTHORIZEDKEYSFILE}"
+  runTest "${type} ${subtype} and mixed item-separator symbol" "${identity_file}" "" || return $?
+
+  for subtype in \
+    "Invalid" \
+    "Subject-" \
+  ; do
+    echo "${sshkeytype} ${subtype} ${subject}" > "${AUTHORIZEDKEYSFILE}"
+    runTest "${type} ${warn}${subtype}${norm}" "${identity_file}" \
+      "autorization type" "Yes" || return $?
+  done
+
+  subtype="Subject"
+  printf "${sshkeytype} ${subtype}," > "${AUTHORIZEDKEYSFILE}"
+  runTest "${type} ${warn}empty${norm} ${subtype}" "${identity_file}" \
+    "" "Yes" || return $?
+
+  subtype="Subject"
+  ( printf "${sshkeytype} ${subtype}"
+    echo "${subject}" | cut -c -40
+  ) > "${AUTHORIZEDKEYSFILE}"
+  runTest "${type} ${warn}invalid${norm} ${subtype}" "${identity_file}" \
+    "" "Yes" || return $?
+
+  return 0
+}
+
+
+# ===
+
+do_test () {
+  echo "* ${extd}against ${attn}CACertificateFile${norm} and autorization by x509 ${attn}'Distinguished Name'${norm}:"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+      printSeparator
+      echo "Begin test with base key_file ${attn}${SSH_CLIENTKEY}${norm} ..."
+
+      for type in ${SSH_SIGN_TYPES}; do
+        testDNautorizations1 || exit $?
+      done
+    done
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-dn_auth_path.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-dn_auth_path.sh.inc
--- openssh-7.5p1/tests/CA/test-dn_auth_path.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-dn_auth_path.sh.inc	2017-05-20 20:45:28.000000000 +0300
@@ -0,0 +1,141 @@
+#
+# Copyright (c) 2002-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate Subject;
+#  - authorization against exact intermediate CA certificate in
+#    server x509 store (legacy public key algorithm);
+#  - authorization against only root CA certificate in
+#    server x509 store (RFC6187 key algorithms).
+
+
+# ===
+cre_hash_link () {
+  HASH=`$OPENSSL x509 -in "$1" -noout -hash` || return $?
+
+  rm -f "$HASH.0" &&
+  ln -s "$1" "$HASH.0" &&
+  #link might never fail ;-(
+  test -h "$HASH.0"
+}
+
+
+# ===
+#env. vars:
+#  SSH_CLIENTKEY
+#  catype
+#  type
+testDNautorizations2 () {
+  identity_file="${SSH_CLIENTKEY}-${type}"
+
+  creX509AuthorizedKeysFile "${identity_file}" || return $?
+
+  expect_success=:
+  if $SSH_LEGACY_FORMAT ; then
+    test "$type" != "$catype" && expect_success=false
+  fi
+  if $expect_success ; then
+    runTest "${extd}${type}${norm}" \
+      "${identity_file}"\
+      "" ""
+  else
+    runTest "${type}" \
+      "${identity_file}" \
+      "${warn}!${norm}" "Yes"
+  fi
+}
+
+
+# ===
+#env. vars:
+#  catype
+do_test_catype () {
+  echo "  - autorization by x509 ${attn}Subject${norm} against CA key ${attn}${catype}${norm}"
+
+  for type in ${SSH_SIGN_TYPES}; do
+    testDNautorizations2 "${catype}" "${type}" || return $?
+  done
+}
+
+
+# ===
+
+do_test () {
+  echo "* ${extd}against ${attn}CACertificatePath${norm}:"
+
+  CRT_TEST_DIR="${SSH_CAROOT}/crt-test"
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile /file/not/found
+CACertificatePath ${CRT_TEST_DIR}
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+
+  runSSHdaemon || return $?
+  (
+    for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+      printSeparator
+      echo "Begin test with base key_file ${attn}${SSH_CLIENTKEY}${norm} ..."
+
+      #TODO rsa/dsa in RFC6187 format
+      SSH_LEGACY_FORMAT=false
+      case $SSH_CLIENTKEY in
+      testid_ecc*) ;;
+      *) SSH_LEGACY_FORMAT=: ;;
+      esac
+
+      if test ! -d "${CRT_TEST_DIR}"; then
+        mkdir "$CRT_TEST_DIR" || exit $?
+      fi
+      rm -rf "${CRT_TEST_DIR}/"* 2>/dev/null
+
+      for catype in ${SSH_SIGN_TYPES}; do
+        ( cd "$CRT_TEST_DIR" &&
+          rm -f "$CRT_TEST_DIR"/* &&
+          for level in 0; do
+            cre_hash_link "$SSH_CACERTDIR/$CAKEY_PREFIX"-root${level}.crt.pem || exit $?
+          done
+          if $SSH_LEGACY_FORMAT ; then
+            cre_hash_link "$SSH_CACERTDIR/${CAKEY_PREFIX}-${catype}.crt.pem"
+          fi
+        ) &&
+        do_test_catype; retval=$?
+        rm -f "$CRT_TEST_DIR"/*
+        if test $retval -ne 0; then
+          break
+        fi
+      done
+
+      rmdir "${CRT_TEST_DIR}"
+      if test $retval -ne 0; then
+        exit $retval
+      fi
+    done
+
+    exit 0
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-hostalg.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-hostalg.sh.inc
--- openssh-7.5p1/tests/CA/test-hostalg.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-hostalg.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,175 @@
+#
+# Copyright (c) 2012-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and optional X.509 certificate;
+#  - "AuthorizedKeysFile" contain encoded client public key;
+#  - user "KnownHostsFile" contain records for each host key;
+#  - client accept certain hostkey algorithm.
+#
+
+
+USERKNOWNHOSTSFILE="$USERDIR/known_hosts-HostsTests"
+for RSA_DGST in $SSH_SIGN_TYPES; do
+  # get first key rsa....
+  break
+done
+
+
+# ===
+
+HOSTKEYtestBREAK() {
+  echo
+  rm -f $USERKNOWNHOSTSFILE
+  rm -f $SSHD_CFG.tmp
+  testBREAK
+}
+
+trap HOSTKEYtestBREAK INT QUIT ABRT KILL TERM || exit 1
+
+
+# ===
+
+do_test () {
+  echo "* with ${extd}different ${attn}hostkey${norm} algorithms:"
+
+  creTestSSHDcfgFile
+
+  cat >> "$SSHD_CFG" <<EOF
+CACertificateFile $SSH_CAROOT/$CACERTFILE
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  mv $SSHD_CFG $SSHD_CFG.tmp
+  grep -v HostKey $SSHD_CFG.tmp > $SSHD_CFG
+  rm $SSHD_CFG.tmp
+
+  cat >> "$SSHD_CFG" <<EOF
+# ssh-rsa
+HostKey "$CWD/testhostkey_rsa"
+# ssh-dsa
+HostKey "$CWD/testhostkey_dsa"
+# x509v3-*-rsa (legacy or RFC6187)
+HostKey "$CWD/testhostkey_rsa-$RSA_DGST"
+# x509v3-*-dss (legacy or RFC6187)
+HostKey "$CWD/testhostkey_dsa-dsa"
+# x509v3-ecdsa-sha2-* (RFC6187)
+EOF
+(
+  for alg in $SSH_ALGS_X509_EC ; do
+    case $alg in
+    x509v3-ecdsa-sha2-*)
+      curve=`echo $alg | sed 's/^.*ecdsa-sha2-//'`
+      hostkey=ecc$curve-$RSA_DGST
+      echo HostKey "\"$CWD/testhostkey_$hostkey\""
+      ;;
+    esac
+  done
+) >> "$SSHD_CFG"
+
+  runSSHdaemon || return $?
+  (
+    identity_file="testid_rsa-$RSA_DGST"
+    "$TEST_SSH_SSHKEYGEN" -f "$identity_file" -y 2>/dev/null > "$AUTHORIZEDKEYSFILE" || exit $?
+
+    printSeparator
+    echo "  - with ${attn}same public${norm} identity in known hosts file:"
+
+    for alg in \
+      $SSH_ALGS_X509_RSA \
+      $SSH_ALGS_X509_DSA \
+      $SSH_ALGS_X509_EC \
+      ssh-rsa \
+      ssh-dss \
+      $SSH_EC_ALGS_PLAIN \
+    ; do
+
+case $alg in
+x509v3-ssh-*) continue;; #TODO (not yet)
+esac
+
+      case $alg in
+      x509v3-*-rsa) hostkey=rsa-$RSA_DGST;;
+      x509v3-*-dss) hostkey=dsa-dsa;;
+      x509v3-ecdsa-sha2-*)
+                       curve=`echo $alg | sed 's/^.*ecdsa-sha2-//'`
+                       hostkey=ecc$curve-$RSA_DGST;;
+      ssh-rsa)         hostkey=rsa;;
+      ssh-dss)         hostkey=dsa;;
+      ecdsa-sha2-*)    curve=`echo $alg | sed 's/^.*ecdsa-sha2-//'`
+                       hostkey=ecc$curve;;
+      *)
+        echo "${warn}unsupported public key algorithm : $alg${norm}"
+        exit 1;;
+      esac
+
+      cat > $USERKNOWNHOSTSFILE <<EOF
+[$SSHD_LISTENADDRESS]:$SSHD_PORT `cat "$CWD"/testhostkey_$hostkey.pub`
+EOF
+
+      TEST_CLIENT_CFG="\
+HostKeyAlgorithms $alg
+"
+
+      typemsg="$alg"
+      infomsg=".../testhostkey_$hostkey.pub"
+      mustfail=no
+      errmsg=
+      case $alg in
+      ecdsa-sha2-*)
+        # hostkey aliases are not supported yet
+        infomsg="${warn}!${norm} $infomsg"
+        mustfail=yes
+        #errmsg="no hostkey alg" before OpenSSH 6.8
+        errmsg="no matching host key type found"
+        ;;
+      esac
+
+      runTest "$typemsg" "$identity_file" "$infomsg" $mustfail "$errmsg" || exit $?
+
+    done
+    rm -f $USERKNOWNHOSTSFILE
+
+exit 0
+    # reserved for future use ... (hostkey aliases)
+
+    printSeparator
+    echo "  - with ${attn}public key${norm} in known hosts file:"
+    #TODO
+    rm -f $USERKNOWNHOSTSFILE
+
+    printSeparator
+    echo "  - with ${attn}X.509 certificate${norm} in known hosts file:"
+    #TODO
+    rm -f $USERKNOWNHOSTSFILE
+
+    printSeparator
+    echo "  - with ${attn}X.509 distinguished name${norm} in known hosts file:"
+    #TODO
+    rm -f $USERKNOWNHOSTSFILE
+
+  ); retval=$?
+  killSSHdaemon
+
+  return $retval
+}
diff -ruN openssh-7.5p1/tests/CA/test-ocsp.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-ocsp.sh.inc
--- openssh-7.5p1/tests/CA/test-ocsp.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-ocsp.sh.inc	2016-02-28 21:01:05.000000000 +0200
@@ -0,0 +1,260 @@
+#
+# Copyright (c) 2004-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and x509 certificate;
+#  - "AuthorizedKeysFile" contain certificate Subject;
+#  - validation against:
+#    - OCSP provider from certificate
+#    - specified in configuration OCSP provider
+#    - TODO:specified OCSP provider with revoked provider certificate
+#  Note:
+#  Due to OpenSSL limitations no one of tests starts OCSP provider with dsa key.
+#
+
+
+# ===
+openssl_ocsp_tmout() {
+(
+  if test -z "$SSH_OPENSSL_OCSP_TMOUT"; then
+    sleep 1
+    exit 0
+  fi
+
+  count=$SSH_OPENSSL_OCSP_TMOUT
+  # for slow workstations or virtual environment: +4sec. :(
+  echo "OpenSSL OCSP responder socket timeout ${count}+4[sec.]" >&2
+  count=`expr ${count}`
+  while test ${count} -gt 0; do
+    printf 'O'; sleep 1
+    count=`expr ${count} - 1`
+  done
+  printf '-'; sleep 1
+  printf '/'; sleep 1
+  printf '-'; sleep 1
+  printf 'X'; sleep 1
+  printf '\n'
+)
+}
+
+
+# ===
+killResponders() {
+(
+  if test -z "$SSH_OPENSSL_OCSP_TMOUT"; then
+  (
+    has=""
+    for pidfile in va-*.pid; do
+      if test -r "${pidfile}"; then
+        kill `cat "${pidfile}"` > /dev/null 2>&1
+        has="yes"
+      fi
+    done
+    if test -n "${has}"; then
+      openssl_ocsp_tmout
+    fi
+  )
+  fi
+  (
+    has=""
+    for pidfile in va-*.pid; do
+      if test -r "${pidfile}"; then
+        kill -9 `cat "${pidfile}"` > /dev/null 2>&1
+        rm -f "${pidfile}"
+        has="yes"
+      fi
+    done
+    if test -n "${has}"; then
+      openssl_ocsp_tmout
+    fi
+  )
+  :
+)
+}
+
+
+# ===
+OCSPtestBREAK() {
+  echo
+  killResponders
+  testBREAK
+}
+
+trap OCSPtestBREAK INT QUIT ABRT KILL TERM || exit 1
+
+
+# ===
+#args:
+#  $1 - port
+#env. vars:
+#  OCSP_RESPKEY
+#  type
+runResponder() {
+(
+  port=$1
+
+  pidfile="va-${port}.pid"
+  test -r "${pidfile}" && exit 1
+
+  printf '  %s' "starting OCSP ${extd}responder${norm}(${attn}${type}${norm}) on ${attn}${SSHD_LISTENADDRESS}:${port}${norm}"
+  (
+  ${OPENSSL} ocsp \
+    -CA      "${SSH_CACERTDIR}/${CAKEY_PREFIX}-${type}.crt.pem" \
+    -rsigner "${OCSP_RESPKEY}-${type}.crt" \
+    -rkey    "${OCSP_RESPKEY}" \
+    -index   "${SSH_CAROOT}/index-${type}.txt" \
+    -host ${SSHD_LISTENADDRESS} \
+    -port ${port} 2> va-${type}.log &
+  pid=$!
+  echo ${pid} > "${pidfile}"
+  wait ${pid}
+  rm -f "${pidfile}"
+  ) 2> /dev/null &
+
+  sleep 1
+  test -r "${pidfile}"; show_status $?
+)
+}
+
+
+# ===
+test_ocsp_cert () {
+(
+  printSeparator
+  echo "Begin test ${extd}against${norm} OCSP provider from ${attn}certificate${norm} ..."
+
+  retval=1
+  for OCSP_RESPKEY in ${TEST_OCSP_RESPKEYS}; do
+    printSeparator
+    echo "  respoder key base ${attn}${OCSP_RESPKEY}${norm} ..."
+
+    creTestSSHDcfgFile
+    cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+VAType ocspcert
+EOF
+
+    port=${SSH_VA_BASEPORT}
+    for type in ${SSH_SIGN_TYPES}; do
+      runResponder ${port}; retval=$?
+      if test ${retval} -ne 0; then
+        break
+      fi
+      port=`expr ${port} + 1`
+    done
+    if test ${retval} -eq 0; then
+      runSSHdaemon &&
+      (
+        for type in ${SSH_SIGN_TYPES}; do
+          test_by_keytype || exit $?
+        done
+      ); retval=$?
+      killSSHdaemon
+    fi
+    killResponders
+    if test ${retval} -ne 0; then
+      exit ${retval}
+    fi
+  done
+
+  exit ${retval}
+)
+}
+
+
+# ===
+#env. vars:
+#  type
+test_by_keytype() {
+(
+  for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do
+    identity_file="${SSH_CLIENTKEY}-${type}"
+    creX509AuthorizedKeysFile "${identity_file}" &&
+    runTest "${identity_file}" \
+      "${identity_file}" "" "" || exit $?
+
+    identity_file="${SSH_CLIENTKEY}-${type}-revoked"
+    creX509AuthorizedKeysFile "${identity_file}" &&
+    runTest "${SSH_CLIENTKEY}-${type}${warn}-revoked${norm}" \
+      "${identity_file}" "" "Yes" || exit $?
+  done
+)
+}
+
+
+# ===
+test_ocsp_spec () {
+(
+  printSeparator
+  echo "Begin test ${extd}against${norm} ${attn}specified${norm} OCSP provider ..."
+
+  #OpenSSL OCSP responder support only one CA!
+  #For each signature type we have different CA, i.e. we must start
+  #corresponding OCSP responder.
+  #Note: OpenSSL OCSP responder doesn't support dsa keys!!!
+  retval=1
+  for OCSP_RESPKEY in ${TEST_OCSP_RESPKEYS}; do
+    printSeparator
+    echo "  respoder key base ${attn}${OCSP_RESPKEY}${norm} ..."
+
+    for type in ${SSH_SIGN_TYPES}; do
+      creTestSSHDcfgFile
+      cat >> "$SSHD_CFG" <<EOF
+CACertificateFile ${SSH_CAROOT}/${CACERTFILE}
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+VAType ocspspec
+VAOCSPResponderURL http://${SSHD_LISTENADDRESS}:${SSH_VA_BASEPORT}
+#VACertificateFile `pwd`/${OCSP_RESPKEY}-${type}.crt
+EOF
+
+      runResponder ${SSH_VA_BASEPORT} &&
+      runSSHdaemon &&
+      test_by_keytype; retval=$?
+      killSSHdaemon
+      killResponders
+      if test ${retval} -ne 0; then
+        exit ${retval}
+      fi
+    done
+  done
+
+  exit ${retval}
+)
+}
+
+
+# ===
+
+do_test () {
+  if test "x${SSH_OCSP_ENABLED}" = "xno"; then
+    echo "* ${extd}OCSP${norm} is ${attn}disabled${norm}"
+    return 1
+  fi
+  echo "* ${extd}against ${attn}CACertificateFile${norm} and ${attn}OCSP provider${norm}:"
+
+  test_ocsp_cert &&
+  test_ocsp_spec
+}
diff -ruN openssh-7.5p1/tests/CA/test-self.sh.inc openssh-7.5p1+x509-10.2/tests/CA/test-self.sh.inc
--- openssh-7.5p1/tests/CA/test-self.sh.inc	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/test-self.sh.inc	2017-02-22 21:32:00.259966725 +0200
@@ -0,0 +1,232 @@
+#
+# Copyright (c) 2006-2017 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Test client authentication:
+#  - "IdentityFile" contain private key and self-signed x509 certificate;
+#  - "AuthorizedKeysFile" contain encoded either public key or X.509
+#   certificate or certificate DN.
+#
+
+
+# ===
+#args:
+#  $1 - request to fail flag for encoded identity
+#  $2 - request to fail flag for DN
+test_self() {
+
+  case $1 in
+    Y|y|Yes|yes|YES|1)
+      encoded_fail=yes;;
+    *)
+      encoded_fail=no;;
+  esac
+  case $2 in
+    Y|y|Yes|yes|YES|1)
+      dn_msg="${warn}DN${norm}";;
+    *)
+      dn_msg="${extd}DN${norm}";;
+  esac
+
+  for keytype in rsa dsa; do
+    SSH_CLIENTKEY="selfid_${keytype}"
+
+    for type in ${SSH_SIGN_TYPES}; do
+      case $keytype in
+        rsa)
+          case $type in
+            *dsa*) continue;;
+          esac
+          ;;
+        dsa)
+          case $type in
+            *rsa*) continue;;
+          esac
+          ;;
+      esac
+
+      identity_file="${SSH_CLIENTKEY}-${type}"
+
+      # public key
+      if test yes = $encoded_fail; then
+        blob_msg="encoded ${warn}public${norm} key"
+      else
+        blob_msg="encoded ${extd}public${norm} key"
+      fi
+      cat "$SSH_CLIENTKEY.pub" > "$AUTHORIZEDKEYSFILE" &&
+      runTest '' "$identity_file" "$type $blob_msg" $encoded_fail \
+      || return $?
+
+      # X.509 certificate
+      if test yes = $encoded_fail; then
+        blob_msg="encoded ${warn}X.509${norm} certificate"
+      else
+        blob_msg="encoded ${extd}X.509${norm} certificate"
+      fi
+      cat "$identity_file.pub" > "$AUTHORIZEDKEYSFILE" &&
+      runTest '' "$identity_file" "$type $blob_msg" $encoded_fail \
+      || return $?
+
+      # X.509 certificate distinguished name
+      sshkeytype=`getSSHkeyType "$identity_file"` || return $?
+      subject=`getSubject "$identity_file"` || return $?
+
+      echo "$sshkeytype Subject: $subject" > "$AUTHORIZEDKEYSFILE" &&
+      runTest '' "$identity_file" "$type $dn_msg" "$2" \
+      || return $?
+    done
+  done
+}
+
+# ===
+
+test_store () {
+  retval=0
+  echo "  - ${attn}with${norm} self-signed trusted by ${extd}x509store${norm}:"
+  printSeparator
+
+  cat selfid_*.crt > $CWD/selfid-bundle
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+AllowedCertPurpose skip
+KeyAllowSelfIssued no
+CACertificateFile $CWD/selfid-bundle
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    test_self "no" "no"
+  ); retval=$?
+  killSSHdaemon
+  rm -f $CWD/selfid-bundle
+  return $retval
+}
+
+# ===
+
+test_pkey_no () {
+  retval=0
+  echo "  - ${attn}without${norm} self-signed allowed by encoded ${extd}public identity${norm}:"
+  printSeparator
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+AllowedCertPurpose skip
+KeyAllowSelfIssued no
+CACertificateFile /file/not/found
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    test_self "yes" "yes"
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
+
+# ===
+
+test_pkey_yes () {
+  retval=0
+  echo "  - ${attn}with${norm} self-signed allowed by encoded ${extd}public identity${norm}:"
+  printSeparator
+
+  # check if exist X.509 verification bug
+  # (see mail thread "1.0.2beta2 and X.509 certificate verification")
+  # expected if only
+  # 'error 18 at 0 depth lookup:self signed certificate'
+  # buggy if return extra:
+  # 'error 20 at 0 depth lookup:unable to get local issuer certificate'
+  if $OPENSSL verify "$SSH_CACERTDIR"/"$CAKEY_PREFIX"-root0.crt.pem | grep 'error 20' > /dev/null ; then
+    echo "${warn}skipped due to openssl verification bug${norm}" >&2
+    echo "(see email thread ${attn}1.0.2beta2 and X.509 certificate verification${norm})" >&2
+    return 0
+  fi
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+AllowedCertPurpose skip
+KeyAllowSelfIssued yes
+CACertificateFile /file/not/found
+CACertificatePath /path/not/found
+CARevocationFile  /crlfile/not/found
+CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    test_self "no" "yes"
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
+
+# ===
+
+test_pkey () {
+  retval=0
+  echo "  - ${attn}with${norm} self-signed allowed by encoded ${extd}public identity${norm}:"
+  printSeparator
+
+  creTestSSHDcfgFile
+  cat >> "$SSHD_CFG" <<EOF
+AllowedCertPurpose skip
+#Unsupported options:
+#KeyAllowSelfIssued no
+#CACertificateFile /file/not/found
+#CACertificatePath /path/not/found
+#CARevocationFile  /crlfile/not/found
+#CARevocationPath  /crlpath/not/found
+EOF
+
+  runSSHdaemon || return $?
+  (
+    test_self "no" "yes"
+  ); retval=$?
+  killSSHdaemon
+  return $retval
+}
+
+# ===
+SELFtestBREAK() {
+  echo
+  rm -f $CWD/selfid-bundle
+  testBREAK
+}
+
+trap SELFtestBREAK INT QUIT ABRT KILL TERM || exit 1
+
+
+# ===
+
+do_test () {
+  echo "* ${extd}self-signed${norm}:"
+
+  test_store &&
+  test_pkey_no &&
+  test_pkey_yes
+}
diff -ruN openssh-7.5p1/tests/CA/verify.sh openssh-7.5p1+x509-10.2/tests/CA/verify.sh
--- openssh-7.5p1/tests/CA/verify.sh	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/tests/CA/verify.sh	2015-03-28 18:58:45.737396591 +0200
@@ -0,0 +1,44 @@
+#! /bin/sh
+# Copyright (c) 2002-2015 Roumen Petrov, Sofia, Bulgaria
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# DESCRIPTION: Verify all testid_*.crt testhostkey_*.crt files in current
+# directory agains "Test CA".
+#
+
+CWD=`pwd`
+SCRIPTDIR=`echo $0 | sed 's/verify.sh//'`
+. "${SCRIPTDIR}functions"
+. "${SCRIPTDIR}config"
+
+
+for VERIFY in \
+  "$OPENSSL verify -CAfile $SSH_CAROOT/$CACERTFILE" \
+  "$OPENSSL verify -CApath $SSH_CACERTDIR" \
+; do
+  echo ${attn}$VERIFY ....${norm}
+  for F in \
+    testid_*.crt \
+    testhostkey_*.crt \
+    testocsp_*.crt \
+  ; do
+    $VERIFY "$F" || exit 1
+  done
+done
diff -ruN openssh-7.5p1/version.h openssh-7.5p1+x509-10.2/version.h
--- openssh-7.5p1/version.h	2017-03-20 04:39:27.000000000 +0200
+++ openssh-7.5p1+x509-10.2/version.h	2017-05-20 21:07:00.000000000 +0300
@@ -2,5 +2,4 @@
 
 #define SSH_VERSION	"OpenSSH_7.5"
 
-#define SSH_PORTABLE	"p1"
-#define SSH_RELEASE	SSH_VERSION SSH_PORTABLE
+#define SSH_RELEASE	PACKAGE_STRING ", " SSH_VERSION "p1"
diff -ruN openssh-7.5p1/version.m4 openssh-7.5p1+x509-10.2/version.m4
--- openssh-7.5p1/version.m4	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/version.m4	2017-05-20 20:45:28.000000000 +0300
@@ -0,0 +1,7 @@
+# update version number here and if necessary
+# in version.h and in contrib/*/*.spec
+
+m4_define([SSH_PACKAGE], [PKIX-SSH])
+m4_define([SSH_VERSION], [10.2])
+m4_define([SSH_BUGREPORT], [ssh_x509@roumenpetrov.info])
+m4_define([SSH_URL], [http://roumenpetrov.info/secsh])
diff -ruN openssh-7.5p1/x509_by_ldap.c openssh-7.5p1+x509-10.2/x509_by_ldap.c
--- openssh-7.5p1/x509_by_ldap.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/x509_by_ldap.c	2016-08-26 21:18:51.692923466 +0300
@@ -0,0 +1,897 @@
+/*
+ * Copyright (c) 2004-2016 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "x509_by_ldap.h"
+
+/* prefer X509_NAME_cmp method from ssh-x509.c */
+extern int     ssh_X509_NAME_cmp(X509_NAME *a, X509_NAME *b);
+
+#include <string.h>
+#ifndef LDAP_DEPRECATED
+   /* to suppress warnings in some 2.3x versions */
+#  define LDAP_DEPRECATED 0
+#endif
+#include <ldap.h>
+
+
+/* ================================================================== */
+/* backport OpenSSL 1.1 functions */
+#ifndef HAVE_X509_STORE_GET0_OBJECTS
+static inline STACK_OF(X509_OBJECT)*
+X509_STORE_get0_objects(X509_STORE *store) {
+	return(store->objs);
+}
+#endif /*ndef HAVE_X509_STORE_GET0_OBJECTS*/
+
+
+#ifndef HAVE_X509_STORE_LOCK
+static inline int
+X509_STORE_lock(X509_STORE *s) {
+	(void)s;
+#ifdef CRYPTO_LOCK_X509_STORE
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+#endif
+	return(1);
+}
+
+static inline int
+X509_STORE_unlock(X509_STORE *s) {
+	(void)s;
+#ifdef CRYPTO_LOCK_X509_STORE
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+#endif
+	return(1);
+}
+#endif /*def HAVE_X509_STORE_LOCK*/
+
+
+#ifndef HAVE_STRUCT_X509_LOOKUP_METHOD_ST
+/* temporary for some OpenSSL 1.1 "alpha" versions */
+struct x509_lookup_method_st {
+	const char *name;
+	int (*new_item) (X509_LOOKUP *ctx);
+	void (*free) (X509_LOOKUP *ctx);
+	int (*init) (X509_LOOKUP *ctx);
+	int (*shutdown) (X509_LOOKUP *ctx);
+	int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret);
+	int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret);
+	int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, ASN1_INTEGER *serial, X509_OBJECT *ret);
+	int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, unsigned char *bytes, int len, X509_OBJECT *ret);
+	int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, X509_OBJECT *ret);
+};
+
+struct x509_lookup_st {
+	int init;                   /* have we been started */
+	int skip;                   /* don't use us. */
+	X509_LOOKUP_METHOD *method; /* the functions */
+	char *method_data;          /* method data */
+	X509_STORE *store_ctx;      /* who owns us */
+};
+
+struct x509_object_st {
+	X509_LOOKUP_TYPE type;
+	union {
+		char *ptr;
+		X509 *x509;
+		X509_CRL *crl;
+		EVP_PKEY *pkey;
+	} data;
+};
+#endif /*ndef HAVE_STRUCT_X509_LOOKUP_METHOD_ST*/
+
+
+/* ================================================================== */
+/* ERRORS */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA X509byLDAP_str_functs[] = {
+	{ ERR_PACK(0, X509byLDAP_F_LOOKUPCRTL, 0)	, "LOOKUPCRTL" },
+	{ ERR_PACK(0, X509byLDAP_F_LDAPHOST_NEW, 0)	, "LDAPHOST_NEW" },
+	{ ERR_PACK(0, X509byLDAP_F_SET_PROTOCOL, 0)	, "SET_PROTOCOL" },
+	{ ERR_PACK(0, X509byLDAP_F_RESULT2STORE, 0)	, "RESULT2STORE" },
+	{ ERR_PACK(0, X509byLDAP_F_GET_BY_SUBJECT, 0)	, "GET_BY_SUBJECT" },
+	{ 0, NULL }
+};
+
+
+static ERR_STRING_DATA X509byLDAP_str_reasons[] = {
+	{ X509byLDAP_R_INVALID_CRTLCMD			, "invalid control command" },
+	{ X509byLDAP_R_NOT_LDAP_URL			, "not ldap url" },
+	{ X509byLDAP_R_INVALID_URL			, "invalid ldap url" },
+	{ X509byLDAP_R_INITIALIZATION_ERROR		, "ldap initialization error" },
+	{ X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION	, "unable to get ldap protocol version" },
+	{ X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION	, "unable to set ldap protocol version" },
+	{ X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES		, "unable to count ldap entries" },
+	{ X509byLDAP_R_WRONG_LOOKUP_TYPE		, "wrong lookup type" },
+	{ X509byLDAP_R_UNABLE_TO_GET_FILTER		, "unable to get ldap filter" },
+	{ X509byLDAP_R_UNABLE_TO_BIND			, "unable to bind to ldap server" },
+	{ X509byLDAP_R_SEARCH_FAIL			, "search failure" },
+	{ 0, NULL }
+};
+#endif /*ndef OPENSSL_NO_ERR*/
+
+
+static int ERR_LIB_X509byLDAP = 0;
+#define X509byLDAPerr(f,r) ERR_PUT_error(ERR_LIB_X509byLDAP,(f),(r),__FILE__,__LINE__)
+
+
+void
+ERR_load_X509byLDAP_strings(void) {
+	static int init = 1;
+
+	if (init) {
+		init = 0;
+#ifndef OPENSSL_NO_ERR
+		ERR_LIB_X509byLDAP = ERR_get_next_error_library();
+		ERR_load_strings(ERR_LIB_X509byLDAP, X509byLDAP_str_functs);
+		ERR_load_strings(ERR_LIB_X509byLDAP, X509byLDAP_str_reasons);
+#endif
+	}
+}
+
+
+static char*
+ldap_errormsg(char *buf, size_t len, int err) {
+	snprintf(buf, len, "ldaperror=0x%x(%.256s)", err, ldap_err2string(err));
+	return(buf);
+}
+
+
+static void
+openssl_add_ldap_error(int err) {
+	char	buf[512];
+	ERR_add_error_data(1, ldap_errormsg(buf, sizeof(buf), err));
+}
+
+
+/* ================================================================== */
+/* wrappers to some depricated functions */
+static void
+ldaplookup_parse_result (
+	LDAP *ld,
+	LDAPMessage *res
+) {
+	static const int freeit = 0;
+	int result;
+#ifdef HAVE_LDAP_PARSE_RESULT
+	int ret;
+	char *matcheddn;
+	char *errmsg;
+
+	ret = ldap_parse_result(ld, res, &result, &matcheddn, &errmsg, NULL, NULL, freeit);
+	if (ret == LDAP_SUCCESS) {
+		if (errmsg) ERR_add_error_data(1, errmsg);
+	}
+	if (matcheddn) ldap_memfree(matcheddn);
+	if (errmsg)    ldap_memfree(errmsg);
+#else
+	result = ldap_result2error(ld, res, freeit);
+	openssl_add_ldap_error(result);
+#endif
+}
+
+
+static int
+ldaplookup_bind_s(LDAP *ld) {
+	int result;
+
+	/* anonymous bind - data must be retrieved by anybody */
+#ifdef HAVE_LDAP_SASL_BIND_S
+{
+	static struct berval	cred = { 0, (char*)"" };
+
+	result = ldap_sasl_bind_s(
+		ld, NULL/*dn*/, LDAP_SASL_SIMPLE, &cred,
+		NULL, NULL, NULL);
+}
+#else
+	result = ldap_simple_bind_s(ld, NULL/*binddn*/, NULL/*bindpw*/);
+#endif
+
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_bind_s:"
+" ldap_XXX_bind_s return 0x%x(%s)\n"
+, result, ldap_err2string(result));
+#endif
+	return(result);
+}
+
+
+static int
+ldaplookup_search_s(
+	LDAP *ld,
+	LDAP_CONST char *base,
+	int scope,
+	LDAP_CONST char *filter,
+	char **attrs,
+	int attrsonly,
+	LDAPMessage **res
+) {
+	int result;
+#ifdef HAVE_LDAP_SEARCH_EXT_S
+	result = ldap_search_ext_s(ld, base,
+		scope, filter, attrs, attrsonly,
+		NULL, NULL, NULL, 0, res);
+#else
+	result = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
+#endif
+
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_search_s:"
+"\n base=%s\n filter=%s\n"
+" ldap_search_{XXX}s return 0x%x(%s)\n"
+, base, filter
+, result, ldap_err2string(result));
+#endif
+	return(result);
+}
+
+
+/* ================================================================== */
+/* LOOKUP by LDAP */
+
+static const char ATTR_CACERT[] = "cACertificate";
+static const char ATTR_CACRL[] = "certificateRevocationList";
+
+typedef struct ldaphost_s ldaphost;
+struct ldaphost_s {
+	char        *url;
+	char        *binddn;
+	char        *bindpw;
+	LDAPURLDesc *ldapurl;
+	LDAP        *ld;
+	ldaphost    *next;
+};
+
+
+static ldaphost* ldaphost_new(const char *url);
+static void ldaphost_free(ldaphost *p);
+
+
+static int  ldaplookup_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret);
+static int  ldaplookup_new(X509_LOOKUP *ctx);
+static void ldaplookup_free(X509_LOOKUP *ctx);
+static int  ldaplookup_init(X509_LOOKUP *ctx);
+static int  ldaplookup_shutdown(X509_LOOKUP *ctx);
+static int  ldaplookup_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret);
+
+static int  ldaplookup_add_search(X509_LOOKUP *ctx, const char *url);
+static int  ldaplookup_set_protocol(X509_LOOKUP *ctx, const char *ver);
+
+
+X509_LOOKUP_METHOD x509_ldap_lookup = {
+	"Load certs and crls from LDAP server",
+	ldaplookup_new,		/* new */
+	ldaplookup_free,	/* free */
+	ldaplookup_init,	/* init */
+	ldaplookup_shutdown,	/* shutdown */
+	ldaplookup_ctrl,	/* ctrl */
+	ldaplookup_by_subject,	/* get_by_subject */
+	NULL,			/* get_by_issuer_serial */
+	NULL,			/* get_by_fingerprint */
+	NULL,			/* get_by_alias */
+};
+
+
+X509_LOOKUP_METHOD*
+X509_LOOKUP_ldap(void) {
+	return(&x509_ldap_lookup);
+}
+
+
+static int
+ldaplookup_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **retp) {
+	int ret = 0;
+
+	(void)argl;
+	(void)retp;
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_ctrl: cmd=%d, argc=%s\n", cmd, argc);
+#endif
+	switch (cmd) {
+	case X509_L_LDAP_HOST:
+		ret = ldaplookup_add_search(ctx, argc);
+		break;
+	case X509_L_LDAP_VERSION:
+		ret = ldaplookup_set_protocol(ctx, argc);
+		break;
+	default:
+		X509byLDAPerr(X509byLDAP_F_LOOKUPCRTL, X509byLDAP_R_INVALID_CRTLCMD);
+		break;
+	}
+	return(ret);
+}
+
+
+static int
+ldaplookup_new(X509_LOOKUP *ctx) {
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_new:\n");
+#endif
+	if (ctx == NULL)
+		return(0);
+
+	ctx->method_data = NULL;
+	return(1);
+}
+
+
+static void
+ldaplookup_free(X509_LOOKUP *ctx) {
+	ldaphost *p;
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_free:\n");
+#endif
+
+	if (ctx == NULL)
+		return;
+
+	p = (ldaphost*) ctx->method_data;
+	while (p != NULL) {
+		ldaphost *q = p;
+		p = p->next;
+		ldaphost_free(q);
+	}
+}
+
+
+static int
+ldaplookup_init(X509_LOOKUP *ctx) {
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_init:\n");
+#endif
+	(void)ctx;
+	return(1);
+}
+
+
+static int
+ldaplookup_shutdown(X509_LOOKUP *ctx) {
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_shutdown:\n");
+#endif
+	(void)ctx;
+	return(1);
+}
+
+
+static ldaphost*
+ldaphost_new(const char *url) {
+	ldaphost *p;
+	int          ret;
+
+	p = OPENSSL_malloc(sizeof(ldaphost));
+	if (p == NULL) return(NULL);
+
+	memset(p, 0, sizeof(ldaphost));
+
+	p->url = OPENSSL_malloc(strlen(url) + 1);
+	if (p->url == NULL) goto error;
+	strcpy(p->url, url);
+
+	/*ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] */
+	ret = ldap_is_ldap_url(url);
+	if (ret < 0) {
+		X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_NOT_LDAP_URL);
+		goto error;
+	}
+
+	ret = ldap_url_parse(p->url, &p->ldapurl);
+	if (ret != 0) {
+		X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INVALID_URL);
+		openssl_add_ldap_error(ret);
+		goto error;
+	}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_url_desc2str=%s\n", ldap_url_desc2str(p->ldapurl));
+fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldapurl->%s://%s:%d\n", p->ldapurl->lud_scheme, p->ldapurl->lud_host, p->ldapurl->lud_port);
+#endif
+
+	/* open ldap connection */
+#ifdef HAVE_LDAP_INITIALIZE
+	ret = ldap_initialize(&p->ld, p->url);
+	if (ret != LDAP_SUCCESS) {
+		X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR);
+		openssl_add_ldap_error(ret);
+		goto error;
+	}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_initialize(..., url=%s)\n", p->url);
+#endif
+#else /*ndef HAVE_LDAP_INITIALIZE*/
+	p->ld = ldap_init(p->ldapurl->lud_host, p->ldapurl->lud_port);
+	if(p->ld == NULL) {
+		X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR);
+		goto error;
+	}
+#endif /*ndef HAVE_LDAP_INITIALIZE*/
+
+	{
+		int version = -1;
+
+		ret = ldap_get_option(p->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+		if (ret != LDAP_OPT_SUCCESS) {
+			X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION );
+			goto error;
+		}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: using ldap v%d protocol\n", version);
+#endif
+	}
+
+	return(p);
+error:
+	ldaphost_free(p);
+	return(NULL);
+}
+
+
+static void
+ldaphost_free(ldaphost *p) {
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaphost_free:\n");
+#endif
+	if (p == NULL) return;
+	if (p->url    != NULL) OPENSSL_free(p->url);
+	if (p->binddn != NULL) OPENSSL_free(p->binddn);
+	if (p->bindpw != NULL) OPENSSL_free(p->bindpw);
+	if (p->ldapurl != NULL) {
+		ldap_free_urldesc(p->ldapurl);
+		p->ldapurl = NULL;
+	}
+	if (p->ld != NULL) {
+		/* how to free ld ???*/
+		p->ld = NULL;
+	}
+	OPENSSL_free(p);
+}
+
+
+static int/*bool*/
+ldaplookup_add_search(X509_LOOKUP *ctx, const char *url) {
+	ldaphost *p, *q;
+
+	if (ctx == NULL) return(0);
+	if (url == NULL) return(0);
+
+	q = ldaphost_new(url);
+	if (q == NULL) return(0);
+
+	p = (ldaphost*) ctx->method_data;
+	if (p == NULL) {
+		ctx->method_data = (void*) q;
+		return(1);
+	}
+
+	for(; p->next != NULL; p = p->next) {
+		/*find list end*/
+	}
+	p->next = q;
+
+	return(1);
+}
+
+
+static int/*bool*/
+ldaplookup_set_protocol(X509_LOOKUP *ctx, const char *ver) {
+	ldaphost *p;
+	char *q = NULL;
+	int n;
+
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(..., %s)\n", ver);
+#endif
+	if (ctx == NULL) return(0);
+	if (ver == NULL) return(0);
+
+	p = (ldaphost*) ctx->method_data;
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(..., %s) p=%p\n", ver, (void*)p);
+#endif
+	if (p == NULL) return(0);
+
+	n = (int) strtol(ver, &q, 10);
+	if (*q != '\0') return(0);
+	if ((n < LDAP_VERSION_MIN) || (n > LDAP_VERSION_MAX)) return(0);
+
+	for(; p->next != NULL; p = p->next) {
+		/*find list end*/
+	}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(...): ver=%d\n", n);
+#endif
+	{
+		int ret;
+		const int version = n;
+
+		ret = ldap_set_option(p->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+		if (ret != LDAP_OPT_SUCCESS) {
+			X509byLDAPerr(X509byLDAP_F_SET_PROTOCOL, X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION);
+			openssl_add_ldap_error(ret);
+			return(0);
+		}
+	}
+
+	return(1);
+}
+
+
+static char*
+ldaplookup_attr(ASN1_STRING *nv) {
+	char *p = NULL;
+	int k;
+	BIO *mbio;
+
+	mbio = BIO_new(BIO_s_mem());
+	if (mbio == NULL) return(NULL);
+
+	k = ASN1_STRING_print_ex(mbio, nv, XN_FLAG_RFC2253);
+	p = OPENSSL_malloc(k + 1);
+	if (p == NULL) goto done;
+
+	k = BIO_read(mbio, p, k);
+	p[k] = '\0';
+
+done:
+	BIO_free_all(mbio);
+	return(p);
+}
+
+
+static char*
+ldaplookup_filter(X509_NAME *name, const char *attribute) {
+	char *p = NULL;
+	int k;
+	BIO *mbio;
+
+	mbio = BIO_new(BIO_s_mem());
+	if (mbio == NULL) return(NULL);
+
+	BIO_puts(mbio, "(&");
+
+	k = X509_NAME_entry_count(name);
+	for (--k; k >= 0; k--) {
+		X509_NAME_ENTRY *ne;
+		ASN1_STRING     *nv;
+		int nid;
+
+		ne = X509_NAME_get_entry(name, k);
+		nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
+
+		if (
+			(nid != NID_organizationName) &&
+			(nid != NID_organizationalUnitName) &&
+			(nid != NID_commonName)
+		) continue;
+
+		BIO_puts(mbio, "(");
+		BIO_puts(mbio, OBJ_nid2sn(nid));
+		BIO_puts(mbio, "=");
+		nv = X509_NAME_ENTRY_get_data(ne);
+		{
+			char *q, *s;
+
+			q = ldaplookup_attr(nv);
+			if (q == NULL) goto done;
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_filter: ldaplookup_attr(nv) return '%.512s'\n", q);
+#endif
+			/* escape some charecters according to RFC2254 */
+			for (s=q; *s; s++) {
+				if ((*s == '*') ||
+				    (*s == '(') ||
+				    (*s == ')')
+				    /* character '\' should be already escaped ! */
+				) {
+					/* RFC2254 recommendation */
+					BIO_printf(mbio, "\\%02X", (int)*s);
+					continue;
+				}
+				BIO_write(mbio, s, 1);
+			}
+
+			OPENSSL_free(q);
+		}
+		BIO_puts(mbio, ")");
+	}
+
+	BIO_puts(mbio, "(");
+	BIO_puts(mbio, attribute);
+	BIO_puts(mbio, "=*)");
+
+	BIO_puts(mbio, ")");
+	(void)BIO_flush(mbio);
+
+	k = BIO_pending(mbio);
+	p = OPENSSL_malloc(k + 1);
+	if (p == NULL) goto done;
+
+	k = BIO_read(mbio, p, k);
+	p[k] = '\0';
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_filter: p=%.512s\n", p);
+#endif
+
+done:
+	BIO_free_all(mbio);
+	return(p);
+}
+
+
+static int/*bool*/
+ldaplookup_check_attr(
+	int type,
+	const char *attr
+) {
+	if (type == X509_LU_X509)
+		return(strncmp(attr, ATTR_CACERT, sizeof(ATTR_CACERT)) != 0);
+
+	if (type == X509_LU_CRL)
+		return(strncmp(attr, ATTR_CACRL, sizeof(ATTR_CACRL)) != 0);
+
+	return(0);
+}
+
+
+/*
+ * We will put into store X509 object from passed data in buffer only
+ * when object name match passed. To compare both names we use our
+ * method "ssh_X509_NAME_cmp"(it is more general).
+ */
+static int/*bool*/
+ldaplookup_data2store(
+	int         type,
+	X509_NAME*  name,
+	void*       buf,
+	int         len,
+	X509_STORE* store
+) {
+	int ok = 0;
+	BIO *mbio;
+
+	if (name == NULL) return(0);
+	if (buf == NULL) return(0);
+	if (len <= 0) return(0);
+	if (store == NULL) return(0);
+
+	mbio = BIO_new_mem_buf(buf, len);
+	if (mbio == NULL) return(0);
+
+	switch (type) {
+	case X509_LU_X509: {
+		X509 *x509 = d2i_X509_bio(mbio, NULL);
+		if(x509 == NULL) goto exit;
+
+		/*This is correct since lookup method is by subject*/
+		if (ssh_X509_NAME_cmp(name, X509_get_subject_name(x509)) != 0) goto exit;
+
+		ok = X509_STORE_add_cert(store, x509);
+		} break;
+	case X509_LU_CRL: {
+		X509_CRL *crl = d2i_X509_CRL_bio(mbio, NULL);
+		if(crl == NULL) goto exit;
+
+		if (ssh_X509_NAME_cmp(name, X509_CRL_get_issuer(crl)) != 0) goto exit;
+
+		ok = X509_STORE_add_crl(store, crl);
+		} break;
+	}
+
+exit:
+	if (mbio != NULL) BIO_free_all(mbio);
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_data2store: ok=%d\n", ok);
+#endif
+	return(ok);
+}
+
+
+static int
+ldaplookup_result2store(
+	int          type,
+	X509_NAME*   name,
+	LDAP*        ld,
+	LDAPMessage* res,
+	X509_STORE*  store
+) {
+	int count = 0;
+	int result;
+	LDAPMessage *entry;
+
+	result = ldap_count_entries(ld, res);
+	if (result < 0) {
+		X509byLDAPerr(X509byLDAP_F_RESULT2STORE, X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES);
+		ldaplookup_parse_result (ld, res);
+		goto done;
+	}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: ldap_count_entries=%d\n", result);
+#endif
+
+	for(entry = ldap_first_entry(ld, res);
+	    entry != NULL;
+	    entry = ldap_next_entry(ld, entry)
+	) {
+		char *attr;
+		BerElement *ber;
+#ifdef TRACE_BY_LDAP
+{
+char *dn = ldap_get_dn(ld, entry);
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store(): ldap_get_dn=%s\n", dn);
+ldap_memfree(dn);
+}
+#endif
+		for(attr = ldap_first_attribute(ld, entry, &ber);
+		    attr != NULL;
+		    attr = ldap_next_attribute(ld, entry, ber)
+		) {
+			struct berval **vals;
+			struct berval **p;
+
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: attr=%s\n", attr);
+#endif
+			if (!ldaplookup_check_attr(type, attr))	continue;
+
+			vals = ldap_get_values_len(ld, entry, attr);
+			if (vals == NULL) continue;
+
+			for(p = vals; *p; p++) {
+				struct berval *q = *p;
+				if (ldaplookup_data2store(type, name, q->bv_val, q->bv_len, store)) {
+					count++;
+				}
+			}
+			ldap_value_free_len(vals);
+		}
+		ber_free(ber, 0);
+	}
+done:
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: count=%d\n", count);
+#endif
+	return(count);
+}
+
+
+static int
+ldaplookup_by_subject(
+	X509_LOOKUP *ctx,
+	int          type,
+	X509_NAME   *name,
+	X509_OBJECT *ret
+) {
+	int count = 0;
+	ldaphost *lh;
+	const char *attrs[2];
+	char *filter = NULL;
+
+
+	if (ctx == NULL) return(0);
+	if (name == NULL) return(0);
+
+	lh = (ldaphost*) ctx->method_data;
+	if (lh == NULL) return(0);
+
+	switch(type) {
+	case X509_LU_X509: {
+		attrs[0] = ATTR_CACERT;
+		} break;
+	case X509_LU_CRL: {
+		attrs[0] = ATTR_CACRL;
+		} break;
+	default: {
+		X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_WRONG_LOOKUP_TYPE);
+		goto done;
+		}
+	}
+	attrs[1] = NULL;
+
+	filter = ldaplookup_filter(name, attrs[0]);
+	if (filter == NULL) {
+		X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_GET_FILTER);
+		goto done;
+	}
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: filter=%s\n", filter);
+#endif
+
+	for (; lh != NULL; lh = lh->next) {
+		LDAPMessage *res = NULL;
+		int result;
+
+#ifdef TRACE_BY_LDAP
+{
+int version = -1;
+
+ldap_get_option(lh->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject:"
+" bind to \"%s://%s:%d\""
+" using ldap v%d protocol\n"
+, lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port
+, version
+);
+}
+#endif
+
+		result = ldaplookup_bind_s(lh->ld);
+		if (result != LDAP_SUCCESS) {
+			X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_BIND);
+			{
+				char	buf[1024];
+				snprintf(buf, sizeof(buf),
+					" url=\"%s://%s:%d\""
+					" ldaperror=0x%x(%.256s)"
+					, lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port
+					, result, ldap_err2string(result)
+				);
+				ERR_add_error_data(1, buf);
+			}
+			continue;
+		}
+
+		result = ldaplookup_search_s(lh->ld, lh->ldapurl->lud_dn,
+				LDAP_SCOPE_SUBTREE, filter, (char**)attrs, 0, &res);
+		if (result != LDAP_SUCCESS) {
+			X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_SEARCH_FAIL);
+			ldap_msgfree(res);
+			continue;
+		}
+
+		result = ldaplookup_result2store(type, name, lh->ld, res, ctx->store_ctx);
+		if (result > 0) count += result;
+
+		ldap_msgfree(res);
+
+		/*do not call ldap_unbind_s*/
+	}
+
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: count=%d\n", count);
+#endif
+	if (count > 0) {
+		X509_OBJECT *tmp;
+
+		X509_STORE_lock(ctx->store_ctx);
+		{	STACK_OF(X509_OBJECT) *objs;
+			objs = X509_STORE_get0_objects(ctx->store_ctx);
+			tmp = X509_OBJECT_retrieve_by_subject(objs, type, name);
+		}
+		X509_STORE_unlock(ctx->store_ctx);
+#ifdef TRACE_BY_LDAP
+fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: tmp=%p\n", (void*)tmp);
+#endif
+
+		if (tmp == NULL) {
+			count = 0;
+			goto done;
+		}
+
+		ret->type = tmp->type;
+		memcpy(&ret->data, &tmp->data, sizeof(ret->data));
+	}
+
+done:
+	if (filter != NULL) OPENSSL_free(filter);
+	return(count > 0);
+}
diff -ruN openssh-7.5p1/x509_by_ldap.h openssh-7.5p1+x509-10.2/x509_by_ldap.h
--- openssh-7.5p1/x509_by_ldap.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/x509_by_ldap.h	2015-07-01 22:07:31.250331265 +0300
@@ -0,0 +1,94 @@
+#ifndef X509_BY_LDAP_H
+#define X509_BY_LDAP_H
+/*
+ * Copyright (c) 2004-2015 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* openssh specific includes */
+#include "includes.h"
+#ifndef LDAP_ENABLED
+#  include "error: LDAP is disabled"
+#endif
+
+/* required includes */
+#include <openssl/x509_vfy.h>
+#include <openssl/err.h>
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+X509_LOOKUP_METHOD* X509_LOOKUP_ldap(void);
+
+#define X509_L_LDAP_HOST	1
+#define X509_L_LDAP_VERSION	2
+
+#define X509_LOOKUP_add_ldap(x,value) \
+		X509_LOOKUP_ctrl((x),X509_L_LDAP_HOST,(value),(long)(0),NULL)
+#define X509_LOOKUP_set_protocol(x,value) \
+		X509_LOOKUP_ctrl((x),X509_L_LDAP_VERSION,(value),(long)(0),NULL)
+
+
+/* Error codes for the X509byLDAP functions. */
+#ifdef NO_ERR /* openssl < 0.7.x */
+#  define OPENSSL_NO_ERR /* openssl >= 0.7.x */
+#endif
+
+#ifndef OPENSSL_NO_ERR
+
+void ERR_load_X509byLDAP_strings(void);
+
+/* library */
+/* BEGIN ERROR CODES */
+
+/* Function codes. */
+#define X509byLDAP_F_LOOKUPCRTL			100
+#define X509byLDAP_F_LDAPHOST_NEW		101
+#define X509byLDAP_F_SET_PROTOCOL		102
+#define X509byLDAP_F_RESULT2STORE		103
+#define X509byLDAP_F_GET_BY_SUBJECT		104
+
+/* Reason codes. */
+#define X509byLDAP_R_INVALID_CRTLCMD			100
+#define X509byLDAP_R_NOT_LDAP_URL			101
+#define X509byLDAP_R_INVALID_URL			102
+#define X509byLDAP_R_INITIALIZATION_ERROR		103
+#define X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION	104
+#define X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION	105
+#define X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES		106
+#define X509byLDAP_R_WRONG_LOOKUP_TYPE			107
+#define X509byLDAP_R_UNABLE_TO_GET_FILTER		108
+#define X509byLDAP_R_UNABLE_TO_BIND			109
+#define X509byLDAP_R_SEARCH_FAIL			110
+
+#endif /*ndef OPENSSL_NO_ERR*/
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#endif /*ndef X509_BY_LDAP_H*/
diff -ruN openssh-7.5p1/x509_nm_cmp.c openssh-7.5p1+x509-10.2/x509_nm_cmp.c
--- openssh-7.5p1/x509_nm_cmp.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/x509_nm_cmp.c	2017-02-22 21:32:00.136967255 +0200
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2005-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* initial code is moved from ssh-x509.c */
+#include "includes.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#include "x509store.h"
+#include "log.h"
+#include "xmalloc.h"
+
+/* NOTE: OpenSSL ASN1_STRING methods surprisingly require non-const
+ * ASN1_STRING arguments! With replace from macros to methods we
+ * also change our definitions to non-const ASN1_STRING.
+ */
+
+
+#if 1
+#  define COMPARE_X509_NAME_ENTRY_OBJECT
+#endif
+
+#ifdef COMPARE_X509_NAME_ENTRY_OBJECT
+static int
+ssh_ASN1_OBJECT_cmp(ASN1_OBJECT *a, ASN1_OBJECT *b) {
+	int a_length;
+	int b_length;
+	int ret;
+
+	a_length = i2d_ASN1_OBJECT(a, NULL);
+	b_length = i2d_ASN1_OBJECT(b, NULL);
+
+{
+	unsigned char *a_data = malloc(a_length);
+	unsigned char *b_data = malloc(b_length);
+	int lmin = MIN(a_length, b_length);
+
+	if (a_data == NULL) return(1);
+	if (b_data == NULL) return(-1);
+
+{	unsigned char *p = a_data;
+	(void)i2d_ASN1_OBJECT(a, &p);
+}
+{	unsigned char *p = b_data;
+	(void)i2d_ASN1_OBJECT(a, &p);
+}
+
+	ret = memcmp(a_data, b_data, lmin);
+
+	free(a_data);
+	free(b_data);
+}
+
+	return((ret == 0)
+		? (b_length - a_length)
+		: ret);
+}
+#endif /*def COMPARE_X509_NAME_ENTRY_OBJECT*/
+
+
+static int
+ssh_ASN1_STRING_casecmp(ASN1_STRING *a, ASN1_STRING *b) {
+	const u_char *sa, *sb;
+	int la, lb;
+
+	ssh_ASN1_STRING_get0_data(a, &sa, &la);
+	ssh_ASN1_STRING_get0_data(b, &sb, &lb);
+
+	return((strncasecmp(sa, sb, MIN(la, lb)) != 0) ? (lb - la) : 0);
+}
+
+
+/* - from RFC3280 (obsoletes: 2459)
+ *   (d) attribute values in PrintableString are compared after
+ *   removing leading and trailing white space and converting internal
+ *   substrings of one or more consecutive white space characters to a
+ *   single space.
+ * - from RFC5280 (obsoletes: 3280, 4325, 4630)
+ *  Before comparing names using the caseIgnoreMatch matching rule,
+ *  conforming implementations MUST perform the six-step string
+ *  preparation algorithm described in [RFC4518] for each attribute of
+ *  type DirectoryString, with the following clarifications:
+ *     *  In step 2, Map, the mapping shall include case folding as
+ *        specified in Appendix B.2 of [RFC3454].
+ *     *  In step 6, Insignificant Character Removal, perform white space
+ *        compression as specified in Section 2.6.1, Insignificant Space
+ *        Handling, of [RFC4518].
+ * NOTE: In "Section 2.6.1, Insignificant Space Handling, of RFC4518"
+ *  space is defined to be the "SPACE (U+0020) code point followed by
+ *  no combining marks".
+ */
+static int
+ssh_printable_casecmp(const u_char *pa, int la, const u_char *pb, int lb)
+{
+/*
+ * Be careful: this method work fine only in "C(POSIX)" locale.
+ * Since OpenSSH now run without to set locale, i.e.
+ * following comparision is OK.
+ * This implementation should be changed for other locales !!!
+ *
+ * Note pa or pb may contain utf8 characters !
+ */
+	/* skip leading spaces */
+	for (; la > 0 && isspace((int)*pa); la--, pa++);
+	for (; lb > 0 && isspace((int)*pb); lb--, pb++);
+
+	/* skip trailing spaces */
+	{
+		const u_char *p;
+		for (p = pa + la - 1; la > 0 && isspace((int)*p); la--, p--);
+		for (p = pb + lb - 1; lb > 0 && isspace((int)*p); lb--, p--);
+	}
+
+	while (la > 0 && lb > 0)
+	{
+		int chA = tolower((int)*pa);
+		int chB = tolower((int)*pb);
+
+		if (chA != chB)
+			return(chB - chA);
+
+		pa++; pb++;
+		la--; lb--;
+		if (isspace(chA)) {
+			/* skip inner spaces */
+			for (; la > 0 && isspace((int)*pa); la--, pa++);
+			for (; lb > 0 && isspace((int)*pb); lb--, pb++);
+		}
+	}
+	return(lb - la);
+}
+
+
+static int
+ssh_ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) {
+/*
+ * Note before OpenSSL versions 0.9.7e method ASN1_STRING_to_UTF8
+ * fail when ASN1_STRING is utf8String !
+ */
+	int tag;
+	const u_char *s;
+	int l;
+
+	if (!in) return(-1);
+
+	tag = ASN1_STRING_type(in);
+	if (tag != V_ASN1_UTF8STRING) {
+		return(ASN1_STRING_to_UTF8(out, in));
+	}
+
+	ssh_ASN1_STRING_get0_data(in, &s, &l);
+	if (out) {
+		u_char *p;
+
+		if (*out) {
+			error("ssh_ASN1_STRING_to_UTF8: *out is not NULL");
+			return(-1);
+		}
+		/* we MUST allocate memory with OPENSSL method! */
+		p = OPENSSL_malloc(l + 1);
+		if (p == NULL) {
+			fatal("ssh_ASN1_STRING_to_UTF8: out of memory (allocating %d bytes)", (l + 1));
+		}
+		memcpy(p, s, l);
+		p[l] = 0;
+		*out = p;
+	}
+	return(l);
+}
+
+
+static int
+ssh_ASN1_PRINTABLESTRING_cmp(ASN1_STRING *a, ASN1_STRING *b) {
+	int n = -1;
+	int tagA, tagB;
+	int la, lb;
+	const u_char *pa, *pb;
+	u_char *ua = NULL, *ub = NULL;
+
+	tagA = ASN1_STRING_type(a);
+	tagB = ASN1_STRING_type(b);
+	if (tagA != V_ASN1_PRINTABLESTRING) {
+		debug3("ssh_ASN1_PRINTABLESTRING_cmp: a->type=%d(%.30s) is not PrintableString", tagA, ASN1_tag2str(tagA));
+		/* just in case - see caling methods */
+		if (tagB != V_ASN1_PRINTABLESTRING) {
+			error("ssh_ASN1_PRINTABLESTRING_cmp: b is not PrintableString too");
+			return(-1);
+		}
+	}
+	if (tagB != V_ASN1_PRINTABLESTRING) {
+		debug3("ssh_ASN1_PRINTABLESTRING_cmp: b->type=%d(%.30s) is not PrintableString", tagB, ASN1_tag2str(tagB));
+		/* just in case - see caling methods */
+		if (tagA != V_ASN1_PRINTABLESTRING) {
+			error("ssh_ASN1_PRINTABLESTRING_cmp: a is not PrintableString too");
+			return(1);
+		}
+	}
+
+	if (tagA == tagB) {
+		/*both are PrintableString*/
+		ssh_ASN1_STRING_get0_data(a, &pa, &la);
+		ssh_ASN1_STRING_get0_data(a, &pb, &lb);
+	} else {
+		/*convert strings to utf8*/
+		la = ssh_ASN1_STRING_to_UTF8(&ua, a);
+		if (la <= 0) {
+			/*first string is lower in case of error or zero length*/
+			n = -1;
+			goto done;
+		}
+		lb = ssh_ASN1_STRING_to_UTF8(&ub, b);
+		if (lb <= 0) {
+			/*second string is greater in case of error or zero length*/
+			n = 1;
+			goto done;
+		}
+		pa = ua;
+		pb = ub;
+	}
+
+	n = ssh_printable_casecmp(pa, la, pb, lb);
+
+done:
+	if(ua) OPENSSL_free(ua);
+	if(ub) OPENSSL_free(ub);
+#ifdef SSHX509TEST_DBGCMP
+fprintf(stderr, "ssh_ASN1_PRINTABLESTRING_cmp: return %d\n", n);
+#endif
+	return(n);
+}
+
+
+/*
+ * =====================================================================
+ * from RFC3280 and oldest 2459:
+ * DirectoryString ::= CHOICE {
+ *        teletexString           TeletexString (SIZE (1..MAX)),
+ *        printableString         PrintableString (SIZE (1..MAX)),
+ *        universalString         UniversalString (SIZE (1..MAX)),
+ *        utf8String              UTF8String (SIZE (1..MAX)),
+ *        bmpString               BMPString (SIZE (1..MAX)) }
+ *.....
+ * The DirectoryString type is defined as a choice of PrintableString,
+ * TeletexString, BMPString, UTF8String, and UniversalString.  The
+ * UTF8String encoding is the preferred encoding, and all certificates
+ * issued after December 31, 2003 MUST use the UTF8String encoding of
+ * DirectoryString (except as noted below).  Until that date, conforming
+ * CAs MUST choose from the following options when creating a
+ * distinguished name, including their own:
+ *    (a) if the character set is sufficient, the string MAY be
+ *    represented as a PrintableString;
+ *    (b) failing (a), if the BMPString character set is sufficient the
+ *    string MAY be represented as a BMPString; and
+ *    (c) failing (a) and (b), the string MUST be represented as a
+ *    UTF8String.  If (a) or (b) is satisfied, the CA MAY still choose
+ *    to represent the string as a UTF8String.
+ *.....
+ * later in RFCs:
+ *    (a) attribute values encoded in different types (e.g.,
+ *    PrintableString and BMPString) may be assumed to represent
+ *    different strings;
+ *    (b) attribute values in types other than PrintableString are case
+ *    sensitive (this permits matching of attribute values as binary
+ *    objects);
+ *    (c) attribute values in PrintableString are not case sensitive
+ *    (e.g., "Marianne Swanson" is the same as "MARIANNE SWANSON"); and
+ *    (d) attribute values in PrintableString are compared after
+ *    removing leading and trailing white space and converting internal
+ *    substrings of one or more consecutive white space characters to a
+ *    single space.
+ * =====================================================================
+ *
+ * OpenSSH implementation:
+ * - assume that all DirectoryStrings represent same strings regardless
+ * of type. When strings are from different types they will be converted
+ * to utf8 before comparison.
+ * - when one of the strings is PrintableString they will be compared
+ * with method that ignore cases and spaces and convert to utf8
+ * if necessary.
+ *
+ * Note calling method shoud ensure that both strings are
+ * DirectoryString !!!
+ */
+static int
+ssh_ASN1_DIRECTORYSTRING_cmp(ASN1_STRING *a, ASN1_STRING *b) {
+/* NOTE:
+ * - RFC3280 required only binary comparison of attribute values encoded in
+ * UTF8String.
+ * - RFC5280 conforming implementations for DirectoryString type MUST support
+ * name comparisons using caseIgnoreMatch - see Appendix B.2 of RFC3454.
+ */
+	int n = -1;
+	int tagA, tagB;
+	int la, lb;
+	const u_char *pa, *pb;
+	u_char *ua = NULL, *ub = NULL;
+
+	tagA = ASN1_STRING_type(a);
+	tagB = ASN1_STRING_type(b);
+
+	/* just in case of PrintableString - see caling method ;-) */
+	if ((tagA == V_ASN1_PRINTABLESTRING) ||
+	    (tagB == V_ASN1_PRINTABLESTRING) ) {
+		/*
+		 * one is PrintableString and we will compare
+		 * according rules for PrintableString.
+		 */
+		return(ssh_ASN1_PRINTABLESTRING_cmp(a, b));
+	}
+/*....*/
+	if (tagA == tagB) {
+		ssh_ASN1_STRING_get0_data(a, &pa, &la);
+		ssh_ASN1_STRING_get0_data(b, &pb, &lb);
+	} else {
+		/*convert both string to utf8*/
+		la = ssh_ASN1_STRING_to_UTF8(&ua, a);
+		if (la <= 0) {
+			/*first string is lower in case of error or zero length*/
+			n = -1;
+			goto done;
+		}
+		lb = ssh_ASN1_STRING_to_UTF8(&ub, b);
+		if (lb <= 0) {
+			/*second string is greater in case of error or zero length*/
+			logit("ssh_ASN1_DIRECTORYSTRING_cmp lb=%d", lb);
+			n = 1;
+			goto done;
+		}
+#ifdef SSHX509TEST_DBGCMP
+fprintf(stderr, "ssh_ASN1_DIRECTORYSTRING_cmp ua='%s'\n", ua);
+fprintf(stderr, "ssh_ASN1_DIRECTORYSTRING_cmp ub='%s'\n", ub);
+#endif
+		pa = (const char *)ua;
+		pb = (const char *)ub;
+	}
+
+	n = memcmp(pa, pb, (size_t)MIN(la, lb));
+#ifdef SSHX509TEST_DBGCMP
+fprintf(stderr, "ssh_ASN1_DIRECTORYSTRING_cmp n=%d, la=%d, lb=%d\n", n, la, lb);
+#endif
+	if (n == 0) n = (lb - la);
+
+done:
+	if(ua) OPENSSL_free(ua);
+	if(ub) OPENSSL_free(ub);
+#ifdef SSHX509TEST_DBGCMP
+fprintf(stderr, "ssh_ASN1_DIRECTORYSTRING_cmp: return %d\n", n);
+#endif
+	return(n);
+}
+
+
+static int/*bool*/
+ssh_is_DirectoryString(ASN1_STRING* s) {
+	int tag = ASN1_STRING_type(s);
+
+	switch(tag) {
+	case V_ASN1_T61STRING: /*==V_ASN1_TELETEXSTRING*/
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_BMPSTRING:
+		return(1);
+	default:
+		return(0);
+	}
+}
+
+
+/*
+ * 1.)
+ *   Since version 0.9.7.beta4 and 0.9.6h OpenSSL function X509_NAME_cmp
+ *   is more restrictive but more correct (!).
+ *   Problem is that some x509 implementation set X509_NAME entry
+ *   incorrectly to "Printable String" :-[ .
+ *   Work around: when one entry is "Printable String" method compare
+ *   to corresponding entry as "Printable String".
+ * 2.)
+ *   OpenSSL functions X509_NAME_cmp check nids order in X509_NAME.
+ *   i.e. X509_NAME{"/C=XX/O=YY"} is not equal to X509_NAME{"/O=YY/C=XX"}
+ */
+int
+ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b) {
+	int k, n;
+	X509_NAME *b;
+
+#if 1
+	/*XXX: to call fatal when _a or _b is NULL or to use next*/
+	if (_a == NULL) {
+		return((_b == NULL) ? 0 : 1);
+	} else {
+		if (_b == NULL) return(-1);
+	}
+#else
+	if (_a == NULL) {
+		fatal("ssh_X509_NAME_cmp: first name is NULL");
+	}
+	if (_b == NULL) {
+		fatal("ssh_X509_NAME_cmp: second name is NULL");
+	}
+#endif
+
+	k = X509_NAME_entry_count(_a);
+	n = X509_NAME_entry_count(_b);
+
+	if (k != n)
+		return(n - k);
+
+	b = X509_NAME_dup(_b);
+	n = 0;
+	for (--k; k >= 0; k--) {
+		X509_NAME_ENTRY *neA;
+		ASN1_STRING     *nvA;
+		ASN1_OBJECT     *noA;
+		int nid;
+		X509_NAME_ENTRY *neB;
+		ASN1_STRING     *nvB;
+	#ifdef COMPARE_X509_NAME_ENTRY_OBJECT
+		ASN1_OBJECT     *noB;
+	#endif
+		int              loc;
+
+		neA = X509_NAME_get_entry(_a, k);
+		nvA = X509_NAME_ENTRY_get_data(neA);
+		noA = X509_NAME_ENTRY_get_object(neA);
+		nid = OBJ_obj2nid(noA);
+		loc = X509_NAME_get_index_by_NID(b, nid, -1);
+		if (loc < 0) {
+			char *buf1, *buf2;
+
+			buf1 = ssh_X509_NAME_oneline(_a); /*fatal on error*/
+			buf2 = ssh_X509_NAME_oneline(_b); /*fatal on error*/
+			debug3("ssh_X509_NAME_cmp: insufficient entries with nid=%d(%.40s) in second name."
+				" na=%s, nb=%s",
+				nid, OBJ_nid2ln(nid),
+				buf1, buf2);
+			free(buf1);
+			free(buf2);
+			n = -1;
+			break;
+		}
+trynextentry:
+		neB = X509_NAME_get_entry(b, loc);
+		nvB = X509_NAME_ENTRY_get_data(neB);
+#ifdef SSHX509TEST_DBGCMP
+{
+	int l, tag;
+
+	l   = ASN1_STRING_length(nvA);
+	tag = ASN1_STRING_type  (nvA);
+	fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l);
+	ASN1_STRING_print_ex_fp(stderr, nvA, /*flags*/0);
+	fputs("'\n", stderr);
+
+	l   = ASN1_STRING_length(nvB);
+	tag = ASN1_STRING_type  (nvB);
+	fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l);
+	ASN1_STRING_print_ex_fp(stderr, nvB, /*flags*/0);
+	fputs("'\n", stderr);
+}
+#endif
+
+		if (nid == NID_pkcs9_emailAddress) {
+			int tag;
+
+			tag = ASN1_STRING_type(nvA);
+			if (tag != V_ASN1_IA5STRING) {
+				/* to be strict and return nonzero or ... ? XXX
+				n = -1;
+				break;
+				*/
+				error("ssh_X509_NAME_cmp: incorrect type for emailAddress(a) %d(%.30s)", tag, ASN1_tag2str(tag));
+			}
+
+			tag = ASN1_STRING_type(nvB);
+			if (tag != V_ASN1_IA5STRING) {
+				/* to be strict and return nonzero or ... ? XXX
+				n = 1;
+				break;
+				*/
+				error("ssh_X509_NAME_cmp: incorrect type for emailAddress(b) %d(%.30s)", tag, ASN1_tag2str(tag));
+			}
+
+			n = ssh_ASN1_STRING_casecmp(nvA, nvB);
+			if (n == 0) goto entryisok;
+
+			goto getnextentry;
+		}
+		if ((ASN1_STRING_type(nvA) == V_ASN1_PRINTABLESTRING) ||
+		    (ASN1_STRING_type(nvB) == V_ASN1_PRINTABLESTRING) ) {
+			n = ssh_ASN1_PRINTABLESTRING_cmp(nvA, nvB);
+			if (n == 0) goto entryisok;
+
+			goto getnextentry;
+		}
+		if (ssh_is_DirectoryString(nvA) &&
+		    ssh_is_DirectoryString(nvB)) {
+			n = ssh_ASN1_DIRECTORYSTRING_cmp(nvA, nvB);
+			if (n == 0) goto entryisok;
+
+			goto getnextentry;
+		}
+
+		n = ASN1_STRING_length(nvA) - ASN1_STRING_length(nvB);
+		if (n != 0) goto getnextentry;
+
+		n = ASN1_STRING_length(nvA);
+		n = memcmp(nvA->data, nvB->data, n);
+		if (n != 0) goto getnextentry;
+
+#ifdef COMPARE_X509_NAME_ENTRY_OBJECT
+/* NAME_ENTRY object is field name. We could omit object compare
+ * as we peek from second name entry with same nid as current
+ */
+		/* openssl check object too */
+		noB = X509_NAME_ENTRY_get_object(neB);
+		n = ssh_ASN1_OBJECT_cmp(noA, noB);
+		if (n != 0) goto getnextentry;
+#endif
+
+entryisok:
+		{
+			X509_NAME_ENTRY *ne = X509_NAME_delete_entry(b, loc);
+			X509_NAME_ENTRY_free(ne);
+		}
+		continue;
+getnextentry:
+		loc = X509_NAME_get_index_by_NID(b, nid, loc);
+		if (loc < 0) {
+			break;
+		}
+		goto trynextentry;
+	}
+
+	X509_NAME_free(b);
+#ifdef SSHX509TEST_DBGCMP
+fprintf(stderr, "ssh_X509_NAME_cmp: return %d\n", n);
+#endif
+	return(n);
+}
diff -ruN openssh-7.5p1/x509store.c openssh-7.5p1+x509-10.2/x509store.c
--- openssh-7.5p1/x509store.c	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/x509store.c	2017-02-22 21:32:00.136967255 +0200
@@ -0,0 +1,1352 @@
+/*
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "x509store.h"
+#include <openssl/x509v3.h>
+#include "log.h"
+
+#include <string.h>
+#include <openssl/err.h>
+
+#include "xmalloc.h"
+#include "pathnames.h"
+#include "misc.h"
+#include <openssl/x509_vfy.h>
+#ifdef LDAP_ENABLED
+#  include "x509_by_ldap.h"
+#endif
+
+#ifndef HAVE_X509_STORE_SET_VERIFY_CB		/* OpenSSL < 1.0.0 */
+static inline void
+X509_STORE_set_verify_cb(X509_STORE *ctx, int (*verify_cb) (int, X509_STORE_CTX *)) {
+	ctx->verify_cb = verify_cb;
+}
+#endif /*ndef HAVE_X509_STORE_SET_VERIFY_CB*/
+
+/* "bye, bye xfree()" ;) */
+#define xfree free
+
+
+SSH_X509Flags
+ssh_x509flags = {
+	0,	/* is_server */
+	-1,	/* allowedcertpurpose */
+	-1,	/* key_allow_selfissued */
+	-1	/* mandatory_crl */
+};
+
+
+static X509_STORE	*x509store = NULL;
+
+
+#if 0
+# define USE_X509_STORE_CTX_INDEX	1
+#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
+/* Temporary work-arround for opaque structure X509_VERIFY_PARAM
+ * in OpenSSL master branch (version 1.1)
+ */
+#  ifndef USE_X509_STORE_CTX_INDEX
+#    define USE_X509_STORE_CTX_INDEX	1
+#  endif
+#endif
+
+
+#ifdef USE_X509_STORE_CTX_INDEX
+static int	ssh_X509_STORE_CTX_index = -1;
+
+struct ssh_X509_STORE_CTX_data_st {
+	time_t	check_time;
+};
+
+typedef struct ssh_X509_STORE_CTX_data_st SSH_X509_STORE_CTX_DATA;
+
+
+static inline SSH_X509_STORE_CTX_DATA*
+SSH_X509_STORE_CTX_DATA_new(void) {
+	SSH_X509_STORE_CTX_DATA *p;
+
+	p = malloc(sizeof(SSH_X509_STORE_CTX_DATA));
+	if (p != NULL) {
+		p->check_time = 0;
+	}
+	return (p);
+}
+
+static inline void
+SSH_X509_STORE_CTX_DATA_free(SSH_X509_STORE_CTX_DATA* p) {
+	free(p);
+}
+#endif /*def USE_X509_STORE_CTX_INDEX*/
+
+
+#ifndef HAVE_X509_CRL_GET0_LASTUPDATE		/* OpenSSL < 1.1 */
+static inline const ASN1_TIME*
+X509_CRL_get0_lastUpdate(const X509_CRL *crl) {
+	return X509_CRL_get_lastUpdate(crl);
+}
+
+static inline const ASN1_TIME*
+X509_CRL_get0_nextUpdate(const X509_CRL *crl) {
+	return X509_CRL_get_nextUpdate(crl);
+}
+#endif /* ndef HAVE_X509_CRL_GET0_LASTUPDATE	OpenSSL < 1.1 */
+
+
+#ifndef HAVE_X509_OBJECT_NEW	/* OpenSSL < 1.1 */
+/* backport specific OpenSSL X509_OBJECT functions */
+static inline X509_OBJECT*
+X509_OBJECT_new(void) {
+	X509_OBJECT *xobj;
+
+	xobj = OPENSSL_malloc(sizeof (X509_OBJECT));
+	if (xobj != NULL) {
+		memset(xobj, '\0', sizeof(*xobj));
+		xobj->type = X509_LU_FAIL;
+	}
+	return(xobj);
+}
+
+static inline void
+X509_OBJECT_free(X509_OBJECT *xobj) {
+	if (xobj == NULL) return;
+
+	X509_OBJECT_free_contents(xobj);
+	OPENSSL_free(xobj);
+}
+
+static inline X509*
+X509_OBJECT_get0_X509(const X509_OBJECT *xobj) {
+	if (xobj == NULL) return NULL;
+	if (xobj->type != X509_LU_X509) return NULL;
+
+	return(xobj->data.x509);
+}
+
+static inline X509_CRL*
+X509_OBJECT_get0_X509_CRL(const X509_OBJECT *xobj) {
+	if (xobj == NULL) return NULL;
+	if (xobj->type != X509_LU_CRL) return NULL;
+
+	return(xobj->data.crl);
+}
+#endif /*ndef HAVE_X509_OBJECT_NEW*/
+
+
+#if 1
+#  define SSH_CHECK_REVOKED
+#endif
+
+
+#ifdef SSH_CHECK_REVOKED
+static X509_STORE	*x509revoked = NULL;
+static int ssh_x509revoked_cb(int ok, X509_STORE_CTX *ctx);
+
+
+static char *
+ssh_ASN1_INTEGER_2_string(ASN1_INTEGER *_asni) {
+	BIO  *bio;
+	int   k;
+	char *p;
+
+	if (_asni == NULL) {
+		error("ssh_ASN1_INTEGER_2_string: _asni is NULL");
+		return(NULL);
+	}
+
+	bio = BIO_new(BIO_s_mem());
+	if (bio == NULL) {
+		fatal("ssh_ASN1_INTEGER_2_string: out of memory");
+		return(NULL); /* ;-) */
+	}
+
+	i2a_ASN1_INTEGER(bio, _asni);
+	k = BIO_pending(bio);
+	p = xmalloc(k + 1); /*fatal on error*/
+	k = BIO_read(bio, p, k);
+	p[k] = '\0';
+	BIO_free_all(bio);
+
+	return(p);
+}
+#endif /*def SSH_CHECK_REVOKED*/
+
+
+static int
+ssh_x509store_lookup(X509_STORE *store, int type, X509_NAME *name, X509_OBJECT *xobj) {
+	X509_STORE_CTX *csc;
+	int ret = -1;
+
+	csc = X509_STORE_CTX_new();
+	if (csc == NULL) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("ssh_x509store_lookup: X509_STORE_CTX_new failed with '%.*s'",
+		      (int)sizeof(ebuf), ebuf);
+		return(-1);
+	}
+
+	if (X509_STORE_CTX_init(csc, store, NULL, NULL) <= 0) {
+		/*memory allocation error*/
+		error("ssh_x509store_lookup: cannot initialize x509store context");
+		goto done;
+	}
+	ret = X509_STORE_get_by_subject(csc, type, name, xobj);
+	X509_STORE_CTX_cleanup(csc);
+
+done:
+	X509_STORE_CTX_free(csc);
+
+	return(ret);
+}
+
+
+X509*
+ssh_x509store_get_cert_by_subject(X509_STORE *store, X509_NAME *name) {
+	X509 *ret = NULL;
+
+{	/* opaque use of X509_OBJECT */
+	X509_OBJECT *xobj;
+
+	xobj = X509_OBJECT_new();
+	if (xobj == NULL) {
+		error("ssh_x509store_get_cert_by_subject: cannot allocate X509_OBJECT");
+		return(NULL);
+	}
+
+	if (ssh_x509store_lookup(store, X509_LU_X509, name, xobj) > 0)
+		ret = X509_OBJECT_get0_X509(xobj);
+
+	X509_OBJECT_free(xobj);
+}
+
+	return(ret);
+}
+
+
+X509_CRL*
+ssh_x509store_get_crl_by_subject(X509_STORE *store, X509_NAME *name) {
+	X509_CRL *ret = NULL;
+
+{	/* opaque use of X509_OBJECT */
+	X509_OBJECT *xobj;
+
+	xobj = X509_OBJECT_new();
+	if (xobj == NULL) {
+		error("ssh_X509_STORE_get_X509_CRL_by_subject: cannot allocate X509_OBJECT");
+		return(NULL);
+	}
+
+	if (ssh_x509store_lookup(store, X509_LU_CRL, name, xobj) > 0)
+		ret = X509_OBJECT_get0_X509_CRL(xobj);
+
+	X509_OBJECT_free(xobj);
+}
+
+	return(ret);
+}
+
+
+static int
+ssh_x509store_cb(int ok, X509_STORE_CTX *ctx) {
+	int ctx_error = X509_STORE_CTX_get_error(ctx);
+	X509 *ctx_cert = X509_STORE_CTX_get_current_cert(ctx);
+	int self_signed = 0;
+
+	if ((!ok) &&
+	    (ctx_error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+	) {
+		if (ssh_x509flags.key_allow_selfissued) {
+			ok = ssh_X509_is_selfsigned(ctx_cert);
+			if (ok)
+				self_signed = 1;
+		}
+	}
+	if (!ok) {
+		char *buf;
+		buf = ssh_X509_NAME_oneline(X509_get_subject_name(ctx_cert)); /*fatal on error*/
+		error("ssh_x509store_cb: subject='%s', error %d at %d depth lookup:%.200s",
+			buf,
+			ctx_error,
+			X509_STORE_CTX_get_error_depth(ctx),
+			X509_verify_cert_error_string(ctx_error));
+		xfree(buf);
+	}
+#ifdef SSH_CHECK_REVOKED
+	if (ok && !self_signed) {
+		ok = ssh_x509revoked_cb(ok, ctx);
+	}
+#endif
+	return(ok);
+}
+
+
+typedef struct  {
+	const char **synonyms;
+}	CertPurposes;
+
+
+static const char *__purpose_any[] = {
+	"any", "any purpose", "any_purpose", "anypurpose", NULL
+};
+
+
+static const char *__purpose_sslclient[] = {
+	"sslclient", "ssl client", "ssl_client", "client", NULL
+};
+
+
+static const char *__purpose_sslserver[] = {
+	"sslserver", "ssl server", "ssl_server", "server", NULL
+};
+
+
+static CertPurposes
+sslclient_purposes[] = {
+	{ __purpose_sslclient },
+	{ __purpose_any },
+	{ NULL }
+};
+
+
+static CertPurposes
+sslserver_purposes [] = {
+	{ __purpose_sslserver },
+	{ __purpose_any },
+	{ NULL }
+};
+
+
+static const char*
+get_cert_purpose(const char* _purpose_synonym, CertPurposes *_purposes) {
+	int i;
+
+	for (i = 0; _purposes[i].synonyms; i++) {
+		const char *q = _purposes[i].synonyms[0];
+		if (strcasecmp(_purpose_synonym, q) == 0) {
+			return(q);
+		} else {
+			const char **p;
+			for (p = (_purposes[i].synonyms) + 1; *p; p++) {
+				if (strcasecmp(_purpose_synonym, *p) == 0 ) {
+					return(q);
+				}
+			}
+		}
+	}
+	return(NULL);
+}
+
+
+void
+ssh_x509flags_initialize(SSH_X509Flags *flags, int is_server) {
+	flags->is_server = is_server;
+	flags->allowedcertpurpose = -1;
+	flags->key_allow_selfissued = -1;
+	flags->mandatory_crl = -1;
+}
+
+
+void
+ssh_x509flags_defaults(SSH_X509Flags *flags) {
+	if (flags->allowedcertpurpose == -1) {
+		int is_server = flags->is_server;
+		const char* purpose_synonym = is_server ? __purpose_sslclient[0] : __purpose_sslserver[0];
+
+		flags->allowedcertpurpose = ssh_get_x509purpose_s(is_server, purpose_synonym);
+	}
+	if (flags->key_allow_selfissued == -1) {
+		flags->key_allow_selfissued = 0;
+	}
+#ifdef SSH_CHECK_REVOKED
+	if (flags->mandatory_crl == -1) {
+		flags->mandatory_crl = 0;
+	}
+#else
+	if (flags->mandatory_crl != -1) {
+		logit("useless option: mandatory_crl");
+	}
+#endif
+}
+
+
+int
+ssh_get_x509purpose_s(int _is_server, const char* _purpose_synonym) {
+	const char * sslpurpose;
+
+	sslpurpose = get_cert_purpose(_purpose_synonym,
+		(_is_server ? sslclient_purposes : sslserver_purposes));
+	if (sslpurpose != NULL) {
+		int purpose_index = X509_PURPOSE_get_by_sname((char*)sslpurpose);
+		if (purpose_index  < 0)
+			fatal(	"ssh_get_x509purpose_s(%.10s): "
+				"X509_PURPOSE_get_by_sname fail for argument '%.30s(%.40s)'",
+				(_is_server ? "server" : "client"),
+				sslpurpose, _purpose_synonym);
+		return(purpose_index);
+	}
+	return(-1);
+}
+
+
+char*
+format_x509_purpose(int purpose_index) {
+	X509_PURPOSE *xp;
+
+	xp = X509_PURPOSE_get0(purpose_index);
+	if (xp == NULL) {
+		fatal("format_x509_purpose: cannot get purpose from index");
+		return("skip"); /* ;-) */
+	}
+	return(X509_PURPOSE_get0_sname(xp));
+}
+
+
+int/*bool*/
+ssh_X509_is_selfsigned(X509 *_cert) {
+#ifdef EXFLAG_SS
+  /* OpenSSL 0.9.7+ */
+  #if 0
+    #define USE_EXFLAG_SS
+  #endif
+#endif
+#ifdef USE_EXFLAG_SS
+	X509_check_purpose(_cert, -1, 0); /* set flags */
+	return (_cert->ex_flags & EXFLAG_SS) != 0;
+#else
+	X509_NAME *issuer, *subject;
+
+	issuer  = X509_get_issuer_name(_cert);
+	subject = X509_get_subject_name(_cert);
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		char *buf;
+
+		buf = ssh_X509_NAME_oneline(issuer);  /*fatal on error*/
+		debug3("%s: issuer='%s'", __func__, buf);
+		xfree(buf);
+
+		buf = ssh_X509_NAME_oneline(subject); /*fatal on error*/
+		debug3("%s: subject='%s'", __func__, buf);
+		xfree(buf);
+	}
+
+	return (ssh_X509_NAME_cmp(issuer, subject) == 0);
+#endif
+}
+
+
+void
+X509StoreOptions_init(X509StoreOptions *options) {
+	options->certificate_file = NULL;
+	options->certificate_path = NULL;
+	options->revocation_file = NULL;
+	options->revocation_path = NULL;
+#ifdef LDAP_ENABLED
+	options->ldap_ver = NULL;
+	options->ldap_url = NULL;
+#endif
+}
+
+
+void
+X509StoreOptions_reset(X509StoreOptions *options) {
+	free((char*)options->certificate_file);	options->certificate_file = NULL;
+	free((char*)options->certificate_path);	options->certificate_path = NULL;
+	free((char*)options->revocation_file);		options->revocation_file = NULL;
+	free((char*)options->revocation_path);		options->revocation_path = NULL;
+#ifdef LDAP_ENABLED
+	free((char*)options->ldap_ver);		options->ldap_ver = NULL;
+	free((char*)options->ldap_url);		options->ldap_url = NULL;
+#endif
+}
+
+
+void
+X509StoreOptions_system_defaults(X509StoreOptions *options) {
+	if (options->certificate_file == NULL)
+		options->certificate_file = xstrdup(_PATH_CA_CERTIFICATE_FILE);
+	if (options->certificate_path == NULL)
+		options->certificate_path = xstrdup(_PATH_CA_CERTIFICATE_PATH);
+	if (options->revocation_file == NULL)
+		options->revocation_file = xstrdup(_PATH_CA_REVOCATION_FILE);
+	if (options->revocation_path == NULL)
+		options->revocation_path = xstrdup(_PATH_CA_REVOCATION_PATH);
+#ifdef LDAP_ENABLED
+	/*nothing to do ;-)*/
+#endif
+}
+
+
+static void
+tilde_expand_filename2(const char **_fn, const char* _default, uid_t uid) {
+	if (*_fn == NULL) {
+		*_fn = tilde_expand_filename(_default, uid);
+	} else {
+		const char *p = *_fn;
+		*_fn = tilde_expand_filename(p, uid);
+		xfree((void*)p);
+	}
+}
+
+
+void
+X509StoreOptions_user_defaults(X509StoreOptions *options, uid_t uid) {
+	tilde_expand_filename2(&options->certificate_file, _PATH_USERCA_CERTIFICATE_FILE, uid);
+	tilde_expand_filename2(&options->certificate_path, _PATH_USERCA_CERTIFICATE_PATH, uid);
+	tilde_expand_filename2(&options->revocation_file , _PATH_USERCA_REVOCATION_FILE , uid);
+	tilde_expand_filename2(&options->revocation_path , _PATH_USERCA_REVOCATION_PATH , uid);
+#ifdef LDAP_ENABLED
+	/*nothing to do ;-)*/
+#endif
+}
+
+
+static void
+ssh_x509store_initcontext(void) {
+#ifdef USE_X509_STORE_CTX_INDEX
+	if (ssh_X509_STORE_CTX_index < 0)
+		ssh_X509_STORE_CTX_index = X509_STORE_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+#endif
+	if (x509store == NULL) {
+		x509store = X509_STORE_new();
+		if (x509store == NULL) {
+			fatal("cannot create x509store context");
+		}
+		X509_STORE_set_verify_cb(x509store, ssh_x509store_cb);
+	}
+#ifdef SSH_CHECK_REVOKED
+	if (x509revoked == NULL) {
+		x509revoked = X509_STORE_new();
+		if (x509revoked == NULL) {
+			fatal("cannot create x509revoked context");
+		}
+	}
+#endif
+}
+
+
+void
+ssh_x509store_cleanup(void) {
+	if (x509store != NULL) {
+		X509_STORE_free(x509store);
+		x509store = NULL;
+	}
+#ifdef SSH_CHECK_REVOKED
+	if (x509revoked != NULL) {
+		X509_STORE_free(x509revoked);
+		x509revoked = NULL;
+	}
+#endif
+}
+
+
+int/*bool*/
+ssh_x509store_addlocations(const X509StoreOptions *_locations) {
+	int flag;
+
+	if (_locations == NULL) {
+		error("ssh_x509store_addlocations: _locations is NULL");
+		return(0);
+	}
+	if ((_locations->certificate_path == NULL) &&
+	    (_locations->certificate_file == NULL)) {
+		error("ssh_x509store_addlocations: certificate path and file are NULLs");
+		return(0);
+	}
+#ifdef SSH_CHECK_REVOKED
+	if ((_locations->revocation_path == NULL) &&
+	    (_locations->revocation_file == NULL)) {
+		error("ssh_x509store_addlocations: revocation path and file are NULLs");
+		return(0);
+	}
+#endif
+	ssh_x509store_initcontext();
+
+	flag = 0;
+	/*
+	 * Note:
+	 * After X509_LOOKUP_{add_dir|load_file} calls we must call
+	 * ERR_clear_error() otherwise when the first call to
+	 * X509_LOOKUP_XXXX fail the second call fail too !
+	 */
+	if (_locations->certificate_path != NULL) {
+		X509_LOOKUP *lookup = X509_STORE_add_lookup(x509store, X509_LOOKUP_hash_dir());
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add hash dir lookup !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_add_dir(lookup, _locations->certificate_path, X509_FILETYPE_PEM)) {
+			debug2("hash dir '%.400s' added to x509 store", _locations->certificate_path);
+			flag = 1;
+		}
+		ERR_clear_error();
+	}
+	if (_locations->certificate_file != NULL) {
+		X509_LOOKUP *lookup = X509_STORE_add_lookup(x509store, X509_LOOKUP_file());
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add file lookup !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_load_file(lookup, _locations->certificate_file, X509_FILETYPE_PEM)) {
+			debug2("file '%.400s' added to x509 store", _locations->certificate_file);
+			flag = 1;
+		}
+		ERR_clear_error();
+	}
+	/*at least one lookup should succeed*/
+	if (flag == 0) return(0);
+
+	flag = 0;
+#ifdef SSH_CHECK_REVOKED
+	if (_locations->revocation_path != NULL
+	/* NOTE configuration parser does not allow empty string but
+	 * we use enmpty string in ssh-agent to avoid blocking
+	 * exception above!
+	 */
+	&& _locations->revocation_path[0] != '\0'
+	) {
+		X509_LOOKUP *lookup = X509_STORE_add_lookup(x509revoked, X509_LOOKUP_hash_dir());
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add hash dir revocation lookup !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_add_dir(lookup, _locations->revocation_path, X509_FILETYPE_PEM)) {
+			debug2("hash dir '%.400s' added to x509 revocation store", _locations->revocation_path);
+			flag = 1;
+		}
+		ERR_clear_error();
+	}
+	if (_locations->revocation_file != NULL) {
+		X509_LOOKUP *lookup = X509_STORE_add_lookup(x509revoked, X509_LOOKUP_file());
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add file revocation lookup !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_load_file(lookup, _locations->revocation_file, X509_FILETYPE_PEM)) {
+			debug2("file '%.400s' added to x509 revocation store", _locations->revocation_file);
+			flag = 1;
+		}
+		ERR_clear_error();
+	}
+#else /*ndef SSH_CHECK_REVOKED*/
+	if (_locations->revocation_path != NULL) {
+		logit("useless option: revocation_path");
+	}
+	if (_locations->revocation_file != NULL) {
+		logit("useless option: revocation_file");
+	}
+	flag = 1;
+#endif /*ndef SSH_CHECK_REVOKED*/
+	/*at least one revocation lookup should succeed*/
+	if (flag == 0) return(0);
+
+#ifdef LDAP_ENABLED
+{
+	X509_LOOKUP_METHOD* lookup_method = X509_LOOKUP_ldap();
+
+	if (_locations->ldap_url != NULL && lookup_method != NULL) {
+		X509_LOOKUP *lookup;
+
+		lookup = X509_STORE_add_lookup(x509store, lookup_method);
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add ldap lookup !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_add_ldap(lookup, _locations->ldap_url)) {
+			debug2("ldap url '%.400s' added to x509 store", _locations->ldap_url);
+		}
+		if (_locations->ldap_ver != NULL) {
+			if (!X509_LOOKUP_set_protocol(lookup, _locations->ldap_ver)) {
+				fatal("ssh_x509store_addlocations: cannot set ldap version !");
+				return(0); /* ;-) */
+			}
+		}
+		/*ERR_clear_error();*/
+
+#ifdef SSH_CHECK_REVOKED
+		lookup = X509_STORE_add_lookup(x509revoked, lookup_method);
+		if (lookup == NULL) {
+			fatal("ssh_x509store_addlocations: cannot add ldap lookup(revoked) !");
+			return(0); /* ;-) */
+		}
+		if (X509_LOOKUP_add_ldap(lookup, _locations->ldap_url)) {
+			debug2("ldap url '%.400s' added to x509 store(revoked)", _locations->ldap_url);
+		}
+		if (_locations->ldap_ver != NULL) {
+			if (!X509_LOOKUP_set_protocol(lookup, _locations->ldap_ver)) {
+				fatal("ssh_x509store_addlocations: cannot set ldap version(revoked) !");
+				return(0); /* ;-) */
+			}
+		}
+		/*ERR_clear_error();*/
+#endif /*def SSH_CHECK_REVOKED*/
+	}
+}
+#endif /*def LDAP_ENABLED*/
+
+	return(1);
+}
+
+
+static int
+ssh_verify_cert(X509_STORE_CTX *_csc) {
+	int flag;
+
+	if (ssh_x509flags.allowedcertpurpose >= 0) {
+		int def_purpose =  ( ssh_x509flags.is_server
+			? X509_PURPOSE_SSL_CLIENT
+			: X509_PURPOSE_SSL_SERVER
+		);
+		X509_PURPOSE *xptmp = X509_PURPOSE_get0(ssh_x509flags.allowedcertpurpose);
+		int purpose;
+		if (xptmp == NULL) {
+			fatal("ssh_verify_cert: cannot get purpose from index");
+			return(-1); /* ;-) */
+		}
+		purpose = X509_PURPOSE_get_id(xptmp);
+		flag = X509_STORE_CTX_purpose_inherit(_csc, def_purpose, purpose, 0);
+		if (flag <= 0) {
+			/*
+			 * By default openssl applications don't check return code from
+			 * X509_STORE_CTX_set_purpose or X509_STORE_CTX_purpose_inherit.
+			 *
+			 * Both methods return 0 (zero) and don't change purpose in context when:
+			 * -X509_STORE_CTX_set_purpose(...)
+			 *   purpose is X509_PURPOSE_ANY
+			 * -X509_STORE_CTX_purpose_inherit(...)
+			 *   purpose is X509_PURPOSE_ANY and default purpose is zero (!)
+			 *
+			 * Take note when purpose is "any" check method in current
+			 * OpenSSL code just return 1. This openssl behavior is same
+			 * as ssh option "AllowedCertPurpose=skip".
+			 */
+			int ecode;
+			char ebuf[256];
+
+			ecode = X509_STORE_CTX_get_error(_csc);
+			error("ssh_verify_cert: context purpose error, code=%d, msg='%.200s'"
+				, ecode
+				, X509_verify_cert_error_string(ecode));
+
+			openssl_errormsg(ebuf, sizeof(ebuf));
+			error("ssh_verify_cert: X509_STORE_CTX_purpose_inherit failed with '%.256s'"
+				, ebuf);
+			return(-1);
+		}
+	}
+
+{	/* lets use same time in all time checks */
+	time_t check_time;
+
+	time(&check_time);
+	X509_STORE_CTX_set_time(_csc, 0, check_time);
+#ifdef USE_X509_STORE_CTX_INDEX
+{	SSH_X509_STORE_CTX_DATA* data = NULL;
+
+	if (ssh_X509_STORE_CTX_index >= 0)
+		data = SSH_X509_STORE_CTX_DATA_new();
+
+	if (data != NULL) {
+		data->check_time = check_time;
+		X509_STORE_CTX_set_ex_data(_csc, ssh_X509_STORE_CTX_index, data);
+	}
+}
+#endif /*def USE_X509_STORE_CTX_INDEX*/
+}
+
+	flag = X509_verify_cert(_csc);
+
+#ifdef USE_X509_STORE_CTX_INDEX
+{	SSH_X509_STORE_CTX_DATA* data = NULL;
+
+	if (ssh_X509_STORE_CTX_index >= 0)
+		data = X509_STORE_CTX_get_ex_data(_csc, ssh_X509_STORE_CTX_index);
+
+	if (data != NULL) {
+		X509_STORE_CTX_set_ex_data(_csc, ssh_X509_STORE_CTX_index, NULL);
+		SSH_X509_STORE_CTX_DATA_free(data);
+	}
+}
+#endif /*def USE_X509_STORE_CTX_INDEX*/
+
+	if (flag < 0) {
+		/* NOTE: negative result is returned only if certificate to check
+		 * is not set in context. This function is called if _cert is non
+		 * NULL, i.e. certificate has to be set in context!
+		 * Lets log (posible in future) cases with negative value.
+		 */
+		logit("ssh_verify_cert: X509_verify_cert return unexpected negative value: '%d'", flag);
+		return(-1);
+	}
+	if (flag == 0) {
+		int ecode = X509_STORE_CTX_get_error(_csc);
+		error("ssh_verify_cert: verify error, code=%d, msg='%.200s'"
+			, ecode
+			, X509_verify_cert_error_string(ecode));
+		return(-1);
+	}
+
+	return(1);
+}
+
+
+int
+ssh_x509store_verify_cert(X509 *_cert, STACK_OF(X509) *_chain) {
+	int ret = 1;
+	X509_STORE_CTX *csc;
+
+	if (_cert == NULL) {
+		/*already checked but ...*/
+		error("%s: cert is NULL", __func__);
+		ret = -1;
+		goto done;
+	}
+	/* _chain could be NULL */
+	if (x509store == NULL) {
+		error("%s: context is NULL", __func__);
+		ret = -1;
+		goto done;
+	}
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		char *buf;
+		buf = ssh_X509_NAME_oneline(X509_get_subject_name(_cert)); /*fatal on error*/
+		debug3("%s: for '%s'", __func__, buf);
+		xfree(buf);
+	}
+
+	csc = X509_STORE_CTX_new();
+	if (csc == NULL) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: X509_STORE_CTX_new failed with '%.*s'", __func__,
+		      (int)sizeof(ebuf), ebuf);
+		ret = -1;
+		goto done;
+	}
+
+	if (X509_STORE_CTX_init(csc, x509store, _cert, _chain) <= 0) {
+		/*memory allocation error*/
+		error("%s: cannot initialize x509store context", __func__);
+		ret = -1;
+		goto donecsc;
+	}
+	ret = ssh_verify_cert(csc);
+	X509_STORE_CTX_cleanup(csc);
+donecsc:
+	X509_STORE_CTX_free(csc);
+#ifdef SSH_OCSP_ENABLED
+	if (ret > 0) {
+/*
+ * OpenSSH implementation first verify and validate certificate by
+ * "X.509 store" with certs and crls from file system. It is fast
+ * check. After this when certificate chain is correct and
+ * certificate is not revoked we send a status request to an OCSP
+ * responder if configured.
+ *
+ * RFC2560(OCSP):
+ * ...
+ * 2.7 CA Key Compromise
+ * If an OCSP responder knows that a particular CA's private key
+ * has been compromised, it MAY return the revoked state for all
+ * certificates issued by that CA.
+ * ...
+ * 5. Security Considerations
+ * For this service to be effective, certificate using systems must
+ * connect to the certificate status service provider. In the event
+ * such a connection cannot be obtained, certificate-using systems
+ * could implement CRL processing logic as a fall-back position.
+ * ...
+ * RFC2560(OCSP)^
+ *
+ * About OpenSSH implementation:
+ * 1.) We preffer to delegate validation of issuer certificates to
+ * 'OCSP Provider'. It is easy and simple to configure an OCSP
+ * responder to return revoked state for all certificates issued
+ * by a CA. Usually 'OCSP Provider' admins shall be first informed
+ * for certificates with changed state. In each case this simplify
+ * 'OCSP client'.
+ * 2.) To conform to RFC2560 we should use OCSP to check status of
+ * all certificates in the chain. Since this is network request it
+ * is good to implement a cache and to save status with lifetime.
+ * Might is good to have an OCSP cache server ;-).
+ *
+ * To minimize network latency and keeping in mind 1.) we send
+ * 'OCSP request' only for the last certificate in the chain, i.e.
+ * sended client or server certificate.
+ *
+ * Therefore instead to send OCSP request in ssh_x509revoked_cb()
+ * we do this here.
+ */
+		ret = ssh_ocsp_validate(_cert, x509store);
+	}
+#endif /*def SSH_OCSP_ENABLED*/
+
+done:
+{
+	const char *msg_ok = "trusted";
+	const char *msg;
+	msg = (ret > 0) ? msg_ok : (ret < 0 ? "error" : "rejected");
+	debug3("%s: return %d(%s)", __func__, ret, msg);
+}
+	return(ret);
+}
+
+
+static int
+ssh_build_certchain_cb(int ok, X509_STORE_CTX *ctx) {
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		X509 *ctx_cert = X509_STORE_CTX_get_current_cert(ctx);
+		char *buf;
+
+		buf = ssh_X509_NAME_oneline(X509_get_subject_name(ctx_cert)); /*fatal on error*/
+		debug3("ssh_build_certchain_cb: subject='%s'", buf);
+		free(buf);
+	}
+
+	return(ok);
+}
+
+
+STACK_OF(X509)*
+ssh_x509store_build_certchain(X509 *cert, STACK_OF(X509) *untrusted) {
+	STACK_OF(X509) *ret = NULL;
+	X509_STORE_CTX *csc;
+
+	if (cert == NULL) {
+		/*already checked but ...*/
+		error("%s: cert is NULL", __func__);
+		return(NULL);
+	}
+	/* _chain could be NULL */
+	if (x509store == NULL) {
+		error("%s: X.509 store in not initialized", __func__);
+		return(NULL);
+	}
+
+	csc = X509_STORE_CTX_new();
+	if (csc == NULL) {
+		char ebuf[512];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: X509_STORE_CTX_new failed with '%.*s'", __func__,
+		      (int)sizeof(ebuf), ebuf);
+		return(NULL);
+	}
+
+	if (X509_STORE_CTX_init(csc, x509store, cert, untrusted) <= 0) {
+		/*memory allocation error*/
+		error("%s: cannot initialize X.509 store context", __func__);
+		goto donecsc;
+	}
+
+	X509_STORE_CTX_set_verify_cb(csc, ssh_build_certchain_cb);
+
+	if (X509_verify_cert(csc) > 0) {
+		X509 *x;
+		ret = X509_STORE_CTX_get1_chain(csc);
+		/*pop certificate - it must be first in chain*/
+		x = sk_X509_delete(ret, 0);
+		X509_free(x);
+	} else {
+		int ecode = X509_STORE_CTX_get_error(csc);
+		verbose("cannot build certificate chain, code=%d, msg='%.200s'"
+			, ecode
+			, X509_verify_cert_error_string(ecode));
+	}
+
+donecsc:
+	X509_STORE_CTX_free(csc);
+	return(ret);
+}
+
+
+#ifdef SSH_CHECK_REVOKED
+static void
+ssh_get_namestr_and_hash(
+	X509_NAME *name,
+	char **buf,
+	u_long *hash
+) {
+	if (name == NULL) {
+		debug("ssh_get_namestr_and_hash: name is NULL");
+		if (buf ) *buf  = NULL;
+		if (hash) *hash = 0; /* not correct but :-( */
+		return;
+	}
+
+	if (buf ) *buf  = ssh_X509_NAME_oneline(name); /*fatal on error*/
+	if (hash) *hash = X509_NAME_hash(name);
+}
+
+
+static inline uint32_t
+ssh_X509_get_key_usage(X509 *x) {
+#ifdef HAVE_X509_GET_KEY_USAGE
+	/* defined in openssl 1.1+ */
+	return X509_get_key_usage(x);
+#else
+	X509_check_purpose(x, -1, -1);
+	return x->ex_flags & EXFLAG_KUSAGE ? x->ex_kusage : UINT32_MAX;
+#endif
+}
+
+
+static inline unsigned long
+ssh_X509_STORE_CTX_get_verify_flags(X509_STORE_CTX *ctx) {
+#ifdef HAVE_X509_STORE_CTX_GET0_PARAM
+	/* struct X509_VERIFY_PARAM is defined in OpenSSL 0.9.8+ */
+	X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
+	return X509_VERIFY_PARAM_get_flags(param);
+#else
+	return ctx->flags;
+#endif
+}
+
+
+static inline time_t
+X509_STORE_CTX_get_verify_check_time(X509_STORE_CTX *ctx) {
+#ifndef USE_X509_STORE_CTX_INDEX
+#ifdef HAVE_X509_STORE_CTX_GET0_PARAM
+	/* struct X509_VERIFY_PARAM is defined in OpenSSL 0.9.8+ */
+	X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
+	return param->check_time;
+#else
+	return ctx->check_time;
+#endif
+#else /*def USE_X509_STORE_CTX_INDEX*/
+	SSH_X509_STORE_CTX_DATA* data = NULL;
+
+	if (ssh_X509_STORE_CTX_index >= 0)
+		data = X509_STORE_CTX_get_ex_data(ctx, ssh_X509_STORE_CTX_index);
+
+	if (data != NULL)
+		return(data->check_time);
+
+{	/*failback to current time*/
+	time_t check_time;
+	time(&check_time);
+	return(check_time);
+}
+#endif
+}
+
+
+static int/*bool*/
+ssh_check_crl(X509_STORE_CTX *_ctx, X509* _issuer, X509_CRL *_crl) {
+	time_t  check_time;
+	time_t *pcheck_time;
+	int     k;
+	u_long hash;
+
+	if (_issuer == NULL) {
+		error("ssh_check_crl: issuer is NULL");
+		return(0);
+	}
+	if (_crl == NULL) {
+		debug("ssh_check_crl: crl is NULL");
+		return(1);
+	}
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		BIO *bio;
+		char *p;
+
+		bio = BIO_new(BIO_s_mem());
+		if (bio == NULL) {
+			fatal("ssh_check_crl: out of memory");
+			return(0); /* ;-) */
+		}
+
+		ssh_X509_NAME_print(bio, X509_CRL_get_issuer(_crl));
+
+		BIO_printf(bio, "; Last Update: ");
+		ASN1_UTCTIME_print(bio, X509_CRL_get0_lastUpdate(_crl));
+
+		BIO_printf(bio, "; Next Update: ");
+		ASN1_UTCTIME_print(bio, X509_CRL_get0_nextUpdate(_crl));
+
+		k = BIO_pending(bio);
+		p = xmalloc(k + 1); /*fatal on error*/
+		k = BIO_read(bio, p, k);
+		p[k] = '\0';
+
+		debug3("ssh_check_crl: Issuer: %s", p);
+
+		xfree(p);
+		BIO_free(bio);
+	}
+
+/* RFC 3280:
+ * The cRLSign bit is asserted when the subject public key is used
+ * for verifying a signature on certificate revocation list (e.g., a
+ * CRL, delta CRL, or an ARL).  This bit MUST be asserted in
+ * certificates that are used to verify signatures on CRLs.
+ */
+	if (!(ssh_X509_get_key_usage(_issuer) & KU_CRL_SIGN)) {
+		char *buf;
+	#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN
+		/*first defined in OpenSSL 0.9.7d*/
+		X509_STORE_CTX_set_error(_ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN);
+	#endif
+		ssh_get_namestr_and_hash(X509_get_subject_name(_issuer), &buf, &hash);
+		error("ssh_check_crl:"
+			" to verify crl signature key usage 'cRLSign'"
+			" must present in issuer certificate '%s' with hash=0x%08lx"
+			, buf, hash
+		);
+		xfree(buf);
+		return(0);
+	}
+
+	{
+		EVP_PKEY *pkey = X509_get_pubkey(_issuer);
+		if (pkey == NULL) {
+			error("ssh_check_crl: unable to decode issuer public key");
+			X509_STORE_CTX_set_error(_ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
+			return(0);
+		}
+
+		if (X509_CRL_verify(_crl, pkey) <= 0) {
+			char *buf;
+
+			ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash);
+			error("ssh_check_crl: CRL has invalid signature"
+				": issuer='%s', hash=0x%08lx"
+				, buf, hash
+			);
+			X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
+			xfree(buf);
+			EVP_PKEY_free(pkey);
+			return(0);
+		}
+		EVP_PKEY_free(pkey);
+	}
+
+
+	if (ssh_X509_STORE_CTX_get_verify_flags(_ctx) & X509_V_FLAG_USE_CHECK_TIME) {
+		check_time = X509_STORE_CTX_get_verify_check_time(_ctx);
+		pcheck_time = &check_time;
+	} else
+		pcheck_time = NULL;
+
+	k = X509_cmp_time(X509_CRL_get0_lastUpdate(_crl), pcheck_time);
+	if (k == 0) {
+		char *buf;
+
+		ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash);
+		error("ssh_check_crl: CRL has invalid lastUpdate field"
+			": issuer='%s', hash=0x%08lx"
+			, buf, hash
+		);
+		X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);
+		xfree(buf);
+		return(0);
+	}
+	if (k > 0) {
+		char *buf;
+
+		ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash);
+		error("ssh_check_crl: CRL is not yet valid"
+			": issuer='%s', hash=0x%08lx"
+			, buf, hash
+		);
+		X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_NOT_YET_VALID);
+		xfree(buf);
+		return(0);
+	}
+
+	k = X509_cmp_time(X509_CRL_get0_nextUpdate(_crl), pcheck_time);
+	if (k == 0) {
+		char *buf;
+
+		ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash);
+		error("ssh_check_crl: CRL has invalid nextUpdate field"
+			": issuer='%s', hash=0x%08lx"
+			, buf, hash
+		);
+		X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
+		xfree(buf);
+		return(0);
+	}
+#if 0
+	/*test "extend time limit"*/
+	if (k < 0) {
+		time_t	tm;
+		if (pcheck_time == NULL) {
+			tm = time(NULL);
+			pcheck_time = &tm;
+		}
+		*pcheck_time -= convtime("1w");
+		k = X509_cmp_time(X509_CRL_get_nextUpdate(_crl), pcheck_time);
+	}
+#endif
+	if (k < 0) {
+		char *buf;
+
+		ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash);
+		error("ssh_check_crl: CRL is expired"
+			": issuer='%s', hash=0x%08lx"
+			, buf, hash
+		);
+		X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
+		xfree(buf);
+		return(0);
+	}
+
+	return(1);
+}
+
+
+static int/*bool*/
+ssh_is_cert_revoked(X509_STORE_CTX *_ctx, X509_CRL *_crl, X509 *_cert) {
+	X509_REVOKED *revoked;
+	ASN1_INTEGER *serial;
+	int ret = 1;
+	int k;
+
+	if (_crl == NULL) return(1);
+
+	revoked = X509_REVOKED_new();
+	if (revoked == NULL) {
+		char ebuf[256];
+		openssl_errormsg(ebuf, sizeof(ebuf));
+		error("%s: X509_REVOKED_new failed with '%.*s'", __func__,
+		      (int)sizeof(ebuf), ebuf);
+		return(1);
+	}
+
+	serial = X509_get_serialNumber(_cert);
+	X509_REVOKED_set_serialNumber(revoked, serial);
+	k = sk_X509_REVOKED_find(X509_CRL_get_REVOKED(_crl), revoked);
+	if (k < 0) {
+		ret = 0;
+		goto done;
+	}
+
+	X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CERT_REVOKED);
+	/* yes, revoked. print log and ...*/
+{
+	char *dn, *ser, *in;
+
+	dn  = ssh_X509_NAME_oneline(X509_get_subject_name(_cert)); /*fatal on error*/
+	ser = ssh_ASN1_INTEGER_2_string(serial);
+	in  = ssh_X509_NAME_oneline(X509_CRL_get_issuer  (_crl )); /*fatal on error*/
+
+	error("certificate '%s' with serial '%.40s' revoked from issuer '%s'"
+		, dn, ser, in);
+	xfree(dn);
+	xfree(ser);
+	xfree(in);
+}
+done:
+	if (revoked) X509_REVOKED_free(revoked);
+	return (ret);
+}
+
+
+static int
+ssh_x509revoked_cb(int ok, X509_STORE_CTX *ctx) {
+	X509     *cert;
+	X509_CRL *crl;
+
+	if (!ok) return(0);
+	if (x509revoked == NULL)
+		return(ok); /* XXX:hmm */
+
+	cert = X509_STORE_CTX_get_current_cert(ctx);
+	if (cert == NULL) {
+		error("ssh_x509revoked_cb: missing current certificate in x509store context");
+		return(0);
+	}
+
+	if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) {
+		char *buf;
+
+		buf = ssh_X509_NAME_oneline(X509_get_issuer_name(cert)); /*fatal on error*/
+		debug3("ssh_x509revoked_cb: Issuer: %s", buf);
+		xfree(buf);
+
+		buf = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/
+		debug3("ssh_x509revoked_cb: Subject: %s", buf);
+		xfree(buf);
+	}
+
+/* TODO:
+ * NID_crl_distribution_points may contain one or more
+ * CRLissuer != cert issuer
+ */
+	crl = ssh_x509store_get_crl_by_subject(
+	    x509revoked,
+	    X509_get_subject_name(cert)
+	);
+	if (crl != NULL) {
+/*
+ * In callback we cannot check CRL signature at this point when we use
+ * X509_get_issuer_name(), because we don't know issuer public key!
+ * Of course we can get the public key from X509_STORE defined by
+ * static variable "x509store".
+ * Of course we can check revocation outside callback, but we should
+ * try to find public key in X509_STORE[s].
+ *
+ * At this point we can get easy public key of "current certificate"!
+ *
+ * Method: "look forward"
+ * At this call we check CLR (signature and other) issued with "current
+ * certificate" ("CertA"). If all is OK with "CertA" by next call of
+ * callback method "current certificate" is signed from "CertA" and the
+ * CRL issued from "CertA", if any is already verified - cool ;-).
+ *
+ * Note that when a certificate is revoked all signed from that
+ * certificate are revoked automatically too. With method "look forward"
+ * we already know that all issuers of "current certificate" aren't
+ * revoked.
+ */
+		ok = ssh_check_crl(ctx, cert, crl);
+	} else {
+		if (ssh_x509flags.mandatory_crl == 1) {
+			int loc;
+			loc = X509_get_ext_by_NID(cert, NID_crl_distribution_points, -1);
+			ok = (loc < 0);
+			if (!ok) {
+				error("ssh_x509revoked_cb: unable to get issued CRL");
+				X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
+			}
+		}
+	}
+	if (!ok) return(0);
+
+	crl = ssh_x509store_get_crl_by_subject(
+	      x509revoked,
+	      X509_get_issuer_name(cert)
+	);
+	if (crl != NULL) {
+		ok = !ssh_is_cert_revoked(ctx, crl, cert);
+	}
+	if (!ok) return(0);
+
+	return(ok);
+}
+#endif
diff -ruN openssh-7.5p1/x509store.h openssh-7.5p1+x509-10.2/x509store.h
--- openssh-7.5p1/x509store.h	1970-01-01 02:00:00.000000000 +0200
+++ openssh-7.5p1+x509-10.2/x509store.h	2017-02-22 21:32:00.136967255 +0200
@@ -0,0 +1,138 @@
+#ifndef X509STORE_H
+#define X509STORE_H
+/*
+ * Copyright (c) 2002-2017 Roumen Petrov.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include <openssl/x509.h>
+
+
+int	ssh_X509_NAME_print(BIO* bio, X509_NAME *xn);
+char*	ssh_X509_NAME_oneline(X509_NAME *xn);
+
+#ifndef HAVE_ASN1_STRING_GET0_DATA		/* OpenSSL < 1.1 */
+static inline const unsigned char *
+ASN1_STRING_get0_data(const ASN1_STRING *x) {
+	 return(x->data);
+}
+#endif /*ndef HAVE_ASN1_STRING_GET0_DATA	OpenSSL < 1.1 */
+
+static inline void
+ssh_ASN1_STRING_get0_data(const ASN1_STRING *a,
+    const unsigned char **p, int *len
+) {
+	if (p != NULL)
+		*p = ASN1_STRING_get0_data(a);
+	if (len != NULL)
+		*len = ASN1_STRING_length(
+		    (ASN1_STRING_LENGTH_CONST ASN1_STRING*) a);
+}
+
+
+int ssh_x509store_verify_cert(X509 *_cert, STACK_OF(X509) *_chain);
+
+STACK_OF(X509)* ssh_x509store_build_certchain(X509 *_cert, STACK_OF(X509) *_untrusted);
+
+
+typedef struct {
+	int is_server;
+	/* allowed client/server certificate purpose */
+	int allowedcertpurpose; /* note field contain purpose index */
+	int key_allow_selfissued; /* make sense only when x509store is enabled */
+	int mandatory_crl;
+}       SSH_X509Flags;
+
+extern SSH_X509Flags ssh_x509flags;
+
+void ssh_x509flags_initialize(SSH_X509Flags *flags, int is_server);
+void ssh_x509flags_defaults(SSH_X509Flags *flags);
+
+/* return purpose index, not purpose id (!) */
+int ssh_get_x509purpose_s(int _is_server, const char* _purpose_synonym);
+
+char* format_x509_purpose(int purpose_index);
+
+
+int	ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b);
+int/*bool*/	ssh_X509_is_selfsigned(X509 *_cert);
+
+typedef struct {
+	/* ssh PKI(X509) store */
+	const char   *certificate_file;
+	const char   *certificate_path;
+	const char   *revocation_file;
+	const char   *revocation_path;
+#ifdef LDAP_ENABLED
+	const char   *ldap_ver;
+	const char   *ldap_url;
+#endif
+}       X509StoreOptions;
+
+void X509StoreOptions_init(X509StoreOptions *options);
+void X509StoreOptions_reset(X509StoreOptions *options);
+void X509StoreOptions_system_defaults(X509StoreOptions *options);
+void X509StoreOptions_user_defaults(X509StoreOptions *options, uid_t uid);
+
+int/*bool*/ ssh_x509store_addlocations(const X509StoreOptions *_locations);
+void ssh_x509store_cleanup(void);
+
+X509*
+ssh_x509store_get_cert_by_subject(X509_STORE *store, X509_NAME *name);
+
+X509_CRL*
+ssh_x509store_get_crl_by_subject(X509_STORE *store, X509_NAME *name);
+
+
+#ifdef SSH_OCSP_ENABLED
+
+enum va_type {
+	SSHVA_NONE,
+	SSHVA_OCSP_CERT,
+	SSHVA_OCSP_SPEC
+};
+
+
+typedef struct {
+	int type; /*allowed values from enum va_type*/
+
+	/* file with additional trusted certificates */
+	const char *certificate_file;
+
+	/* ssh OCSP Provider(Respoder) URL */
+	const char *responder_url;
+}       VAOptions;
+
+int ssh_get_default_vatype(void);
+int ssh_get_vatype_s(const char* type);
+const char*
+ssh_get_vatype_i(int id);
+
+void ssh_set_validator(const VAOptions *_va); /*fatal on error*/
+
+int ssh_ocsp_validate(X509 *cert, X509_STORE *x509store);
+
+#endif /*def SSH_OCSP_ENABLED*/
+
+
+#endif /* X509STORE_H */
