summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/regress/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/regress/unittests')
-rw-r--r--crypto/openssh/regress/unittests/Makefile6
-rw-r--r--crypto/openssh/regress/unittests/Makefile.inc4
-rw-r--r--crypto/openssh/regress/unittests/bitmap/Makefile12
-rw-r--r--crypto/openssh/regress/unittests/bitmap/tests.c135
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/Makefile12
-rwxr-xr-xcrypto/openssh/regress/unittests/hostkeys/mktestdata.sh94
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/test_iterate.c1171
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts61
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub1
-rw-r--r--crypto/openssh/regress/unittests/hostkeys/tests.c16
-rw-r--r--crypto/openssh/regress/unittests/kex/Makefile14
-rw-r--r--crypto/openssh/regress/unittests/kex/test_kex.c197
-rw-r--r--crypto/openssh/regress/unittests/kex/tests.c14
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c8
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c4
-rw-r--r--crypto/openssh/regress/unittests/sshkey/common.c4
-rwxr-xr-xcrypto/openssh/regress/unittests/sshkey/mktestdata.sh4
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_file.c33
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_fuzz.c13
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_sshkey.c192
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp2
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp2
-rw-r--r--crypto/openssh/regress/unittests/test_helper/Makefile5
-rw-r--r--crypto/openssh/regress/unittests/test_helper/fuzz.c102
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.c67
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.h13
67 files changed, 2148 insertions, 91 deletions
diff --git a/crypto/openssh/regress/unittests/Makefile b/crypto/openssh/regress/unittests/Makefile
index bdb4574..d3d9082 100644
--- a/crypto/openssh/regress/unittests/Makefile
+++ b/crypto/openssh/regress/unittests/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
-
-SUBDIR= test_helper sshbuf sshkey
+# $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $
+REGRESS_FAIL_EARLY= yes
+SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys
.include <bsd.subdir.mk>
diff --git a/crypto/openssh/regress/unittests/Makefile.inc b/crypto/openssh/regress/unittests/Makefile.inc
index 4c33637..c55d00c 100644
--- a/crypto/openssh/regress/unittests/Makefile.inc
+++ b/crypto/openssh/regress/unittests/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
+# $OpenBSD: Makefile.inc,v 1.3 2015/01/23 21:21:23 miod Exp $
.include <bsd.own.mk>
.include <bsd.obj.mk>
@@ -21,7 +21,6 @@ CDIAGFLAGS+= -Wmissing-declarations
CDIAGFLAGS+= -Wmissing-prototypes
CDIAGFLAGS+= -Wparentheses
CDIAGFLAGS+= -Wpointer-arith
-CDIAGFLAGS+= -Wpointer-sign
CDIAGFLAGS+= -Wreturn-type
CDIAGFLAGS+= -Wshadow
CDIAGFLAGS+= -Wsign-compare
@@ -32,6 +31,7 @@ CDIAGFLAGS+= -Wtrigraphs
CDIAGFLAGS+= -Wuninitialized
CDIAGFLAGS+= -Wunused
.if ${COMPILER_VERSION} == "gcc4"
+CDIAGFLAGS+= -Wpointer-sign
CDIAGFLAGS+= -Wold-style-definition
.endif
diff --git a/crypto/openssh/regress/unittests/bitmap/Makefile b/crypto/openssh/regress/unittests/bitmap/Makefile
new file mode 100644
index 0000000..b704d22
--- /dev/null
+++ b/crypto/openssh/regress/unittests/bitmap/Makefile
@@ -0,0 +1,12 @@
+# $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+PROG=test_bitmap
+SRCS=tests.c
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG}
+
+.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/bitmap/tests.c b/crypto/openssh/regress/unittests/bitmap/tests.c
new file mode 100644
index 0000000..23025f9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/bitmap/tests.c
@@ -0,0 +1,135 @@
+/* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */
+/*
+ * Regress test for bitmap.h bitmap API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "bitmap.h"
+
+#define NTESTS 131
+
+void
+tests(void)
+{
+ struct bitmap *b;
+ BIGNUM *bn;
+ size_t len;
+ int i, j, k, n;
+ u_char bbuf[1024], bnbuf[1024];
+ int r;
+
+ TEST_START("bitmap_new");
+ b = bitmap_new();
+ ASSERT_PTR_NE(b, NULL);
+ bn = BN_new();
+ ASSERT_PTR_NE(bn, NULL);
+ TEST_DONE();
+
+ TEST_START("bitmap_set_bit / bitmap_test_bit");
+ for (i = -1; i < NTESTS; i++) {
+ for (j = -1; j < NTESTS; j++) {
+ for (k = -1; k < NTESTS; k++) {
+ bitmap_zero(b);
+ BN_clear(bn);
+
+ test_subtest_info("set %d/%d/%d", i, j, k);
+ /* Set bits */
+ if (i >= 0) {
+ ASSERT_INT_EQ(bitmap_set_bit(b, i), 0);
+ ASSERT_INT_EQ(BN_set_bit(bn, i), 1);
+ }
+ if (j >= 0) {
+ ASSERT_INT_EQ(bitmap_set_bit(b, j), 0);
+ ASSERT_INT_EQ(BN_set_bit(bn, j), 1);
+ }
+ if (k >= 0) {
+ ASSERT_INT_EQ(bitmap_set_bit(b, k), 0);
+ ASSERT_INT_EQ(BN_set_bit(bn, k), 1);
+ }
+
+ /* Check perfect match between bitmap and bn */
+ test_subtest_info("match %d/%d/%d", i, j, k);
+ for (n = 0; n < NTESTS; n++) {
+ ASSERT_INT_EQ(BN_is_bit_set(bn, n),
+ bitmap_test_bit(b, n));
+ }
+
+ /* Test length calculations */
+ test_subtest_info("length %d/%d/%d", i, j, k);
+ ASSERT_INT_EQ(BN_num_bits(bn),
+ (int)bitmap_nbits(b));
+ ASSERT_INT_EQ(BN_num_bytes(bn),
+ (int)bitmap_nbytes(b));
+
+ /* Test serialisation */
+ test_subtest_info("serialise %d/%d/%d",
+ i, j, k);
+ len = bitmap_nbytes(b);
+ memset(bbuf, 0xfc, sizeof(bbuf));
+ ASSERT_INT_EQ(bitmap_to_string(b, bbuf,
+ sizeof(bbuf)), 0);
+ for (n = len; n < (int)sizeof(bbuf); n++)
+ ASSERT_U8_EQ(bbuf[n], 0xfc);
+ r = BN_bn2bin(bn, bnbuf);
+ ASSERT_INT_GE(r, 0);
+ ASSERT_INT_EQ(r, (int)len);
+ ASSERT_MEM_EQ(bbuf, bnbuf, len);
+
+ /* Test deserialisation */
+ test_subtest_info("deserialise %d/%d/%d",
+ i, j, k);
+ bitmap_zero(b);
+ ASSERT_INT_EQ(bitmap_from_string(b, bnbuf,
+ len), 0);
+ for (n = 0; n < NTESTS; n++) {
+ ASSERT_INT_EQ(BN_is_bit_set(bn, n),
+ bitmap_test_bit(b, n));
+ }
+
+ /* Test clearing bits */
+ test_subtest_info("clear %d/%d/%d",
+ i, j, k);
+ for (n = 0; n < NTESTS; n++) {
+ ASSERT_INT_EQ(bitmap_set_bit(b, n), 0);
+ ASSERT_INT_EQ(BN_set_bit(bn, n), 1);
+ }
+ if (i >= 0) {
+ bitmap_clear_bit(b, i);
+ BN_clear_bit(bn, i);
+ }
+ if (j >= 0) {
+ bitmap_clear_bit(b, j);
+ BN_clear_bit(bn, j);
+ }
+ if (k >= 0) {
+ bitmap_clear_bit(b, k);
+ BN_clear_bit(bn, k);
+ }
+ for (n = 0; n < NTESTS; n++) {
+ ASSERT_INT_EQ(BN_is_bit_set(bn, n),
+ bitmap_test_bit(b, n));
+ }
+ }
+ }
+ }
+ bitmap_free(b);
+ BN_free(bn);
+ TEST_DONE();
+}
+
diff --git a/crypto/openssh/regress/unittests/hostkeys/Makefile b/crypto/openssh/regress/unittests/hostkeys/Makefile
new file mode 100644
index 0000000..f52a85f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/Makefile
@@ -0,0 +1,12 @@
+# $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+PROG=test_hostkeys
+SRCS=tests.c test_iterate.c
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
+
+.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh
new file mode 100755
index 0000000..36890ba
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+# $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $
+
+set -ex
+
+cd testdata
+
+rm -f rsa1* rsa* dsa* ecdsa* ed25519*
+rm -f known_hosts*
+
+gen_all() {
+ _n=$1
+ _ecdsa_bits=256
+ test "x$_n" = "x1" && _ecdsa_bits=384
+ test "x$_n" = "x2" && _ecdsa_bits=521
+ ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n
+ ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n
+ ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n
+ ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n
+ ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n
+ # Don't need private keys
+ rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n
+}
+
+hentries() {
+ _preamble=$1
+ _kspec=$2
+ for k in `ls -1 $_kspec | sort` ; do
+ printf "$_preamble "
+ cat $k
+ done
+ echo
+}
+
+gen_all 1
+gen_all 2
+gen_all 3
+gen_all 4
+gen_all 5
+gen_all 6
+
+# A section of known_hosts with hashed hostnames.
+(
+ hentries "sisyphus.example.com" "*_5.pub"
+ hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub"
+) > known_hosts_hash_frag
+ssh-keygen -Hf known_hosts_hash_frag
+rm -f known_hosts_hash_frag.old
+
+# Populated known_hosts, including comments, hashed names and invalid lines
+(
+ echo "# Plain host keys, plain host names"
+ hentries "sisyphus.example.com" "*_1.pub"
+
+ echo "# Plain host keys, hostnames + addresses"
+ hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub"
+
+ echo "# Some hosts with wildcard names / IPs"
+ hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub"
+
+ echo "# Hashed hostname and address entries"
+ cat known_hosts_hash_frag
+ rm -f known_hosts_hash_frag
+ echo
+
+ echo "# Revoked and CA keys"
+ printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub
+ printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub
+ printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub
+ printf "@cert-authority *.example.com " ; cat dsa_4.pub
+
+ printf "\n"
+ echo "# Some invalid lines"
+ # Invalid marker
+ printf "@what sisyphus.example.com " ; cat rsa1_1.pub
+ # Key missing
+ echo "sisyphus.example.com "
+ # Key blob missing
+ echo "prometheus.example.com ssh-ed25519 "
+ # Key blob truncated
+ echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz"
+ # RSA1 key truncated after key bits
+ echo "prometheus.example.com 1024 "
+ # RSA1 key truncated after exponent
+ echo "sisyphus.example.com 1024 65535 "
+ # RSA1 key incorrect key bits
+ printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub
+ # Invalid type
+ echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg=="
+ # Type mismatch with blob
+ echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg=="
+) > known_hosts
+
+echo OK
diff --git a/crypto/openssh/regress/unittests/hostkeys/test_iterate.c b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c
new file mode 100644
index 0000000..d81291b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c
@@ -0,0 +1,1171 @@
+/* $OpenBSD: test_iterate.c,v 1.3 2015/03/07 04:41:48 djm Exp $ */
+/*
+ * Regress test for hostfile.h hostkeys_foreach()
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "sshkey.h"
+#include "authfile.h"
+#include "hostfile.h"
+
+struct expected {
+ const char *key_file; /* Path for key, NULL for none */
+ int no_parse_status; /* Expected status w/o key parsing */
+ int no_parse_keytype; /* Expected keytype w/o key parsing */
+ int match_host_p; /* Match 'prometheus.example.com' */
+ int match_host_s; /* Match 'sisyphus.example.com' */
+ int match_ipv4; /* Match '192.0.2.1' */
+ int match_ipv6; /* Match '2001:db8::1' */
+ int match_flags; /* Expected flags from match */
+ struct hostkey_foreach_line l; /* Expected line contents */
+};
+
+struct cbctx {
+ const struct expected *expected;
+ size_t nexpected;
+ size_t i;
+ int flags;
+ int match_host_p;
+ int match_host_s;
+ int match_ipv4;
+ int match_ipv6;
+};
+
+/*
+ * hostkeys_foreach() iterator callback that verifies the line passed
+ * against an array of expected entries.
+ */
+static int
+check(struct hostkey_foreach_line *l, void *_ctx)
+{
+ struct cbctx *ctx = (struct cbctx *)_ctx;
+ const struct expected *expected;
+ int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0;
+ const int matching = (ctx->flags & HKF_WANT_MATCH) != 0;
+ u_int expected_status, expected_match;
+ int expected_keytype;
+
+ test_subtest_info("entry %zu/%zu, file line %ld",
+ ctx->i + 1, ctx->nexpected, l->linenum);
+
+ for (;;) {
+ ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected);
+ expected = ctx->expected + ctx->i++;
+ /* If we are matching host/IP then skip entries that don't */
+ if (!matching)
+ break;
+ if (ctx->match_host_p && expected->match_host_p)
+ break;
+ if (ctx->match_host_s && expected->match_host_s)
+ break;
+ if (ctx->match_ipv4 && expected->match_ipv4)
+ break;
+ if (ctx->match_ipv6 && expected->match_ipv6)
+ break;
+ }
+ expected_status = (parse_key || expected->no_parse_status < 0) ?
+ expected->l.status : (u_int)expected->no_parse_status;
+ expected_match = expected->l.match;
+#define UPDATE_MATCH_STATUS(x) do { \
+ if (ctx->x && expected->x) { \
+ expected_match |= expected->x; \
+ if (expected_status == HKF_STATUS_OK) \
+ expected_status = HKF_STATUS_MATCHED; \
+ } \
+ } while (0)
+ expected_keytype = (parse_key || expected->no_parse_keytype < 0) ?
+ expected->l.keytype : expected->no_parse_keytype;
+
+#ifndef WITH_SSH1
+ if (expected->l.keytype == KEY_RSA1 ||
+ expected->no_parse_keytype == KEY_RSA1) {
+ expected_status = HKF_STATUS_INVALID;
+ expected_keytype = KEY_UNSPEC;
+ parse_key = 0;
+ }
+#endif
+#ifndef OPENSSL_HAS_ECC
+ if (expected->l.keytype == KEY_ECDSA ||
+ expected->no_parse_keytype == KEY_ECDSA) {
+ expected_status = HKF_STATUS_INVALID;
+ expected_keytype = KEY_UNSPEC;
+ parse_key = 0;
+ }
+#endif
+
+ UPDATE_MATCH_STATUS(match_host_p);
+ UPDATE_MATCH_STATUS(match_host_s);
+ UPDATE_MATCH_STATUS(match_ipv4);
+ UPDATE_MATCH_STATUS(match_ipv6);
+
+ ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */
+ ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum);
+ ASSERT_U_INT_EQ(l->status, expected_status);
+ ASSERT_U_INT_EQ(l->match, expected_match);
+ /* Not all test entries contain fulltext */
+ if (expected->l.line != NULL)
+ ASSERT_STRING_EQ(l->line, expected->l.line);
+ ASSERT_INT_EQ(l->marker, expected->l.marker);
+ /* XXX we skip hashed hostnames for now; implement checking */
+ if (expected->l.hosts != NULL)
+ ASSERT_STRING_EQ(l->hosts, expected->l.hosts);
+ /* Not all test entries contain raw keys */
+ if (expected->l.rawkey != NULL)
+ ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey);
+ /* XXX synthesise raw key for cases lacking and compare */
+ ASSERT_INT_EQ(l->keytype, expected_keytype);
+ if (parse_key) {
+ if (expected->l.key == NULL)
+ ASSERT_PTR_EQ(l->key, NULL);
+ if (expected->l.key != NULL) {
+ ASSERT_PTR_NE(l->key, NULL);
+ ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1);
+ }
+ }
+ if (parse_key && !(l->comment == NULL && expected->l.comment == NULL))
+ ASSERT_STRING_EQ(l->comment, expected->l.comment);
+ return 0;
+}
+
+/* Loads public keys for a set of expected results */
+static void
+prepare_expected(struct expected *expected, size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ if (expected[i].key_file == NULL)
+ continue;
+#ifndef WITH_SSH1
+ if (expected[i].l.keytype == KEY_RSA1)
+ continue;
+#endif
+#ifndef OPENSSL_HAS_ECC
+ if (expected[i].l.keytype == KEY_ECDSA)
+ continue;
+#endif
+ ASSERT_INT_EQ(sshkey_load_public(
+ test_data_file(expected[i].key_file), &expected[i].l.key,
+ NULL), 0);
+ }
+}
+
+struct expected expected_full[] = {
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL, /* path, don't care */
+ 1, /* line number */
+ HKF_STATUS_COMMENT, /* status */
+ 0, /* match flags */
+ "# Plain host keys, plain host names", /* full line, optional */
+ MRK_NONE, /* marker (CA / revoked) */
+ NULL, /* hosts text */
+ NULL, /* raw key, optional */
+ KEY_UNSPEC, /* key type */
+ NULL, /* deserialised key */
+ NULL, /* comment */
+ } },
+ { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 2,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #1",
+ } },
+ { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 3,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #1",
+ } },
+ { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 4,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #1",
+ } },
+ { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 5,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #1",
+ } },
+ { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 6,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #1",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 7,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 8,
+ HKF_STATUS_COMMENT,
+ 0,
+ "# Plain host keys, hostnames + addresses",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 9,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com,192.0.2.1,2001:db8::1",
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #2",
+ } },
+ { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 10,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com,192.0.2.1,2001:db8::1",
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #2",
+ } },
+ { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 11,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com,192.0.2.1,2001:db8::1",
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #2",
+ } },
+ { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 12,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com,192.0.2.1,2001:db8::1",
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #2",
+ } },
+ { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 13,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com,192.0.2.1,2001:db8::1",
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #2",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 14,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 15,
+ HKF_STATUS_COMMENT,
+ 0,
+ "# Some hosts with wildcard names / IPs",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 16,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "*.example.com,192.0.2.*,2001:*",
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #3",
+ } },
+ { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 17,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "*.example.com,192.0.2.*,2001:*",
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #3",
+ } },
+ { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 18,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "*.example.com,192.0.2.*,2001:*",
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #3",
+ } },
+ { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 19,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "*.example.com,192.0.2.*,2001:*",
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #3",
+ } },
+ { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
+ NULL,
+ 20,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ "*.example.com,192.0.2.*,2001:*",
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #3",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 21,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 22,
+ HKF_STATUS_COMMENT,
+ 0,
+ "# Hashed hostname and address entries",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
+ NULL,
+ 23,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #5",
+ } },
+ { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
+ NULL,
+ 24,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #5",
+ } },
+ { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
+ NULL,
+ 25,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #5",
+ } },
+ { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
+ NULL,
+ 26,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #5",
+ } },
+ { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
+ NULL,
+ 27,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #5",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 28,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ /*
+ * The next series have each key listed multiple times, as the
+ * hostname and addresses in the pre-hashed known_hosts are split
+ * to separate lines.
+ */
+ { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
+ NULL,
+ 29,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #6",
+ } },
+ { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
+ NULL,
+ 30,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #6",
+ } },
+ { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
+ NULL,
+ 31,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #6",
+ } },
+ { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
+ NULL,
+ 32,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #6",
+ } },
+ { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
+ NULL,
+ 33,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #6",
+ } },
+ { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
+ NULL,
+ 34,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #6",
+ } },
+ { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
+ NULL,
+ 35,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #6",
+ } },
+ { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
+ NULL,
+ 36,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #6",
+ } },
+ { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
+ NULL,
+ 37,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #6",
+ } },
+ { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
+ NULL,
+ 38,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #6",
+ } },
+ { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
+ NULL,
+ 39,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #6",
+ } },
+ { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
+ NULL,
+ 40,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #6",
+ } },
+ { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
+ NULL,
+ 41,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #6",
+ } },
+ { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
+ NULL,
+ 42,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #6",
+ } },
+ { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
+ NULL,
+ 43,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_RSA,
+ NULL, /* filled at runtime */
+ "RSA #6",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 44,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 45,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 46,
+ HKF_STATUS_COMMENT,
+ 0,
+ "# Revoked and CA keys",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 47,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_REVOKE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_RSA1,
+ NULL, /* filled at runtime */
+ "RSA1 #4",
+ } },
+ { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 48,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_REVOKE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_ED25519,
+ NULL, /* filled at runtime */
+ "ED25519 #4",
+ } },
+ { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
+ NULL,
+ 49,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_CA,
+ "prometheus.example.com",
+ NULL,
+ KEY_ECDSA,
+ NULL, /* filled at runtime */
+ "ECDSA #4",
+ } },
+ { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 50,
+ HKF_STATUS_OK,
+ 0,
+ NULL,
+ MRK_CA,
+ "*.example.com",
+ NULL,
+ KEY_DSA,
+ NULL, /* filled at runtime */
+ "DSA #4",
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 51,
+ HKF_STATUS_COMMENT,
+ 0,
+ "",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 52,
+ HKF_STATUS_COMMENT,
+ 0,
+ "# Some invalid lines",
+ MRK_NONE,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, 0, 0, 0, -1, {
+ NULL,
+ 53,
+ HKF_STATUS_INVALID,
+ 0,
+ NULL,
+ MRK_ERROR,
+ NULL,
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 54,
+ HKF_STATUS_INVALID,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
+ NULL,
+ 55,
+ HKF_STATUS_INVALID,
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 56,
+ HKF_STATUS_INVALID, /* Would be ok if key not parsed */
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
+ NULL,
+ 57,
+ HKF_STATUS_INVALID, /* Would be ok if key not parsed */
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 58,
+ HKF_STATUS_INVALID, /* Would be ok if key not parsed */
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL,
+ NULL,
+ } },
+ { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, {
+ NULL,
+ 59,
+ HKF_STATUS_INVALID, /* Would be ok if key not parsed */
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL, /* filled at runtime */
+ NULL,
+ } },
+ { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
+ NULL,
+ 60,
+ HKF_STATUS_INVALID,
+ 0,
+ NULL,
+ MRK_NONE,
+ "sisyphus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL, /* filled at runtime */
+ NULL,
+ } },
+ { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
+ NULL,
+ 61,
+ HKF_STATUS_INVALID, /* Would be ok if key not parsed */
+ 0,
+ NULL,
+ MRK_NONE,
+ "prometheus.example.com",
+ NULL,
+ KEY_UNSPEC,
+ NULL, /* filled at runtime */
+ NULL,
+ } },
+};
+
+void test_iterate(void);
+
+void
+test_iterate(void)
+{
+ struct cbctx ctx;
+
+ TEST_START("hostkeys_iterate all with key parse");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_PARSE_KEY;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, NULL, NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate all without key parse");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, NULL, NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify host 1");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ ctx.match_host_p = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify host 2");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ ctx.match_host_s = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match host 1");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ ctx.match_host_p = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match host 2");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ ctx.match_host_s = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify host missing");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match host missing");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify IPv4");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ ctx.match_ipv4 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify IPv6");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ ctx.match_ipv6 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match IPv4");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ ctx.match_ipv4 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match IPv6");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ ctx.match_ipv6 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify addr missing");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match addr missing");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify host 2 and IPv4");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = 0;
+ ctx.match_host_s = 1;
+ ctx.match_ipv4 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match host 1 and IPv6");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH;
+ ctx.match_host_p = 1;
+ ctx.match_ipv6 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_PARSE_KEY;
+ ctx.match_host_s = 1;
+ ctx.match_ipv4 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
+ TEST_DONE();
+
+ TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse");
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.expected = expected_full;
+ ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
+ ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY;
+ ctx.match_host_p = 1;
+ ctx.match_ipv6 = 1;
+ prepare_expected(expected_full, ctx.nexpected);
+ ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
+ check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
+ TEST_DONE();
+}
+
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub
new file mode 100644
index 0000000..56e1e37
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub
new file mode 100644
index 0000000..394e0bf
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub
new file mode 100644
index 0000000..e506ea4
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub
new file mode 100644
index 0000000..8552c38
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub
new file mode 100644
index 0000000..149e1ef
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub
new file mode 100644
index 0000000..edbb976
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub
new file mode 100644
index 0000000..16a535b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub
new file mode 100644
index 0000000..d2bad11
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub
new file mode 100644
index 0000000..e3ea925
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub
new file mode 100644
index 0000000..2d616f5
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub
new file mode 100644
index 0000000..a3df9b3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub
new file mode 100644
index 0000000..139f5a7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub
new file mode 100644
index 0000000..0b12efe
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub
new file mode 100644
index 0000000..78e262b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub
new file mode 100644
index 0000000..64e5f12
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub
new file mode 100644
index 0000000..47b6724
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub
new file mode 100644
index 0000000..72ccae6
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub
new file mode 100644
index 0000000..0f71973
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts b/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts
new file mode 100644
index 0000000..3740f67
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts
@@ -0,0 +1,61 @@
+# Plain host keys, plain host names
+sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1
+sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1
+sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1
+sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
+sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1
+
+# Plain host keys, hostnames + addresses
+prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2
+prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2
+prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2
+prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2
+prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2
+
+# Some hosts with wildcard names / IPs
+*.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3
+*.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3
+*.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3
+*.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3
+*.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3
+
+# Hashed hostname and address entries
+|1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5
+|1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5
+|1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5
+|1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5
+|1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
+
+|1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
+|1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
+|1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
+|1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
+|1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
+|1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
+|1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
+|1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
+|1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
+|1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
+|1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
+|1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
+|1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
+|1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
+|1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
+
+
+# Revoked and CA keys
+@revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4
+@revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4
+@cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4
+@cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4
+
+# Some invalid lines
+@what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
+sisyphus.example.com
+prometheus.example.com ssh-ed25519
+sisyphus.example.com ssh-dsa AAAATgAAAAdz
+prometheus.example.com 1024
+sisyphus.example.com 1024 65535
+prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
+sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
+prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub
new file mode 100644
index 0000000..772ce9c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub
@@ -0,0 +1 @@
+1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub
new file mode 100644
index 0000000..78794b9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub
@@ -0,0 +1 @@
+1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub
new file mode 100644
index 0000000..0c035fe
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub
@@ -0,0 +1 @@
+1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub
new file mode 100644
index 0000000..00064423
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub
@@ -0,0 +1 @@
+1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub
new file mode 100644
index 0000000..bb53c26
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub
@@ -0,0 +1 @@
+1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub
new file mode 100644
index 0000000..85d6576
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub
@@ -0,0 +1 @@
+1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub
new file mode 100644
index 0000000..2b87885
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub
new file mode 100644
index 0000000..33f1fd9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub
new file mode 100644
index 0000000..c2f6b20
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub
new file mode 100644
index 0000000..35545a7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub
new file mode 100644
index 0000000..befbaa7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub
new file mode 100644
index 0000000..393e116
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
diff --git a/crypto/openssh/regress/unittests/hostkeys/tests.c b/crypto/openssh/regress/unittests/hostkeys/tests.c
new file mode 100644
index 0000000..92c7646
--- /dev/null
+++ b/crypto/openssh/regress/unittests/hostkeys/tests.c
@@ -0,0 +1,16 @@
+/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */
+/*
+ * Regress test for known_hosts-related API.
+ *
+ * Placed in the public domain
+ */
+
+void tests(void);
+void test_iterate(void); /* test_iterate.c */
+
+void
+tests(void)
+{
+ test_iterate();
+}
+
diff --git a/crypto/openssh/regress/unittests/kex/Makefile b/crypto/openssh/regress/unittests/kex/Makefile
new file mode 100644
index 0000000..6532cb0
--- /dev/null
+++ b/crypto/openssh/regress/unittests/kex/Makefile
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+PROG=test_kex
+SRCS=tests.c test_kex.c
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG}
+
+.include <bsd.regress.mk>
+
+LDADD+=-lz
diff --git a/crypto/openssh/regress/unittests/kex/test_kex.c b/crypto/openssh/regress/unittests/kex/test_kex.c
new file mode 100644
index 0000000..c61e2bd
--- /dev/null
+++ b/crypto/openssh/regress/unittests/kex/test_kex.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: test_kex.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */
+/*
+ * Regress test KEX
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "ssh_api.h"
+#include "sshbuf.h"
+#include "packet.h"
+#include "myproposal.h"
+
+struct ssh *active_state = NULL; /* XXX - needed for linking */
+
+void kex_tests(void);
+static int do_debug = 0;
+
+static int
+do_send_and_receive(struct ssh *from, struct ssh *to)
+{
+ u_char type;
+ size_t len;
+ const u_char *buf;
+ int r;
+
+ for (;;) {
+ if ((r = ssh_packet_next(from, &type)) != 0) {
+ fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r));
+ return r;
+ }
+ if (type != 0)
+ return 0;
+ buf = ssh_output_ptr(from, &len);
+ if (do_debug)
+ printf("%zu", len);
+ if (len == 0)
+ return 0;
+ if ((r = ssh_output_consume(from, len)) != 0 ||
+ (r = ssh_input_append(to, buf, len)) != 0)
+ return r;
+ }
+}
+
+static void
+run_kex(struct ssh *client, struct ssh *server)
+{
+ int r = 0;
+
+ while (!server->kex->done || !client->kex->done) {
+ if (do_debug)
+ printf(" S:");
+ if ((r = do_send_and_receive(server, client)))
+ break;
+ if (do_debug)
+ printf(" C:");
+ if ((r = do_send_and_receive(client, server)))
+ break;
+ }
+ if (do_debug)
+ printf("done: %s\n", ssh_err(r));
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_INT_EQ(server->kex->done, 1);
+ ASSERT_INT_EQ(client->kex->done, 1);
+}
+
+static void
+do_kex_with_key(char *kex, int keytype, int bits)
+{
+ struct ssh *client = NULL, *server = NULL, *server2 = NULL;
+ struct sshkey *private, *public;
+ struct sshbuf *state;
+ struct kex_params kex_params;
+ char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
+
+ TEST_START("sshkey_generate");
+ ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0);
+ TEST_DONE();
+
+ TEST_START("sshkey_from_private");
+ ASSERT_INT_EQ(sshkey_from_private(private, &public), 0);
+ TEST_DONE();
+
+ TEST_START("ssh_init");
+ memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
+ if (kex != NULL)
+ kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
+ ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
+ ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0);
+ ASSERT_PTR_NE(client, NULL);
+ ASSERT_PTR_NE(server, NULL);
+ TEST_DONE();
+
+ TEST_START("ssh_add_hostkey");
+ ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0);
+ ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0);
+ TEST_DONE();
+
+ TEST_START("kex");
+ run_kex(client, server);
+ TEST_DONE();
+
+ TEST_START("rekeying client");
+ ASSERT_INT_EQ(kex_send_kexinit(client), 0);
+ run_kex(client, server);
+ TEST_DONE();
+
+ TEST_START("rekeying server");
+ ASSERT_INT_EQ(kex_send_kexinit(server), 0);
+ run_kex(client, server);
+ TEST_DONE();
+
+ TEST_START("ssh_packet_get_state");
+ state = sshbuf_new();
+ ASSERT_PTR_NE(state, NULL);
+ ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0);
+ ASSERT_INT_GE(sshbuf_len(state), 1);
+ TEST_DONE();
+
+ TEST_START("ssh_packet_set_state");
+ server2 = NULL;
+ ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0);
+ ASSERT_PTR_NE(server2, NULL);
+ ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0);
+ kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */
+ ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0);
+ ASSERT_INT_EQ(sshbuf_len(state), 0);
+ sshbuf_free(state);
+ ASSERT_PTR_NE(server2->kex, NULL);
+ /* XXX we need to set the callbacks */
+ 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;
+ 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;
+ TEST_DONE();
+
+ TEST_START("rekeying server2");
+ ASSERT_INT_EQ(kex_send_kexinit(server2), 0);
+ run_kex(client, server2);
+ ASSERT_INT_EQ(kex_send_kexinit(client), 0);
+ run_kex(client, server2);
+ TEST_DONE();
+
+ TEST_START("cleanup");
+ sshkey_free(private);
+ sshkey_free(public);
+ ssh_free(client);
+ ssh_free(server);
+ ssh_free(server2);
+ TEST_DONE();
+}
+
+static void
+do_kex(char *kex)
+{
+ do_kex_with_key(kex, KEY_RSA, 2048);
+ do_kex_with_key(kex, KEY_DSA, 1024);
+#ifdef OPENSSL_HAS_ECC
+ do_kex_with_key(kex, KEY_ECDSA, 256);
+#endif
+ do_kex_with_key(kex, KEY_ED25519, 256);
+}
+
+void
+kex_tests(void)
+{
+ do_kex("curve25519-sha256@libssh.org");
+#ifdef OPENSSL_HAS_ECC
+ do_kex("ecdh-sha2-nistp256");
+ do_kex("ecdh-sha2-nistp384");
+ do_kex("ecdh-sha2-nistp521");
+#endif
+ do_kex("diffie-hellman-group-exchange-sha256");
+ do_kex("diffie-hellman-group-exchange-sha1");
+ do_kex("diffie-hellman-group14-sha1");
+ do_kex("diffie-hellman-group1-sha1");
+}
diff --git a/crypto/openssh/regress/unittests/kex/tests.c b/crypto/openssh/regress/unittests/kex/tests.c
new file mode 100644
index 0000000..e7036ec
--- /dev/null
+++ b/crypto/openssh/regress/unittests/kex/tests.c
@@ -0,0 +1,14 @@
+/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */
+/*
+ * Placed in the public domain
+ */
+
+#include "../test_helper/test_helper.h"
+
+void kex_tests(void);
+
+void
+tests(void)
+{
+ kex_tests();
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
index 0c4c71e..a68e132 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -32,8 +32,6 @@ void
sshbuf_getput_crypto_tests(void)
{
struct sshbuf *p1;
- const u_char *d;
- size_t s;
BIGNUM *bn, *bn2;
/* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
@@ -48,7 +46,9 @@ sshbuf_getput_crypto_tests(void)
0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
0x7f, 0xff, 0x11
};
-#ifdef OPENSSL_HAS_NISTP256
+#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
+ const u_char *d;
+ size_t s;
BIGNUM *bn_x, *bn_y;
int ec256_nid = NID_X9_62_prime256v1;
char *ec256_x = "0C828004839D0106AA59575216191357"
@@ -352,7 +352,7 @@ sshbuf_getput_crypto_tests(void)
sshbuf_free(p1);
TEST_DONE();
-#ifdef OPENSSL_HAS_NISTP256
+#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
TEST_START("sshbuf_put_ec");
eck = EC_KEY_new_by_curve_name(ec256_nid);
ASSERT_PTR_NE(eck, NULL);
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
index 8c3269b..c6b5c29 100644
--- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -33,7 +33,7 @@ attempt_parse_blob(u_char *blob, size_t len)
{
struct sshbuf *p1;
BIGNUM *bn;
-#ifdef OPENSSL_HAS_NISTP256
+#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
EC_KEY *eck;
#endif
u_char *s;
@@ -60,7 +60,7 @@ attempt_parse_blob(u_char *blob, size_t len)
bn = BN_new();
sshbuf_get_bignum2(p1, bn);
BN_clear_free(bn);
-#ifdef OPENSSL_HAS_NISTP256
+#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
ASSERT_PTR_NE(eck, NULL);
sshbuf_get_eckey(p1, eck);
diff --git a/crypto/openssh/regress/unittests/sshkey/common.c b/crypto/openssh/regress/unittests/sshkey/common.c
index 0a4b3a9..b598f05 100644
--- a/crypto/openssh/regress/unittests/sshkey/common.c
+++ b/crypto/openssh/regress/unittests/sshkey/common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */
/*
* Helpers for key API tests
*
@@ -44,7 +44,7 @@ load_file(const char *name)
ASSERT_PTR_NE(ret = sshbuf_new(), NULL);
ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1);
- ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0);
+ ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0);
close(fd);
return ret;
}
diff --git a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
index ee1fe39..09165af 100755
--- a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
+++ b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $
+# $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $
PW=mekmitasdigoat
@@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
+# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against)
+
echo "$PW" > pw
diff --git a/crypto/openssh/regress/unittests/sshkey/test_file.c b/crypto/openssh/regress/unittests/sshkey/test_file.c
index 764f7fb..fa95212 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_file.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: test_file.c,v 1.3 2015/03/04 23:22:35 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -33,6 +33,7 @@
#include "authfile.h"
#include "sshkey.h"
#include "sshbuf.h"
+#include "digest.h"
#include "common.h"
@@ -50,6 +51,7 @@ sshkey_file_tests(void)
pw = load_text_file("pw");
TEST_DONE();
+#ifdef WITH_SSH1
TEST_START("parse RSA1 from private");
buf = load_file("rsa1_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
@@ -81,7 +83,7 @@ sshkey_file_tests(void)
TEST_START("RSA1 key hex fingerprint");
buf = load_text_file("rsa1_1.fp");
- cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -90,7 +92,7 @@ sshkey_file_tests(void)
TEST_START("RSA1 key bubblebabble fingerprint");
buf = load_text_file("rsa1_1.fp.bb");
- cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -98,6 +100,7 @@ sshkey_file_tests(void)
TEST_DONE();
sshkey_free(k1);
+#endif
TEST_START("parse RSA from private");
buf = load_file("rsa_1");
@@ -164,7 +167,7 @@ sshkey_file_tests(void)
TEST_START("RSA key hex fingerprint");
buf = load_text_file("rsa_1.fp");
- cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -173,7 +176,7 @@ sshkey_file_tests(void)
TEST_START("RSA cert hex fingerprint");
buf = load_text_file("rsa_1-cert.fp");
- cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -183,7 +186,7 @@ sshkey_file_tests(void)
TEST_START("RSA key bubblebabble fingerprint");
buf = load_text_file("rsa_1.fp.bb");
- cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -257,7 +260,7 @@ sshkey_file_tests(void)
TEST_START("DSA key hex fingerprint");
buf = load_text_file("dsa_1.fp");
- cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -266,7 +269,7 @@ sshkey_file_tests(void)
TEST_START("DSA cert hex fingerprint");
buf = load_text_file("dsa_1-cert.fp");
- cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -276,7 +279,7 @@ sshkey_file_tests(void)
TEST_START("DSA key bubblebabble fingerprint");
buf = load_text_file("dsa_1.fp.bb");
- cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -357,7 +360,7 @@ sshkey_file_tests(void)
TEST_START("ECDSA key hex fingerprint");
buf = load_text_file("ecdsa_1.fp");
- cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -366,7 +369,7 @@ sshkey_file_tests(void)
TEST_START("ECDSA cert hex fingerprint");
buf = load_text_file("ecdsa_1-cert.fp");
- cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -376,7 +379,7 @@ sshkey_file_tests(void)
TEST_START("ECDSA key bubblebabble fingerprint");
buf = load_text_file("ecdsa_1.fp.bb");
- cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -424,7 +427,7 @@ sshkey_file_tests(void)
TEST_START("Ed25519 key hex fingerprint");
buf = load_text_file("ed25519_1.fp");
- cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -433,7 +436,7 @@ sshkey_file_tests(void)
TEST_START("Ed25519 cert hex fingerprint");
buf = load_text_file("ed25519_1-cert.fp");
- cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
@@ -443,7 +446,7 @@ sshkey_file_tests(void)
TEST_START("Ed25519 key bubblebabble fingerprint");
buf = load_text_file("ed25519_1.fp.bb");
- cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
ASSERT_PTR_NE(cp, NULL);
ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
sshbuf_free(buf);
diff --git a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
index a3f61a6..1f08a2e4 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */
/*
* Fuzz tests for key parsing
*
@@ -53,7 +53,7 @@ public_fuzz(struct sshkey *k)
struct fuzz *fuzz;
ASSERT_PTR_NE(buf = sshbuf_new(), NULL);
- ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0);
+ ASSERT_INT_EQ(sshkey_putb(k, buf), 0);
/* XXX need a way to run the tests in "slow, but complete" mode */
fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */
FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */
@@ -87,8 +87,11 @@ sig_fuzz(struct sshkey *k)
free(sig);
TEST_ONERROR(onerror, fuzz);
for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
- sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
- c, sizeof(c), 0);
+ /* Ensure 1-bit difference at least */
+ if (fuzz_matches_original(fuzz))
+ continue;
+ ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
+ c, sizeof(c), 0), 0);
}
fuzz_cleanup(fuzz);
}
@@ -101,6 +104,7 @@ sshkey_fuzz_tests(void)
struct fuzz *fuzz;
int r;
+#ifdef WITH_SSH1
TEST_START("fuzz RSA1 private");
buf = load_file("rsa1_1");
fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
@@ -144,6 +148,7 @@ sshkey_fuzz_tests(void)
sshbuf_free(fuzzed);
fuzz_cleanup(fuzz);
TEST_DONE();
+#endif
TEST_START("fuzz RSA private");
buf = load_file("rsa_1");
diff --git a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
index ef0c679..ad10c9b 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: test_sshkey.c,v 1.3 2015/01/26 06:11:28 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -19,7 +19,7 @@
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
-#ifdef OPENSSL_HAS_NISTP256
+#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
# include <openssl/ec.h>
#endif
@@ -37,6 +37,20 @@
void sshkey_tests(void);
static void
+put_opt(struct sshbuf *b, const char *name, const char *value)
+{
+ struct sshbuf *sect;
+
+ sect = sshbuf_new();
+ ASSERT_PTR_NE(sect, NULL);
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
+ if (value != NULL)
+ ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
+ sshbuf_free(sect);
+}
+
+static void
build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
const struct sshkey *sign_key, const struct sshkey *ca_key)
{
@@ -45,25 +59,31 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
size_t siglen;
ca_buf = sshbuf_new();
- ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
+ ASSERT_PTR_NE(ca_buf, NULL);
+ ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
/*
* Get the public key serialisation by rendering the key and skipping
* the type string. This is a bit of a hack :/
*/
pk = sshbuf_new();
- ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
+ ASSERT_PTR_NE(pk, NULL);
+ ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0);
ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
principals = sshbuf_new();
+ ASSERT_PTR_NE(principals, NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
critopts = sshbuf_new();
- /* XXX fill this in */
+ ASSERT_PTR_NE(critopts, NULL);
+ put_opt(critopts, "force-command", "/usr/local/bin/nethack");
+ put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
exts = sshbuf_new();
- /* XXX fill this in */
+ ASSERT_PTR_NE(exts, NULL);
+ put_opt(critopts, "permit-X11-forwarding", NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
@@ -90,10 +110,74 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
sshbuf_free(pk);
}
+static void
+signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l)
+{
+ size_t len;
+ u_char *sig;
+
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0);
+ ASSERT_SIZE_T_GT(len, 8);
+ ASSERT_PTR_NE(sig, NULL);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0);
+ /* Fuzz test is more comprehensive, this is just a smoke test */
+ sig[len - 5] ^= 0x10;
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0);
+ free(sig);
+}
+
+static void
+banana(u_char *s, size_t l)
+{
+ size_t o;
+ const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
+
+ for (o = 0; o < l; o += sizeof(the_banana)) {
+ if (l - o < sizeof(the_banana)) {
+ memcpy(s + o, "nanananana", l - o);
+ break;
+ }
+ memcpy(s + o, banana, sizeof(the_banana));
+ }
+}
+
+static void
+signature_tests(struct sshkey *k, struct sshkey *bad)
+{
+ u_char i, buf[2049];
+ size_t lens[] = {
+ 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
+ 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
+ };
+
+ for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
+ test_subtest_info("%s key, banana length %zu",
+ sshkey_type(k), lens[i]);
+ banana(buf, lens[i]);
+ signature_test(k, bad, buf, lens[i]);
+ }
+}
+
+static struct sshkey *
+get_private(const char *n)
+{
+ struct sshbuf *b;
+ struct sshkey *ret;
+
+ b = load_file(n);
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0);
+ sshbuf_free(b);
+ return ret;
+}
+
void
sshkey_tests(void)
{
- struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf;
+ struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf;
+#ifdef OPENSSL_HAS_ECC
+ struct sshkey *ke;
+#endif
struct sshbuf *b;
TEST_START("new invalid");
@@ -136,12 +220,14 @@ sshkey_tests(void)
sshkey_free(k1);
TEST_DONE();
+#ifdef OPENSSL_HAS_ECC
TEST_START("new/free KEY_ECDSA");
k1 = sshkey_new(KEY_ECDSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
sshkey_free(k1);
TEST_DONE();
+#endif
TEST_START("new/free KEY_ED25519");
k1 = sshkey_new(KEY_ED25519);
@@ -192,12 +278,14 @@ sshkey_tests(void)
sshkey_free(k1);
TEST_DONE();
+#ifdef OPENSSL_HAS_ECC
TEST_START("generate KEY_ECDSA wrong bits");
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
SSH_ERR_INVALID_ARGUMENT);
ASSERT_PTR_EQ(k1, NULL);
sshkey_free(k1);
TEST_DONE();
+#endif
TEST_START("generate KEY_RSA");
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0);
@@ -332,26 +420,100 @@ sshkey_tests(void)
#endif
sshkey_free(kf);
-/* XXX certify test */
-/* XXX sign test */
-/* XXX verify test */
+ TEST_START("certify key");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
+ &k1, NULL), 0);
+ k2 = get_private("ed25519_2");
+ ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0);
+ ASSERT_PTR_NE(k1->cert, NULL);
+ k1->cert->type = SSH2_CERT_TYPE_USER;
+ k1->cert->serial = 1234;
+ k1->cert->key_id = strdup("estragon");
+ ASSERT_PTR_NE(k1->cert->key_id, NULL);
+ k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
+ ASSERT_PTR_NE(k1->cert->principals, NULL);
+ k1->cert->principals[0] = strdup("estragon");
+ k1->cert->principals[1] = strdup("vladimir");
+ k1->cert->principals[2] = strdup("pozzo");
+ k1->cert->principals[3] = strdup("lucky");
+ ASSERT_PTR_NE(k1->cert->principals[0], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[1], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[2], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[3], NULL);
+ k1->cert->valid_after = 0;
+ k1->cert->valid_before = (u_int64_t)-1;
+ k1->cert->critical = sshbuf_new();
+ ASSERT_PTR_NE(k1->cert->critical, NULL);
+ k1->cert->extensions = sshbuf_new();
+ ASSERT_PTR_NE(k1->cert->extensions, NULL);
+ put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
+ put_opt(k1->cert->critical, "source-address", "127.0.0.1");
+ put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
+ put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
+ ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
+ ASSERT_INT_EQ(sshkey_certify(k1, k2), 0);
+ b = sshbuf_new();
+ ASSERT_PTR_NE(b, NULL);
+ ASSERT_INT_EQ(sshkey_putb(k1, b), 0);
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
+
+ sshkey_free(k1);
+ sshkey_free(k2);
+ sshkey_free(k3);
+ sshbuf_reset(b);
+ TEST_DONE();
+
+ TEST_START("sign and verify RSA");
+ k1 = get_private("rsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("sign and verify DSA");
+ k1 = get_private("dsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("sign and verify ECDSA");
+ k1 = get_private("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+#endif
+
+ TEST_START("sign and verify ED25519");
+ k1 = get_private("ed25519_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
TEST_START("nested certificate");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
- b = load_file("rsa_2");
- ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
- &k3, NULL), 0);
- sshbuf_reset(b);
+ k3 = get_private("ed25519_2");
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
- sshbuf_free(b);
sshkey_free(k1);
sshkey_free(k2);
sshkey_free(k3);
+ sshbuf_free(b);
TEST_DONE();
}
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp
index 56ee1f8..b26145b 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp
@@ -1 +1 @@
-5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
+MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp
index 56ee1f8..b26145b 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp
@@ -1 +1 @@
-5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
+MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp
index ba9de82..8226574 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp
@@ -1 +1 @@
-72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a
+MD5:72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
index a56dbc8..c3d747a 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
@@ -1 +1 @@
-f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
+MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp
index a56dbc8..c3d747a 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp
@@ -1 +1 @@
-f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
+MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp
index eb4bbdf..fe7526b 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp
@@ -1 +1 @@
-51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70
+MD5:51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
index e6d23d0..fbde87a 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
@@ -1 +1 @@
-19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
+MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp
index e6d23d0..fbde87a 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp
@@ -1 +1 @@
-19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
+MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp
index 02c684f..ec1cdbb 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp
@@ -1 +1 @@
-5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9
+MD5:5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
index 782ece0..2e1068c 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
@@ -1 +1 @@
-a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80
+MD5:a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
index c332537..cd00393 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
@@ -1 +1 @@
-c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c
+MD5:c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp
index bf9c2e3..1cf780d 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp
@@ -1 +1 @@
-be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
+MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp
index bf9c2e3..1cf780d 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp
@@ -1 +1 @@
-be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
+MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp
index 53939f4..8d43676 100644
--- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp
@@ -1 +1 @@
-fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0
+MD5:fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0
diff --git a/crypto/openssh/regress/unittests/test_helper/Makefile b/crypto/openssh/regress/unittests/test_helper/Makefile
index 3e90903..5b3894c 100644
--- a/crypto/openssh/regress/unittests/test_helper/Makefile
+++ b/crypto/openssh/regress/unittests/test_helper/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
+# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $
LIB= test_helper
SRCS= test_helper.c fuzz.c
@@ -7,6 +7,9 @@ DEBUGLIBS= no
NOPROFILE= yes
NOPIC= yes
+# Hack to allow building with SUBDIR in ../../Makefile
+regress: all
+
install:
@echo -n
diff --git a/crypto/openssh/regress/unittests/test_helper/fuzz.c b/crypto/openssh/regress/unittests/test_helper/fuzz.c
index 77c6e7c..99f1d03 100644
--- a/crypto/openssh/regress/unittests/test_helper/fuzz.c
+++ b/crypto/openssh/regress/unittests/test_helper/fuzz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */
+/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -20,6 +20,7 @@
#include "includes.h"
#include <sys/types.h>
+#include <sys/uio.h>
#include <assert.h>
#include <ctype.h>
@@ -29,9 +30,11 @@
#endif
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
+#include <signal.h>
+#include <unistd.h>
#include "test_helper.h"
+#include "atomicio.h"
/* #define FUZZ_DEBUG */
@@ -96,60 +99,66 @@ fuzz_ntop(u_int n)
}
}
-void
-fuzz_dump(struct fuzz *fuzz)
+static int
+fuzz_fmt(struct fuzz *fuzz, char *s, size_t n)
{
- u_char *p = fuzz_ptr(fuzz);
- size_t i, j, len = fuzz_len(fuzz);
+ if (fuzz == NULL)
+ return -1;
switch (fuzz->strategy) {
case FUZZ_1_BIT_FLIP:
- fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n",
+ snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen * 8, fuzz->o1);
- break;
+ return 0;
case FUZZ_2_BIT_FLIP:
- fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n",
+ snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n",
fuzz_ntop(fuzz->strategy),
(((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
fuzz->o1, fuzz->o2);
- break;
+ return 0;
case FUZZ_1_BYTE_FLIP:
- fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n",
+ snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
- break;
+ return 0;
case FUZZ_2_BYTE_FLIP:
- fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n",
+ snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n",
fuzz_ntop(fuzz->strategy),
(((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
((fuzz_ullong)fuzz->slen) * fuzz->slen,
fuzz->o1, fuzz->o2);
- break;
+ return 0;
case FUZZ_TRUNCATE_START:
- fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
+ snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
- break;
+ return 0;
case FUZZ_TRUNCATE_END:
- fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
+ snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
fuzz_ntop(fuzz->strategy),
fuzz->o1, fuzz->slen, fuzz->o1);
- break;
+ return 0;
case FUZZ_BASE64:
assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
- fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n",
+ snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n",
fuzz_ntop(fuzz->strategy),
(fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
fuzz->slen * (fuzz_ullong)64, fuzz->o1,
fuzz_b64chars[fuzz->o2]);
- break;
+ return 0;
default:
+ return -1;
abort();
}
+}
+
+static void
+dump(u_char *p, size_t len)
+{
+ size_t i, j;
- fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
for (i = 0; i < len; i += 16) {
fprintf(stderr, "%.4zd: ", i);
for (j = i; j < i + 16; j++) {
@@ -171,6 +180,39 @@ fuzz_dump(struct fuzz *fuzz)
}
}
+void
+fuzz_dump(struct fuzz *fuzz)
+{
+ char buf[256];
+
+ if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) {
+ fprintf(stderr, "%s: fuzz invalid\n", __func__);
+ abort();
+ }
+ fputs(buf, stderr);
+ fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen);
+ dump(fuzz->seed, fuzz->slen);
+ fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz));
+ dump(fuzz_ptr(fuzz), fuzz_len(fuzz));
+}
+
+#ifdef SIGINFO
+static struct fuzz *last_fuzz;
+
+static void
+siginfo(int unused __attribute__((__unused__)))
+{
+ char buf[256];
+
+ test_info(buf, sizeof(buf));
+ atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
+ if (last_fuzz != NULL) {
+ fuzz_fmt(last_fuzz, buf, sizeof(buf));
+ atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
+ }
+}
+#endif
+
struct fuzz *
fuzz_begin(u_int strategies, const void *p, size_t l)
{
@@ -190,6 +232,12 @@ fuzz_begin(u_int strategies, const void *p, size_t l)
FUZZ_DBG(("begin, ret = %p", ret));
fuzz_next(ret);
+
+#ifdef SIGINFO
+ last_fuzz = ret;
+ signal(SIGINFO, siginfo);
+#endif
+
return ret;
}
@@ -197,6 +245,10 @@ void
fuzz_cleanup(struct fuzz *fuzz)
{
FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
+#ifdef SIGINFO
+ last_fuzz = NULL;
+ signal(SIGINFO, SIG_DFL);
+#endif
assert(fuzz != NULL);
assert(fuzz->seed != NULL);
assert(fuzz->fuzzed != NULL);
@@ -326,6 +378,14 @@ fuzz_next(struct fuzz *fuzz)
}
int
+fuzz_matches_original(struct fuzz *fuzz)
+{
+ if (fuzz_len(fuzz) != fuzz->slen)
+ return 0;
+ return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0;
+}
+
+int
fuzz_done(struct fuzz *fuzz)
{
FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.c b/crypto/openssh/regress/unittests/test_helper/test_helper.c
index d0bc678..26ca26b 100644
--- a/crypto/openssh/regress/unittests/test_helper/test_helper.c
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */
+/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/uio.h>
#include <fcntl.h>
#include <stdio.h>
@@ -31,6 +32,7 @@
#include <string.h>
#include <assert.h>
#include <unistd.h>
+#include <signal.h>
#include <openssl/bn.h>
@@ -39,6 +41,7 @@
#endif
#include "test_helper.h"
+#include "atomicio.h"
#define TEST_CHECK_INT(r, pred) do { \
switch (pred) { \
@@ -111,6 +114,7 @@ static u_int test_number = 0;
static test_onerror_func_t *test_onerror = NULL;
static void *onerror_ctx = NULL;
static const char *data_dir = NULL;
+static char subtest_info[512];
int
main(int argc, char **argv)
@@ -180,13 +184,36 @@ test_data_file(const char *name)
}
void
+test_info(char *s, size_t len)
+{
+ snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number,
+ active_test_name == NULL ? "<none>" : active_test_name,
+ *subtest_info != '\0' ? " - " : "", subtest_info);
+}
+
+#ifdef SIGINFO
+static void
+siginfo(int unused __attribute__((__unused__)))
+{
+ char buf[256];
+
+ test_info(buf, sizeof(buf));
+ atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
+}
+#endif
+
+void
test_start(const char *n)
{
assert(active_test_name == NULL);
assert((active_test_name = strdup(n)) != NULL);
+ *subtest_info = '\0';
if (verbose_mode)
printf("test %u - \"%s\": ", test_number, active_test_name);
test_number++;
+#ifdef SIGINFO
+ signal(SIGINFO, siginfo);
+#endif
}
void
@@ -199,6 +226,7 @@ set_onerror_func(test_onerror_func_t *f, void *ctx)
void
test_done(void)
{
+ *subtest_info = '\0';
assert(active_test_name != NULL);
free(active_test_name);
active_test_name = NULL;
@@ -211,6 +239,16 @@ test_done(void)
}
void
+test_subtest_info(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap);
+ va_end(ap);
+}
+
+void
ssl_err_check(const char *file, int line)
{
long openssl_error = ERR_get_error();
@@ -256,8 +294,9 @@ static void
test_header(const char *file, int line, const char *a1, const char *a2,
const char *name, enum test_predicate pred)
{
- fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
- file, line, test_number, active_test_name);
+ fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n",
+ file, line, test_number, active_test_name,
+ *subtest_info != '\0' ? " - " : "", subtest_info);
fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
name, pred_name(pred), a1,
a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
@@ -280,8 +319,13 @@ void
assert_string(const char *file, int line, const char *a1, const char *a2,
const char *aa1, const char *aa2, enum test_predicate pred)
{
- int r = strcmp(aa1, aa2);
+ int r;
+ /* Verify pointers are not NULL */
+ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
+ assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
+
+ r = strcmp(aa1, aa2);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, a2, "STRING", pred);
fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
@@ -310,8 +354,15 @@ void
assert_mem(const char *file, int line, const char *a1, const char *a2,
const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
{
- int r = memcmp(aa1, aa2, l);
+ int r;
+ if (l == 0)
+ return;
+ /* If length is >0, then verify pointers are not NULL */
+ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
+ assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
+
+ r = memcmp(aa1, aa2, l);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, a2, "STRING", pred);
fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
@@ -338,11 +389,15 @@ assert_mem_filled(const char *file, int line, const char *a1,
const void *aa1, u_char v, size_t l, enum test_predicate pred)
{
size_t where = -1;
- int r = memvalcmp(aa1, v, l, &where);
+ int r;
char tmp[64];
if (l == 0)
return;
+ /* If length is >0, then verify the pointer is not NULL */
+ assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
+
+ r = memvalcmp(aa1, v, l, &where);
TEST_CHECK_INT(r, pred);
test_header(file, line, a1, NULL, "MEM_ZERO", pred);
fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.h b/crypto/openssh/regress/unittests/test_helper/test_helper.h
index a398c61..1d9c669 100644
--- a/crypto/openssh/regress/unittests/test_helper/test_helper.h
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */
+/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -40,8 +40,11 @@ void tests(void);
const char *test_data_file(const char *name);
void test_start(const char *n);
+void test_info(char *s, size_t len);
void set_onerror_func(test_onerror_func_t *f, void *ctx);
void test_done(void);
+void test_subtest_info(const char *fmt, ...)
+ __attribute__((format(printf, 1, 2)));
void ssl_err_check(const char *file, int line);
void assert_bignum(const char *file, int line,
const char *a1, const char *a2,
@@ -280,6 +283,13 @@ void fuzz_cleanup(struct fuzz *fuzz);
/* Prepare the next fuzz case in the series */
void fuzz_next(struct fuzz *fuzz);
+/*
+ * Check whether this fuzz case is identical to the original
+ * This is slow, but useful if the caller needs to ensure that all tests
+ * generated change the input (e.g. when fuzzing signatures).
+ */
+int fuzz_matches_original(struct fuzz *fuzz);
+
/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
int fuzz_done(struct fuzz *fuzz);
@@ -289,4 +299,5 @@ u_char *fuzz_ptr(struct fuzz *fuzz);
/* Dump the current fuzz case to stderr */
void fuzz_dump(struct fuzz *fuzz);
+
#endif /* _TEST_HELPER_H */
OpenPOWER on IntegriCloud