summaryrefslogtreecommitdiff
path: root/regress/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2014-06-24 01:14:19 +0000
committerDamien Miller <djm@cvs.openbsd.org>2014-06-24 01:14:19 +0000
commitd13708b95430abd20d6e2db1263f826e6077dce4 (patch)
tree8c16ebd24a1e210c2a38c1502206ab6562f3bf1f /regress/usr.bin
parent6eeffb4d8cef5c4af07cdfe1568ddd07732d938d (diff)
unit and fuzz tests for new key API
Diffstat (limited to 'regress/usr.bin')
-rw-r--r--regress/usr.bin/ssh/Makefile6
-rw-r--r--regress/usr.bin/ssh/unittests/Makefile6
-rw-r--r--regress/usr.bin/ssh/unittests/Makefile.inc15
-rw-r--r--regress/usr.bin/ssh/unittests/sshbuf/Makefile7
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/Makefile13
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/common.c78
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/common.h16
-rwxr-xr-xregress/usr.bin/ssh/unittests/sshkey/mktestdata.sh189
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/test_file.c449
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/test_fuzz.c394
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c341
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_112
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.g1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.priv1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1_pw15
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_212
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n12
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n_pw21
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_15
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.curve1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.priv1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1_pw8
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_27
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.curve1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.priv1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n5
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n_pw9
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_17
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1_pw8
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_27
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/pw1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1bin0 -> 421 bytes
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.param.n1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1_pwbin0 -> 421 bytes
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2bin0 -> 981 bytes
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.param.n1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_112
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.n1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.p1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.q1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1_pw15
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_227
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp.bb1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.n1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.p1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.q1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.pub1
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n12
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n_pw14
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/tests.c25
89 files changed, 1796 insertions, 7 deletions
diff --git a/regress/usr.bin/ssh/Makefile b/regress/usr.bin/ssh/Makefile
index d3798bf6846..58faf64ecac 100644
--- a/regress/usr.bin/ssh/Makefile
+++ b/regress/usr.bin/ssh/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.69 2014/04/30 05:32:00 djm Exp $
+# $OpenBSD: Makefile,v 1.70 2014/06/24 01:14:17 djm Exp $
REGRESS_FAIL_EARLY= yes
REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9
@@ -86,7 +86,9 @@ SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER}
TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
unit:
- (set -e ; cd ${.CURDIR}/unittests ; make)
+ if test -z "${SKIP_UNIT}" ; then \
+ (set -e ; cd ${.CURDIR}/unittests ; make) \
+ fi
t1:
ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
diff --git a/regress/usr.bin/ssh/unittests/Makefile b/regress/usr.bin/ssh/unittests/Makefile
index 2581a5853a9..aaf9da63777 100644
--- a/regress/usr.bin/ssh/unittests/Makefile
+++ b/regress/usr.bin/ssh/unittests/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
-
-SUBDIR= test_helper sshbuf
+# $OpenBSD: Makefile,v 1.2 2014/06/24 01:14:18 djm Exp $
+REGRESS_FAIL_EARLY= yes
+SUBDIR= test_helper sshbuf sshkey
.include <bsd.subdir.mk>
diff --git a/regress/usr.bin/ssh/unittests/Makefile.inc b/regress/usr.bin/ssh/unittests/Makefile.inc
index 4c33637495c..2f431344600 100644
--- a/regress/usr.bin/ssh/unittests/Makefile.inc
+++ b/regress/usr.bin/ssh/unittests/Makefile.inc
@@ -1,8 +1,16 @@
-# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
+# $OpenBSD: Makefile.inc,v 1.2 2014/06/24 01:14:18 djm Exp $
.include <bsd.own.mk>
.include <bsd.obj.mk>
+REGRESS_FAIL_EARLY= yes
+
+# XXX detect from ssh binary?
+OPENSSL?= yes
+.if (${OPENSSL:L} == "yes")
+CFLAGS+= -DWITH_OPENSSL -DWITH_SSH1
+.endif
+
# enable warnings
WARNINGS=Yes
@@ -55,5 +63,10 @@ LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh
DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a
.endif
+LDADD+= -lutil
+DPADD+= ${LIBUTIL}
+
+.if (${OPENSSL:L} == "yes")
LDADD+= -lcrypto
DPADD+= ${LIBCRYPTO}
+.endif
diff --git a/regress/usr.bin/ssh/unittests/sshbuf/Makefile b/regress/usr.bin/ssh/unittests/sshbuf/Makefile
index 85f99ac3831..42b7a20c217 100644
--- a/regress/usr.bin/ssh/unittests/sshbuf/Makefile
+++ b/regress/usr.bin/ssh/unittests/sshbuf/Makefile
@@ -1,4 +1,6 @@
-# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
+# $OpenBSD: Makefile,v 1.2 2014/06/24 01:14:18 djm Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
PROG=test_sshbuf
SRCS=tests.c
@@ -10,5 +12,8 @@ SRCS+=test_sshbuf_fuzz.c
SRCS+=test_sshbuf_getput_fuzz.c
SRCS+=test_sshbuf_fixed.c
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG}
+
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/ssh/unittests/sshkey/Makefile b/regress/usr.bin/ssh/unittests/sshkey/Makefile
new file mode 100644
index 00000000000..1bcd266762a
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/Makefile
@@ -0,0 +1,13 @@
+# $OpenBSD: Makefile,v 1.1 2014/06/24 01:14:18 djm Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+PROG=test_sshkey
+SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
+
+.include <bsd.regress.mk>
+
diff --git a/regress/usr.bin/ssh/unittests/sshkey/common.c b/regress/usr.bin/ssh/unittests/sshkey/common.c
new file mode 100644
index 00000000000..022931b6e3c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/common.c
@@ -0,0 +1,78 @@
+/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Helpers for key API tests
+ *
+ * Placed in the public domain
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+
+#include "test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+struct sshbuf *
+load_file(const char *name)
+{
+ int fd;
+ struct sshbuf *ret;
+
+ ASSERT_PTR_NE(ret = sshbuf_new(), NULL);
+ ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1);
+ ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0);
+ close(fd);
+ return ret;
+}
+
+struct sshbuf *
+load_text_file(const char *name)
+{
+ struct sshbuf *ret = load_file(name);
+ const u_char *p;
+
+ /* Trim whitespace at EOL */
+ for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) {
+ if (p[sshbuf_len(ret) - 1] == '\r' ||
+ p[sshbuf_len(ret) - 1] == '\t' ||
+ p[sshbuf_len(ret) - 1] == ' ' ||
+ p[sshbuf_len(ret) - 1] == '\n')
+ ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0);
+ else
+ break;
+ }
+ /* \0 terminate */
+ ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0);
+ return ret;
+}
+
+BIGNUM *
+load_bignum(const char *name)
+{
+ BIGNUM *ret = NULL;
+ struct sshbuf *buf;
+
+ buf = load_text_file(name);
+ ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0);
+ sshbuf_free(buf);
+ return ret;
+}
+
diff --git a/regress/usr.bin/ssh/unittests/sshkey/common.h b/regress/usr.bin/ssh/unittests/sshkey/common.h
new file mode 100644
index 00000000000..bf7d19dce39
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/common.h
@@ -0,0 +1,16 @@
+/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Helpers for key API tests
+ *
+ * Placed in the public domain
+ */
+
+/* Load a binary file into a buffer */
+struct sshbuf *load_file(const char *name);
+
+/* Load a text file into a buffer */
+struct sshbuf *load_text_file(const char *name);
+
+/* Load a bignum from a file */
+BIGNUM *load_bignum(const char *name);
+
diff --git a/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh b/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh
new file mode 100755
index 00000000000..2039bf97480
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh
@@ -0,0 +1,189 @@
+#!/bin/sh
+
+PW=mekmitasdigoat
+
+rsa1_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ ssh-keygen -f $_in -e -m pkcs8 | \
+ openssl rsa -noout -text -pubin | \
+ awk '/^Modulus:$/,/^Exponent:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
+ # XXX need conversion support in ssh-keygen for the other params
+ for x in n ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+rsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl rsa -noout -text -in $_in | \
+ awk '/^modulus:$/,/^publicExponent:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
+ openssl rsa -noout -text -in $_in | \
+ awk '/^prime1:$/,/^prime2:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.p
+ openssl rsa -noout -text -in $_in | \
+ awk '/^prime2:$/,/^exponent1:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.q
+ for x in n p q ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+dsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl dsa -noout -text -in $_in | \
+ awk '/^priv:$/,/^pub:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
+ openssl dsa -noout -text -in $_in | \
+ awk '/^pub:/,/^P:/' | #\
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
+ openssl dsa -noout -text -in $_in | \
+ awk '/^G:/,0' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g
+ for x in priv pub g ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+ecdsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl ec -noout -text -in $_in | \
+ awk '/^priv:$/,/^pub:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
+ openssl ec -noout -text -in $_in | \
+ awk '/^pub:/,/^ASN1 OID:/' | #\
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
+ openssl ec -noout -text -in $_in | \
+ grep "ASN1 OID:" | tr -d '\n' | \
+ sed 's/.*: //;s/ *$//' > ${_outbase}.curve
+ for x in priv pub curve ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+set -ex
+
+cd testdata
+
+rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1
+rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2
+rm -f rsa_n dsa_n ecdsa_n # new-format keys
+rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw
+rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw
+rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb
+
+ssh-keygen -t rsa1 -b 768 -C "RSA1 test key #1" -N "" -f rsa1_1
+ssh-keygen -t rsa -b 768 -C "RSA test key #1" -N "" -f rsa_1
+ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1
+ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1
+ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1
+
+ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2
+ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2
+ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2
+ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2
+ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_2
+
+cp rsa_1 rsa_n
+cp dsa_1 dsa_n
+cp ecdsa_1 ecdsa_n
+
+cp rsa1_1 rsa1_1_pw
+cp rsa_1 rsa_1_pw
+cp dsa_1 dsa_1_pw
+cp ecdsa_1 ecdsa_1_pw
+cp ed25519_1 ed25519_1_pw
+cp rsa_1 rsa_n_pw
+cp dsa_1 dsa_n_pw
+cp ecdsa_1 ecdsa_n_pw
+
+ssh-keygen -pf rsa1_1_pw -N "$PW"
+ssh-keygen -pf rsa_1_pw -N "$PW"
+ssh-keygen -pf dsa_1_pw -N "$PW"
+ssh-keygen -pf ecdsa_1_pw -N "$PW"
+ssh-keygen -pf ed25519_1_pw -N "$PW"
+ssh-keygen -opf rsa_n_pw -N "$PW"
+ssh-keygen -opf dsa_n_pw -N "$PW"
+ssh-keygen -opf ecdsa_n_pw -N "$PW"
+
+rsa1_params rsa1_1 rsa1_1.param
+rsa1_params rsa1_2 rsa1_2.param
+rsa_params rsa_1 rsa_1.param
+rsa_params rsa_2 rsa_2.param
+dsa_params dsa_1 dsa_1.param
+dsa_params dsa_1 dsa_1.param
+ecdsa_params ecdsa_1 ecdsa_1.param
+ecdsa_params ecdsa_2 ecdsa_2.param
+# XXX ed25519 params
+
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 1 rsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 2 dsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 3 ecdsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 4 ed25519_1.pub
+
+ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 5 rsa_1.pub
+ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 6 dsa_1.pub
+ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 7 ecdsa_1.pub
+ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 8 ed25519_1.pub
+
+ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp
+ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp
+ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp
+ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp
+ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp
+ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp
+ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp
+ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp
+ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp
+ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp
+
+ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp
+ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp
+ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp
+ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp
+
+ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb
+ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb
+ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb
+ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb
+ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb
+ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb
+ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb
+ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
+ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
+ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
+
+echo "$PW" > pw
diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_file.c b/regress/usr.bin/ssh/unittests/sshkey/test_file.c
new file mode 100644
index 00000000000..19056b52ae8
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/test_file.c
@@ -0,0 +1,449 @@
+/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshkey.h key management API
+ *
+ * Placed in the public domain
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+
+#include "test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+void sshkey_file_tests(void);
+
+void
+sshkey_file_tests(void)
+{
+ struct sshkey *k1, *k2;
+ struct sshbuf *buf, *pw;
+ BIGNUM *a, *b, *c;
+ char *cp;
+
+ TEST_START("load passphrase");
+ pw = load_text_file("pw");
+ TEST_DONE();
+
+ TEST_START("parse RSA1 from private");
+ buf = load_file("rsa1_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("rsa1_1.param.n");
+ ASSERT_BIGNUM_EQ(k1->rsa->n, a);
+ BN_free(a);
+ TEST_DONE();
+
+ TEST_START("parse RSA1 from private w/ passphrase");
+ buf = load_file("rsa1_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA1 from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("RSA1 key hex fingerprint");
+ buf = load_text_file("rsa1_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("RSA1 key bubblebabble fingerprint");
+ buf = load_text_file("rsa1_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse RSA from private");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("rsa_1.param.n");
+ b = load_bignum("rsa_1.param.p");
+ c = load_bignum("rsa_1.param.q");
+ ASSERT_BIGNUM_EQ(k1->rsa->n, a);
+ ASSERT_BIGNUM_EQ(k1->rsa->p, b);
+ ASSERT_BIGNUM_EQ(k1->rsa->q, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse RSA from private w/ passphrase");
+ buf = load_file("rsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse RSA from new-format");
+ buf = load_file("rsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "rsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse RSA from new-format w/ passphrase");
+ buf = load_file("rsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_RSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("RSA key hex fingerprint");
+ buf = load_text_file("rsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("RSA cert hex fingerprint");
+ buf = load_text_file("rsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("RSA key bubblebabble fingerprint");
+ buf = load_text_file("rsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse DSA from private");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("dsa_1.param.g");
+ b = load_bignum("dsa_1.param.priv");
+ c = load_bignum("dsa_1.param.pub");
+ ASSERT_BIGNUM_EQ(k1->dsa->g, a);
+ ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
+ ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse DSA from private w/ passphrase");
+ buf = load_file("dsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse DSA from new-format");
+ buf = load_file("dsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "dsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse DSA from new-format w/ passphrase");
+ buf = load_file("dsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load DSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load DSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_DSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("DSA key hex fingerprint");
+ buf = load_text_file("dsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("DSA cert hex fingerprint");
+ buf = load_text_file("dsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("DSA key bubblebabble fingerprint");
+ buf = load_text_file("dsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse ECDSA from private");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ buf = load_text_file("ecdsa_1.param.curve");
+ ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf),
+ OBJ_nid2sn(k1->ecdsa_nid));
+ sshbuf_free(buf);
+ a = load_bignum("ecdsa_1.param.priv");
+ b = load_bignum("ecdsa_1.param.pub");
+ c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa),
+ EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED,
+ NULL, NULL);
+ ASSERT_PTR_NE(c, NULL);
+ ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a);
+ ASSERT_BIGNUM_EQ(b, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from private w/ passphrase");
+ buf = load_file("ecdsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from new-format");
+ buf = load_file("ecdsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "ecdsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from new-format w/ passphrase");
+ buf = load_file("ecdsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load ECDSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load ECDSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("ECDSA key hex fingerprint");
+ buf = load_text_file("ecdsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("ECDSA cert hex fingerprint");
+ buf = load_text_file("ecdsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("ECDSA key bubblebabble fingerprint");
+ buf = load_text_file("ecdsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse Ed25519 from private");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_INT_EQ(k1->type, KEY_ED25519);
+ /* XXX check key contents */
+ TEST_DONE();
+
+ TEST_START("parse Ed25519 from private w/ passphrase");
+ buf = load_file("ed25519_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load Ed25519 from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load Ed25519 cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("Ed25519 key hex fingerprint");
+ buf = load_text_file("ed25519_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("Ed25519 cert hex fingerprint");
+ buf = load_text_file("ed25519_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("Ed25519 key bubblebabble fingerprint");
+ buf = load_text_file("ed25519_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ sshbuf_free(pw);
+
+}
diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_fuzz.c b/regress/usr.bin/ssh/unittests/sshkey/test_fuzz.c
new file mode 100644
index 00000000000..936a8899cad
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/test_fuzz.c
@@ -0,0 +1,394 @@
+/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Fuzz tests for key parsing
+ *
+ * Placed in the public domain
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+
+#include "test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+void sshkey_fuzz_tests(void);
+
+static void
+onerror(void *fuzz)
+{
+ fprintf(stderr, "Failed during fuzz:\n");
+ fuzz_dump((struct fuzz *)fuzz);
+}
+
+static void
+public_fuzz(struct sshkey *k)
+{
+ struct sshkey *k1;
+ struct sshbuf *buf;
+ struct fuzz *fuzz;
+
+ ASSERT_PTR_NE(buf = sshbuf_new(), NULL);
+ ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0);
+ /* XXX need a way to run the tests in "slow, but complete" mode */
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */
+ FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf),
+ &k1), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0)
+ sshkey_free(k1);
+ }
+ fuzz_cleanup(fuzz);
+}
+
+static void
+sig_fuzz(struct sshkey *k)
+{
+ struct fuzz *fuzz;
+ u_char *sig, c[] = "some junk to be signed";
+ size_t l;
+
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0);
+ ASSERT_SIZE_T_GT(l, 0);
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */
+ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0);
+ free(sig);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
+ c, sizeof(c), 0);
+ }
+ fuzz_cleanup(fuzz);
+}
+
+void
+sshkey_fuzz_tests(void)
+{
+ struct sshkey *k1;
+ struct sshbuf *buf, *fuzzed;
+ struct fuzz *fuzz;
+ int r;
+
+ TEST_START("fuzz RSA1 private");
+ buf = load_file("rsa1_1");
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA1 public");
+ buf = load_file("rsa1_1_pw");
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA private");
+ buf = load_file("rsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA new-format private");
+ buf = load_file("rsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA private");
+ buf = load_file("dsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA new-format private");
+ buf = load_file("dsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA private");
+ buf = load_file("ecdsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA new-format private");
+ buf = load_file("ecdsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz Ed25519 private");
+ buf = load_file("ed25519_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA public");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA public");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA public");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz Ed25519 public");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz Ed25519 cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA sig");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA sig");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA sig");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz Ed25519 sig");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+/* XXX fuzz decoded new-format blobs too */
+
+}
diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c
new file mode 100644
index 00000000000..0864ffd78a0
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c
@@ -0,0 +1,341 @@
+/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshkey.h key management API
+ *
+ * Placed in the public domain
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#include "test_helper.h"
+
+#include "ssherr.h"
+#include "sshbuf.h"
+#define SSHBUF_INTERNAL 1 /* access internals for testing */
+#include "sshkey.h"
+
+#include "authfile.h"
+#include "common.h"
+#include "ssh2.h"
+
+void sshkey_tests(void);
+
+static void
+build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
+ const struct sshkey *sign_key, const struct sshkey *ca_key)
+{
+ struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
+ u_char *sigblob;
+ size_t siglen;
+
+ ca_buf = sshbuf_new();
+ ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
+
+ /*
+ * Get the public key serialisation by rendering the key and skipping
+ * the type string. This is a bit of a hack :/
+ */
+ pk = sshbuf_new();
+ ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
+ ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
+
+ principals = sshbuf_new();
+ ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
+ ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
+
+ critopts = sshbuf_new();
+ /* XXX fill this in */
+
+ exts = sshbuf_new();
+ /* XXX fill this in */
+
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
+ ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */
+ ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */
+ ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
+ ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
+ sshbuf_ptr(b), sshbuf_len(b), 0), 0);
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
+
+ free(sigblob);
+ sshbuf_free(ca_buf);
+ sshbuf_free(exts);
+ sshbuf_free(critopts);
+ sshbuf_free(principals);
+ sshbuf_free(pk);
+}
+
+void
+sshkey_tests(void)
+{
+ struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf;
+ struct sshbuf *b;
+
+ TEST_START("new invalid");
+ k1 = sshkey_new(-42);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_UNSPEC");
+ k1 = sshkey_new(KEY_UNSPEC);
+ ASSERT_PTR_NE(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_RSA1");
+ k1 = sshkey_new(KEY_RSA1);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_RSA");
+ k1 = sshkey_new(KEY_RSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_DSA");
+ k1 = sshkey_new(KEY_DSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_ECDSA");
+ k1 = sshkey_new(KEY_ECDSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_ED25519");
+ k1 = sshkey_new(KEY_ED25519);
+ ASSERT_PTR_NE(k1, NULL);
+ /* These should be blank until key loaded or generated */
+ ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
+ ASSERT_PTR_EQ(k1->ed25519_pk, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new_private KEY_RSA");
+ k1 = sshkey_new_private(KEY_RSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_NE(k1->rsa->p, NULL);
+ ASSERT_INT_EQ(sshkey_add_private(k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new_private KEY_DSA");
+ k1 = sshkey_new_private(KEY_DSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
+ ASSERT_INT_EQ(sshkey_add_private(k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA too small modulus");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA too large modulus");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_DSA wrong bits");
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_ECDSA wrong bits");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0);
+ ASSERT_PTR_NE(kr, NULL);
+ ASSERT_PTR_NE(kr->rsa, NULL);
+ ASSERT_PTR_NE(kr->rsa->n, NULL);
+ ASSERT_PTR_NE(kr->rsa->e, NULL);
+ ASSERT_PTR_NE(kr->rsa->p, NULL);
+ ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768);
+ TEST_DONE();
+
+ TEST_START("generate KEY_DSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
+ ASSERT_PTR_NE(kd, NULL);
+ ASSERT_PTR_NE(kd->dsa, NULL);
+ ASSERT_PTR_NE(kd->dsa->g, NULL);
+ ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
+ ASSERT_PTR_NE(ke, NULL);
+ ASSERT_PTR_NE(ke->ecdsa, NULL);
+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
+ ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
+ ASSERT_PTR_NE(kf, NULL);
+ ASSERT_INT_EQ(kf->type, KEY_ED25519);
+ ASSERT_PTR_NE(kf->ed25519_pk, NULL);
+ ASSERT_PTR_NE(kf->ed25519_sk, NULL);
+ TEST_DONE();
+
+ TEST_START("demote KEY_RSA");
+ ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kr, k1);
+ ASSERT_INT_EQ(k1->type, KEY_RSA);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_RSA/demoted KEY_RSA");
+ ASSERT_INT_EQ(sshkey_equal(kr, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("demote KEY_DSA");
+ ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kd, k1);
+ ASSERT_INT_EQ(k1->type, KEY_DSA);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_DSA/demoted KEY_DSA");
+ ASSERT_INT_EQ(sshkey_equal(kd, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("demote KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(ke, k1);
+ ASSERT_INT_EQ(k1->type, KEY_ECDSA);
+ ASSERT_PTR_NE(k1->ecdsa, NULL);
+ ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
+ ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("demote KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kf, k1);
+ ASSERT_INT_EQ(k1->type, KEY_ED25519);
+ ASSERT_PTR_NE(k1->ed25519_pk, NULL);
+ ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_ED25519/demoted KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_equal(kf, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("equal mismatched key types");
+ ASSERT_INT_EQ(sshkey_equal(kd, kr), 0);
+ ASSERT_INT_EQ(sshkey_equal(kd, ke), 0);
+ ASSERT_INT_EQ(sshkey_equal(kr, ke), 0);
+ ASSERT_INT_EQ(sshkey_equal(ke, kf), 0);
+ ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
+ TEST_DONE();
+
+ TEST_START("equal different keys");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
+ sshkey_free(k1);
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kd, k1), 0);
+ sshkey_free(k1);
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
+ sshkey_free(k1);
+ ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ sshkey_free(kr);
+ sshkey_free(kd);
+ sshkey_free(ke);
+ sshkey_free(kf);
+
+/* XXX certify test */
+/* XXX sign test */
+/* XXX verify test */
+
+ TEST_START("nested certificate");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
+ NULL), 0);
+ b = load_file("rsa_2");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
+ &k3, NULL), 0);
+ sshbuf_reset(b);
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
+ SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
+ ASSERT_PTR_EQ(k4, NULL);
+ sshbuf_free(b);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ sshkey_free(k3);
+ TEST_DONE();
+
+}
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1 b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1
new file mode 100644
index 00000000000..7517963d444
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCB2IZRhajAULw+W8SLX5kxD/88CuVIKqojrZD5C+4T5D4YwQ0L
+6DvbvPHRhid1jmL4VLrG1MfOQvFMbePC9ydvf6CKDK/LPb8Wiq0cR2uBit2CVDIo
+4M7bk4X9+u7AwgENNbEAbdNBJRuMxwJiv4OawFGmFaASFNqVCRaq7MzA8wIVAMHA
+azJLtfjdILh3uV77BT3MxGIPAoGASU6xzUFx2PG3g81RBIO09NauCcf/0EYpyMls
+xNJ3MrQnVPWQwqjFepsEcU95ItbsUVkav0mqW319Am6/EAvroYcCHDyo+JUAUPiL
+WXmF6eEMNa97aNM5cQQwzYQvqt+F2mjK4SPxQObCA3O/YEmB8xUtn09BPDP2r/4Z
+y2ywGIECgYB6/rbpAUv4klwv7fX+v5nBFB3pnt5QPZrC6BxDmhG1v5vdNkvIWo4t
+OYnxV/5O3vJQQGi81uA0LjrpH3K9HRos8QP7QnsDYdAYyqLekrFzmnQOxMnYoj0n
+rZBr07TFifBI/m+/vboaegF93/xyNiGcG39i9sWoUQ+Qu1rsdLLg7QIVAITGqmpX
+T8lOnqkCA3X/7XZfZKUb
+-----END DSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.fp
new file mode 100644
index 00000000000..79009e5ddf6
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.fp
@@ -0,0 +1 @@
+6d:a9:24:3f:d5:b0:51:76:6d:98:2a:eb:64:ad:e1:3e
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.pub
new file mode 100644
index 00000000000..ccc9e34f800
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1-cert.pub
@@ -0,0 +1 @@
+ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgyiDlcNJnT+1aDuTAT6IFROmPV36yZXS1+eg8j93Lbv4AAACBAIHYhlGFqMBQvD5bxItfmTEP/zwK5UgqqiOtkPkL7hPkPhjBDQvoO9u88dGGJ3WOYvhUusbUx85C8Uxt48L3J29/oIoMr8s9vxaKrRxHa4GK3YJUMijgztuThf367sDCAQ01sQBt00ElG4zHAmK/g5rAUaYVoBIU2pUJFqrszMDzAAAAFQDBwGsyS7X43SC4d7le+wU9zMRiDwAAAIBJTrHNQXHY8beDzVEEg7T01q4Jx//QRinIyWzE0ncytCdU9ZDCqMV6mwRxT3ki1uxRWRq/SapbfX0Cbr8QC+uhhwIcPKj4lQBQ+ItZeYXp4Qw1r3to0zlxBDDNhC+q34XaaMrhI/FA5sIDc79gSYHzFS2fT0E8M/av/hnLbLAYgQAAAIB6/rbpAUv4klwv7fX+v5nBFB3pnt5QPZrC6BxDmhG1v5vdNkvIWo4tOYnxV/5O3vJQQGi81uA0LjrpH3K9HRos8QP7QnsDYdAYyqLekrFzmnQOxMnYoj0nrZBr07TFifBI/m+/vboaegF93/xyNiGcG39i9sWoUQ+Qu1rsdLLg7QAAAAAAAAAGAAAAAgAAAAZqdWxpdXMAAAASAAAABWhvc3QxAAAABWhvc3QyAAAAADaLg2AAAAAATR3h4AAAAAAAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEEeFVBN9rCVt76ZAhb71aQxLwcmq5SigrJG8nRvoBI3Tzfa8/Sp16hupzUeHJht3/BNI8sPvcI1DMVTuOREstl6wAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAgMIrMGDb0MQT95GiXw93m4l7D+ruiJKLclEP/e68J/GMAAAAhAMbXfc7vVtOU4ofibChKSTHAUrDotY+qr50UDVhCIBhJ DSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp
new file mode 100644
index 00000000000..79009e5ddf6
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp
@@ -0,0 +1 @@
+6d:a9:24:3f:d5:b0:51:76:6d:98:2a:eb:64:ad:e1:3e
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp.bb
new file mode 100644
index 00000000000..9d0d51a635e
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.fp.bb
@@ -0,0 +1 @@
+xumel-lusic-nevym-gyfup-ginyg-deliv-tetam-humef-vykul-tadit-pixix
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.g b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.g
new file mode 100644
index 00000000000..deb29000ca3
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.g
@@ -0,0 +1 @@
+494eb1cd4171d8f1b783cd510483b4f4d6ae09c7ffd04629c8c96cc4d27732b42754f590c2a8c57a9b04714f7922d6ec51591abf49aa5b7d7d026ebf100beba187021c3ca8f8950050f88b597985e9e10c35af7b68d339710430cd842faadf85da68cae123f140e6c20373bf604981f3152d9f4f413c33f6affe19cb6cb01881
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.priv b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.priv
new file mode 100644
index 00000000000..314148b5539
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.priv
@@ -0,0 +1 @@
+0084c6aa6a574fc94e9ea9020375ffed765f64a51b
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.pub
new file mode 100644
index 00000000000..bde5b10a32c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.param.pub
@@ -0,0 +1 @@
+7afeb6e9014bf8925c2fedf5febf99c1141de99ede503d9ac2e81c439a11b5bf9bdd364bc85a8e2d3989f157fe4edef2504068bcd6e0342e3ae91f72bd1d1a2cf103fb427b0361d018caa2de92b1739a740ec4c9d8a23d27ad906bd3b4c589f048fe6fbfbdba1a7a017ddffc7236219c1b7f62f6c5a8510f90bb5aec74b2e0ed
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.pub
new file mode 100644
index 00000000000..51c2c1bb343
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAIHYhlGFqMBQvD5bxItfmTEP/zwK5UgqqiOtkPkL7hPkPhjBDQvoO9u88dGGJ3WOYvhUusbUx85C8Uxt48L3J29/oIoMr8s9vxaKrRxHa4GK3YJUMijgztuThf367sDCAQ01sQBt00ElG4zHAmK/g5rAUaYVoBIU2pUJFqrszMDzAAAAFQDBwGsyS7X43SC4d7le+wU9zMRiDwAAAIBJTrHNQXHY8beDzVEEg7T01q4Jx//QRinIyWzE0ncytCdU9ZDCqMV6mwRxT3ki1uxRWRq/SapbfX0Cbr8QC+uhhwIcPKj4lQBQ+ItZeYXp4Qw1r3to0zlxBDDNhC+q34XaaMrhI/FA5sIDc79gSYHzFS2fT0E8M/av/hnLbLAYgQAAAIB6/rbpAUv4klwv7fX+v5nBFB3pnt5QPZrC6BxDmhG1v5vdNkvIWo4tOYnxV/5O3vJQQGi81uA0LjrpH3K9HRos8QP7QnsDYdAYyqLekrFzmnQOxMnYoj0nrZBr07TFifBI/m+/vboaegF93/xyNiGcG39i9sWoUQ+Qu1rsdLLg7Q== DSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1_pw
new file mode 100644
index 00000000000..1bedcb0cee8
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_1_pw
@@ -0,0 +1,15 @@
+-----BEGIN DSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,65B3055CF40728FF588846F0AEFE21B2
+
+I3cUBSbhjltkTMvTaDABixfwLr8faxL9/YOoEFenmBj0JwwrSV7L8VGbb68BbwCr
+5EOgySFEazgXUbiuILg47lWxp/IKegz1KrO6bXoE1bKT+UxjrI+e8CDi4kpEh98F
+jM6V0QZmotMVwJh6NIfuuOBN92mS8In8remGGBA08VWPjW1CsmjmTDFNzOW5Uzo9
+gG9dM08NljQ8Mf3L2iKoTpLQVr//0Q//0Ei3qCEUOvOOH05mWiecGwPAiCSH2jSO
+GlP59jbwxfIZ2klGrj9D8xCBzTZgdHDlS2cdnJ0GasaPiFnWwX91zaatK+vCvWp6
+apWY6biRn0g9EGJob9YZ6eg3ZGHcFsf/7yDbSjuG3Uj8FhmrP/MkK7Ht7db2hiGL
+9uUrNcZhLUFyynTcEfBOFuAtoqktDNTN2VjMj9szJWipF8U9hGeRfw4hFeMXYPHD
+k/+j4qS4fc5EAx1Vd6iMXRzxiUre8GGzyq2nSm1POtyQPG+3UQTRU3zBBudIx9N9
+WCXWHw0+xNHgOX/HtLUkq+2ghxnU+6Whew5eqSdKLMoB7KIKxsxf8wNkv4yOM1KJ
+JWXaXOCyIWclCuc1Uj27Zw==
+-----END DSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2 b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2
new file mode 100644
index 00000000000..2ad7393c4a6
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDzY25r/QuRHe5YvbwajDpB4/DyY3LH/OTVWcQdflDH2xH6823W
+H2i7FwnuYzsAJkbM1L9n3N9bOXhiGmYIpUKfkE1EKRekNnLW9D0/AvkVzcBN/Lqc
+zy4TxmE7oxClIS+6uksoRHhohFkHPWZDYTxo6mD5vVfzCh2jSSzjEhzFLwIVANtk
+v40w5aRP8C8TQciVJCUy5yp1AoGBAO+s5wkzEftttboUCci3pK0L9wUPHkhTNgC+
+sFjdtiVVpptGkLsujyllEyIFChVUrN5ZNgjv7bzSEe0FSU0XtmZ77GU96ff7jWmD
+9xUqm4aIwu/3DSgitOO+XLgb2J08eLY+Lglp40AoWFfwy57flpPMT4q5nk77QfS1
+gzC2X0CtAoGAPfbEG6KUOec9H1xfnwb8AVCk6jOy+XfiGtE3cnlECNQjQkPcp1Jm
+CrhrEh1rRmOwJdMkDLhmOHy6IFnzvj85IAm9qY6M2f8svZ/ASCAnQ6SnHDwhl3eO
+ZQPi03Fka3QXjkwJb/gnmoWuGayM7dPbJg0Ib62GrPGj6/vkaQsGy3ACFQDL5o4e
+vjA1Kf3kA2WYhOy/8kfeJg==
+-----END DSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp
new file mode 100644
index 00000000000..a9a2a45dee3
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp
@@ -0,0 +1 @@
+3d:fb:a3:22:95:17:89:1f:24:31:e7:ec:9f:ce:09:0b
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp.bb
new file mode 100644
index 00000000000..788bffee5a3
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.fp.bb
@@ -0,0 +1 @@
+xuzoh-nuhut-lyrum-luhap-givyl-nygiz-nybyr-higes-pahor-nivic-zyxex
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.pub
new file mode 100644
index 00000000000..da4ac7f8783
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_2.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAPNjbmv9C5Ed7li9vBqMOkHj8PJjcsf85NVZxB1+UMfbEfrzbdYfaLsXCe5jOwAmRszUv2fc31s5eGIaZgilQp+QTUQpF6Q2ctb0PT8C+RXNwE38upzPLhPGYTujEKUhL7q6SyhEeGiEWQc9ZkNhPGjqYPm9V/MKHaNJLOMSHMUvAAAAFQDbZL+NMOWkT/AvE0HIlSQlMucqdQAAAIEA76znCTMR+221uhQJyLekrQv3BQ8eSFM2AL6wWN22JVWmm0aQuy6PKWUTIgUKFVSs3lk2CO/tvNIR7QVJTRe2ZnvsZT3p9/uNaYP3FSqbhojC7/cNKCK0475cuBvYnTx4tj4uCWnjQChYV/DLnt+Wk8xPirmeTvtB9LWDMLZfQK0AAACAPfbEG6KUOec9H1xfnwb8AVCk6jOy+XfiGtE3cnlECNQjQkPcp1JmCrhrEh1rRmOwJdMkDLhmOHy6IFnzvj85IAm9qY6M2f8svZ/ASCAnQ6SnHDwhl3eOZQPi03Fka3QXjkwJb/gnmoWuGayM7dPbJg0Ib62GrPGj6/vkaQsGy3A= DSA test key #2
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n
new file mode 100644
index 00000000000..7517963d444
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCB2IZRhajAULw+W8SLX5kxD/88CuVIKqojrZD5C+4T5D4YwQ0L
+6DvbvPHRhid1jmL4VLrG1MfOQvFMbePC9ydvf6CKDK/LPb8Wiq0cR2uBit2CVDIo
+4M7bk4X9+u7AwgENNbEAbdNBJRuMxwJiv4OawFGmFaASFNqVCRaq7MzA8wIVAMHA
+azJLtfjdILh3uV77BT3MxGIPAoGASU6xzUFx2PG3g81RBIO09NauCcf/0EYpyMls
+xNJ3MrQnVPWQwqjFepsEcU95ItbsUVkav0mqW319Am6/EAvroYcCHDyo+JUAUPiL
+WXmF6eEMNa97aNM5cQQwzYQvqt+F2mjK4SPxQObCA3O/YEmB8xUtn09BPDP2r/4Z
+y2ywGIECgYB6/rbpAUv4klwv7fX+v5nBFB3pnt5QPZrC6BxDmhG1v5vdNkvIWo4t
+OYnxV/5O3vJQQGi81uA0LjrpH3K9HRos8QP7QnsDYdAYyqLekrFzmnQOxMnYoj0n
+rZBr07TFifBI/m+/vboaegF93/xyNiGcG39i9sWoUQ+Qu1rsdLLg7QIVAITGqmpX
+T8lOnqkCA3X/7XZfZKUb
+-----END DSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n_pw
new file mode 100644
index 00000000000..568f8512d74
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/dsa_n_pw
@@ -0,0 +1,21 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABB7JzB0sx
+h4pg63zhB6eD3vAAAAEAAAAAEAAAGxAAAAB3NzaC1kc3MAAACBAIHYhlGFqMBQvD5bxItf
+mTEP/zwK5UgqqiOtkPkL7hPkPhjBDQvoO9u88dGGJ3WOYvhUusbUx85C8Uxt48L3J29/oI
+oMr8s9vxaKrRxHa4GK3YJUMijgztuThf367sDCAQ01sQBt00ElG4zHAmK/g5rAUaYVoBIU
+2pUJFqrszMDzAAAAFQDBwGsyS7X43SC4d7le+wU9zMRiDwAAAIBJTrHNQXHY8beDzVEEg7
+T01q4Jx//QRinIyWzE0ncytCdU9ZDCqMV6mwRxT3ki1uxRWRq/SapbfX0Cbr8QC+uhhwIc
+PKj4lQBQ+ItZeYXp4Qw1r3to0zlxBDDNhC+q34XaaMrhI/FA5sIDc79gSYHzFS2fT0E8M/
+av/hnLbLAYgQAAAIB6/rbpAUv4klwv7fX+v5nBFB3pnt5QPZrC6BxDmhG1v5vdNkvIWo4t
+OYnxV/5O3vJQQGi81uA0LjrpH3K9HRos8QP7QnsDYdAYyqLekrFzmnQOxMnYoj0nrZBr07
+TFifBI/m+/vboaegF93/xyNiGcG39i9sWoUQ+Qu1rsdLLg7QAAAeDozqkOSFq7z2LnfJ2b
+jVVwsNdNDn1K3DBONYaoz3R1CyNSmfdTOylCkw/VXQ/7Wlw52+ot/mEIdtjv6uK7NCjAyL
+XLGkq2yMRmitPFxiLRSNo9/Sirpviaq7zJyOBbZiB+wrJgnSdg+185u1t5Qd19hi+XEKcM
+DyTfAj6MPGe/uBmuxIVaVEf9BknyQ74+D5HD6KApcxWI6WNJH9hAkSON8hA1EUWRc+N2hD
+624dEkuJBkCBCgmFbfD7QthBXrGMuSo78Xz0XRpuP+cOQvs/U2wl8OLXuqyzmZtGnDGfjW
+9Z2qF4sKUKV2A3Q97WAjm/p04TxDXUEChI3D12dbwN0dGYEZW2XSBYxhK/YbTpjKKXzpJs
+R7U2Avm1krEql7+4fEb876i1+/6w2aFBfn8tx5vvdRehvIXqcg6n4KhIO7d3MS62A19m68
+OYQu1veaUxu9oO2D5byV0GIqZbVWCtaVh/8hLQcGMgz+43HGIMHiJRX9EWenOqEeK7Pam0
+BLkCoFycbGa3fI/reyoQ/g/tlmHjq3kdO9SKZYIcUPk4tnImStHsPEU1X7/WbvV+j0jTtZ
+nxJ2E/z5gdeDeJ9VJcdwofd6BpEwd2WML1o3kZYNwY+K2HJ3JnYfWsJanb6YlRA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1 b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1
new file mode 100644
index 00000000000..9b8b9f43271
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIDUJpHhcwtTxAYqTeBC2WNcZJ3VJrAI97F2n2PeootjCoAoGCCqGSM49
+AwEHoUQDQgAEeFVBN9rCVt76ZAhb71aQxLwcmq5SigrJG8nRvoBI3Tzfa8/Sp16h
+upzUeHJht3/BNI8sPvcI1DMVTuOREstl6w==
+-----END EC PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.fp
new file mode 100644
index 00000000000..fec523c47b8
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.fp
@@ -0,0 +1 @@
+db:df:20:25:bf:74:fc:1d:61:2f:c0:cd:53:7f:a0:69
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.pub
new file mode 100644
index 00000000000..1dde0640cd2
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1-cert.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg99cLkLZdAh1Q9TLiiFjDgLeXcncoQ2ChPj6vheH5aDAAAAAIbmlzdHAyNTYAAABBBHhVQTfawlbe+mQIW+9WkMS8HJquUooKyRvJ0b6ASN0832vP0qdeobqc1HhyYbd/wTSPLD73CNQzFU7jkRLLZesAAAAAAAAABwAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHhVQTfawlbe+mQIW+9WkMS8HJquUooKyRvJ0b6ASN0832vP0qdeobqc1HhyYbd/wTSPLD73CNQzFU7jkRLLZesAAABlAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABKAAAAIQCNyzewlmw65HO5pgVlhNhTds90xhHWG7E26+w37vS6AQAAACEAofQD+jXVJIw0JFuL/4pEpHV8LA9swBOlr+0QSHOvrO8= ECDSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp
new file mode 100644
index 00000000000..fec523c47b8
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp
@@ -0,0 +1 @@
+db:df:20:25:bf:74:fc:1d:61:2f:c0:cd:53:7f:a0:69
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp.bb
new file mode 100644
index 00000000000..9816feccd58
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.fp.bb
@@ -0,0 +1 @@
+xeroh-pefer-fypid-kipem-fosag-ludoz-vilym-nuvoz-rilyv-nonut-raxex
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.curve b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.curve
new file mode 100644
index 00000000000..fa04004670c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.curve
@@ -0,0 +1 @@
+prime256v1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.priv b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.priv
new file mode 100644
index 00000000000..7196f0c73cd
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.priv
@@ -0,0 +1 @@
+3509a4785cc2d4f1018a937810b658d719277549ac023dec5da7d8f7a8a2d8c2
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.pub
new file mode 100644
index 00000000000..189f3182859
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.param.pub
@@ -0,0 +1 @@
+0478554137dac256defa64085bef5690c4bc1c9aae528a0ac91bc9d1be8048dd3cdf6bcfd2a75ea1ba9cd4787261b77fc1348f2c3ef708d433154ee39112cb65eb
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.pub
new file mode 100644
index 00000000000..cea2861b5d9
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHhVQTfawlbe+mQIW+9WkMS8HJquUooKyRvJ0b6ASN0832vP0qdeobqc1HhyYbd/wTSPLD73CNQzFU7jkRLLZes= ECDSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1_pw
new file mode 100644
index 00000000000..7fcf57a03c3
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_1_pw
@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,332EEE2B8008A91D1F4342B9DEBE4FEA
+
+nMCab7D2wbVoKZvM37ZbTXiajSmyvWFQd3Mt3zeeEBoL6ib/48BFDogWlcDvRP7y
+tgKYhqK7JBO4GjSssL4Bu/rQgNK/0ZmS/V7hLN7wsU3DcrHYhfHknL8LbRfiJarB
+772nLAie9oaQcZZloNVa477CBGh7WXux/vRk2NlJ0Uo=
+-----END EC PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2 b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2
new file mode 100644
index 00000000000..651b00c937c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB7SsuJvR+4aK3Js4gEaJ5UDEa2hJTCBM+/PBYv9ZUkf9PohUvfPfh
+xHRcF6tUhZDmChFeNQpt3sic2uTXa4lU8oigBwYFK4EEACOhgYkDgYYABABLAXz5
+fCAiumZWlWqzG5NxJx1a17WgZ2o+ffYrAJgXVrGGJudmIZSCDWFABtpuY7Ws3zRa
+CM3DZj+ua+qMWsUysQGwiC6n1YEUdVZste5Vdh1YqhImJcT3//TzJ6lfMaUpJxdU
+MeYe8bw+zuNAEJ+ax8W6lWKQwu4sh3Ffc6WmU+qYkg==
+-----END EC PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp
new file mode 100644
index 00000000000..a8b8320fb24
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp
@@ -0,0 +1 @@
+1e:54:1d:9d:43:f0:c9:2b:68:7a:6a:c3:33:36:66:92
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp.bb
new file mode 100644
index 00000000000..5863db4cade
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.fp.bb
@@ -0,0 +1 @@
+xefak-fyfim-lytem-nusir-kycog-vybyt-peguk-deniv-pukub-bydyr-rexux
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.curve b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.curve
new file mode 100644
index 00000000000..617ea2fb8ca
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.curve
@@ -0,0 +1 @@
+secp521r1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.priv b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.priv
new file mode 100644
index 00000000000..66d88239034
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.priv
@@ -0,0 +1 @@
+01ed2b2e26f47ee1a2b726ce2011a27950311ada125308133efcf058bfd65491ff4fa2152f7cf7e1c4745c17ab548590e60a115e350a6ddec89cdae4d76b8954f288
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.pub
new file mode 100644
index 00000000000..646a3769cf0
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.param.pub
@@ -0,0 +1 @@
+04004b017cf97c2022ba6656956ab31b9371271d5ad7b5a0676a3e7df62b00981756b18626e7662194820d614006da6e63b5acdf345a08cdc3663fae6bea8c5ac532b101b0882ea7d5811475566cb5ee55761d58aa122625c4f7fff4f327a95f31a52927175431e61ef1bc3ecee340109f9ac7c5ba956290c2ee2c87715f73a5a653ea9892
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.pub
new file mode 100644
index 00000000000..2ca38b7b097
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_2.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABLAXz5fCAiumZWlWqzG5NxJx1a17WgZ2o+ffYrAJgXVrGGJudmIZSCDWFABtpuY7Ws3zRaCM3DZj+ua+qMWsUysQGwiC6n1YEUdVZste5Vdh1YqhImJcT3//TzJ6lfMaUpJxdUMeYe8bw+zuNAEJ+ax8W6lWKQwu4sh3Ffc6WmU+qYkg== ECDSA test key #2
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n
new file mode 100644
index 00000000000..9b8b9f43271
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIDUJpHhcwtTxAYqTeBC2WNcZJ3VJrAI97F2n2PeootjCoAoGCCqGSM49
+AwEHoUQDQgAEeFVBN9rCVt76ZAhb71aQxLwcmq5SigrJG8nRvoBI3Tzfa8/Sp16h
+upzUeHJht3/BNI8sPvcI1DMVTuOREstl6w==
+-----END EC PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n_pw
new file mode 100644
index 00000000000..1a232a53091
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ecdsa_n_pw
@@ -0,0 +1,9 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBjrPF4oU
+razQUC36K0kiJSAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz
+dHAyNTYAAABBBHhVQTfawlbe+mQIW+9WkMS8HJquUooKyRvJ0b6ASN0832vP0qdeobqc1H
+hyYbd/wTSPLD73CNQzFU7jkRLLZesAAACwRIjJkfLwAv6pn+FV4zyB7jwNpiM/Tvi8G9L1
+tyjowAbH5QspKcUk2QlGwAfDzZkwZaeO3AHN+jrxUZe59U39nBPUQTJtfwHB/9YDQmkxDf
+PSjPhSUgTJTjO7ZnJhiBhopSecrLlw9jEG3aU6jXrtLHvoeWsqgNC4FPR+NONY56Cp6HH/
+xcNMcG3bdfsLV7/aKN6L8xFOcwv5PZguUX+akbm28L2RtdwomHLlinxCBZQ=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1 b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1
new file mode 100644
index 00000000000..9834e6b1670
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACD9nC84xPJD/K1WHPNss8ONwRTYYXhE+JfNMTACxwMC9QAAAJgHI6RaByOk
+WgAAAAtzc2gtZWQyNTUxOQAAACD9nC84xPJD/K1WHPNss8ONwRTYYXhE+JfNMTACxwMC9Q
+AAAEBTSW4tcSIyBvJIs9X0+veV3KEnF5tMFTuDRn2UUCDg4f2cLzjE8kP8rVYc82yzw43B
+FNhheET4l80xMALHAwL1AAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.fp
new file mode 100644
index 00000000000..a1065afb133
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.fp
@@ -0,0 +1 @@
+c5:bc:c6:f0:71:ff:18:01:b6:bb:20:0e:5c:c9:45:dd
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.pub
new file mode 100644
index 00000000000..e1af85b51d2
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1-cert.pub
@@ -0,0 +1 @@
+ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAICJMFRc+O68lpgxZhFEBSABACLSyhq6uRr5p64SX7rG8AAAAIP2cLzjE8kP8rVYc82yzw43BFNhheET4l80xMALHAwL1AAAAAAAAAAgAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANouDYAAAAABNHeHgAAAAAAAAAAAAAAAAAAAAaAAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQR4VUE32sJW3vpkCFvvVpDEvByarlKKCskbydG+gEjdPN9rz9KnXqG6nNR4cmG3f8E0jyw+9wjUMxVO45ESy2XrAAAAZQAAABNlY2RzYS1zaGEyLW5pc3RwMjU2AAAASgAAACEAmB/afp9JrHKRDZjHg7t4gguDZUlM7TbJh/QGWBJtKNwAAAAhAIfciGrKUngYx8c+MrLs9xm/H15UjQ1b/hmDjHPnBUXJ ED25519 test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp
new file mode 100644
index 00000000000..a1065afb133
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp
@@ -0,0 +1 @@
+c5:bc:c6:f0:71:ff:18:01:b6:bb:20:0e:5c:c9:45:dd
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp.bb
new file mode 100644
index 00000000000..19fed08195c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.fp.bb
@@ -0,0 +1 @@
+xunad-cibit-losah-sapes-fegor-fypyg-sifuv-buciv-cacim-votid-guxex
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.pub
new file mode 100644
index 00000000000..585c72389d6
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP2cLzjE8kP8rVYc82yzw43BFNhheET4l80xMALHAwL1 ED25519 test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1_pw
new file mode 100644
index 00000000000..995e4c06aba
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_1_pw
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABDAj0Bpln
+j9yho1+E35Cs50AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIP2cLzjE8kP8rVYc
+82yzw43BFNhheET4l80xMALHAwL1AAAAkOUMXMXJCs4Ra9eTz7ZmI+62mynIdc75adQIJ6
+Y1FhHU1FiNKA6thIsJQ2GkVraYUbsRr2cSId0wOdDyqCz8qGtUJGJf/CpC8xGyDiFxSRmX
+Q/jVwSPluusjq3hXSXgVkhMCl7x6wvdOYrgir1JAmt7xZ+GH16h9UshdQJQP2WRreYzBGa
+epCGVXiKDRt1h6qQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2 b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2
new file mode 100644
index 00000000000..cffc23eba04
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACD9RTuggxlEg440MCY7b8x7AXErFCkvyqOBzGa2H72HgAAAAJjVTVis1U1Y
+rAAAAAtzc2gtZWQyNTUxOQAAACD9RTuggxlEg440MCY7b8x7AXErFCkvyqOBzGa2H72HgA
+AAAECg5ZFCAGyGayR8cfdh9Z+atBw2D7iDCyhlM/Z9BhS8Y/1FO6CDGUSDjjQwJjtvzHsB
+cSsUKS/Ko4HMZrYfvYeAAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp
new file mode 100644
index 00000000000..bd9bdf1bb32
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp
@@ -0,0 +1 @@
+8a:9b:6b:7a:72:4a:33:e7:82:f4:44:36:4f:03:ab:fb
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp.bb
new file mode 100644
index 00000000000..d344f8b7a78
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.fp.bb
@@ -0,0 +1 @@
+xopaz-sytem-gohun-gekug-nupyz-mizeb-satur-gykyz-bytuk-cynak-zoxax
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.pub
new file mode 100644
index 00000000000..36f769adef9
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/ed25519_2.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP1FO6CDGUSDjjQwJjtvzHsBcSsUKS/Ko4HMZrYfvYeA ED25519 test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/pw
new file mode 100644
index 00000000000..8a1dff98aa9
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/pw
@@ -0,0 +1 @@
+mekmitasdigoat
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1 b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1
new file mode 100644
index 00000000000..2ec1d9ee645
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1
Binary files differ
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp
new file mode 100644
index 00000000000..f124ea658da
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp
@@ -0,0 +1 @@
+ca:c8:b5:7e:5e:c3:0d:b9:7a:01:08:07:e6:8d:84:ff
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp.bb
new file mode 100644
index 00000000000..cbcd469dc9a
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.fp.bb
@@ -0,0 +1 @@
+xolod-lezac-hozas-zyvam-femup-resyn-tabeh-cimil-todab-pimak-maxox
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.param.n b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.param.n
new file mode 100644
index 00000000000..50b9f6805fb
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.param.n
@@ -0,0 +1 @@
+00c410f14bcebcbddc6ffeaa710252ad90fbef0d050ec87d3383a9d238d6711fbef589e4878403c264c7966fe49bad711536dce5d87a955b85e59407cb05b42fa7403d9f69ff0939dc6c706bdcf06b6b261d989bd36b3285406a2ed222823c2395
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.pub
new file mode 100644
index 00000000000..bc70397b724
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1.pub
@@ -0,0 +1 @@
+768 65537 1189048026044302003027146850139461857907776498392388644081572317839873971656566933581374195515931390619470169918301657448827055049126798186766951463208246494942453808397018298947013383501856813897052663039958494425741000753698055061 RSA1 test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1_pw
new file mode 100644
index 00000000000..a3a18aa8c33
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_1_pw
Binary files differ
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2 b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2
new file mode 100644
index 00000000000..ae266299ae2
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2
Binary files differ
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp
new file mode 100644
index 00000000000..8b3bdd3a970
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp
@@ -0,0 +1 @@
+81:76:19:cb:e3:ea:6f:5d:44:0d:c2:0b:de:f1:57:c4
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp.bb
new file mode 100644
index 00000000000..d519e7b9beb
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.fp.bb
@@ -0,0 +1 @@
+xocoh-kufyf-rirac-kepuc-gurig-mekog-pylir-fezyd-nosub-govug-lyxyx
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.param.n b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.param.n
new file mode 100644
index 00000000000..6a88ee87f39
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.param.n
@@ -0,0 +1 @@
+00f41a2e0ea0e61ba8c26cf6e1bd44a78406681186a7791de3242bedc244e06c17a18747fb88b1380aeba3c857923452b9e38673817bd1a23f7d2075923b1d95d9969bbcd21aa04dfe467e4c7d8a47a10bd63dd6dce4ffe779a61f4540bcfcd9300d69055260be095e5e8460e82396779c0a50625fb85604899e443135ca261860351264b5cd9347b3b2d0493dc8ab58a76739834e94e6a931a81b47ec07a0d18e6326cf141c4cecf21ce33e55c4337b58e81f98ba37aa2363c4b7b9b681832fc82bfd065e78225963b5dee3339fc5f93b1e03fb23b944af1044c428face1e9074cac094e1b1466567bcd0052c7a3cd54413e0223cd3ead772c224fe9992a1cc4d
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.pub
new file mode 100644
index 00000000000..c57a552dd45
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa1_2.pub
@@ -0,0 +1 @@
+2048 65537 30815056206845718337883693475648720850145825019377625660339254990170671928186378018861225635606515759973597729576094610770872780661576141002020091115398326221356676709078132441993985409561447755934597661311399662597377239284991122793182116387265444497738700221133645372503575578155284370786624391167692459891729408171168746091407569853493645212173229529277332482208795686490659301613799014974247858014846717332898701883748838319394666276585141978582467494951081034069208462692298663692548804886954137194606203245934935998707318505433583480495694779849614216589821145199486122690013311036780783985671309143185809329229 RSA1 test key #2
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1 b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1
new file mode 100644
index 00000000000..a84a9e2eb7d
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIByQIBAAJhAKAJGOfpr4S2inakOMcqjGQ1RLNwp4FWvWYc+xxnAqfJS7vwZ8ie
+2fcniZMS69o9CXiACUw2LYbNGZMfrnzjQEaKlObDi5HB1XNE+9z01m2GS9XH+Eg0
+ilNeAx/hfNEDVQIDAQABAmB8O3OtHHhXYskMHqHA4qPHap6hWZN+0RIIQfkhbEng
+bGAxTgeS8tWrinK+zFJwwS3tYmSc8YfT/4gX/DG1nudv+Pjjhwom/HMTiK/Tw4JN
+ZhWCPKB8T1rICkGAtbMq2KECMQDTa9o6g/Nb2zkvJq+04SQ5ivqZdWXaeZixz1Xt
+JKgqRLoMxny81E/LaeeKXfNACE0CMQDBx4hGEBlm8aJwj6SdZ50Ulu8c4hz4ZcJo
+v2T+BY8ogmlaF1ADcFXeHDmE7Cg16ykCMF7zTCIFirERRqBXdof8qSEyupNa9zBk
+deA9ZrDHSsMY9JmyNukzTNblLDinMwzp7QIwUq/O4X6rKDdBhmB08MmuyINjQuLl
+U8UwQLwy3wYGQVXsmInMFbuQmHdYv/R5cBCJAjAquE/FnCRxuI2NEhoqrO3FG0wO
+cByLc/Svz1ct3eGUMabUxfQdi8Ka97gv9CW9EbI=
+-----END RSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.fp
new file mode 100644
index 00000000000..66002343a79
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.fp
@@ -0,0 +1 @@
+93:53:33:f1:ca:bc:c2:df:a1:a2:0e:df:2d:d4:32:77
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.pub
new file mode 100644
index 00000000000..aea5a04d61f
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1-cert.pub
@@ -0,0 +1 @@
+ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgAkIaUrWrYvXkf55DvHtHsjLNCn22Hvx4PpKyeW7fvA0AAAADAQABAAAAYQCgCRjn6a+Etop2pDjHKoxkNUSzcKeBVr1mHPscZwKnyUu78GfIntn3J4mTEuvaPQl4gAlMNi2GzRmTH65840BGipTmw4uRwdVzRPvc9NZthkvVx/hINIpTXgMf4XzRA1UAAAAAAAAABQAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHhVQTfawlbe+mQIW+9WkMS8HJquUooKyRvJ0b6ASN0832vP0qdeobqc1HhyYbd/wTSPLD73CNQzFU7jkRLLZesAAABlAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABKAAAAIQDEZOWcEwfnm+mpfKMsGdXgWkTZDM9FD7tXGjHhTAIXnwAAACEA4eTYbu8nl1ycJnHUAWmy4sayJNm4vHZNYH1Wzvsh3dQ= RSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp
new file mode 100644
index 00000000000..66002343a79
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp
@@ -0,0 +1 @@
+93:53:33:f1:ca:bc:c2:df:a1:a2:0e:df:2d:d4:32:77
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp.bb
new file mode 100644
index 00000000000..11f62b45922
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.fp.bb
@@ -0,0 +1 @@
+xiriz-botoh-migez-rorom-fekat-hytar-bykys-selos-hanez-sukil-moxox
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.n b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.n
new file mode 100644
index 00000000000..6c83fd7943d
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.n
@@ -0,0 +1 @@
+00a00918e7e9af84b68a76a438c72a8c643544b370a78156bd661cfb1c6702a7c94bbbf067c89ed9f727899312ebda3d097880094c362d86cd19931fae7ce340468a94e6c38b91c1d57344fbdcf4d66d864bd5c7f848348a535e031fe17cd10355
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.p b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.p
new file mode 100644
index 00000000000..92c064b2a6a
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.p
@@ -0,0 +1 @@
+00d36bda3a83f35bdb392f26afb4e124398afa997565da7998b1cf55ed24a82a44ba0cc67cbcd44fcb69e78a5df340084d
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.q b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.q
new file mode 100644
index 00000000000..f19e1b769d5
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.param.q
@@ -0,0 +1 @@
+00c1c78846101966f1a2708fa49d679d1496ef1ce21cf865c268bf64fe058f2882695a1750037055de1c3984ec2835eb29
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.pub
new file mode 100644
index 00000000000..54517b47cd0
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQCgCRjn6a+Etop2pDjHKoxkNUSzcKeBVr1mHPscZwKnyUu78GfIntn3J4mTEuvaPQl4gAlMNi2GzRmTH65840BGipTmw4uRwdVzRPvc9NZthkvVx/hINIpTXgMf4XzRA1U= RSA test key #1
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1_pw
new file mode 100644
index 00000000000..c2df7719612
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_1_pw
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,64F8EBAD788B4A84B988458AE466E543
+
+Sce5ZTGCDNjY3mXUZohtyPyR7CFo9zaC4NWRDhYVOYT1l3vOX/ULXvvGo/VtsXOw
+eP+TCKYRKAm9yoOVh0E+MwI1TN4vnS8tuE6H5HJxpsE126Q3wFX1mY3ar+laTbrJ
+3uMm2suNSKSh4p46XRC9XFBnxjxaN7RfbwvAaSckqbNjc++NRDOfbE9QS9VlbPA1
+LxUzjAOhgRtQouaQzh2fwcv2xwq2K53iQch/eKe1BqUyv0v6Xb5SalrZa582c9ax
+W4OErS+NrvpI2DxKmoptM24kGaulRggANh+b6k2ZK5GtkSE00kPSVz30po4oo9vb
+oj1tTPjjlW4AGhiCOJM8EGpBJQztGzOCrOLT9bLL0GKE8m3MuwD5+xg/mWAylVnI
+a4LB20Nv9q8yv+6gKgDuMMVdnQit2NEN/s/vW9XOftDO45DgQkib6UTKi/QfVpNW
+/t2Cdd/NH/JRZuvsq/ywMxHf7r65YZ0Ncgv8oEhvIi0mNRI7i3MIvDB0eo8rFQ8E
+R+hNgVkOQS1XGSPacj0GktvQHvysKqzlAq/LDE2tsb9bVh1R8st99R7nCN0RZ1Fc
+PgQkod7cQluBexoqIPTPYJJzVVF0OYjV1WnLXc4MTcY=
+-----END RSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2 b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2
new file mode 100644
index 00000000000..9ab9fa4ee7e
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEA48Cz/hGQvEfUsgObwAZo73nBa/aplYHvUuFJgcTJOXXWRmqI
+St4S2aA2YRZ/vSEo5d8XVTDqQlsxhDFQt1fI72N3rljMut/DLev96MzyCiCUFjP9
+U0c7mYHRh5WZccGBfTD6EcBC3XhDa4znJWsfbyHE0USdYrWjRav37p5+//ZQ3F5k
+Nk6d5zw9lvRHyl1T6b7iux375JWYbWVpwc+bpXRIS7EdZNQKkCIhJoUFBWy3O3vg
+7i9leY5tOtbiAAzWR7ccE/3MPKPwK/pZHWftJVPgBUNwrTPR7K/fviUhdMWmV9d3
+Nz4YBru2y87d4HiJte3D0OXAroUnPxDlGtbTfQIDAQABAoIBAQCIUTzqYyUYLH44
+FkTQyIViYKPOtRKHs//Ewac3jstKIyefegAdn5H0xBoIPmkykHhkLgVPLjnogaC/
+mKzRMC/KaOSna+sOJwQxpkCRaKmuOhWovHFxuP8JQFRjLL1tAv84KWpj2Ymr+WGR
+LALluJpV8AZXoxP4kvMormd1YVRuaqR5qpUlOLUDhGWPq+C/KGfe+eMAYARY8yaq
+YKc880Y9Szgp0OH1QVY9vByq0nn61Gt1GsmDSlesjXbKXgeDFp/OQ9Ir5dYn+Z9O
+Owltm3MwfUaDIbHHR/wpoN6+uzFHNuNiqfu8XsrVRhaM9tu3++DwAqGqDgsbwjVV
+2NMqw/lZAoGBAPpbuMcqo7f0xjZY6px6qDRt7drOm7hEbuMeKWbsihMNLlftJ1Hb
+hfHEbnQxCdhSICkNh4GHA6Uw1hg8MFnIEA8wTRt6dHg2VKkko+RlvE2uqL3SYhUk
+yqTtTA6ZQmY8v4hTeNTorsQKlk3o3rExfJnTreNEDB+xNIrMT4GTlywnAoGBAOji
+ksymSgvxEXoyIzKAymsF3K/h8VLgsw1MyPSHsmWzm9q/WvobZN0jc7POL3pADimI
+xdK8KDh6tDYxF+T52za2EgnKZGOcUwPjIK574kgnwz+Jy8aVaamPj9Pp8NCirOLQ
+RJduiQQM86ri7dIUhc4oHBN6EcKnQ4Z6/ZSifrW7AoGBAOGan9MSMIBHmgpFa/1g
+Zo0AdrOTNS4CtO4DMwnlo7LxUM65DZKtQHGSMnqP6jA+KW71GyP0t6s3a+Zg7q0p
+JJebThCx85yUUQwu0WWy69IQz0xm9i3ZfqbKk5wgLX6VxX8iwSMTHtHYPIOukmaY
+kpDH+M1wd4BjnlZpMEgy6KpHAoGBAIIxWFwsgqzWYizsJp0vPvpB1rRFHgJ1N+Qx
+jw6VZfhRRsotvBCii+rMzPwyQnyXntM9cUp0gg/BGUpKe884l4KomsD6ctD1Lbu4
+mCazfzdTc2XsBQ3Jrb5rUb7oxAX/S6OpRw9ZbiPjkb1xC/8sFfnAlqGU1qT5mVhv
+HaCgjzHNAoGBAM9VmCbSUOdIQhS2QgpnFOWjpMblzmLW4zP9GmUt61myf/l6qckb
+qfqL614w2awtzaFCU7mmfjNqg8zcJ01sI2rT+Sxk9pjK2dbrfGq6eyw1JaZDTAiK
+TQRKjwzfIyzecxWQW7PXBYh12G7a82sJMIQdEQ+wCKpOHDZ/BPmGUaSX
+-----END RSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp
new file mode 100644
index 00000000000..b0188f744cd
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp
@@ -0,0 +1 @@
+01:8d:df:4c:ac:4a:94:eb:27:97:cb:94:fd:cb:7a:15
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp.bb b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp.bb
new file mode 100644
index 00000000000..eafc066a66c
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.fp.bb
@@ -0,0 +1 @@
+xekar-cohun-vigov-suzus-filiv-vomit-dobor-kimuk-bekop-rinal-hexox
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.n b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.n
new file mode 100644
index 00000000000..891f02072be
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.n
@@ -0,0 +1 @@
+00e3c0b3fe1190bc47d4b2039bc00668ef79c16bf6a99581ef52e14981c4c93975d6466a884ade12d9a03661167fbd2128e5df175530ea425b31843150b757c8ef6377ae58ccbadfc32debfde8ccf20a20941633fd53473b9981d187959971c1817d30fa11c042dd78436b8ce7256b1f6f21c4d1449d62b5a345abf7ee9e7efff650dc5e64364e9de73c3d96f447ca5d53e9bee2bb1dfbe495986d6569c1cf9ba574484bb11d64d40a902221268505056cb73b7be0ee2f65798e6d3ad6e2000cd647b71c13fdcc3ca3f02bfa591d67ed2553e0054370ad33d1ecafdfbe252174c5a657d777373e1806bbb6cbcedde07889b5edc3d0e5c0ae85273f10e51ad6d37d
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.p b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.p
new file mode 100644
index 00000000000..e0933e108b1
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.p
@@ -0,0 +1 @@
+00fa5bb8c72aa3b7f4c63658ea9c7aa8346deddace9bb8446ee31e2966ec8a130d2e57ed2751db85f1c46e743109d85220290d87818703a530d6183c3059c8100f304d1b7a74783654a924a3e465bc4daea8bdd2621524caa4ed4c0e9942663cbf885378d4e8aec40a964de8deb1317c99d3ade3440c1fb1348acc4f8193972c27
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.q b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.q
new file mode 100644
index 00000000000..62fc2107653
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.param.q
@@ -0,0 +1 @@
+00e8e292cca64a0bf1117a32233280ca6b05dcafe1f152e0b30d4cc8f487b265b39bdabf5afa1b64dd2373b3ce2f7a400e2988c5d2bc28387ab4363117e4f9db36b61209ca64639c5303e320ae7be24827c33f89cbc69569a98f8fd3e9f0d0a2ace2d044976e89040cf3aae2edd21485ce281c137a11c2a743867afd94a27eb5bb
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.pub b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.pub
new file mode 100644
index 00000000000..9af3bf39f7d
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_2.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjwLP+EZC8R9SyA5vABmjvecFr9qmVge9S4UmBxMk5ddZGaohK3hLZoDZhFn+9ISjl3xdVMOpCWzGEMVC3V8jvY3euWMy638Mt6/3ozPIKIJQWM/1TRzuZgdGHlZlxwYF9MPoRwELdeENrjOclax9vIcTRRJ1itaNFq/funn7/9lDcXmQ2Tp3nPD2W9EfKXVPpvuK7HfvklZhtZWnBz5uldEhLsR1k1AqQIiEmhQUFbLc7e+DuL2V5jm061uIADNZHtxwT/cw8o/Ar+lkdZ+0lU+AFQ3CtM9Hsr9++JSF0xaZX13c3PhgGu7bLzt3geIm17cPQ5cCuhSc/EOUa1tN9 RSA test key #2
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n
new file mode 100644
index 00000000000..a84a9e2eb7d
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIByQIBAAJhAKAJGOfpr4S2inakOMcqjGQ1RLNwp4FWvWYc+xxnAqfJS7vwZ8ie
+2fcniZMS69o9CXiACUw2LYbNGZMfrnzjQEaKlObDi5HB1XNE+9z01m2GS9XH+Eg0
+ilNeAx/hfNEDVQIDAQABAmB8O3OtHHhXYskMHqHA4qPHap6hWZN+0RIIQfkhbEng
+bGAxTgeS8tWrinK+zFJwwS3tYmSc8YfT/4gX/DG1nudv+Pjjhwom/HMTiK/Tw4JN
+ZhWCPKB8T1rICkGAtbMq2KECMQDTa9o6g/Nb2zkvJq+04SQ5ivqZdWXaeZixz1Xt
+JKgqRLoMxny81E/LaeeKXfNACE0CMQDBx4hGEBlm8aJwj6SdZ50Ulu8c4hz4ZcJo
+v2T+BY8ogmlaF1ADcFXeHDmE7Cg16ykCMF7zTCIFirERRqBXdof8qSEyupNa9zBk
+deA9ZrDHSsMY9JmyNukzTNblLDinMwzp7QIwUq/O4X6rKDdBhmB08MmuyINjQuLl
+U8UwQLwy3wYGQVXsmInMFbuQmHdYv/R5cBCJAjAquE/FnCRxuI2NEhoqrO3FG0wO
+cByLc/Svz1ct3eGUMabUxfQdi8Ka97gv9CW9EbI=
+-----END RSA PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n_pw b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n_pw
new file mode 100644
index 00000000000..1f8b01b2c75
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/testdata/rsa_n_pw
@@ -0,0 +1,14 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAXd4Cj36
+3zRAFUwdBRAs0yAAAAEAAAAAEAAAB3AAAAB3NzaC1yc2EAAAADAQABAAAAYQCgCRjn6a+E
+top2pDjHKoxkNUSzcKeBVr1mHPscZwKnyUu78GfIntn3J4mTEuvaPQl4gAlMNi2GzRmTH6
+5840BGipTmw4uRwdVzRPvc9NZthkvVx/hINIpTXgMf4XzRA1UAAAGQYoRrooXzXUXdgJVU
+6oeuIcZiBeomdRKu5LrGZF3l2TjLy51+OzJI3ML7f61QneTh8YF8p0UIu6hUM14kifbTse
+qPJZPiLcSM0wbqQz/TRsWwC02wNo4nrHOHwLhqog1l5R52+Ac9O3axuA8t5zfqEMbU8tNE
+GR090/TL1dSQ8z9sHa2ofzODqyuNQZRLKWwhVq/auUiaaUYdTi5i5lInVc9iHaEoCvvp0k
+maG34o4GMHrrp857EmhTL7BrOa5VKYnHW9A3eHcf3JvDNR0crt5ER0wvmivPVr4efy9Cln
+sNBCtZ8rvgsABgM6U6DneX92IogICQGT6nRfyttsMXPO6wt0HUTUAXuD90IAjBueJSvMIO
+g5os68pBvL5rDuB2XCasBIJU27f4NnDQ3aPoSzBA+UgluUs5iWP9+FakY4cQ1cH6tMXGDM
+yW/hSSGzLWukKnFj2XX41boSdH53ZJamL3OoM+ApKSKryOvpTGHQexuFdp1jlZbemKZwBM
+5R7E70V2EaRAxqkRzJyHBQtWIoVQ==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/usr.bin/ssh/unittests/sshkey/tests.c b/regress/usr.bin/ssh/unittests/sshkey/tests.c
new file mode 100644
index 00000000000..df7f4a596d4
--- /dev/null
+++ b/regress/usr.bin/ssh/unittests/sshkey/tests.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include <openssl/evp.h>
+
+#include "test_helper.h"
+
+void sshkey_tests(void);
+void sshkey_file_tests(void);
+void sshkey_fuzz_tests(void);
+
+void
+tests(void)
+{
+ OpenSSL_add_all_algorithms();
+ ERR_load_CRYPTO_strings();
+
+ sshkey_tests();
+ sshkey_file_tests();
+ sshkey_fuzz_tests();
+}