summaryrefslogtreecommitdiff
path: root/regress/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'regress/unittests')
-rw-r--r--regress/unittests/Makefile6
-rw-r--r--regress/unittests/Makefile.inc4
-rw-r--r--regress/unittests/bitmap/Makefile12
-rw-r--r--regress/unittests/bitmap/tests.c135
-rw-r--r--regress/unittests/hostkeys/Makefile12
-rw-r--r--regress/unittests/hostkeys/mktestdata.sh94
-rw-r--r--regress/unittests/hostkeys/test_iterate.c1171
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_1.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_2.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_3.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_4.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_5.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/dsa_6.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_1.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_2.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_3.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_4.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_5.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ecdsa_6.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_1.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_2.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_3.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_4.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_5.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/ed25519_6.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/known_hosts61
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_1.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_2.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_3.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_4.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_5.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa1_6.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_1.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_2.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_3.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_4.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_5.pub1
-rw-r--r--regress/unittests/hostkeys/testdata/rsa_6.pub1
-rw-r--r--regress/unittests/hostkeys/tests.c16
-rw-r--r--regress/unittests/kex/Makefile14
-rw-r--r--regress/unittests/kex/test_kex.c197
-rw-r--r--regress/unittests/kex/tests.c14
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_crypto.c8
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c4
-rw-r--r--regress/unittests/sshkey/common.c4
-rwxr-xr-xregress/unittests/sshkey/mktestdata.sh4
-rw-r--r--regress/unittests/sshkey/test_file.c33
-rw-r--r--regress/unittests/sshkey/test_fuzz.c13
-rw-r--r--regress/unittests/sshkey/test_sshkey.c192
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1-cert.fp2
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.fp2
-rw-r--r--regress/unittests/sshkey/testdata/dsa_2.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1-cert.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1-cert.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1.fp2
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_2.fp2
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1.fp2
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2.fp2
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1-cert.fp2
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.fp2
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.fp2
-rw-r--r--regress/unittests/test_helper/Makefile5
-rw-r--r--regress/unittests/test_helper/fuzz.c102
-rw-r--r--regress/unittests/test_helper/test_helper.c67
-rw-r--r--regress/unittests/test_helper/test_helper.h13
67 files changed, 2148 insertions, 91 deletions
diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile
index bdb4574e2..d3d90823f 100644
--- a/regress/unittests/Makefile
+++ b/regress/unittests/Makefile
@@ -1,5 +1,5 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ 1# $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $
2 2REGRESS_FAIL_EARLY= yes
3SUBDIR= test_helper sshbuf sshkey 3SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys
4 4
5.include <bsd.subdir.mk> 5.include <bsd.subdir.mk>
diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc
index 4c3363749..c55d00c61 100644
--- a/regress/unittests/Makefile.inc
+++ b/regress/unittests/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $ 1# $OpenBSD: Makefile.inc,v 1.3 2015/01/23 21:21:23 miod Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4.include <bsd.obj.mk> 4.include <bsd.obj.mk>
@@ -21,7 +21,6 @@ CDIAGFLAGS+= -Wmissing-declarations
21CDIAGFLAGS+= -Wmissing-prototypes 21CDIAGFLAGS+= -Wmissing-prototypes
22CDIAGFLAGS+= -Wparentheses 22CDIAGFLAGS+= -Wparentheses
23CDIAGFLAGS+= -Wpointer-arith 23CDIAGFLAGS+= -Wpointer-arith
24CDIAGFLAGS+= -Wpointer-sign
25CDIAGFLAGS+= -Wreturn-type 24CDIAGFLAGS+= -Wreturn-type
26CDIAGFLAGS+= -Wshadow 25CDIAGFLAGS+= -Wshadow
27CDIAGFLAGS+= -Wsign-compare 26CDIAGFLAGS+= -Wsign-compare
@@ -32,6 +31,7 @@ CDIAGFLAGS+= -Wtrigraphs
32CDIAGFLAGS+= -Wuninitialized 31CDIAGFLAGS+= -Wuninitialized
33CDIAGFLAGS+= -Wunused 32CDIAGFLAGS+= -Wunused
34.if ${COMPILER_VERSION} == "gcc4" 33.if ${COMPILER_VERSION} == "gcc4"
34CDIAGFLAGS+= -Wpointer-sign
35CDIAGFLAGS+= -Wold-style-definition 35CDIAGFLAGS+= -Wold-style-definition
36.endif 36.endif
37 37
diff --git a/regress/unittests/bitmap/Makefile b/regress/unittests/bitmap/Makefile
new file mode 100644
index 000000000..b704d22d6
--- /dev/null
+++ b/regress/unittests/bitmap/Makefile
@@ -0,0 +1,12 @@
1# $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $
2
3TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
4
5PROG=test_bitmap
6SRCS=tests.c
7REGRESS_TARGETS=run-regress-${PROG}
8
9run-regress-${PROG}: ${PROG}
10 env ${TEST_ENV} ./${PROG}
11
12.include <bsd.regress.mk>
diff --git a/regress/unittests/bitmap/tests.c b/regress/unittests/bitmap/tests.c
new file mode 100644
index 000000000..23025f90a
--- /dev/null
+++ b/regress/unittests/bitmap/tests.c
@@ -0,0 +1,135 @@
1/* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */
2/*
3 * Regress test for bitmap.h bitmap API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14#include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20
21#include "../test_helper/test_helper.h"
22
23#include "bitmap.h"
24
25#define NTESTS 131
26
27void
28tests(void)
29{
30 struct bitmap *b;
31 BIGNUM *bn;
32 size_t len;
33 int i, j, k, n;
34 u_char bbuf[1024], bnbuf[1024];
35 int r;
36
37 TEST_START("bitmap_new");
38 b = bitmap_new();
39 ASSERT_PTR_NE(b, NULL);
40 bn = BN_new();
41 ASSERT_PTR_NE(bn, NULL);
42 TEST_DONE();
43
44 TEST_START("bitmap_set_bit / bitmap_test_bit");
45 for (i = -1; i < NTESTS; i++) {
46 for (j = -1; j < NTESTS; j++) {
47 for (k = -1; k < NTESTS; k++) {
48 bitmap_zero(b);
49 BN_clear(bn);
50
51 test_subtest_info("set %d/%d/%d", i, j, k);
52 /* Set bits */
53 if (i >= 0) {
54 ASSERT_INT_EQ(bitmap_set_bit(b, i), 0);
55 ASSERT_INT_EQ(BN_set_bit(bn, i), 1);
56 }
57 if (j >= 0) {
58 ASSERT_INT_EQ(bitmap_set_bit(b, j), 0);
59 ASSERT_INT_EQ(BN_set_bit(bn, j), 1);
60 }
61 if (k >= 0) {
62 ASSERT_INT_EQ(bitmap_set_bit(b, k), 0);
63 ASSERT_INT_EQ(BN_set_bit(bn, k), 1);
64 }
65
66 /* Check perfect match between bitmap and bn */
67 test_subtest_info("match %d/%d/%d", i, j, k);
68 for (n = 0; n < NTESTS; n++) {
69 ASSERT_INT_EQ(BN_is_bit_set(bn, n),
70 bitmap_test_bit(b, n));
71 }
72
73 /* Test length calculations */
74 test_subtest_info("length %d/%d/%d", i, j, k);
75 ASSERT_INT_EQ(BN_num_bits(bn),
76 (int)bitmap_nbits(b));
77 ASSERT_INT_EQ(BN_num_bytes(bn),
78 (int)bitmap_nbytes(b));
79
80 /* Test serialisation */
81 test_subtest_info("serialise %d/%d/%d",
82 i, j, k);
83 len = bitmap_nbytes(b);
84 memset(bbuf, 0xfc, sizeof(bbuf));
85 ASSERT_INT_EQ(bitmap_to_string(b, bbuf,
86 sizeof(bbuf)), 0);
87 for (n = len; n < (int)sizeof(bbuf); n++)
88 ASSERT_U8_EQ(bbuf[n], 0xfc);
89 r = BN_bn2bin(bn, bnbuf);
90 ASSERT_INT_GE(r, 0);
91 ASSERT_INT_EQ(r, (int)len);
92 ASSERT_MEM_EQ(bbuf, bnbuf, len);
93
94 /* Test deserialisation */
95 test_subtest_info("deserialise %d/%d/%d",
96 i, j, k);
97 bitmap_zero(b);
98 ASSERT_INT_EQ(bitmap_from_string(b, bnbuf,
99 len), 0);
100 for (n = 0; n < NTESTS; n++) {
101 ASSERT_INT_EQ(BN_is_bit_set(bn, n),
102 bitmap_test_bit(b, n));
103 }
104
105 /* Test clearing bits */
106 test_subtest_info("clear %d/%d/%d",
107 i, j, k);
108 for (n = 0; n < NTESTS; n++) {
109 ASSERT_INT_EQ(bitmap_set_bit(b, n), 0);
110 ASSERT_INT_EQ(BN_set_bit(bn, n), 1);
111 }
112 if (i >= 0) {
113 bitmap_clear_bit(b, i);
114 BN_clear_bit(bn, i);
115 }
116 if (j >= 0) {
117 bitmap_clear_bit(b, j);
118 BN_clear_bit(bn, j);
119 }
120 if (k >= 0) {
121 bitmap_clear_bit(b, k);
122 BN_clear_bit(bn, k);
123 }
124 for (n = 0; n < NTESTS; n++) {
125 ASSERT_INT_EQ(BN_is_bit_set(bn, n),
126 bitmap_test_bit(b, n));
127 }
128 }
129 }
130 }
131 bitmap_free(b);
132 BN_free(bn);
133 TEST_DONE();
134}
135
diff --git a/regress/unittests/hostkeys/Makefile b/regress/unittests/hostkeys/Makefile
new file mode 100644
index 000000000..f52a85fb1
--- /dev/null
+++ b/regress/unittests/hostkeys/Makefile
@@ -0,0 +1,12 @@
1# $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $
2
3TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
4
5PROG=test_hostkeys
6SRCS=tests.c test_iterate.c
7REGRESS_TARGETS=run-regress-${PROG}
8
9run-regress-${PROG}: ${PROG}
10 env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
11
12.include <bsd.regress.mk>
diff --git a/regress/unittests/hostkeys/mktestdata.sh b/regress/unittests/hostkeys/mktestdata.sh
new file mode 100644
index 000000000..36890ba11
--- /dev/null
+++ b/regress/unittests/hostkeys/mktestdata.sh
@@ -0,0 +1,94 @@
1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $
3
4set -ex
5
6cd testdata
7
8rm -f rsa1* rsa* dsa* ecdsa* ed25519*
9rm -f known_hosts*
10
11gen_all() {
12 _n=$1
13 _ecdsa_bits=256
14 test "x$_n" = "x1" && _ecdsa_bits=384
15 test "x$_n" = "x2" && _ecdsa_bits=521
16 ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n
17 ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n
18 ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n
19 ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n
20 ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n
21 # Don't need private keys
22 rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n
23}
24
25hentries() {
26 _preamble=$1
27 _kspec=$2
28 for k in `ls -1 $_kspec | sort` ; do
29 printf "$_preamble "
30 cat $k
31 done
32 echo
33}
34
35gen_all 1
36gen_all 2
37gen_all 3
38gen_all 4
39gen_all 5
40gen_all 6
41
42# A section of known_hosts with hashed hostnames.
43(
44 hentries "sisyphus.example.com" "*_5.pub"
45 hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub"
46) > known_hosts_hash_frag
47ssh-keygen -Hf known_hosts_hash_frag
48rm -f known_hosts_hash_frag.old
49
50# Populated known_hosts, including comments, hashed names and invalid lines
51(
52 echo "# Plain host keys, plain host names"
53 hentries "sisyphus.example.com" "*_1.pub"
54
55 echo "# Plain host keys, hostnames + addresses"
56 hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub"
57
58 echo "# Some hosts with wildcard names / IPs"
59 hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub"
60
61 echo "# Hashed hostname and address entries"
62 cat known_hosts_hash_frag
63 rm -f known_hosts_hash_frag
64 echo
65
66 echo "# Revoked and CA keys"
67 printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub
68 printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub
69 printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub
70 printf "@cert-authority *.example.com " ; cat dsa_4.pub
71
72 printf "\n"
73 echo "# Some invalid lines"
74 # Invalid marker
75 printf "@what sisyphus.example.com " ; cat rsa1_1.pub
76 # Key missing
77 echo "sisyphus.example.com "
78 # Key blob missing
79 echo "prometheus.example.com ssh-ed25519 "
80 # Key blob truncated
81 echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz"
82 # RSA1 key truncated after key bits
83 echo "prometheus.example.com 1024 "
84 # RSA1 key truncated after exponent
85 echo "sisyphus.example.com 1024 65535 "
86 # RSA1 key incorrect key bits
87 printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub
88 # Invalid type
89 echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg=="
90 # Type mismatch with blob
91 echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg=="
92) > known_hosts
93
94echo OK
diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c
new file mode 100644
index 000000000..d81291b68
--- /dev/null
+++ b/regress/unittests/hostkeys/test_iterate.c
@@ -0,0 +1,1171 @@
1/* $OpenBSD: test_iterate.c,v 1.3 2015/03/07 04:41:48 djm Exp $ */
2/*
3 * Regress test for hostfile.h hostkeys_foreach()
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14#include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "sshkey.h"
22#include "authfile.h"
23#include "hostfile.h"
24
25struct expected {
26 const char *key_file; /* Path for key, NULL for none */
27 int no_parse_status; /* Expected status w/o key parsing */
28 int no_parse_keytype; /* Expected keytype w/o key parsing */
29 int match_host_p; /* Match 'prometheus.example.com' */
30 int match_host_s; /* Match 'sisyphus.example.com' */
31 int match_ipv4; /* Match '192.0.2.1' */
32 int match_ipv6; /* Match '2001:db8::1' */
33 int match_flags; /* Expected flags from match */
34 struct hostkey_foreach_line l; /* Expected line contents */
35};
36
37struct cbctx {
38 const struct expected *expected;
39 size_t nexpected;
40 size_t i;
41 int flags;
42 int match_host_p;
43 int match_host_s;
44 int match_ipv4;
45 int match_ipv6;
46};
47
48/*
49 * hostkeys_foreach() iterator callback that verifies the line passed
50 * against an array of expected entries.
51 */
52static int
53check(struct hostkey_foreach_line *l, void *_ctx)
54{
55 struct cbctx *ctx = (struct cbctx *)_ctx;
56 const struct expected *expected;
57 int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0;
58 const int matching = (ctx->flags & HKF_WANT_MATCH) != 0;
59 u_int expected_status, expected_match;
60 int expected_keytype;
61
62 test_subtest_info("entry %zu/%zu, file line %ld",
63 ctx->i + 1, ctx->nexpected, l->linenum);
64
65 for (;;) {
66 ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected);
67 expected = ctx->expected + ctx->i++;
68 /* If we are matching host/IP then skip entries that don't */
69 if (!matching)
70 break;
71 if (ctx->match_host_p && expected->match_host_p)
72 break;
73 if (ctx->match_host_s && expected->match_host_s)
74 break;
75 if (ctx->match_ipv4 && expected->match_ipv4)
76 break;
77 if (ctx->match_ipv6 && expected->match_ipv6)
78 break;
79 }
80 expected_status = (parse_key || expected->no_parse_status < 0) ?
81 expected->l.status : (u_int)expected->no_parse_status;
82 expected_match = expected->l.match;
83#define UPDATE_MATCH_STATUS(x) do { \
84 if (ctx->x && expected->x) { \
85 expected_match |= expected->x; \
86 if (expected_status == HKF_STATUS_OK) \
87 expected_status = HKF_STATUS_MATCHED; \
88 } \
89 } while (0)
90 expected_keytype = (parse_key || expected->no_parse_keytype < 0) ?
91 expected->l.keytype : expected->no_parse_keytype;
92
93#ifndef WITH_SSH1
94 if (expected->l.keytype == KEY_RSA1 ||
95 expected->no_parse_keytype == KEY_RSA1) {
96 expected_status = HKF_STATUS_INVALID;
97 expected_keytype = KEY_UNSPEC;
98 parse_key = 0;
99 }
100#endif
101#ifndef OPENSSL_HAS_ECC
102 if (expected->l.keytype == KEY_ECDSA ||
103 expected->no_parse_keytype == KEY_ECDSA) {
104 expected_status = HKF_STATUS_INVALID;
105 expected_keytype = KEY_UNSPEC;
106 parse_key = 0;
107 }
108#endif
109
110 UPDATE_MATCH_STATUS(match_host_p);
111 UPDATE_MATCH_STATUS(match_host_s);
112 UPDATE_MATCH_STATUS(match_ipv4);
113 UPDATE_MATCH_STATUS(match_ipv6);
114
115 ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */
116 ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum);
117 ASSERT_U_INT_EQ(l->status, expected_status);
118 ASSERT_U_INT_EQ(l->match, expected_match);
119 /* Not all test entries contain fulltext */
120 if (expected->l.line != NULL)
121 ASSERT_STRING_EQ(l->line, expected->l.line);
122 ASSERT_INT_EQ(l->marker, expected->l.marker);
123 /* XXX we skip hashed hostnames for now; implement checking */
124 if (expected->l.hosts != NULL)
125 ASSERT_STRING_EQ(l->hosts, expected->l.hosts);
126 /* Not all test entries contain raw keys */
127 if (expected->l.rawkey != NULL)
128 ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey);
129 /* XXX synthesise raw key for cases lacking and compare */
130 ASSERT_INT_EQ(l->keytype, expected_keytype);
131 if (parse_key) {
132 if (expected->l.key == NULL)
133 ASSERT_PTR_EQ(l->key, NULL);
134 if (expected->l.key != NULL) {
135 ASSERT_PTR_NE(l->key, NULL);
136 ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1);
137 }
138 }
139 if (parse_key && !(l->comment == NULL && expected->l.comment == NULL))
140 ASSERT_STRING_EQ(l->comment, expected->l.comment);
141 return 0;
142}
143
144/* Loads public keys for a set of expected results */
145static void
146prepare_expected(struct expected *expected, size_t n)
147{
148 size_t i;
149
150 for (i = 0; i < n; i++) {
151 if (expected[i].key_file == NULL)
152 continue;
153#ifndef WITH_SSH1
154 if (expected[i].l.keytype == KEY_RSA1)
155 continue;
156#endif
157#ifndef OPENSSL_HAS_ECC
158 if (expected[i].l.keytype == KEY_ECDSA)
159 continue;
160#endif
161 ASSERT_INT_EQ(sshkey_load_public(
162 test_data_file(expected[i].key_file), &expected[i].l.key,
163 NULL), 0);
164 }
165}
166
167struct expected expected_full[] = {
168 { NULL, -1, -1, 0, 0, 0, 0, -1, {
169 NULL, /* path, don't care */
170 1, /* line number */
171 HKF_STATUS_COMMENT, /* status */
172 0, /* match flags */
173 "# Plain host keys, plain host names", /* full line, optional */
174 MRK_NONE, /* marker (CA / revoked) */
175 NULL, /* hosts text */
176 NULL, /* raw key, optional */
177 KEY_UNSPEC, /* key type */
178 NULL, /* deserialised key */
179 NULL, /* comment */
180 } },
181 { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
182 NULL,
183 2,
184 HKF_STATUS_OK,
185 0,
186 NULL,
187 MRK_NONE,
188 "sisyphus.example.com",
189 NULL,
190 KEY_DSA,
191 NULL, /* filled at runtime */
192 "DSA #1",
193 } },
194 { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
195 NULL,
196 3,
197 HKF_STATUS_OK,
198 0,
199 NULL,
200 MRK_NONE,
201 "sisyphus.example.com",
202 NULL,
203 KEY_ECDSA,
204 NULL, /* filled at runtime */
205 "ECDSA #1",
206 } },
207 { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
208 NULL,
209 4,
210 HKF_STATUS_OK,
211 0,
212 NULL,
213 MRK_NONE,
214 "sisyphus.example.com",
215 NULL,
216 KEY_ED25519,
217 NULL, /* filled at runtime */
218 "ED25519 #1",
219 } },
220 { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
221 NULL,
222 5,
223 HKF_STATUS_OK,
224 0,
225 NULL,
226 MRK_NONE,
227 "sisyphus.example.com",
228 NULL,
229 KEY_RSA1,
230 NULL, /* filled at runtime */
231 "RSA1 #1",
232 } },
233 { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
234 NULL,
235 6,
236 HKF_STATUS_OK,
237 0,
238 NULL,
239 MRK_NONE,
240 "sisyphus.example.com",
241 NULL,
242 KEY_RSA,
243 NULL, /* filled at runtime */
244 "RSA #1",
245 } },
246 { NULL, -1, -1, 0, 0, 0, 0, -1, {
247 NULL,
248 7,
249 HKF_STATUS_COMMENT,
250 0,
251 "",
252 MRK_NONE,
253 NULL,
254 NULL,
255 KEY_UNSPEC,
256 NULL,
257 NULL,
258 } },
259 { NULL, -1, -1, 0, 0, 0, 0, -1, {
260 NULL,
261 8,
262 HKF_STATUS_COMMENT,
263 0,
264 "# Plain host keys, hostnames + addresses",
265 MRK_NONE,
266 NULL,
267 NULL,
268 KEY_UNSPEC,
269 NULL,
270 NULL,
271 } },
272 { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
273 NULL,
274 9,
275 HKF_STATUS_OK,
276 0,
277 NULL,
278 MRK_NONE,
279 "prometheus.example.com,192.0.2.1,2001:db8::1",
280 NULL,
281 KEY_DSA,
282 NULL, /* filled at runtime */
283 "DSA #2",
284 } },
285 { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
286 NULL,
287 10,
288 HKF_STATUS_OK,
289 0,
290 NULL,
291 MRK_NONE,
292 "prometheus.example.com,192.0.2.1,2001:db8::1",
293 NULL,
294 KEY_ECDSA,
295 NULL, /* filled at runtime */
296 "ECDSA #2",
297 } },
298 { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
299 NULL,
300 11,
301 HKF_STATUS_OK,
302 0,
303 NULL,
304 MRK_NONE,
305 "prometheus.example.com,192.0.2.1,2001:db8::1",
306 NULL,
307 KEY_ED25519,
308 NULL, /* filled at runtime */
309 "ED25519 #2",
310 } },
311 { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
312 NULL,
313 12,
314 HKF_STATUS_OK,
315 0,
316 NULL,
317 MRK_NONE,
318 "prometheus.example.com,192.0.2.1,2001:db8::1",
319 NULL,
320 KEY_RSA1,
321 NULL, /* filled at runtime */
322 "RSA1 #2",
323 } },
324 { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
325 NULL,
326 13,
327 HKF_STATUS_OK,
328 0,
329 NULL,
330 MRK_NONE,
331 "prometheus.example.com,192.0.2.1,2001:db8::1",
332 NULL,
333 KEY_RSA,
334 NULL, /* filled at runtime */
335 "RSA #2",
336 } },
337 { NULL, -1, -1, 0, 0, 0, 0, -1, {
338 NULL,
339 14,
340 HKF_STATUS_COMMENT,
341 0,
342 "",
343 MRK_NONE,
344 NULL,
345 NULL,
346 KEY_UNSPEC,
347 NULL,
348 NULL,
349 } },
350 { NULL, -1, -1, 0, 0, 0, 0, -1, {
351 NULL,
352 15,
353 HKF_STATUS_COMMENT,
354 0,
355 "# Some hosts with wildcard names / IPs",
356 MRK_NONE,
357 NULL,
358 NULL,
359 KEY_UNSPEC,
360 NULL,
361 NULL,
362 } },
363 { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
364 NULL,
365 16,
366 HKF_STATUS_OK,
367 0,
368 NULL,
369 MRK_NONE,
370 "*.example.com,192.0.2.*,2001:*",
371 NULL,
372 KEY_DSA,
373 NULL, /* filled at runtime */
374 "DSA #3",
375 } },
376 { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
377 NULL,
378 17,
379 HKF_STATUS_OK,
380 0,
381 NULL,
382 MRK_NONE,
383 "*.example.com,192.0.2.*,2001:*",
384 NULL,
385 KEY_ECDSA,
386 NULL, /* filled at runtime */
387 "ECDSA #3",
388 } },
389 { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
390 NULL,
391 18,
392 HKF_STATUS_OK,
393 0,
394 NULL,
395 MRK_NONE,
396 "*.example.com,192.0.2.*,2001:*",
397 NULL,
398 KEY_ED25519,
399 NULL, /* filled at runtime */
400 "ED25519 #3",
401 } },
402 { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
403 NULL,
404 19,
405 HKF_STATUS_OK,
406 0,
407 NULL,
408 MRK_NONE,
409 "*.example.com,192.0.2.*,2001:*",
410 NULL,
411 KEY_RSA1,
412 NULL, /* filled at runtime */
413 "RSA1 #3",
414 } },
415 { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
416 NULL,
417 20,
418 HKF_STATUS_OK,
419 0,
420 NULL,
421 MRK_NONE,
422 "*.example.com,192.0.2.*,2001:*",
423 NULL,
424 KEY_RSA,
425 NULL, /* filled at runtime */
426 "RSA #3",
427 } },
428 { NULL, -1, -1, 0, 0, 0, 0, -1, {
429 NULL,
430 21,
431 HKF_STATUS_COMMENT,
432 0,
433 "",
434 MRK_NONE,
435 NULL,
436 NULL,
437 KEY_UNSPEC,
438 NULL,
439 NULL,
440 } },
441 { NULL, -1, -1, 0, 0, 0, 0, -1, {
442 NULL,
443 22,
444 HKF_STATUS_COMMENT,
445 0,
446 "# Hashed hostname and address entries",
447 MRK_NONE,
448 NULL,
449 NULL,
450 KEY_UNSPEC,
451 NULL,
452 NULL,
453 } },
454 { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
455 NULL,
456 23,
457 HKF_STATUS_OK,
458 0,
459 NULL,
460 MRK_NONE,
461 NULL,
462 NULL,
463 KEY_DSA,
464 NULL, /* filled at runtime */
465 "DSA #5",
466 } },
467 { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
468 NULL,
469 24,
470 HKF_STATUS_OK,
471 0,
472 NULL,
473 MRK_NONE,
474 NULL,
475 NULL,
476 KEY_ECDSA,
477 NULL, /* filled at runtime */
478 "ECDSA #5",
479 } },
480 { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
481 NULL,
482 25,
483 HKF_STATUS_OK,
484 0,
485 NULL,
486 MRK_NONE,
487 NULL,
488 NULL,
489 KEY_ED25519,
490 NULL, /* filled at runtime */
491 "ED25519 #5",
492 } },
493 { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
494 NULL,
495 26,
496 HKF_STATUS_OK,
497 0,
498 NULL,
499 MRK_NONE,
500 NULL,
501 NULL,
502 KEY_RSA1,
503 NULL, /* filled at runtime */
504 "RSA1 #5",
505 } },
506 { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
507 NULL,
508 27,
509 HKF_STATUS_OK,
510 0,
511 NULL,
512 MRK_NONE,
513 NULL,
514 NULL,
515 KEY_RSA,
516 NULL, /* filled at runtime */
517 "RSA #5",
518 } },
519 { NULL, -1, -1, 0, 0, 0, 0, -1, {
520 NULL,
521 28,
522 HKF_STATUS_COMMENT,
523 0,
524 "",
525 MRK_NONE,
526 NULL,
527 NULL,
528 KEY_UNSPEC,
529 NULL,
530 NULL,
531 } },
532 /*
533 * The next series have each key listed multiple times, as the
534 * hostname and addresses in the pre-hashed known_hosts are split
535 * to separate lines.
536 */
537 { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
538 NULL,
539 29,
540 HKF_STATUS_OK,
541 0,
542 NULL,
543 MRK_NONE,
544 NULL,
545 NULL,
546 KEY_DSA,
547 NULL, /* filled at runtime */
548 "DSA #6",
549 } },
550 { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
551 NULL,
552 30,
553 HKF_STATUS_OK,
554 0,
555 NULL,
556 MRK_NONE,
557 NULL,
558 NULL,
559 KEY_DSA,
560 NULL, /* filled at runtime */
561 "DSA #6",
562 } },
563 { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
564 NULL,
565 31,
566 HKF_STATUS_OK,
567 0,
568 NULL,
569 MRK_NONE,
570 NULL,
571 NULL,
572 KEY_DSA,
573 NULL, /* filled at runtime */
574 "DSA #6",
575 } },
576 { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
577 NULL,
578 32,
579 HKF_STATUS_OK,
580 0,
581 NULL,
582 MRK_NONE,
583 NULL,
584 NULL,
585 KEY_ECDSA,
586 NULL, /* filled at runtime */
587 "ECDSA #6",
588 } },
589 { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
590 NULL,
591 33,
592 HKF_STATUS_OK,
593 0,
594 NULL,
595 MRK_NONE,
596 NULL,
597 NULL,
598 KEY_ECDSA,
599 NULL, /* filled at runtime */
600 "ECDSA #6",
601 } },
602 { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
603 NULL,
604 34,
605 HKF_STATUS_OK,
606 0,
607 NULL,
608 MRK_NONE,
609 NULL,
610 NULL,
611 KEY_ECDSA,
612 NULL, /* filled at runtime */
613 "ECDSA #6",
614 } },
615 { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
616 NULL,
617 35,
618 HKF_STATUS_OK,
619 0,
620 NULL,
621 MRK_NONE,
622 NULL,
623 NULL,
624 KEY_ED25519,
625 NULL, /* filled at runtime */
626 "ED25519 #6",
627 } },
628 { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
629 NULL,
630 36,
631 HKF_STATUS_OK,
632 0,
633 NULL,
634 MRK_NONE,
635 NULL,
636 NULL,
637 KEY_ED25519,
638 NULL, /* filled at runtime */
639 "ED25519 #6",
640 } },
641 { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
642 NULL,
643 37,
644 HKF_STATUS_OK,
645 0,
646 NULL,
647 MRK_NONE,
648 NULL,
649 NULL,
650 KEY_ED25519,
651 NULL, /* filled at runtime */
652 "ED25519 #6",
653 } },
654 { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
655 NULL,
656 38,
657 HKF_STATUS_OK,
658 0,
659 NULL,
660 MRK_NONE,
661 NULL,
662 NULL,
663 KEY_RSA1,
664 NULL, /* filled at runtime */
665 "RSA1 #6",
666 } },
667 { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
668 NULL,
669 39,
670 HKF_STATUS_OK,
671 0,
672 NULL,
673 MRK_NONE,
674 NULL,
675 NULL,
676 KEY_RSA1,
677 NULL, /* filled at runtime */
678 "RSA1 #6",
679 } },
680 { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
681 NULL,
682 40,
683 HKF_STATUS_OK,
684 0,
685 NULL,
686 MRK_NONE,
687 NULL,
688 NULL,
689 KEY_RSA1,
690 NULL, /* filled at runtime */
691 "RSA1 #6",
692 } },
693 { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
694 NULL,
695 41,
696 HKF_STATUS_OK,
697 0,
698 NULL,
699 MRK_NONE,
700 NULL,
701 NULL,
702 KEY_RSA,
703 NULL, /* filled at runtime */
704 "RSA #6",
705 } },
706 { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
707 NULL,
708 42,
709 HKF_STATUS_OK,
710 0,
711 NULL,
712 MRK_NONE,
713 NULL,
714 NULL,
715 KEY_RSA,
716 NULL, /* filled at runtime */
717 "RSA #6",
718 } },
719 { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
720 NULL,
721 43,
722 HKF_STATUS_OK,
723 0,
724 NULL,
725 MRK_NONE,
726 NULL,
727 NULL,
728 KEY_RSA,
729 NULL, /* filled at runtime */
730 "RSA #6",
731 } },
732 { NULL, -1, -1, 0, 0, 0, 0, -1, {
733 NULL,
734 44,
735 HKF_STATUS_COMMENT,
736 0,
737 "",
738 MRK_NONE,
739 NULL,
740 NULL,
741 KEY_UNSPEC,
742 NULL,
743 NULL,
744 } },
745 { NULL, -1, -1, 0, 0, 0, 0, -1, {
746 NULL,
747 45,
748 HKF_STATUS_COMMENT,
749 0,
750 "",
751 MRK_NONE,
752 NULL,
753 NULL,
754 KEY_UNSPEC,
755 NULL,
756 NULL,
757 } },
758 { NULL, -1, -1, 0, 0, 0, 0, -1, {
759 NULL,
760 46,
761 HKF_STATUS_COMMENT,
762 0,
763 "# Revoked and CA keys",
764 MRK_NONE,
765 NULL,
766 NULL,
767 KEY_UNSPEC,
768 NULL,
769 NULL,
770 } },
771 { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
772 NULL,
773 47,
774 HKF_STATUS_OK,
775 0,
776 NULL,
777 MRK_REVOKE,
778 "sisyphus.example.com",
779 NULL,
780 KEY_RSA1,
781 NULL, /* filled at runtime */
782 "RSA1 #4",
783 } },
784 { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
785 NULL,
786 48,
787 HKF_STATUS_OK,
788 0,
789 NULL,
790 MRK_REVOKE,
791 "sisyphus.example.com",
792 NULL,
793 KEY_ED25519,
794 NULL, /* filled at runtime */
795 "ED25519 #4",
796 } },
797 { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
798 NULL,
799 49,
800 HKF_STATUS_OK,
801 0,
802 NULL,
803 MRK_CA,
804 "prometheus.example.com",
805 NULL,
806 KEY_ECDSA,
807 NULL, /* filled at runtime */
808 "ECDSA #4",
809 } },
810 { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, {
811 NULL,
812 50,
813 HKF_STATUS_OK,
814 0,
815 NULL,
816 MRK_CA,
817 "*.example.com",
818 NULL,
819 KEY_DSA,
820 NULL, /* filled at runtime */
821 "DSA #4",
822 } },
823 { NULL, -1, -1, 0, 0, 0, 0, -1, {
824 NULL,
825 51,
826 HKF_STATUS_COMMENT,
827 0,
828 "",
829 MRK_NONE,
830 NULL,
831 NULL,
832 KEY_UNSPEC,
833 NULL,
834 NULL,
835 } },
836 { NULL, -1, -1, 0, 0, 0, 0, -1, {
837 NULL,
838 52,
839 HKF_STATUS_COMMENT,
840 0,
841 "# Some invalid lines",
842 MRK_NONE,
843 NULL,
844 NULL,
845 KEY_UNSPEC,
846 NULL,
847 NULL,
848 } },
849 { NULL, -1, -1, 0, 0, 0, 0, -1, {
850 NULL,
851 53,
852 HKF_STATUS_INVALID,
853 0,
854 NULL,
855 MRK_ERROR,
856 NULL,
857 NULL,
858 KEY_UNSPEC,
859 NULL,
860 NULL,
861 } },
862 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
863 NULL,
864 54,
865 HKF_STATUS_INVALID,
866 0,
867 NULL,
868 MRK_NONE,
869 "sisyphus.example.com",
870 NULL,
871 KEY_UNSPEC,
872 NULL,
873 NULL,
874 } },
875 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
876 NULL,
877 55,
878 HKF_STATUS_INVALID,
879 0,
880 NULL,
881 MRK_NONE,
882 "prometheus.example.com",
883 NULL,
884 KEY_UNSPEC,
885 NULL,
886 NULL,
887 } },
888 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
889 NULL,
890 56,
891 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
892 0,
893 NULL,
894 MRK_NONE,
895 "sisyphus.example.com",
896 NULL,
897 KEY_UNSPEC,
898 NULL,
899 NULL,
900 } },
901 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
902 NULL,
903 57,
904 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
905 0,
906 NULL,
907 MRK_NONE,
908 "prometheus.example.com",
909 NULL,
910 KEY_UNSPEC,
911 NULL,
912 NULL,
913 } },
914 { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, {
915 NULL,
916 58,
917 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
918 0,
919 NULL,
920 MRK_NONE,
921 "sisyphus.example.com",
922 NULL,
923 KEY_UNSPEC,
924 NULL,
925 NULL,
926 } },
927 { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, {
928 NULL,
929 59,
930 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
931 0,
932 NULL,
933 MRK_NONE,
934 "prometheus.example.com",
935 NULL,
936 KEY_UNSPEC,
937 NULL, /* filled at runtime */
938 NULL,
939 } },
940 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
941 NULL,
942 60,
943 HKF_STATUS_INVALID,
944 0,
945 NULL,
946 MRK_NONE,
947 "sisyphus.example.com",
948 NULL,
949 KEY_UNSPEC,
950 NULL, /* filled at runtime */
951 NULL,
952 } },
953 { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
954 NULL,
955 61,
956 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
957 0,
958 NULL,
959 MRK_NONE,
960 "prometheus.example.com",
961 NULL,
962 KEY_UNSPEC,
963 NULL, /* filled at runtime */
964 NULL,
965 } },
966};
967
968void test_iterate(void);
969
970void
971test_iterate(void)
972{
973 struct cbctx ctx;
974
975 TEST_START("hostkeys_iterate all with key parse");
976 memset(&ctx, 0, sizeof(ctx));
977 ctx.expected = expected_full;
978 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
979 ctx.flags = HKF_WANT_PARSE_KEY;
980 prepare_expected(expected_full, ctx.nexpected);
981 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
982 check, &ctx, NULL, NULL, ctx.flags), 0);
983 TEST_DONE();
984
985 TEST_START("hostkeys_iterate all without key parse");
986 memset(&ctx, 0, sizeof(ctx));
987 ctx.expected = expected_full;
988 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
989 ctx.flags = 0;
990 prepare_expected(expected_full, ctx.nexpected);
991 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
992 check, &ctx, NULL, NULL, ctx.flags), 0);
993 TEST_DONE();
994
995 TEST_START("hostkeys_iterate specify host 1");
996 memset(&ctx, 0, sizeof(ctx));
997 ctx.expected = expected_full;
998 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
999 ctx.flags = 0;
1000 ctx.match_host_p = 1;
1001 prepare_expected(expected_full, ctx.nexpected);
1002 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1003 check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
1004 TEST_DONE();
1005
1006 TEST_START("hostkeys_iterate specify host 2");
1007 memset(&ctx, 0, sizeof(ctx));
1008 ctx.expected = expected_full;
1009 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1010 ctx.flags = 0;
1011 ctx.match_host_s = 1;
1012 prepare_expected(expected_full, ctx.nexpected);
1013 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1014 check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
1015 TEST_DONE();
1016
1017 TEST_START("hostkeys_iterate match host 1");
1018 memset(&ctx, 0, sizeof(ctx));
1019 ctx.expected = expected_full;
1020 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1021 ctx.flags = HKF_WANT_MATCH;
1022 ctx.match_host_p = 1;
1023 prepare_expected(expected_full, ctx.nexpected);
1024 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1025 check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
1026 TEST_DONE();
1027
1028 TEST_START("hostkeys_iterate match host 2");
1029 memset(&ctx, 0, sizeof(ctx));
1030 ctx.expected = expected_full;
1031 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1032 ctx.flags = HKF_WANT_MATCH;
1033 ctx.match_host_s = 1;
1034 prepare_expected(expected_full, ctx.nexpected);
1035 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1036 check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
1037 TEST_DONE();
1038
1039 TEST_START("hostkeys_iterate specify host missing");
1040 memset(&ctx, 0, sizeof(ctx));
1041 ctx.expected = expected_full;
1042 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1043 ctx.flags = 0;
1044 prepare_expected(expected_full, ctx.nexpected);
1045 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1046 check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
1047 TEST_DONE();
1048
1049 TEST_START("hostkeys_iterate match host missing");
1050 memset(&ctx, 0, sizeof(ctx));
1051 ctx.expected = expected_full;
1052 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1053 ctx.flags = HKF_WANT_MATCH;
1054 prepare_expected(expected_full, ctx.nexpected);
1055 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1056 check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
1057 TEST_DONE();
1058
1059 TEST_START("hostkeys_iterate specify IPv4");
1060 memset(&ctx, 0, sizeof(ctx));
1061 ctx.expected = expected_full;
1062 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1063 ctx.flags = 0;
1064 ctx.match_ipv4 = 1;
1065 prepare_expected(expected_full, ctx.nexpected);
1066 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1067 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
1068 TEST_DONE();
1069
1070 TEST_START("hostkeys_iterate specify IPv6");
1071 memset(&ctx, 0, sizeof(ctx));
1072 ctx.expected = expected_full;
1073 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1074 ctx.flags = 0;
1075 ctx.match_ipv6 = 1;
1076 prepare_expected(expected_full, ctx.nexpected);
1077 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1078 check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
1079 TEST_DONE();
1080
1081 TEST_START("hostkeys_iterate match IPv4");
1082 memset(&ctx, 0, sizeof(ctx));
1083 ctx.expected = expected_full;
1084 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1085 ctx.flags = HKF_WANT_MATCH;
1086 ctx.match_ipv4 = 1;
1087 prepare_expected(expected_full, ctx.nexpected);
1088 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1089 check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
1090 TEST_DONE();
1091
1092 TEST_START("hostkeys_iterate match IPv6");
1093 memset(&ctx, 0, sizeof(ctx));
1094 ctx.expected = expected_full;
1095 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1096 ctx.flags = HKF_WANT_MATCH;
1097 ctx.match_ipv6 = 1;
1098 prepare_expected(expected_full, ctx.nexpected);
1099 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1100 check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
1101 TEST_DONE();
1102
1103 TEST_START("hostkeys_iterate specify addr missing");
1104 memset(&ctx, 0, sizeof(ctx));
1105 ctx.expected = expected_full;
1106 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1107 ctx.flags = 0;
1108 prepare_expected(expected_full, ctx.nexpected);
1109 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1110 check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0);
1111 TEST_DONE();
1112
1113 TEST_START("hostkeys_iterate match addr missing");
1114 memset(&ctx, 0, sizeof(ctx));
1115 ctx.expected = expected_full;
1116 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1117 ctx.flags = HKF_WANT_MATCH;
1118 prepare_expected(expected_full, ctx.nexpected);
1119 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1120 check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0);
1121 TEST_DONE();
1122
1123 TEST_START("hostkeys_iterate specify host 2 and IPv4");
1124 memset(&ctx, 0, sizeof(ctx));
1125 ctx.expected = expected_full;
1126 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1127 ctx.flags = 0;
1128 ctx.match_host_s = 1;
1129 ctx.match_ipv4 = 1;
1130 prepare_expected(expected_full, ctx.nexpected);
1131 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1132 check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
1133 TEST_DONE();
1134
1135 TEST_START("hostkeys_iterate match host 1 and IPv6");
1136 memset(&ctx, 0, sizeof(ctx));
1137 ctx.expected = expected_full;
1138 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1139 ctx.flags = HKF_WANT_MATCH;
1140 ctx.match_host_p = 1;
1141 ctx.match_ipv6 = 1;
1142 prepare_expected(expected_full, ctx.nexpected);
1143 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1144 check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
1145 TEST_DONE();
1146
1147 TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse");
1148 memset(&ctx, 0, sizeof(ctx));
1149 ctx.expected = expected_full;
1150 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1151 ctx.flags = HKF_WANT_PARSE_KEY;
1152 ctx.match_host_s = 1;
1153 ctx.match_ipv4 = 1;
1154 prepare_expected(expected_full, ctx.nexpected);
1155 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1156 check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
1157 TEST_DONE();
1158
1159 TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse");
1160 memset(&ctx, 0, sizeof(ctx));
1161 ctx.expected = expected_full;
1162 ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1163 ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY;
1164 ctx.match_host_p = 1;
1165 ctx.match_ipv6 = 1;
1166 prepare_expected(expected_full, ctx.nexpected);
1167 ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1168 check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
1169 TEST_DONE();
1170}
1171
diff --git a/regress/unittests/hostkeys/testdata/dsa_1.pub b/regress/unittests/hostkeys/testdata/dsa_1.pub
new file mode 100644
index 000000000..56e1e3714
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/dsa_2.pub b/regress/unittests/hostkeys/testdata/dsa_2.pub
new file mode 100644
index 000000000..394e0bf00
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/dsa_3.pub b/regress/unittests/hostkeys/testdata/dsa_3.pub
new file mode 100644
index 000000000..e506ea422
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/dsa_4.pub b/regress/unittests/hostkeys/testdata/dsa_4.pub
new file mode 100644
index 000000000..8552c3819
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/dsa_5.pub b/regress/unittests/hostkeys/testdata/dsa_5.pub
new file mode 100644
index 000000000..149e1efd1
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/dsa_6.pub b/regress/unittests/hostkeys/testdata/dsa_6.pub
new file mode 100644
index 000000000..edbb97643
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/ecdsa_1.pub b/regress/unittests/hostkeys/testdata/ecdsa_1.pub
new file mode 100644
index 000000000..16a535bcc
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ecdsa_1.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_2.pub b/regress/unittests/hostkeys/testdata/ecdsa_2.pub
new file mode 100644
index 000000000..d2bad11e2
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/ecdsa_3.pub b/regress/unittests/hostkeys/testdata/ecdsa_3.pub
new file mode 100644
index 000000000..e3ea9254e
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ecdsa_3.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_4.pub b/regress/unittests/hostkeys/testdata/ecdsa_4.pub
new file mode 100644
index 000000000..2d616f5c6
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ecdsa_4.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_5.pub b/regress/unittests/hostkeys/testdata/ecdsa_5.pub
new file mode 100644
index 000000000..a3df9b3f4
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ecdsa_5.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_6.pub b/regress/unittests/hostkeys/testdata/ecdsa_6.pub
new file mode 100644
index 000000000..139f5a7bf
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ecdsa_6.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
diff --git a/regress/unittests/hostkeys/testdata/ed25519_1.pub b/regress/unittests/hostkeys/testdata/ed25519_1.pub
new file mode 100644
index 000000000..0b12efedb
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_1.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1
diff --git a/regress/unittests/hostkeys/testdata/ed25519_2.pub b/regress/unittests/hostkeys/testdata/ed25519_2.pub
new file mode 100644
index 000000000..78e262bcc
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_2.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2
diff --git a/regress/unittests/hostkeys/testdata/ed25519_3.pub b/regress/unittests/hostkeys/testdata/ed25519_3.pub
new file mode 100644
index 000000000..64e5f12a6
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_3.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3
diff --git a/regress/unittests/hostkeys/testdata/ed25519_4.pub b/regress/unittests/hostkeys/testdata/ed25519_4.pub
new file mode 100644
index 000000000..47b6724ec
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_4.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4
diff --git a/regress/unittests/hostkeys/testdata/ed25519_5.pub b/regress/unittests/hostkeys/testdata/ed25519_5.pub
new file mode 100644
index 000000000..72ccae6fe
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_5.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5
diff --git a/regress/unittests/hostkeys/testdata/ed25519_6.pub b/regress/unittests/hostkeys/testdata/ed25519_6.pub
new file mode 100644
index 000000000..0f719731d
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/ed25519_6.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
diff --git a/regress/unittests/hostkeys/testdata/known_hosts b/regress/unittests/hostkeys/testdata/known_hosts
new file mode 100644
index 000000000..3740f674b
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/known_hosts
@@ -0,0 +1,61 @@
1# Plain host keys, plain host names
2sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1
3sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1
4sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1
5sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
6sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1
7
8# Plain host keys, hostnames + addresses
9prometheus.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
10prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2
11prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2
12prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2
13prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2
14
15# Some hosts with wildcard names / IPs
16*.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
17*.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3
18*.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3
19*.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3
20*.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3
21
22# Hashed hostname and address entries
23|1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5
24|1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5
25|1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5
26|1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5
27|1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
28
29|1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
30|1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
31|1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6
32|1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
33|1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
34|1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
35|1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
36|1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
37|1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
38|1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
39|1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
40|1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
41|1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
42|1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
43|1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
44
45
46# Revoked and CA keys
47@revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4
48@revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4
49@cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4
50@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
51
52# Some invalid lines
53@what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
54sisyphus.example.com
55prometheus.example.com ssh-ed25519
56sisyphus.example.com ssh-dsa AAAATgAAAAdz
57prometheus.example.com 1024
58sisyphus.example.com 1024 65535
59prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
60sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
61prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
diff --git a/regress/unittests/hostkeys/testdata/rsa1_1.pub b/regress/unittests/hostkeys/testdata/rsa1_1.pub
new file mode 100644
index 000000000..772ce9c05
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_1.pub
@@ -0,0 +1 @@
1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
diff --git a/regress/unittests/hostkeys/testdata/rsa1_2.pub b/regress/unittests/hostkeys/testdata/rsa1_2.pub
new file mode 100644
index 000000000..78794b941
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_2.pub
@@ -0,0 +1 @@
1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2
diff --git a/regress/unittests/hostkeys/testdata/rsa1_3.pub b/regress/unittests/hostkeys/testdata/rsa1_3.pub
new file mode 100644
index 000000000..0c035fe0a
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_3.pub
@@ -0,0 +1 @@
1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3
diff --git a/regress/unittests/hostkeys/testdata/rsa1_4.pub b/regress/unittests/hostkeys/testdata/rsa1_4.pub
new file mode 100644
index 000000000..00064423e
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_4.pub
@@ -0,0 +1 @@
1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4
diff --git a/regress/unittests/hostkeys/testdata/rsa1_5.pub b/regress/unittests/hostkeys/testdata/rsa1_5.pub
new file mode 100644
index 000000000..bb53c2642
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_5.pub
@@ -0,0 +1 @@
1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5
diff --git a/regress/unittests/hostkeys/testdata/rsa1_6.pub b/regress/unittests/hostkeys/testdata/rsa1_6.pub
new file mode 100644
index 000000000..85d6576b5
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa1_6.pub
@@ -0,0 +1 @@
1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6
diff --git a/regress/unittests/hostkeys/testdata/rsa_1.pub b/regress/unittests/hostkeys/testdata/rsa_1.pub
new file mode 100644
index 000000000..2b87885a1
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/rsa_2.pub b/regress/unittests/hostkeys/testdata/rsa_2.pub
new file mode 100644
index 000000000..33f1fd93b
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/rsa_3.pub b/regress/unittests/hostkeys/testdata/rsa_3.pub
new file mode 100644
index 000000000..c2f6b208c
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa_3.pub
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3
diff --git a/regress/unittests/hostkeys/testdata/rsa_4.pub b/regress/unittests/hostkeys/testdata/rsa_4.pub
new file mode 100644
index 000000000..35545a713
--- /dev/null
+++ b/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/regress/unittests/hostkeys/testdata/rsa_5.pub b/regress/unittests/hostkeys/testdata/rsa_5.pub
new file mode 100644
index 000000000..befbaa7d9
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa_5.pub
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
diff --git a/regress/unittests/hostkeys/testdata/rsa_6.pub b/regress/unittests/hostkeys/testdata/rsa_6.pub
new file mode 100644
index 000000000..393e11672
--- /dev/null
+++ b/regress/unittests/hostkeys/testdata/rsa_6.pub
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
diff --git a/regress/unittests/hostkeys/tests.c b/regress/unittests/hostkeys/tests.c
new file mode 100644
index 000000000..92c7646ad
--- /dev/null
+++ b/regress/unittests/hostkeys/tests.c
@@ -0,0 +1,16 @@
1/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */
2/*
3 * Regress test for known_hosts-related API.
4 *
5 * Placed in the public domain
6 */
7
8void tests(void);
9void test_iterate(void); /* test_iterate.c */
10
11void
12tests(void)
13{
14 test_iterate();
15}
16
diff --git a/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile
new file mode 100644
index 000000000..6532cb00a
--- /dev/null
+++ b/regress/unittests/kex/Makefile
@@ -0,0 +1,14 @@
1# $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $
2
3TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
4
5PROG=test_kex
6SRCS=tests.c test_kex.c
7REGRESS_TARGETS=run-regress-${PROG}
8
9run-regress-${PROG}: ${PROG}
10 env ${TEST_ENV} ./${PROG}
11
12.include <bsd.regress.mk>
13
14LDADD+=-lz
diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c
new file mode 100644
index 000000000..c61e2bdbb
--- /dev/null
+++ b/regress/unittests/kex/test_kex.c
@@ -0,0 +1,197 @@
1/* $OpenBSD: test_kex.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */
2/*
3 * Regress test KEX
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14#include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "ssherr.h"
22#include "ssh_api.h"
23#include "sshbuf.h"
24#include "packet.h"
25#include "myproposal.h"
26
27struct ssh *active_state = NULL; /* XXX - needed for linking */
28
29void kex_tests(void);
30static int do_debug = 0;
31
32static int
33do_send_and_receive(struct ssh *from, struct ssh *to)
34{
35 u_char type;
36 size_t len;
37 const u_char *buf;
38 int r;
39
40 for (;;) {
41 if ((r = ssh_packet_next(from, &type)) != 0) {
42 fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r));
43 return r;
44 }
45 if (type != 0)
46 return 0;
47 buf = ssh_output_ptr(from, &len);
48 if (do_debug)
49 printf("%zu", len);
50 if (len == 0)
51 return 0;
52 if ((r = ssh_output_consume(from, len)) != 0 ||
53 (r = ssh_input_append(to, buf, len)) != 0)
54 return r;
55 }
56}
57
58static void
59run_kex(struct ssh *client, struct ssh *server)
60{
61 int r = 0;
62
63 while (!server->kex->done || !client->kex->done) {
64 if (do_debug)
65 printf(" S:");
66 if ((r = do_send_and_receive(server, client)))
67 break;
68 if (do_debug)
69 printf(" C:");
70 if ((r = do_send_and_receive(client, server)))
71 break;
72 }
73 if (do_debug)
74 printf("done: %s\n", ssh_err(r));
75 ASSERT_INT_EQ(r, 0);
76 ASSERT_INT_EQ(server->kex->done, 1);
77 ASSERT_INT_EQ(client->kex->done, 1);
78}
79
80static void
81do_kex_with_key(char *kex, int keytype, int bits)
82{
83 struct ssh *client = NULL, *server = NULL, *server2 = NULL;
84 struct sshkey *private, *public;
85 struct sshbuf *state;
86 struct kex_params kex_params;
87 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
88
89 TEST_START("sshkey_generate");
90 ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0);
91 TEST_DONE();
92
93 TEST_START("sshkey_from_private");
94 ASSERT_INT_EQ(sshkey_from_private(private, &public), 0);
95 TEST_DONE();
96
97 TEST_START("ssh_init");
98 memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
99 if (kex != NULL)
100 kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
101 ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
102 ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0);
103 ASSERT_PTR_NE(client, NULL);
104 ASSERT_PTR_NE(server, NULL);
105 TEST_DONE();
106
107 TEST_START("ssh_add_hostkey");
108 ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0);
109 ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0);
110 TEST_DONE();
111
112 TEST_START("kex");
113 run_kex(client, server);
114 TEST_DONE();
115
116 TEST_START("rekeying client");
117 ASSERT_INT_EQ(kex_send_kexinit(client), 0);
118 run_kex(client, server);
119 TEST_DONE();
120
121 TEST_START("rekeying server");
122 ASSERT_INT_EQ(kex_send_kexinit(server), 0);
123 run_kex(client, server);
124 TEST_DONE();
125
126 TEST_START("ssh_packet_get_state");
127 state = sshbuf_new();
128 ASSERT_PTR_NE(state, NULL);
129 ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0);
130 ASSERT_INT_GE(sshbuf_len(state), 1);
131 TEST_DONE();
132
133 TEST_START("ssh_packet_set_state");
134 server2 = NULL;
135 ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0);
136 ASSERT_PTR_NE(server2, NULL);
137 ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0);
138 kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */
139 ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0);
140 ASSERT_INT_EQ(sshbuf_len(state), 0);
141 sshbuf_free(state);
142 ASSERT_PTR_NE(server2->kex, NULL);
143 /* XXX we need to set the callbacks */
144 server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
145 server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
146 server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
147 server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
148#ifdef OPENSSL_HAS_ECC
149 server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
150#endif
151 server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
152 server2->kex->load_host_public_key = server->kex->load_host_public_key;
153 server2->kex->load_host_private_key = server->kex->load_host_private_key;
154 server2->kex->sign = server->kex->sign;
155 TEST_DONE();
156
157 TEST_START("rekeying server2");
158 ASSERT_INT_EQ(kex_send_kexinit(server2), 0);
159 run_kex(client, server2);
160 ASSERT_INT_EQ(kex_send_kexinit(client), 0);
161 run_kex(client, server2);
162 TEST_DONE();
163
164 TEST_START("cleanup");
165 sshkey_free(private);
166 sshkey_free(public);
167 ssh_free(client);
168 ssh_free(server);
169 ssh_free(server2);
170 TEST_DONE();
171}
172
173static void
174do_kex(char *kex)
175{
176 do_kex_with_key(kex, KEY_RSA, 2048);
177 do_kex_with_key(kex, KEY_DSA, 1024);
178#ifdef OPENSSL_HAS_ECC
179 do_kex_with_key(kex, KEY_ECDSA, 256);
180#endif
181 do_kex_with_key(kex, KEY_ED25519, 256);
182}
183
184void
185kex_tests(void)
186{
187 do_kex("curve25519-sha256@libssh.org");
188#ifdef OPENSSL_HAS_ECC
189 do_kex("ecdh-sha2-nistp256");
190 do_kex("ecdh-sha2-nistp384");
191 do_kex("ecdh-sha2-nistp521");
192#endif
193 do_kex("diffie-hellman-group-exchange-sha256");
194 do_kex("diffie-hellman-group-exchange-sha1");
195 do_kex("diffie-hellman-group14-sha1");
196 do_kex("diffie-hellman-group1-sha1");
197}
diff --git a/regress/unittests/kex/tests.c b/regress/unittests/kex/tests.c
new file mode 100644
index 000000000..e7036ec17
--- /dev/null
+++ b/regress/unittests/kex/tests.c
@@ -0,0 +1,14 @@
1/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */
2/*
3 * Placed in the public domain
4 */
5
6#include "../test_helper/test_helper.h"
7
8void kex_tests(void);
9
10void
11tests(void)
12{
13 kex_tests();
14}
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
index 0c4c71ecd..a68e1329e 100644
--- a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -32,8 +32,6 @@ void
32sshbuf_getput_crypto_tests(void) 32sshbuf_getput_crypto_tests(void)
33{ 33{
34 struct sshbuf *p1; 34 struct sshbuf *p1;
35 const u_char *d;
36 size_t s;
37 BIGNUM *bn, *bn2; 35 BIGNUM *bn, *bn2;
38 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ 36 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
39 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; 37 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
@@ -48,7 +46,9 @@ sshbuf_getput_crypto_tests(void)
48 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 46 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
49 0x7f, 0xff, 0x11 47 0x7f, 0xff, 0x11
50 }; 48 };
51#ifdef OPENSSL_HAS_NISTP256 49#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
50 const u_char *d;
51 size_t s;
52 BIGNUM *bn_x, *bn_y; 52 BIGNUM *bn_x, *bn_y;
53 int ec256_nid = NID_X9_62_prime256v1; 53 int ec256_nid = NID_X9_62_prime256v1;
54 char *ec256_x = "0C828004839D0106AA59575216191357" 54 char *ec256_x = "0C828004839D0106AA59575216191357"
@@ -352,7 +352,7 @@ sshbuf_getput_crypto_tests(void)
352 sshbuf_free(p1); 352 sshbuf_free(p1);
353 TEST_DONE(); 353 TEST_DONE();
354 354
355#ifdef OPENSSL_HAS_NISTP256 355#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
356 TEST_START("sshbuf_put_ec"); 356 TEST_START("sshbuf_put_ec");
357 eck = EC_KEY_new_by_curve_name(ec256_nid); 357 eck = EC_KEY_new_by_curve_name(ec256_nid);
358 ASSERT_PTR_NE(eck, NULL); 358 ASSERT_PTR_NE(eck, NULL);
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
index 8c3269b13..c6b5c29d1 100644
--- a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -33,7 +33,7 @@ attempt_parse_blob(u_char *blob, size_t len)
33{ 33{
34 struct sshbuf *p1; 34 struct sshbuf *p1;
35 BIGNUM *bn; 35 BIGNUM *bn;
36#ifdef OPENSSL_HAS_NISTP256 36#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
37 EC_KEY *eck; 37 EC_KEY *eck;
38#endif 38#endif
39 u_char *s; 39 u_char *s;
@@ -60,7 +60,7 @@ attempt_parse_blob(u_char *blob, size_t len)
60 bn = BN_new(); 60 bn = BN_new();
61 sshbuf_get_bignum2(p1, bn); 61 sshbuf_get_bignum2(p1, bn);
62 BN_clear_free(bn); 62 BN_clear_free(bn);
63#ifdef OPENSSL_HAS_NISTP256 63#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
64 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 64 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
65 ASSERT_PTR_NE(eck, NULL); 65 ASSERT_PTR_NE(eck, NULL);
66 sshbuf_get_eckey(p1, eck); 66 sshbuf_get_eckey(p1, eck);
diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c
index 0a4b3a90c..b598f05cb 100644
--- a/regress/unittests/sshkey/common.c
+++ b/regress/unittests/sshkey/common.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 1/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */
2/* 2/*
3 * Helpers for key API tests 3 * Helpers for key API tests
4 * 4 *
@@ -44,7 +44,7 @@ load_file(const char *name)
44 44
45 ASSERT_PTR_NE(ret = sshbuf_new(), NULL); 45 ASSERT_PTR_NE(ret = sshbuf_new(), NULL);
46 ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); 46 ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1);
47 ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0); 47 ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0);
48 close(fd); 48 close(fd);
49 return ret; 49 return ret;
50} 50}
diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh
index ee1fe3962..09165af02 100755
--- a/regress/unittests/sshkey/mktestdata.sh
+++ b/regress/unittests/sshkey/mktestdata.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $ 2# $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $
3 3
4PW=mekmitasdigoat 4PW=mekmitasdigoat
5 5
@@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb 187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
188ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb 188ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
189 189
190# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against)
191
190echo "$PW" > pw 192echo "$PW" > pw
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
index 764f7fb76..fa95212bf 100644
--- a/regress/unittests/sshkey/test_file.c
+++ b/regress/unittests/sshkey/test_file.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 1/* $OpenBSD: test_file.c,v 1.3 2015/03/04 23:22:35 djm Exp $ */
2/* 2/*
3 * Regress test for sshkey.h key management API 3 * Regress test for sshkey.h key management API
4 * 4 *
@@ -33,6 +33,7 @@
33#include "authfile.h" 33#include "authfile.h"
34#include "sshkey.h" 34#include "sshkey.h"
35#include "sshbuf.h" 35#include "sshbuf.h"
36#include "digest.h"
36 37
37#include "common.h" 38#include "common.h"
38 39
@@ -50,6 +51,7 @@ sshkey_file_tests(void)
50 pw = load_text_file("pw"); 51 pw = load_text_file("pw");
51 TEST_DONE(); 52 TEST_DONE();
52 53
54#ifdef WITH_SSH1
53 TEST_START("parse RSA1 from private"); 55 TEST_START("parse RSA1 from private");
54 buf = load_file("rsa1_1"); 56 buf = load_file("rsa1_1");
55 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", 57 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
@@ -81,7 +83,7 @@ sshkey_file_tests(void)
81 83
82 TEST_START("RSA1 key hex fingerprint"); 84 TEST_START("RSA1 key hex fingerprint");
83 buf = load_text_file("rsa1_1.fp"); 85 buf = load_text_file("rsa1_1.fp");
84 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); 86 cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
85 ASSERT_PTR_NE(cp, NULL); 87 ASSERT_PTR_NE(cp, NULL);
86 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 88 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
87 sshbuf_free(buf); 89 sshbuf_free(buf);
@@ -90,7 +92,7 @@ sshkey_file_tests(void)
90 92
91 TEST_START("RSA1 key bubblebabble fingerprint"); 93 TEST_START("RSA1 key bubblebabble fingerprint");
92 buf = load_text_file("rsa1_1.fp.bb"); 94 buf = load_text_file("rsa1_1.fp.bb");
93 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); 95 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
94 ASSERT_PTR_NE(cp, NULL); 96 ASSERT_PTR_NE(cp, NULL);
95 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 97 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
96 sshbuf_free(buf); 98 sshbuf_free(buf);
@@ -98,6 +100,7 @@ sshkey_file_tests(void)
98 TEST_DONE(); 100 TEST_DONE();
99 101
100 sshkey_free(k1); 102 sshkey_free(k1);
103#endif
101 104
102 TEST_START("parse RSA from private"); 105 TEST_START("parse RSA from private");
103 buf = load_file("rsa_1"); 106 buf = load_file("rsa_1");
@@ -164,7 +167,7 @@ sshkey_file_tests(void)
164 167
165 TEST_START("RSA key hex fingerprint"); 168 TEST_START("RSA key hex fingerprint");
166 buf = load_text_file("rsa_1.fp"); 169 buf = load_text_file("rsa_1.fp");
167 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); 170 cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
168 ASSERT_PTR_NE(cp, NULL); 171 ASSERT_PTR_NE(cp, NULL);
169 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 172 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
170 sshbuf_free(buf); 173 sshbuf_free(buf);
@@ -173,7 +176,7 @@ sshkey_file_tests(void)
173 176
174 TEST_START("RSA cert hex fingerprint"); 177 TEST_START("RSA cert hex fingerprint");
175 buf = load_text_file("rsa_1-cert.fp"); 178 buf = load_text_file("rsa_1-cert.fp");
176 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); 179 cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
177 ASSERT_PTR_NE(cp, NULL); 180 ASSERT_PTR_NE(cp, NULL);
178 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 181 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
179 sshbuf_free(buf); 182 sshbuf_free(buf);
@@ -183,7 +186,7 @@ sshkey_file_tests(void)
183 186
184 TEST_START("RSA key bubblebabble fingerprint"); 187 TEST_START("RSA key bubblebabble fingerprint");
185 buf = load_text_file("rsa_1.fp.bb"); 188 buf = load_text_file("rsa_1.fp.bb");
186 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); 189 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
187 ASSERT_PTR_NE(cp, NULL); 190 ASSERT_PTR_NE(cp, NULL);
188 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 191 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
189 sshbuf_free(buf); 192 sshbuf_free(buf);
@@ -257,7 +260,7 @@ sshkey_file_tests(void)
257 260
258 TEST_START("DSA key hex fingerprint"); 261 TEST_START("DSA key hex fingerprint");
259 buf = load_text_file("dsa_1.fp"); 262 buf = load_text_file("dsa_1.fp");
260 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); 263 cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
261 ASSERT_PTR_NE(cp, NULL); 264 ASSERT_PTR_NE(cp, NULL);
262 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 265 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
263 sshbuf_free(buf); 266 sshbuf_free(buf);
@@ -266,7 +269,7 @@ sshkey_file_tests(void)
266 269
267 TEST_START("DSA cert hex fingerprint"); 270 TEST_START("DSA cert hex fingerprint");
268 buf = load_text_file("dsa_1-cert.fp"); 271 buf = load_text_file("dsa_1-cert.fp");
269 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); 272 cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
270 ASSERT_PTR_NE(cp, NULL); 273 ASSERT_PTR_NE(cp, NULL);
271 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 274 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
272 sshbuf_free(buf); 275 sshbuf_free(buf);
@@ -276,7 +279,7 @@ sshkey_file_tests(void)
276 279
277 TEST_START("DSA key bubblebabble fingerprint"); 280 TEST_START("DSA key bubblebabble fingerprint");
278 buf = load_text_file("dsa_1.fp.bb"); 281 buf = load_text_file("dsa_1.fp.bb");
279 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); 282 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
280 ASSERT_PTR_NE(cp, NULL); 283 ASSERT_PTR_NE(cp, NULL);
281 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 284 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
282 sshbuf_free(buf); 285 sshbuf_free(buf);
@@ -357,7 +360,7 @@ sshkey_file_tests(void)
357 360
358 TEST_START("ECDSA key hex fingerprint"); 361 TEST_START("ECDSA key hex fingerprint");
359 buf = load_text_file("ecdsa_1.fp"); 362 buf = load_text_file("ecdsa_1.fp");
360 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); 363 cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
361 ASSERT_PTR_NE(cp, NULL); 364 ASSERT_PTR_NE(cp, NULL);
362 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 365 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
363 sshbuf_free(buf); 366 sshbuf_free(buf);
@@ -366,7 +369,7 @@ sshkey_file_tests(void)
366 369
367 TEST_START("ECDSA cert hex fingerprint"); 370 TEST_START("ECDSA cert hex fingerprint");
368 buf = load_text_file("ecdsa_1-cert.fp"); 371 buf = load_text_file("ecdsa_1-cert.fp");
369 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); 372 cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
370 ASSERT_PTR_NE(cp, NULL); 373 ASSERT_PTR_NE(cp, NULL);
371 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 374 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
372 sshbuf_free(buf); 375 sshbuf_free(buf);
@@ -376,7 +379,7 @@ sshkey_file_tests(void)
376 379
377 TEST_START("ECDSA key bubblebabble fingerprint"); 380 TEST_START("ECDSA key bubblebabble fingerprint");
378 buf = load_text_file("ecdsa_1.fp.bb"); 381 buf = load_text_file("ecdsa_1.fp.bb");
379 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); 382 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
380 ASSERT_PTR_NE(cp, NULL); 383 ASSERT_PTR_NE(cp, NULL);
381 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 384 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
382 sshbuf_free(buf); 385 sshbuf_free(buf);
@@ -424,7 +427,7 @@ sshkey_file_tests(void)
424 427
425 TEST_START("Ed25519 key hex fingerprint"); 428 TEST_START("Ed25519 key hex fingerprint");
426 buf = load_text_file("ed25519_1.fp"); 429 buf = load_text_file("ed25519_1.fp");
427 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); 430 cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX);
428 ASSERT_PTR_NE(cp, NULL); 431 ASSERT_PTR_NE(cp, NULL);
429 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 432 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
430 sshbuf_free(buf); 433 sshbuf_free(buf);
@@ -433,7 +436,7 @@ sshkey_file_tests(void)
433 436
434 TEST_START("Ed25519 cert hex fingerprint"); 437 TEST_START("Ed25519 cert hex fingerprint");
435 buf = load_text_file("ed25519_1-cert.fp"); 438 buf = load_text_file("ed25519_1-cert.fp");
436 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); 439 cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX);
437 ASSERT_PTR_NE(cp, NULL); 440 ASSERT_PTR_NE(cp, NULL);
438 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 441 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
439 sshbuf_free(buf); 442 sshbuf_free(buf);
@@ -443,7 +446,7 @@ sshkey_file_tests(void)
443 446
444 TEST_START("Ed25519 key bubblebabble fingerprint"); 447 TEST_START("Ed25519 key bubblebabble fingerprint");
445 buf = load_text_file("ed25519_1.fp.bb"); 448 buf = load_text_file("ed25519_1.fp.bb");
446 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); 449 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
447 ASSERT_PTR_NE(cp, NULL); 450 ASSERT_PTR_NE(cp, NULL);
448 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); 451 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
449 sshbuf_free(buf); 452 sshbuf_free(buf);
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c
index a3f61a6df..1f08a2e43 100644
--- a/regress/unittests/sshkey/test_fuzz.c
+++ b/regress/unittests/sshkey/test_fuzz.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 1/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */
2/* 2/*
3 * Fuzz tests for key parsing 3 * Fuzz tests for key parsing
4 * 4 *
@@ -53,7 +53,7 @@ public_fuzz(struct sshkey *k)
53 struct fuzz *fuzz; 53 struct fuzz *fuzz;
54 54
55 ASSERT_PTR_NE(buf = sshbuf_new(), NULL); 55 ASSERT_PTR_NE(buf = sshbuf_new(), NULL);
56 ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0); 56 ASSERT_INT_EQ(sshkey_putb(k, buf), 0);
57 /* XXX need a way to run the tests in "slow, but complete" mode */ 57 /* XXX need a way to run the tests in "slow, but complete" mode */
58 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ 58 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */
59 FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ 59 FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */
@@ -87,8 +87,11 @@ sig_fuzz(struct sshkey *k)
87 free(sig); 87 free(sig);
88 TEST_ONERROR(onerror, fuzz); 88 TEST_ONERROR(onerror, fuzz);
89 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 89 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
90 sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), 90 /* Ensure 1-bit difference at least */
91 c, sizeof(c), 0); 91 if (fuzz_matches_original(fuzz))
92 continue;
93 ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
94 c, sizeof(c), 0), 0);
92 } 95 }
93 fuzz_cleanup(fuzz); 96 fuzz_cleanup(fuzz);
94} 97}
@@ -101,6 +104,7 @@ sshkey_fuzz_tests(void)
101 struct fuzz *fuzz; 104 struct fuzz *fuzz;
102 int r; 105 int r;
103 106
107#ifdef WITH_SSH1
104 TEST_START("fuzz RSA1 private"); 108 TEST_START("fuzz RSA1 private");
105 buf = load_file("rsa1_1"); 109 buf = load_file("rsa1_1");
106 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | 110 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
@@ -144,6 +148,7 @@ sshkey_fuzz_tests(void)
144 sshbuf_free(fuzzed); 148 sshbuf_free(fuzzed);
145 fuzz_cleanup(fuzz); 149 fuzz_cleanup(fuzz);
146 TEST_DONE(); 150 TEST_DONE();
151#endif
147 152
148 TEST_START("fuzz RSA private"); 153 TEST_START("fuzz RSA private");
149 buf = load_file("rsa_1"); 154 buf = load_file("rsa_1");
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
index ef0c67956..ad10c9be2 100644
--- a/regress/unittests/sshkey/test_sshkey.c
+++ b/regress/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 1/* $OpenBSD: test_sshkey.c,v 1.3 2015/01/26 06:11:28 djm Exp $ */
2/* 2/*
3 * Regress test for sshkey.h key management API 3 * Regress test for sshkey.h key management API
4 * 4 *
@@ -19,7 +19,7 @@
19#include <openssl/bn.h> 19#include <openssl/bn.h>
20#include <openssl/rsa.h> 20#include <openssl/rsa.h>
21#include <openssl/dsa.h> 21#include <openssl/dsa.h>
22#ifdef OPENSSL_HAS_NISTP256 22#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
23# include <openssl/ec.h> 23# include <openssl/ec.h>
24#endif 24#endif
25 25
@@ -37,6 +37,20 @@
37void sshkey_tests(void); 37void sshkey_tests(void);
38 38
39static void 39static void
40put_opt(struct sshbuf *b, const char *name, const char *value)
41{
42 struct sshbuf *sect;
43
44 sect = sshbuf_new();
45 ASSERT_PTR_NE(sect, NULL);
46 ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
47 if (value != NULL)
48 ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
49 ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
50 sshbuf_free(sect);
51}
52
53static void
40build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, 54build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
41 const struct sshkey *sign_key, const struct sshkey *ca_key) 55 const struct sshkey *sign_key, const struct sshkey *ca_key)
42{ 56{
@@ -45,25 +59,31 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
45 size_t siglen; 59 size_t siglen;
46 60
47 ca_buf = sshbuf_new(); 61 ca_buf = sshbuf_new();
48 ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); 62 ASSERT_PTR_NE(ca_buf, NULL);
63 ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
49 64
50 /* 65 /*
51 * Get the public key serialisation by rendering the key and skipping 66 * Get the public key serialisation by rendering the key and skipping
52 * the type string. This is a bit of a hack :/ 67 * the type string. This is a bit of a hack :/
53 */ 68 */
54 pk = sshbuf_new(); 69 pk = sshbuf_new();
55 ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); 70 ASSERT_PTR_NE(pk, NULL);
71 ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0);
56 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); 72 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
57 73
58 principals = sshbuf_new(); 74 principals = sshbuf_new();
75 ASSERT_PTR_NE(principals, NULL);
59 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); 76 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
60 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); 77 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
61 78
62 critopts = sshbuf_new(); 79 critopts = sshbuf_new();
63 /* XXX fill this in */ 80 ASSERT_PTR_NE(critopts, NULL);
81 put_opt(critopts, "force-command", "/usr/local/bin/nethack");
82 put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
64 83
65 exts = sshbuf_new(); 84 exts = sshbuf_new();
66 /* XXX fill this in */ 85 ASSERT_PTR_NE(exts, NULL);
86 put_opt(critopts, "permit-X11-forwarding", NULL);
67 87
68 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); 88 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
69 ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ 89 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,
90 sshbuf_free(pk); 110 sshbuf_free(pk);
91} 111}
92 112
113static void
114signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l)
115{
116 size_t len;
117 u_char *sig;
118
119 ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0);
120 ASSERT_SIZE_T_GT(len, 8);
121 ASSERT_PTR_NE(sig, NULL);
122 ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
123 ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0);
124 /* Fuzz test is more comprehensive, this is just a smoke test */
125 sig[len - 5] ^= 0x10;
126 ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0);
127 free(sig);
128}
129
130static void
131banana(u_char *s, size_t l)
132{
133 size_t o;
134 const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
135
136 for (o = 0; o < l; o += sizeof(the_banana)) {
137 if (l - o < sizeof(the_banana)) {
138 memcpy(s + o, "nanananana", l - o);
139 break;
140 }
141 memcpy(s + o, banana, sizeof(the_banana));
142 }
143}
144
145static void
146signature_tests(struct sshkey *k, struct sshkey *bad)
147{
148 u_char i, buf[2049];
149 size_t lens[] = {
150 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
151 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
152 };
153
154 for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
155 test_subtest_info("%s key, banana length %zu",
156 sshkey_type(k), lens[i]);
157 banana(buf, lens[i]);
158 signature_test(k, bad, buf, lens[i]);
159 }
160}
161
162static struct sshkey *
163get_private(const char *n)
164{
165 struct sshbuf *b;
166 struct sshkey *ret;
167
168 b = load_file(n);
169 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0);
170 sshbuf_free(b);
171 return ret;
172}
173
93void 174void
94sshkey_tests(void) 175sshkey_tests(void)
95{ 176{
96 struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; 177 struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf;
178#ifdef OPENSSL_HAS_ECC
179 struct sshkey *ke;
180#endif
97 struct sshbuf *b; 181 struct sshbuf *b;
98 182
99 TEST_START("new invalid"); 183 TEST_START("new invalid");
@@ -136,12 +220,14 @@ sshkey_tests(void)
136 sshkey_free(k1); 220 sshkey_free(k1);
137 TEST_DONE(); 221 TEST_DONE();
138 222
223#ifdef OPENSSL_HAS_ECC
139 TEST_START("new/free KEY_ECDSA"); 224 TEST_START("new/free KEY_ECDSA");
140 k1 = sshkey_new(KEY_ECDSA); 225 k1 = sshkey_new(KEY_ECDSA);
141 ASSERT_PTR_NE(k1, NULL); 226 ASSERT_PTR_NE(k1, NULL);
142 ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ 227 ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
143 sshkey_free(k1); 228 sshkey_free(k1);
144 TEST_DONE(); 229 TEST_DONE();
230#endif
145 231
146 TEST_START("new/free KEY_ED25519"); 232 TEST_START("new/free KEY_ED25519");
147 k1 = sshkey_new(KEY_ED25519); 233 k1 = sshkey_new(KEY_ED25519);
@@ -192,12 +278,14 @@ sshkey_tests(void)
192 sshkey_free(k1); 278 sshkey_free(k1);
193 TEST_DONE(); 279 TEST_DONE();
194 280
281#ifdef OPENSSL_HAS_ECC
195 TEST_START("generate KEY_ECDSA wrong bits"); 282 TEST_START("generate KEY_ECDSA wrong bits");
196 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), 283 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
197 SSH_ERR_INVALID_ARGUMENT); 284 SSH_ERR_INVALID_ARGUMENT);
198 ASSERT_PTR_EQ(k1, NULL); 285 ASSERT_PTR_EQ(k1, NULL);
199 sshkey_free(k1); 286 sshkey_free(k1);
200 TEST_DONE(); 287 TEST_DONE();
288#endif
201 289
202 TEST_START("generate KEY_RSA"); 290 TEST_START("generate KEY_RSA");
203 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); 291 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0);
@@ -332,26 +420,100 @@ sshkey_tests(void)
332#endif 420#endif
333 sshkey_free(kf); 421 sshkey_free(kf);
334 422
335/* XXX certify test */ 423 TEST_START("certify key");
336/* XXX sign test */ 424 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
337/* XXX verify test */ 425 &k1, NULL), 0);
426 k2 = get_private("ed25519_2");
427 ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0);
428 ASSERT_PTR_NE(k1->cert, NULL);
429 k1->cert->type = SSH2_CERT_TYPE_USER;
430 k1->cert->serial = 1234;
431 k1->cert->key_id = strdup("estragon");
432 ASSERT_PTR_NE(k1->cert->key_id, NULL);
433 k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
434 ASSERT_PTR_NE(k1->cert->principals, NULL);
435 k1->cert->principals[0] = strdup("estragon");
436 k1->cert->principals[1] = strdup("vladimir");
437 k1->cert->principals[2] = strdup("pozzo");
438 k1->cert->principals[3] = strdup("lucky");
439 ASSERT_PTR_NE(k1->cert->principals[0], NULL);
440 ASSERT_PTR_NE(k1->cert->principals[1], NULL);
441 ASSERT_PTR_NE(k1->cert->principals[2], NULL);
442 ASSERT_PTR_NE(k1->cert->principals[3], NULL);
443 k1->cert->valid_after = 0;
444 k1->cert->valid_before = (u_int64_t)-1;
445 k1->cert->critical = sshbuf_new();
446 ASSERT_PTR_NE(k1->cert->critical, NULL);
447 k1->cert->extensions = sshbuf_new();
448 ASSERT_PTR_NE(k1->cert->extensions, NULL);
449 put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
450 put_opt(k1->cert->critical, "source-address", "127.0.0.1");
451 put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
452 put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
453 ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
454 ASSERT_INT_EQ(sshkey_certify(k1, k2), 0);
455 b = sshbuf_new();
456 ASSERT_PTR_NE(b, NULL);
457 ASSERT_INT_EQ(sshkey_putb(k1, b), 0);
458 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
459
460 sshkey_free(k1);
461 sshkey_free(k2);
462 sshkey_free(k3);
463 sshbuf_reset(b);
464 TEST_DONE();
465
466 TEST_START("sign and verify RSA");
467 k1 = get_private("rsa_1");
468 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
469 NULL), 0);
470 signature_tests(k1, k2);
471 sshkey_free(k1);
472 sshkey_free(k2);
473 TEST_DONE();
474
475 TEST_START("sign and verify DSA");
476 k1 = get_private("dsa_1");
477 ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
478 NULL), 0);
479 signature_tests(k1, k2);
480 sshkey_free(k1);
481 sshkey_free(k2);
482 TEST_DONE();
483
484#ifdef OPENSSL_HAS_ECC
485 TEST_START("sign and verify ECDSA");
486 k1 = get_private("ecdsa_1");
487 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
488 NULL), 0);
489 signature_tests(k1, k2);
490 sshkey_free(k1);
491 sshkey_free(k2);
492 TEST_DONE();
493#endif
494
495 TEST_START("sign and verify ED25519");
496 k1 = get_private("ed25519_1");
497 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
498 NULL), 0);
499 signature_tests(k1, k2);
500 sshkey_free(k1);
501 sshkey_free(k2);
502 TEST_DONE();
338 503
339 TEST_START("nested certificate"); 504 TEST_START("nested certificate");
340 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); 505 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
341 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, 506 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
342 NULL), 0); 507 NULL), 0);
343 b = load_file("rsa_2"); 508 k3 = get_private("ed25519_2");
344 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
345 &k3, NULL), 0);
346 sshbuf_reset(b);
347 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); 509 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
348 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), 510 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
349 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); 511 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
350 ASSERT_PTR_EQ(k4, NULL); 512 ASSERT_PTR_EQ(k4, NULL);
351 sshbuf_free(b);
352 sshkey_free(k1); 513 sshkey_free(k1);
353 sshkey_free(k2); 514 sshkey_free(k2);
354 sshkey_free(k3); 515 sshkey_free(k3);
516 sshbuf_free(b);
355 TEST_DONE(); 517 TEST_DONE();
356 518
357} 519}
diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/unittests/sshkey/testdata/dsa_1-cert.fp
index 56ee1f89b..b26145b24 100644
--- a/regress/unittests/sshkey/testdata/dsa_1-cert.fp
+++ b/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/regress/unittests/sshkey/testdata/dsa_1.fp b/regress/unittests/sshkey/testdata/dsa_1.fp
index 56ee1f89b..b26145b24 100644
--- a/regress/unittests/sshkey/testdata/dsa_1.fp
+++ b/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/regress/unittests/sshkey/testdata/dsa_2.fp b/regress/unittests/sshkey/testdata/dsa_2.fp
index ba9de82a8..822657403 100644
--- a/regress/unittests/sshkey/testdata/dsa_2.fp
+++ b/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/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
index a56dbc8d0..c3d747aff 100644
--- a/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
+++ b/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/regress/unittests/sshkey/testdata/ecdsa_1.fp b/regress/unittests/sshkey/testdata/ecdsa_1.fp
index a56dbc8d0..c3d747aff 100644
--- a/regress/unittests/sshkey/testdata/ecdsa_1.fp
+++ b/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/regress/unittests/sshkey/testdata/ecdsa_2.fp b/regress/unittests/sshkey/testdata/ecdsa_2.fp
index eb4bbdf03..fe7526b92 100644
--- a/regress/unittests/sshkey/testdata/ecdsa_2.fp
+++ b/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/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
index e6d23d0b8..fbde87af0 100644
--- a/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
+++ b/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/regress/unittests/sshkey/testdata/ed25519_1.fp b/regress/unittests/sshkey/testdata/ed25519_1.fp
index e6d23d0b8..fbde87af0 100644
--- a/regress/unittests/sshkey/testdata/ed25519_1.fp
+++ b/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/regress/unittests/sshkey/testdata/ed25519_2.fp b/regress/unittests/sshkey/testdata/ed25519_2.fp
index 02c684f36..ec1cdbb94 100644
--- a/regress/unittests/sshkey/testdata/ed25519_2.fp
+++ b/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/regress/unittests/sshkey/testdata/rsa1_1.fp b/regress/unittests/sshkey/testdata/rsa1_1.fp
index 782ece0db..2e1068c64 100644
--- a/regress/unittests/sshkey/testdata/rsa1_1.fp
+++ b/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/regress/unittests/sshkey/testdata/rsa1_2.fp b/regress/unittests/sshkey/testdata/rsa1_2.fp
index c3325371d..cd0039306 100644
--- a/regress/unittests/sshkey/testdata/rsa1_2.fp
+++ b/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/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/regress/unittests/sshkey/testdata/rsa_1-cert.fp
index bf9c2e362..1cf780dd9 100644
--- a/regress/unittests/sshkey/testdata/rsa_1-cert.fp
+++ b/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/regress/unittests/sshkey/testdata/rsa_1.fp b/regress/unittests/sshkey/testdata/rsa_1.fp
index bf9c2e362..1cf780dd9 100644
--- a/regress/unittests/sshkey/testdata/rsa_1.fp
+++ b/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/regress/unittests/sshkey/testdata/rsa_2.fp b/regress/unittests/sshkey/testdata/rsa_2.fp
index 53939f413..8d4367610 100644
--- a/regress/unittests/sshkey/testdata/rsa_2.fp
+++ b/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/regress/unittests/test_helper/Makefile b/regress/unittests/test_helper/Makefile
index 3e90903ef..5b3894cbf 100644
--- a/regress/unittests/test_helper/Makefile
+++ b/regress/unittests/test_helper/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ 1# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $
2 2
3LIB= test_helper 3LIB= test_helper
4SRCS= test_helper.c fuzz.c 4SRCS= test_helper.c fuzz.c
@@ -7,6 +7,9 @@ DEBUGLIBS= no
7NOPROFILE= yes 7NOPROFILE= yes
8NOPIC= yes 8NOPIC= yes
9 9
10# Hack to allow building with SUBDIR in ../../Makefile
11regress: all
12
10install: 13install:
11 @echo -n 14 @echo -n
12 15
diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c
index 77c6e7cad..99f1d036c 100644
--- a/regress/unittests/test_helper/fuzz.c
+++ b/regress/unittests/test_helper/fuzz.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */ 1/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -20,6 +20,7 @@
20#include "includes.h" 20#include "includes.h"
21 21
22#include <sys/types.h> 22#include <sys/types.h>
23#include <sys/uio.h>
23 24
24#include <assert.h> 25#include <assert.h>
25#include <ctype.h> 26#include <ctype.h>
@@ -29,9 +30,11 @@
29#endif 30#endif
30#include <stdlib.h> 31#include <stdlib.h>
31#include <string.h> 32#include <string.h>
32#include <assert.h> 33#include <signal.h>
34#include <unistd.h>
33 35
34#include "test_helper.h" 36#include "test_helper.h"
37#include "atomicio.h"
35 38
36/* #define FUZZ_DEBUG */ 39/* #define FUZZ_DEBUG */
37 40
@@ -96,60 +99,66 @@ fuzz_ntop(u_int n)
96 } 99 }
97} 100}
98 101
99void 102static int
100fuzz_dump(struct fuzz *fuzz) 103fuzz_fmt(struct fuzz *fuzz, char *s, size_t n)
101{ 104{
102 u_char *p = fuzz_ptr(fuzz); 105 if (fuzz == NULL)
103 size_t i, j, len = fuzz_len(fuzz); 106 return -1;
104 107
105 switch (fuzz->strategy) { 108 switch (fuzz->strategy) {
106 case FUZZ_1_BIT_FLIP: 109 case FUZZ_1_BIT_FLIP:
107 fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n", 110 snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n",
108 fuzz_ntop(fuzz->strategy), 111 fuzz_ntop(fuzz->strategy),
109 fuzz->o1, fuzz->slen * 8, fuzz->o1); 112 fuzz->o1, fuzz->slen * 8, fuzz->o1);
110 break; 113 return 0;
111 case FUZZ_2_BIT_FLIP: 114 case FUZZ_2_BIT_FLIP:
112 fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n", 115 snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n",
113 fuzz_ntop(fuzz->strategy), 116 fuzz_ntop(fuzz->strategy),
114 (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, 117 (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
115 ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, 118 ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
116 fuzz->o1, fuzz->o2); 119 fuzz->o1, fuzz->o2);
117 break; 120 return 0;
118 case FUZZ_1_BYTE_FLIP: 121 case FUZZ_1_BYTE_FLIP:
119 fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n", 122 snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n",
120 fuzz_ntop(fuzz->strategy), 123 fuzz_ntop(fuzz->strategy),
121 fuzz->o1, fuzz->slen, fuzz->o1); 124 fuzz->o1, fuzz->slen, fuzz->o1);
122 break; 125 return 0;
123 case FUZZ_2_BYTE_FLIP: 126 case FUZZ_2_BYTE_FLIP:
124 fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n", 127 snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n",
125 fuzz_ntop(fuzz->strategy), 128 fuzz_ntop(fuzz->strategy),
126 (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, 129 (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
127 ((fuzz_ullong)fuzz->slen) * fuzz->slen, 130 ((fuzz_ullong)fuzz->slen) * fuzz->slen,
128 fuzz->o1, fuzz->o2); 131 fuzz->o1, fuzz->o2);
129 break; 132 return 0;
130 case FUZZ_TRUNCATE_START: 133 case FUZZ_TRUNCATE_START:
131 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", 134 snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
132 fuzz_ntop(fuzz->strategy), 135 fuzz_ntop(fuzz->strategy),
133 fuzz->o1, fuzz->slen, fuzz->o1); 136 fuzz->o1, fuzz->slen, fuzz->o1);
134 break; 137 return 0;
135 case FUZZ_TRUNCATE_END: 138 case FUZZ_TRUNCATE_END:
136 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", 139 snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
137 fuzz_ntop(fuzz->strategy), 140 fuzz_ntop(fuzz->strategy),
138 fuzz->o1, fuzz->slen, fuzz->o1); 141 fuzz->o1, fuzz->slen, fuzz->o1);
139 break; 142 return 0;
140 case FUZZ_BASE64: 143 case FUZZ_BASE64:
141 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); 144 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
142 fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n", 145 snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n",
143 fuzz_ntop(fuzz->strategy), 146 fuzz_ntop(fuzz->strategy),
144 (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, 147 (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
145 fuzz->slen * (fuzz_ullong)64, fuzz->o1, 148 fuzz->slen * (fuzz_ullong)64, fuzz->o1,
146 fuzz_b64chars[fuzz->o2]); 149 fuzz_b64chars[fuzz->o2]);
147 break; 150 return 0;
148 default: 151 default:
152 return -1;
149 abort(); 153 abort();
150 } 154 }
155}
156
157static void
158dump(u_char *p, size_t len)
159{
160 size_t i, j;
151 161
152 fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
153 for (i = 0; i < len; i += 16) { 162 for (i = 0; i < len; i += 16) {
154 fprintf(stderr, "%.4zd: ", i); 163 fprintf(stderr, "%.4zd: ", i);
155 for (j = i; j < i + 16; j++) { 164 for (j = i; j < i + 16; j++) {
@@ -171,6 +180,39 @@ fuzz_dump(struct fuzz *fuzz)
171 } 180 }
172} 181}
173 182
183void
184fuzz_dump(struct fuzz *fuzz)
185{
186 char buf[256];
187
188 if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) {
189 fprintf(stderr, "%s: fuzz invalid\n", __func__);
190 abort();
191 }
192 fputs(buf, stderr);
193 fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen);
194 dump(fuzz->seed, fuzz->slen);
195 fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz));
196 dump(fuzz_ptr(fuzz), fuzz_len(fuzz));
197}
198
199#ifdef SIGINFO
200static struct fuzz *last_fuzz;
201
202static void
203siginfo(int unused __attribute__((__unused__)))
204{
205 char buf[256];
206
207 test_info(buf, sizeof(buf));
208 atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
209 if (last_fuzz != NULL) {
210 fuzz_fmt(last_fuzz, buf, sizeof(buf));
211 atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
212 }
213}
214#endif
215
174struct fuzz * 216struct fuzz *
175fuzz_begin(u_int strategies, const void *p, size_t l) 217fuzz_begin(u_int strategies, const void *p, size_t l)
176{ 218{
@@ -190,6 +232,12 @@ fuzz_begin(u_int strategies, const void *p, size_t l)
190 FUZZ_DBG(("begin, ret = %p", ret)); 232 FUZZ_DBG(("begin, ret = %p", ret));
191 233
192 fuzz_next(ret); 234 fuzz_next(ret);
235
236#ifdef SIGINFO
237 last_fuzz = ret;
238 signal(SIGINFO, siginfo);
239#endif
240
193 return ret; 241 return ret;
194} 242}
195 243
@@ -197,6 +245,10 @@ void
197fuzz_cleanup(struct fuzz *fuzz) 245fuzz_cleanup(struct fuzz *fuzz)
198{ 246{
199 FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); 247 FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
248#ifdef SIGINFO
249 last_fuzz = NULL;
250 signal(SIGINFO, SIG_DFL);
251#endif
200 assert(fuzz != NULL); 252 assert(fuzz != NULL);
201 assert(fuzz->seed != NULL); 253 assert(fuzz->seed != NULL);
202 assert(fuzz->fuzzed != NULL); 254 assert(fuzz->fuzzed != NULL);
@@ -326,6 +378,14 @@ fuzz_next(struct fuzz *fuzz)
326} 378}
327 379
328int 380int
381fuzz_matches_original(struct fuzz *fuzz)
382{
383 if (fuzz_len(fuzz) != fuzz->slen)
384 return 0;
385 return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0;
386}
387
388int
329fuzz_done(struct fuzz *fuzz) 389fuzz_done(struct fuzz *fuzz)
330{ 390{
331 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, 391 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c
index d0bc67833..26ca26b5e 100644
--- a/regress/unittests/test_helper/test_helper.c
+++ b/regress/unittests/test_helper/test_helper.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */ 1/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -21,6 +21,7 @@
21 21
22#include <sys/types.h> 22#include <sys/types.h>
23#include <sys/param.h> 23#include <sys/param.h>
24#include <sys/uio.h>
24 25
25#include <fcntl.h> 26#include <fcntl.h>
26#include <stdio.h> 27#include <stdio.h>
@@ -31,6 +32,7 @@
31#include <string.h> 32#include <string.h>
32#include <assert.h> 33#include <assert.h>
33#include <unistd.h> 34#include <unistd.h>
35#include <signal.h>
34 36
35#include <openssl/bn.h> 37#include <openssl/bn.h>
36 38
@@ -39,6 +41,7 @@
39#endif 41#endif
40 42
41#include "test_helper.h" 43#include "test_helper.h"
44#include "atomicio.h"
42 45
43#define TEST_CHECK_INT(r, pred) do { \ 46#define TEST_CHECK_INT(r, pred) do { \
44 switch (pred) { \ 47 switch (pred) { \
@@ -111,6 +114,7 @@ static u_int test_number = 0;
111static test_onerror_func_t *test_onerror = NULL; 114static test_onerror_func_t *test_onerror = NULL;
112static void *onerror_ctx = NULL; 115static void *onerror_ctx = NULL;
113static const char *data_dir = NULL; 116static const char *data_dir = NULL;
117static char subtest_info[512];
114 118
115int 119int
116main(int argc, char **argv) 120main(int argc, char **argv)
@@ -180,13 +184,36 @@ test_data_file(const char *name)
180} 184}
181 185
182void 186void
187test_info(char *s, size_t len)
188{
189 snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number,
190 active_test_name == NULL ? "<none>" : active_test_name,
191 *subtest_info != '\0' ? " - " : "", subtest_info);
192}
193
194#ifdef SIGINFO
195static void
196siginfo(int unused __attribute__((__unused__)))
197{
198 char buf[256];
199
200 test_info(buf, sizeof(buf));
201 atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
202}
203#endif
204
205void
183test_start(const char *n) 206test_start(const char *n)
184{ 207{
185 assert(active_test_name == NULL); 208 assert(active_test_name == NULL);
186 assert((active_test_name = strdup(n)) != NULL); 209 assert((active_test_name = strdup(n)) != NULL);
210 *subtest_info = '\0';
187 if (verbose_mode) 211 if (verbose_mode)
188 printf("test %u - \"%s\": ", test_number, active_test_name); 212 printf("test %u - \"%s\": ", test_number, active_test_name);
189 test_number++; 213 test_number++;
214#ifdef SIGINFO
215 signal(SIGINFO, siginfo);
216#endif
190} 217}
191 218
192void 219void
@@ -199,6 +226,7 @@ set_onerror_func(test_onerror_func_t *f, void *ctx)
199void 226void
200test_done(void) 227test_done(void)
201{ 228{
229 *subtest_info = '\0';
202 assert(active_test_name != NULL); 230 assert(active_test_name != NULL);
203 free(active_test_name); 231 free(active_test_name);
204 active_test_name = NULL; 232 active_test_name = NULL;
@@ -211,6 +239,16 @@ test_done(void)
211} 239}
212 240
213void 241void
242test_subtest_info(const char *fmt, ...)
243{
244 va_list ap;
245
246 va_start(ap, fmt);
247 vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap);
248 va_end(ap);
249}
250
251void
214ssl_err_check(const char *file, int line) 252ssl_err_check(const char *file, int line)
215{ 253{
216 long openssl_error = ERR_get_error(); 254 long openssl_error = ERR_get_error();
@@ -256,8 +294,9 @@ static void
256test_header(const char *file, int line, const char *a1, const char *a2, 294test_header(const char *file, int line, const char *a1, const char *a2,
257 const char *name, enum test_predicate pred) 295 const char *name, enum test_predicate pred)
258{ 296{
259 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", 297 fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n",
260 file, line, test_number, active_test_name); 298 file, line, test_number, active_test_name,
299 *subtest_info != '\0' ? " - " : "", subtest_info);
261 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 300 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
262 name, pred_name(pred), a1, 301 name, pred_name(pred), a1,
263 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 302 a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
@@ -280,8 +319,13 @@ void
280assert_string(const char *file, int line, const char *a1, const char *a2, 319assert_string(const char *file, int line, const char *a1, const char *a2,
281 const char *aa1, const char *aa2, enum test_predicate pred) 320 const char *aa1, const char *aa2, enum test_predicate pred)
282{ 321{
283 int r = strcmp(aa1, aa2); 322 int r;
284 323
324 /* Verify pointers are not NULL */
325 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
326 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
327
328 r = strcmp(aa1, aa2);
285 TEST_CHECK_INT(r, pred); 329 TEST_CHECK_INT(r, pred);
286 test_header(file, line, a1, a2, "STRING", pred); 330 test_header(file, line, a1, a2, "STRING", pred);
287 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 331 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
@@ -310,8 +354,15 @@ void
310assert_mem(const char *file, int line, const char *a1, const char *a2, 354assert_mem(const char *file, int line, const char *a1, const char *a2,
311 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 355 const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
312{ 356{
313 int r = memcmp(aa1, aa2, l); 357 int r;
314 358
359 if (l == 0)
360 return;
361 /* If length is >0, then verify pointers are not NULL */
362 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
363 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
364
365 r = memcmp(aa1, aa2, l);
315 TEST_CHECK_INT(r, pred); 366 TEST_CHECK_INT(r, pred);
316 test_header(file, line, a1, a2, "STRING", pred); 367 test_header(file, line, a1, a2, "STRING", pred);
317 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); 368 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,
338 const void *aa1, u_char v, size_t l, enum test_predicate pred) 389 const void *aa1, u_char v, size_t l, enum test_predicate pred)
339{ 390{
340 size_t where = -1; 391 size_t where = -1;
341 int r = memvalcmp(aa1, v, l, &where); 392 int r;
342 char tmp[64]; 393 char tmp[64];
343 394
344 if (l == 0) 395 if (l == 0)
345 return; 396 return;
397 /* If length is >0, then verify the pointer is not NULL */
398 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
399
400 r = memvalcmp(aa1, v, l, &where);
346 TEST_CHECK_INT(r, pred); 401 TEST_CHECK_INT(r, pred);
347 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 402 test_header(file, line, a1, NULL, "MEM_ZERO", pred);
348 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 403 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h
index a398c615f..1d9c66986 100644
--- a/regress/unittests/test_helper/test_helper.h
+++ b/regress/unittests/test_helper/test_helper.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */ 1/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -40,8 +40,11 @@ void tests(void);
40 40
41const char *test_data_file(const char *name); 41const char *test_data_file(const char *name);
42void test_start(const char *n); 42void test_start(const char *n);
43void test_info(char *s, size_t len);
43void set_onerror_func(test_onerror_func_t *f, void *ctx); 44void set_onerror_func(test_onerror_func_t *f, void *ctx);
44void test_done(void); 45void test_done(void);
46void test_subtest_info(const char *fmt, ...)
47 __attribute__((format(printf, 1, 2)));
45void ssl_err_check(const char *file, int line); 48void ssl_err_check(const char *file, int line);
46void assert_bignum(const char *file, int line, 49void assert_bignum(const char *file, int line,
47 const char *a1, const char *a2, 50 const char *a1, const char *a2,
@@ -280,6 +283,13 @@ void fuzz_cleanup(struct fuzz *fuzz);
280/* Prepare the next fuzz case in the series */ 283/* Prepare the next fuzz case in the series */
281void fuzz_next(struct fuzz *fuzz); 284void fuzz_next(struct fuzz *fuzz);
282 285
286/*
287 * Check whether this fuzz case is identical to the original
288 * This is slow, but useful if the caller needs to ensure that all tests
289 * generated change the input (e.g. when fuzzing signatures).
290 */
291int fuzz_matches_original(struct fuzz *fuzz);
292
283/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ 293/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
284int fuzz_done(struct fuzz *fuzz); 294int fuzz_done(struct fuzz *fuzz);
285 295
@@ -289,4 +299,5 @@ u_char *fuzz_ptr(struct fuzz *fuzz);
289 299
290/* Dump the current fuzz case to stderr */ 300/* Dump the current fuzz case to stderr */
291void fuzz_dump(struct fuzz *fuzz); 301void fuzz_dump(struct fuzz *fuzz);
302
292#endif /* _TEST_HELPER_H */ 303#endif /* _TEST_HELPER_H */