summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 12:13:50 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 12:13:50 +0100
commit487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (patch)
treea2cff6fec1e6c4b4153a170a3e172cfe6bfdec46 /regress
parent796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (diff)
parent28453d58058a4d60c3ebe7d7f0c31a510cbf6158 (diff)
Import openssh_6.7p1.orig.tar.gz
Diffstat (limited to 'regress')
-rw-r--r--regress/Makefile12
-rw-r--r--regress/connect-privsep.sh4
-rw-r--r--regress/dhgex.sh6
-rw-r--r--regress/forwarding.sh22
-rw-r--r--regress/integrity.sh13
-rw-r--r--regress/kextype.sh7
-rw-r--r--regress/krl.sh5
-rw-r--r--regress/login-timeout.sh3
-rw-r--r--regress/multiplex.sh76
-rw-r--r--regress/proxy-connect.sh29
-rw-r--r--regress/rekey.sh20
-rw-r--r--regress/test-exec.sh11
-rw-r--r--regress/try-ciphers.sh7
-rw-r--r--regress/unittests/Makefile5
-rw-r--r--regress/unittests/Makefile.inc59
-rw-r--r--regress/unittests/sshbuf/Makefile14
-rw-r--r--regress/unittests/sshbuf/test_sshbuf.c240
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fixed.c126
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_fuzz.c127
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_basic.c484
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_crypto.c409
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c130
-rw-r--r--regress/unittests/sshbuf/test_sshbuf_misc.c138
-rw-r--r--regress/unittests/sshbuf/tests.c28
-rw-r--r--regress/unittests/sshkey/Makefile13
-rw-r--r--regress/unittests/sshkey/common.c84
-rw-r--r--regress/unittests/sshkey/common.h16
-rwxr-xr-xregress/unittests/sshkey/mktestdata.sh190
-rw-r--r--regress/unittests/sshkey/test_file.c457
-rw-r--r--regress/unittests/sshkey/test_fuzz.c406
-rw-r--r--regress/unittests/sshkey/test_sshkey.c357
-rw-r--r--regress/unittests/sshkey/testdata/dsa_112
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1-cert.fp1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1-cert.pub1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.fp1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.param.g1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.param.priv1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.param.pub1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1.pub1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_1_pw15
-rw-r--r--regress/unittests/sshkey/testdata/dsa_212
-rw-r--r--regress/unittests/sshkey/testdata/dsa_2.fp1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_2.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_2.pub1
-rw-r--r--regress/unittests/sshkey/testdata/dsa_n12
-rw-r--r--regress/unittests/sshkey/testdata/dsa_n_pw22
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_15
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1-cert.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1-cert.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.param.curve1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.param.priv1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.param.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_1_pw8
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_27
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.param.curve1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.param.priv1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.param.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_2.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_n5
-rw-r--r--regress/unittests/sshkey/testdata/ecdsa_n_pw9
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_17
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1-cert.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1-cert.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1.pub1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_1_pw8
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_27
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_2.fp1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_2.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/ed25519_2.pub1
-rw-r--r--regress/unittests/sshkey/testdata/pw1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1bin0 -> 421 bytes
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1.fp1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1.param.n1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1.pub1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_1_pwbin0 -> 421 bytes
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2bin0 -> 981 bytes
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2.fp1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2.param.n1
-rw-r--r--regress/unittests/sshkey/testdata/rsa1_2.pub1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_112
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1-cert.fp1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1-cert.pub1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.fp1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.param.n1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.param.p1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.param.q1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1.pub1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_1_pw15
-rw-r--r--regress/unittests/sshkey/testdata/rsa_227
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.fp1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.fp.bb1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.param.n1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.param.p1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.param.q1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_2.pub1
-rw-r--r--regress/unittests/sshkey/testdata/rsa_n12
-rw-r--r--regress/unittests/sshkey/testdata/rsa_n_pw14
-rw-r--r--regress/unittests/sshkey/tests.c27
-rw-r--r--regress/unittests/test_helper/Makefile13
-rw-r--r--regress/unittests/test_helper/fuzz.c378
-rw-r--r--regress/unittests/test_helper/test_helper.c471
-rw-r--r--regress/unittests/test_helper/test_helper.h292
113 files changed, 4900 insertions, 44 deletions
diff --git a/regress/Makefile b/regress/Makefile
index 6e3b8d634..3feb7a997 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,6 +1,6 @@
1# $OpenBSD: Makefile,v 1.68 2014/01/25 04:35:32 dtucker Exp $ 1# $OpenBSD: Makefile,v 1.70 2014/06/24 01:14:17 djm Exp $
2 2
3REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec 3REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec
4tests: $(REGRESS_TARGETS) 4tests: $(REGRESS_TARGETS)
5 5
6# Interop tests are not run by default 6# Interop tests are not run by default
@@ -180,3 +180,11 @@ t-exec-interop: ${INTEROP_TESTS:=.sh}
180 180
181# Not run by default 181# Not run by default
182interop: ${INTEROP_TARGETS} 182interop: ${INTEROP_TARGETS}
183
184# Unit tests, built by top-level Makefile
185unit:
186 set -e ; if test -z "${SKIP_UNIT}" ; then \
187 ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \
188 ${.OBJDIR}/unittests/sshkey/test_sshkey \
189 -d ${.CURDIR}//unittests/sshkey/testdata ; \
190 fi
diff --git a/regress/connect-privsep.sh b/regress/connect-privsep.sh
index 94cc64acf..41cb7af69 100644
--- a/regress/connect-privsep.sh
+++ b/regress/connect-privsep.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: connect-privsep.sh,v 1.4 2012/07/02 14:37:06 dtucker Exp $ 1# $OpenBSD: connect-privsep.sh,v 1.5 2014/05/04 10:40:59 logan Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="proxy connect with privsep" 4tid="proxy connect with privsep"
@@ -26,7 +26,7 @@ done
26 26
27# Because sandbox is sensitive to changes in libc, especially malloc, retest 27# Because sandbox is sensitive to changes in libc, especially malloc, retest
28# with every malloc.conf option (and none). 28# with every malloc.conf option (and none).
29for m in '' A F G H J P R S X Z '<' '>'; do 29for m in '' A F G H J P R S X '<' '>'; do
30 for p in 1 2; do 30 for p in 1 2; do
31 env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true 31 env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
32 if [ $? -ne 0 ]; then 32 if [ $? -ne 0 ]; then
diff --git a/regress/dhgex.sh b/regress/dhgex.sh
index 4c1a3d83c..57fca4a32 100644
--- a/regress/dhgex.sh
+++ b/regress/dhgex.sh
@@ -1,10 +1,11 @@
1# $OpenBSD: dhgex.sh,v 1.1 2014/01/25 04:35:32 dtucker Exp $ 1# $OpenBSD: dhgex.sh,v 1.2 2014/04/21 22:15:37 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="dhgex" 4tid="dhgex"
5 5
6LOG=${TEST_SSH_LOGFILE} 6LOG=${TEST_SSH_LOGFILE}
7rm -f ${LOG} 7rm -f ${LOG}
8cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
8 9
9kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange` 10kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange`
10 11
@@ -14,6 +15,9 @@ ssh_test_dhgex()
14 cipher="$1"; shift 15 cipher="$1"; shift
15 kex="$1"; shift 16 kex="$1"; shift
16 17
18 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
19 echo "KexAlgorithms=$kex" >> $OBJ/sshd_proxy
20 echo "Ciphers=$cipher" >> $OBJ/sshd_proxy
17 rm -f ${LOG} 21 rm -f ${LOG}
18 opts="-oKexAlgorithms=$kex -oCiphers=$cipher" 22 opts="-oKexAlgorithms=$kex -oCiphers=$cipher"
19 groupsz="1024<$bits<8192" 23 groupsz="1024<$bits<8192"
diff --git a/regress/forwarding.sh b/regress/forwarding.sh
index 94873f22c..f799d4951 100644
--- a/regress/forwarding.sh
+++ b/regress/forwarding.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: forwarding.sh,v 1.11 2013/06/10 21:56:43 dtucker Exp $ 1# $OpenBSD: forwarding.sh,v 1.12 2014/07/15 15:54:15 millert Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="local and remote forwarding" 4tid="local and remote forwarding"
@@ -28,7 +28,7 @@ for p in 1 2; do
28 trace "transfer over forwarded channels and check result" 28 trace "transfer over forwarded channels and check result"
29 ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ 29 ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \
30 somehost cat ${DATA} > ${COPY} 30 somehost cat ${DATA} > ${COPY}
31 test -f ${COPY} || fail "failed copy of ${DATA}" 31 test -s ${COPY} || fail "failed copy of ${DATA}"
32 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" 32 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
33 33
34 sleep 10 34 sleep 10
@@ -114,8 +114,24 @@ for p in 1 2; do
114 trace "config file: transfer over forwarded channels and check result" 114 trace "config file: transfer over forwarded channels and check result"
115 ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ 115 ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
116 somehost cat ${DATA} > ${COPY} 116 somehost cat ${DATA} > ${COPY}
117 test -f ${COPY} || fail "failed copy of ${DATA}" 117 test -s ${COPY} || fail "failed copy of ${DATA}"
118 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" 118 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
119 119
120 wait 120 wait
121done 121done
122
123for p in 2; do
124 trace "transfer over chained unix domain socket forwards and check result"
125 rm -f $OBJ/unix-[123].fwd
126 ${SSH} -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10
127 ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10
128 ${SSH} -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10
129 ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10
130 ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \
131 somehost cat ${DATA} > ${COPY}
132 test -s ${COPY} || fail "failed copy ${DATA}"
133 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
134
135 #wait
136 sleep 10
137done
diff --git a/regress/integrity.sh b/regress/integrity.sh
index 852d82690..d3a489ff7 100644
--- a/regress/integrity.sh
+++ b/regress/integrity.sh
@@ -1,7 +1,8 @@
1# $OpenBSD: integrity.sh,v 1.12 2013/11/21 03:18:51 djm Exp $ 1# $OpenBSD: integrity.sh,v 1.14 2014/05/21 07:04:21 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="integrity" 4tid="integrity"
5cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
5 6
6# start at byte 2900 (i.e. after kex) and corrupt at different offsets 7# start at byte 2900 (i.e. after kex) and corrupt at different offsets
7# XXX the test hangs if we modify the low bytes of the packet length 8# XXX the test hangs if we modify the low bytes of the packet length
@@ -34,11 +35,15 @@ for m in $macs; do
34 # avoid modifying the high bytes of the length 35 # avoid modifying the high bytes of the length
35 continue 36 continue
36 fi 37 fi
38 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
37 # modify output from sshd at offset $off 39 # modify output from sshd at offset $off
38 pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1" 40 pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1"
39 if ssh -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then 41 if ssh -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then
42 echo "Ciphers=$m" >> $OBJ/sshd_proxy
40 macopt="-c $m" 43 macopt="-c $m"
41 else 44 else
45 echo "Ciphers=aes128-ctr" >> $OBJ/sshd_proxy
46 echo "MACs=$m" >> $OBJ/sshd_proxy
42 macopt="-m $m -c aes128-ctr" 47 macopt="-m $m -c aes128-ctr"
43 fi 48 fi
44 verbose "test $tid: $m @$off" 49 verbose "test $tid: $m @$off"
@@ -49,14 +54,14 @@ for m in $macs; do
49 fail "ssh -m $m succeeds with bit-flip at $off" 54 fail "ssh -m $m succeeds with bit-flip at $off"
50 fi 55 fi
51 ecnt=`expr $ecnt + 1` 56 ecnt=`expr $ecnt + 1`
52 output=$(tail -2 $TEST_SSH_LOGFILE | egrep -v "^debug" | \ 57 out=$(tail -2 $TEST_SSH_LOGFILE | egrep -v "^debug" | \
53 tr -s '\r\n' '.') 58 tr -s '\r\n' '.')
54 case "$output" in 59 case "$out" in
55 Bad?packet*) elen=`expr $elen + 1`; skip=3;; 60 Bad?packet*) elen=`expr $elen + 1`; skip=3;;
56 Corrupted?MAC* | Decryption?integrity?check?failed*) 61 Corrupted?MAC* | Decryption?integrity?check?failed*)
57 emac=`expr $emac + 1`; skip=0;; 62 emac=`expr $emac + 1`; skip=0;;
58 padding*) epad=`expr $epad + 1`; skip=0;; 63 padding*) epad=`expr $epad + 1`; skip=0;;
59 *) fail "unexpected error mac $m at $off";; 64 *) fail "unexpected error mac $m at $off: $out";;
60 esac 65 esac
61 done 66 done
62 verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen" 67 verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen"
diff --git a/regress/kextype.sh b/regress/kextype.sh
index 8c2ac09d6..6f952f4e4 100644
--- a/regress/kextype.sh
+++ b/regress/kextype.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: kextype.sh,v 1.4 2013/11/07 04:26:56 dtucker Exp $ 1# $OpenBSD: kextype.sh,v 1.5 2014/04/21 22:15:37 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="login with different key exchange algorithms" 4tid="login with different key exchange algorithms"
@@ -7,6 +7,11 @@ TIME=/usr/bin/time
7cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 7cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
8cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak 8cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
9 9
10# Make server accept all key exchanges.
11ALLKEX=`ssh -Q kex`
12KEXOPT=`echo $ALLKEX | tr ' ' ,`
13echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy
14
10tries="1 2 3 4" 15tries="1 2 3 4"
11for k in `${SSH} -Q kex`; do 16for k in `${SSH} -Q kex`; do
12 verbose "kex $k" 17 verbose "kex $k"
diff --git a/regress/krl.sh b/regress/krl.sh
index 09246371c..287384b4a 100644
--- a/regress/krl.sh
+++ b/regress/krl.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: krl.sh,v 1.2 2013/11/21 03:15:46 djm Exp $ 1# $OpenBSD: krl.sh,v 1.3 2014/06/24 01:04:43 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="key revocation lists" 4tid="key revocation lists"
@@ -37,6 +37,9 @@ serial: 700-797
37serial: 798 37serial: 798
38serial: 799 38serial: 799
39serial: 599-701 39serial: 599-701
40# Some multiple consecutive serial number ranges
41serial: 10000-20000
42serial: 30000-40000
40EOF 43EOF
41 44
42# A specification that revokes some certificated by key ID. 45# A specification that revokes some certificated by key ID.
diff --git a/regress/login-timeout.sh b/regress/login-timeout.sh
index d9b48f391..eb76f554b 100644
--- a/regress/login-timeout.sh
+++ b/regress/login-timeout.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: login-timeout.sh,v 1.6 2014/02/27 20:04:16 djm Exp $ 1# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="connect after login grace timeout" 4tid="connect after login grace timeout"
@@ -22,6 +22,7 @@ $SUDO kill `$SUDO cat $PIDFILE`
22trace "test login grace without privsep" 22trace "test login grace without privsep"
23echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config 23echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
24start_sshd 24start_sshd
25sleep 1
25 26
26(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & 27(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
27sleep 15 28sleep 15
diff --git a/regress/multiplex.sh b/regress/multiplex.sh
index 3e697e691..8ee140be6 100644
--- a/regress/multiplex.sh
+++ b/regress/multiplex.sh
@@ -1,10 +1,26 @@
1# $OpenBSD: multiplex.sh,v 1.21 2013/05/17 04:29:14 dtucker Exp $ 1# $OpenBSD: multiplex.sh,v 1.25 2014/07/22 01:32:12 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4CTL=/tmp/openssh.regress.ctl-sock.$$ 4CTL=/tmp/openssh.regress.ctl-sock.$$
5 5
6tid="connection multiplexing" 6tid="connection multiplexing"
7 7
8if have_prog nc ; then
9 if nc -h 2>&1 | grep -- -N >/dev/null; then
10 NC="nc -N";
11 elif nc -h 2>&1 | grep -- "-U.*Use UNIX" >/dev/null ; then
12 NC="nc"
13 else
14 echo "nc is incompatible"
15 fi
16fi
17
18if test -z "$NC" ; then
19 echo "skipped (no compatible nc found)"
20 exit 0
21fi
22
23trace "will use ProxyCommand $proxycmd"
8if config_defined DISABLE_FD_PASSING ; then 24if config_defined DISABLE_FD_PASSING ; then
9 echo "skipped (not supported on this platform)" 25 echo "skipped (not supported on this platform)"
10 exit 0 26 exit 0
@@ -29,7 +45,8 @@ start_mux_master()
29 trace "start master, fork to background" 45 trace "start master, fork to background"
30 ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \ 46 ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \
31 -E $TEST_REGRESS_LOGFILE 2>&1 & 47 -E $TEST_REGRESS_LOGFILE 2>&1 &
32 MASTER_PID=$! 48 # NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors.
49 SSH_PID=$!
33 wait_for_mux_master_ready 50 wait_for_mux_master_ready
34} 51}
35 52
@@ -71,6 +88,25 @@ test -f ${COPY} || fail "scp: failed copy ${DATA}"
71cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" 88cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}"
72 89
73rm -f ${COPY} 90rm -f ${COPY}
91verbose "test $tid: forward"
92trace "forward over TCP/IP and check result"
93$NC -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} &
94netcat_pid=$!
95${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1
96$NC -d 127.0.0.1 $((${PORT} + 2)) > ${COPY} < /dev/null
97cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
98kill $netcat_pid 2>/dev/null
99rm -f ${COPY} $OBJ/unix-[123].fwd
100
101trace "forward over UNIX and check result"
102$NC -Ul $OBJ/unix-1.fwd < ${DATA} &
103netcat_pid=$!
104${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
105${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
106$NC -d -U $OBJ/unix-3.fwd > ${COPY} </dev/null
107cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
108kill $netcat_pid 2>/dev/null
109rm -f ${COPY} $OBJ/unix-[123].fwd
74 110
75for s in 0 1 4 5 44; do 111for s in 0 1 4 5 44; do
76 trace "exit status $s over multiplexed connection" 112 trace "exit status $s over multiplexed connection"
@@ -95,7 +131,7 @@ verbose "test $tid: cmd check"
95${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ 131${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
96 || fail "check command failed" 132 || fail "check command failed"
97 133
98verbose "test $tid: cmd forward local" 134verbose "test $tid: cmd forward local (TCP)"
99${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \ 135${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \
100 || fail "request local forward failed" 136 || fail "request local forward failed"
101${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 137${SSH} -F $OBJ/ssh_config -p$P otherhost true \
@@ -105,7 +141,7 @@ ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \
105${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 141${SSH} -F $OBJ/ssh_config -p$P otherhost true \
106 && fail "local forward port still listening" 142 && fail "local forward port still listening"
107 143
108verbose "test $tid: cmd forward remote" 144verbose "test $tid: cmd forward remote (TCP)"
109${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \ 145${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \
110 || fail "request remote forward failed" 146 || fail "request remote forward failed"
111${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 147${SSH} -F $OBJ/ssh_config -p$P otherhost true \
@@ -115,13 +151,35 @@ ${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \
115${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 151${SSH} -F $OBJ/ssh_config -p$P otherhost true \
116 && fail "remote forward port still listening" 152 && fail "remote forward port still listening"
117 153
154verbose "test $tid: cmd forward local (UNIX)"
155${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
156 || fail "request local forward failed"
157echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \
158 || fail "connect to local forward path failed"
159${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
160 || fail "cancel local forward failed"
161N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
162test ${N} -eq 0 || fail "local forward path still listening"
163rm -f $OBJ/unix-1.fwd
164
165verbose "test $tid: cmd forward remote (UNIX)"
166${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
167 || fail "request remote forward failed"
168echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \
169 || fail "connect to remote forwarded path failed"
170${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
171 || fail "cancel remote forward failed"
172N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
173test ${N} -eq 0 || fail "remote forward path still listening"
174rm -f $OBJ/unix-1.fwd
175
118verbose "test $tid: cmd exit" 176verbose "test $tid: cmd exit"
119${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ 177${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
120 || fail "send exit command failed" 178 || fail "send exit command failed"
121 179
122# Wait for master to exit 180# Wait for master to exit
123wait $MASTER_PID 181wait $SSH_PID
124kill -0 $MASTER_PID >/dev/null 2>&1 && fail "exit command failed" 182kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed"
125 183
126# Restart master and test -O stop command with master using -N 184# Restart master and test -O stop command with master using -N
127verbose "test $tid: cmd stop" 185verbose "test $tid: cmd stop"
@@ -138,6 +196,8 @@ ${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1
138# wait until both long-running command and master have exited. 196# wait until both long-running command and master have exited.
139wait $SLEEP_PID 197wait $SLEEP_PID
140[ $! != 0 ] || fail "waiting for concurrent command" 198[ $! != 0 ] || fail "waiting for concurrent command"
141wait $MASTER_PID 199wait $SSH_PID
142[ $! != 0 ] || fail "waiting for master stop" 200[ $! != 0 ] || fail "waiting for master stop"
143kill -0 $MASTER_PID >/dev/null 2>&1 && fail "stop command failed" 201kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed"
202SSH_PID="" # Already gone, so don't kill in cleanup
203
diff --git a/regress/proxy-connect.sh b/regress/proxy-connect.sh
index 76e602dd6..023ba7367 100644
--- a/regress/proxy-connect.sh
+++ b/regress/proxy-connect.sh
@@ -1,26 +1,31 @@
1# $OpenBSD: proxy-connect.sh,v 1.6 2013/03/07 00:20:34 djm Exp $ 1# $OpenBSD: proxy-connect.sh,v 1.7 2014/05/03 18:46:14 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="proxy connect" 4tid="proxy connect"
5 5
6verbose "plain username" 6mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
7for p in 1 2; do 7
8 ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true 8for ps in no yes; do
9 if [ $? -ne 0 ]; then 9 cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
10 fail "ssh proxyconnect protocol $p failed" 10 echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
11 fi 11
12 SSH_CONNECTION=`${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 'echo $SSH_CONNECTION'` 12 for p in 1 2; do
13 for c in no yes; do
14 verbose "plain username protocol $p privsep=$ps comp=$c"
15 opts="-$p -oCompression=$c -F $OBJ/ssh_proxy"
16 SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
13 if [ $? -ne 0 ]; then 17 if [ $? -ne 0 ]; then
14 fail "ssh proxyconnect protocol $p failed" 18 fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed"
15 fi 19 fi
16 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then 20 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
17 fail "bad SSH_CONNECTION" 21 fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c"
18 fi 22 fi
23 done
24 done
19done 25done
20 26
21verbose "username with style"
22for p in 1 2; do 27for p in 1 2; do
28 verbose "username with style protocol $p"
23 ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ 29 ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \
24 fail "ssh proxyconnect protocol $p failed" 30 fail "ssh proxyconnect protocol $p failed"
25done 31done
26
diff --git a/regress/rekey.sh b/regress/rekey.sh
index cf9401ea0..fd452b034 100644
--- a/regress/rekey.sh
+++ b/regress/rekey.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: rekey.sh,v 1.14 2013/11/21 03:18:51 djm Exp $ 1# $OpenBSD: rekey.sh,v 1.15 2014/04/21 22:15:37 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="rekey" 4tid="rekey"
@@ -6,14 +6,22 @@ tid="rekey"
6LOG=${TEST_SSH_LOGFILE} 6LOG=${TEST_SSH_LOGFILE}
7 7
8rm -f ${LOG} 8rm -f ${LOG}
9cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
9 10
10# Test rekeying based on data volume only. 11# Test rekeying based on data volume only.
11# Arguments will be passed to ssh. 12# Arguments will be passed to ssh.
12ssh_data_rekeying() 13ssh_data_rekeying()
13{ 14{
15 _kexopt=$1 ; shift
16 _opts="$@"
17 if ! test -z "$_kexopts" ; then
18 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
19 echo "$_kexopt" >> $OBJ/sshd_proxy
20 _opts="$_opts -o$_kexopt"
21 fi
14 rm -f ${COPY} ${LOG} 22 rm -f ${COPY} ${LOG}
15 ${SSH} <${DATA} -oCompression=no $@ -v -F $OBJ/ssh_proxy somehost \ 23 _opts="$_opts -oCompression=no"
16 "cat > ${COPY}" 24 ${SSH} <${DATA} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}"
17 if [ $? -ne 0 ]; then 25 if [ $? -ne 0 ]; then
18 fail "ssh failed ($@)" 26 fail "ssh failed ($@)"
19 fi 27 fi
@@ -41,7 +49,7 @@ done
41 49
42for opt in $opts; do 50for opt in $opts; do
43 verbose "client rekey $opt" 51 verbose "client rekey $opt"
44 ssh_data_rekeying -oRekeyLimit=256k -o$opt 52 ssh_data_rekeying "$opt" -oRekeyLimit=256k
45done 53done
46 54
47# AEAD ciphers are magical so test with all KexAlgorithms 55# AEAD ciphers are magical so test with all KexAlgorithms
@@ -49,14 +57,14 @@ if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then
49 for c in `${SSH} -Q cipher-auth`; do 57 for c in `${SSH} -Q cipher-auth`; do
50 for kex in `${SSH} -Q kex`; do 58 for kex in `${SSH} -Q kex`; do
51 verbose "client rekey $c $kex" 59 verbose "client rekey $c $kex"
52 ssh_data_rekeying -oRekeyLimit=256k -oCiphers=$c -oKexAlgorithms=$kex 60 ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c
53 done 61 done
54 done 62 done
55fi 63fi
56 64
57for s in 16 1k 128k 256k; do 65for s in 16 1k 128k 256k; do
58 verbose "client rekeylimit ${s}" 66 verbose "client rekeylimit ${s}"
59 ssh_data_rekeying -oCompression=no -oRekeyLimit=$s 67 ssh_data_rekeying "" -oCompression=no -oRekeyLimit=$s
60done 68done
61 69
62for s in 5 10; do 70for s in 5 10; do
diff --git a/regress/test-exec.sh b/regress/test-exec.sh
index aac8aa5c2..a1bab832f 100644
--- a/regress/test-exec.sh
+++ b/regress/test-exec.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: test-exec.sh,v 1.47 2013/11/09 05:41:34 dtucker Exp $ 1# $OpenBSD: test-exec.sh,v 1.48 2014/07/06 07:42:03 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4#SUDO=sudo 4#SUDO=sudo
@@ -240,13 +240,20 @@ md5 () {
240# helper 240# helper
241cleanup () 241cleanup ()
242{ 242{
243 if [ "x$SSH_PID" != "x" ]; then
244 if [ $SSH_PID -lt 2 ]; then
245 echo bad pid for ssh: $SSH_PID
246 else
247 kill $SSH_PID
248 fi
249 fi
243 if [ -f $PIDFILE ]; then 250 if [ -f $PIDFILE ]; then
244 pid=`$SUDO cat $PIDFILE` 251 pid=`$SUDO cat $PIDFILE`
245 if [ "X$pid" = "X" ]; then 252 if [ "X$pid" = "X" ]; then
246 echo no sshd running 253 echo no sshd running
247 else 254 else
248 if [ $pid -lt 2 ]; then 255 if [ $pid -lt 2 ]; then
249 echo bad pid for ssh: $pid 256 echo bad pid for sshd: $pid
250 else 257 else
251 $SUDO kill $pid 258 $SUDO kill $pid
252 trace "wait for sshd to exit" 259 trace "wait for sshd to exit"
diff --git a/regress/try-ciphers.sh b/regress/try-ciphers.sh
index ac34cedbf..2881ce16c 100644
--- a/regress/try-ciphers.sh
+++ b/regress/try-ciphers.sh
@@ -1,13 +1,18 @@
1# $OpenBSD: try-ciphers.sh,v 1.22 2013/11/21 03:18:51 djm Exp $ 1# $OpenBSD: try-ciphers.sh,v 1.23 2014/04/21 22:15:37 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="try ciphers" 4tid="try ciphers"
5 5
6cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
7
6for c in `${SSH} -Q cipher`; do 8for c in `${SSH} -Q cipher`; do
7 n=0 9 n=0
8 for m in `${SSH} -Q mac`; do 10 for m in `${SSH} -Q mac`; do
9 trace "proto 2 cipher $c mac $m" 11 trace "proto 2 cipher $c mac $m"
10 verbose "test $tid: proto 2 cipher $c mac $m" 12 verbose "test $tid: proto 2 cipher $c mac $m"
13 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
14 echo "Ciphers=$c" >> $OBJ/sshd_proxy
15 echo "MACs=$m" >> $OBJ/sshd_proxy
11 ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true 16 ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true
12 if [ $? -ne 0 ]; then 17 if [ $? -ne 0 ]; then
13 fail "ssh -2 failed with mac $m cipher $c" 18 fail "ssh -2 failed with mac $m cipher $c"
diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile
new file mode 100644
index 000000000..bdb4574e2
--- /dev/null
+++ b/regress/unittests/Makefile
@@ -0,0 +1,5 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3SUBDIR= test_helper sshbuf sshkey
4
5.include <bsd.subdir.mk>
diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc
new file mode 100644
index 000000000..4c3363749
--- /dev/null
+++ b/regress/unittests/Makefile.inc
@@ -0,0 +1,59 @@
1# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3.include <bsd.own.mk>
4.include <bsd.obj.mk>
5
6# enable warnings
7WARNINGS=Yes
8
9DEBUG=-g
10CFLAGS+= -fstack-protector-all
11CDIAGFLAGS= -Wall
12CDIAGFLAGS+= -Wextra
13CDIAGFLAGS+= -Werror
14CDIAGFLAGS+= -Wchar-subscripts
15CDIAGFLAGS+= -Wcomment
16CDIAGFLAGS+= -Wformat
17CDIAGFLAGS+= -Wformat-security
18CDIAGFLAGS+= -Wimplicit
19CDIAGFLAGS+= -Winline
20CDIAGFLAGS+= -Wmissing-declarations
21CDIAGFLAGS+= -Wmissing-prototypes
22CDIAGFLAGS+= -Wparentheses
23CDIAGFLAGS+= -Wpointer-arith
24CDIAGFLAGS+= -Wpointer-sign
25CDIAGFLAGS+= -Wreturn-type
26CDIAGFLAGS+= -Wshadow
27CDIAGFLAGS+= -Wsign-compare
28CDIAGFLAGS+= -Wstrict-aliasing
29CDIAGFLAGS+= -Wstrict-prototypes
30CDIAGFLAGS+= -Wswitch
31CDIAGFLAGS+= -Wtrigraphs
32CDIAGFLAGS+= -Wuninitialized
33CDIAGFLAGS+= -Wunused
34.if ${COMPILER_VERSION} == "gcc4"
35CDIAGFLAGS+= -Wold-style-definition
36.endif
37
38SSHREL=../../../../../usr.bin/ssh
39
40CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL}
41
42.if exists(${.CURDIR}/../test_helper/${__objdir})
43LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper
44DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a
45.else
46LDADD+=-L${.CURDIR}/../test_helper -ltest_helper
47DPADD+=${.CURDIR}/../test_helper/libtest_helper.a
48.endif
49
50.if exists(${.CURDIR}/${SSHREL}/lib/${__objdir})
51LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh
52DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a
53.else
54LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh
55DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a
56.endif
57
58LDADD+= -lcrypto
59DPADD+= ${LIBCRYPTO}
diff --git a/regress/unittests/sshbuf/Makefile b/regress/unittests/sshbuf/Makefile
new file mode 100644
index 000000000..85f99ac38
--- /dev/null
+++ b/regress/unittests/sshbuf/Makefile
@@ -0,0 +1,14 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3PROG=test_sshbuf
4SRCS=tests.c
5SRCS+=test_sshbuf.c
6SRCS+=test_sshbuf_getput_basic.c
7SRCS+=test_sshbuf_getput_crypto.c
8SRCS+=test_sshbuf_misc.c
9SRCS+=test_sshbuf_fuzz.c
10SRCS+=test_sshbuf_getput_fuzz.c
11SRCS+=test_sshbuf_fixed.c
12
13.include <bsd.regress.mk>
14
diff --git a/regress/unittests/sshbuf/test_sshbuf.c b/regress/unittests/sshbuf/test_sshbuf.c
new file mode 100644
index 000000000..ee77d6934
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf.c
@@ -0,0 +1,240 @@
1/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#define SSHBUF_INTERNAL 1 /* access internals for testing */
9#include "includes.h"
10
11#include <sys/types.h>
12#include <sys/param.h>
13#include <stdio.h>
14#ifdef HAVE_STDINT_H
15# include <stdint.h>
16#endif
17#include <stdlib.h>
18#include <string.h>
19
20#include "../test_helper/test_helper.h"
21
22#include "ssherr.h"
23#include "sshbuf.h"
24
25void sshbuf_tests(void);
26
27void
28sshbuf_tests(void)
29{
30 struct sshbuf *p1;
31 const u_char *cdp;
32 u_char *dp;
33 size_t sz;
34 int r;
35
36 TEST_START("allocate sshbuf");
37 p1 = sshbuf_new();
38 ASSERT_PTR_NE(p1, NULL);
39 TEST_DONE();
40
41 TEST_START("max size on fresh buffer");
42 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
43 TEST_DONE();
44
45 TEST_START("available on fresh buffer");
46 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
47 TEST_DONE();
48
49 TEST_START("len = 0 on empty buffer");
50 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
51 TEST_DONE();
52
53 TEST_START("set valid max size");
54 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
55 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
56 TEST_DONE();
57
58 TEST_START("available on limited buffer");
59 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
60 TEST_DONE();
61
62 TEST_START("free");
63 sshbuf_free(p1);
64 TEST_DONE();
65
66 TEST_START("consume on empty buffer");
67 p1 = sshbuf_new();
68 ASSERT_PTR_NE(p1, NULL);
69 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
70 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
71 sshbuf_free(p1);
72 TEST_DONE();
73
74 TEST_START("consume_end on empty buffer");
75 p1 = sshbuf_new();
76 ASSERT_PTR_NE(p1, NULL);
77 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
78 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
79 sshbuf_free(p1);
80 TEST_DONE();
81
82 TEST_START("reserve space");
83 p1 = sshbuf_new();
84 ASSERT_PTR_NE(p1, NULL);
85 r = sshbuf_reserve(p1, 1, &dp);
86 ASSERT_INT_EQ(r, 0);
87 ASSERT_PTR_NE(dp, NULL);
88 *dp = 0x11;
89 r = sshbuf_reserve(p1, 3, &dp);
90 ASSERT_INT_EQ(r, 0);
91 ASSERT_PTR_NE(dp, NULL);
92 *dp++ = 0x22;
93 *dp++ = 0x33;
94 *dp++ = 0x44;
95 TEST_DONE();
96
97 TEST_START("sshbuf_len on filled buffer");
98 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
99 TEST_DONE();
100
101 TEST_START("sshbuf_ptr on filled buffer");
102 cdp = sshbuf_ptr(p1);
103 ASSERT_PTR_NE(cdp, NULL);
104 ASSERT_U8_EQ(cdp[0], 0x11);
105 ASSERT_U8_EQ(cdp[1], 0x22);
106 ASSERT_U8_EQ(cdp[2], 0x33);
107 ASSERT_U8_EQ(cdp[3], 0x44);
108 TEST_DONE();
109
110 TEST_START("consume on filled buffer");
111 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
112 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
113 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
114 r = sshbuf_consume(p1, 64);
115 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
116 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
117 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
118 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
119 cdp = sshbuf_ptr(p1);
120 ASSERT_PTR_NE(p1, NULL);
121 ASSERT_U8_EQ(cdp[0], 0x22);
122 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
124 cdp = sshbuf_ptr(p1);
125 ASSERT_PTR_NE(p1, NULL);
126 ASSERT_U8_EQ(cdp[0], 0x44);
127 r = sshbuf_consume(p1, 2);
128 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
129 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
130 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
131 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
132 r = sshbuf_consume(p1, 1);
133 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
134 sshbuf_free(p1);
135 TEST_DONE();
136
137 TEST_START("consume_end on filled buffer");
138 p1 = sshbuf_new();
139 ASSERT_PTR_NE(p1, NULL);
140 r = sshbuf_reserve(p1, 4, &dp);
141 ASSERT_INT_EQ(r, 0);
142 ASSERT_PTR_NE(dp, NULL);
143 *dp++ = 0x11;
144 *dp++ = 0x22;
145 *dp++ = 0x33;
146 *dp++ = 0x44;
147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
148 r = sshbuf_consume_end(p1, 5);
149 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
150 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
151 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
152 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
153 cdp = sshbuf_ptr(p1);
154 ASSERT_PTR_NE(cdp, NULL);
155 ASSERT_U8_EQ(*cdp, 0x11);
156 r = sshbuf_consume_end(p1, 2);
157 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
158 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
159 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
160 sshbuf_free(p1);
161 TEST_DONE();
162
163 TEST_START("fill limited buffer");
164 p1 = sshbuf_new();
165 ASSERT_PTR_NE(p1, NULL);
166 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
167 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
168 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
169 r = sshbuf_reserve(p1, 1223, &dp);
170 ASSERT_INT_EQ(r, 0);
171 ASSERT_PTR_NE(dp, NULL);
172 memset(dp, 0xd7, 1223);
173 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
174 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
175 r = sshbuf_reserve(p1, 1, &dp);
176 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
177 ASSERT_PTR_EQ(dp, NULL);
178 TEST_DONE();
179
180 TEST_START("consume and force compaction");
181 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
182 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
183 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
184 r = sshbuf_reserve(p1, 224, &dp);
185 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
186 ASSERT_PTR_EQ(dp, NULL);
187 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
188 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
189 r = sshbuf_reserve(p1, 223, &dp);
190 ASSERT_INT_EQ(r, 0);
191 ASSERT_PTR_NE(dp, NULL);
192 memset(dp, 0x7d, 223);
193 cdp = sshbuf_ptr(p1);
194 ASSERT_PTR_NE(cdp, NULL);
195 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
196 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
197 TEST_DONE();
198
199 TEST_START("resize full buffer");
200 r = sshbuf_set_max_size(p1, 1000);
201 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
202 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
203 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
204 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
205 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
206 ASSERT_INT_EQ(sshbuf_len(p1), 1223);
207 TEST_DONE();
208
209 /* NB. uses sshbuf internals */
210 TEST_START("alloc chunking");
211 r = sshbuf_reserve(p1, 1, &dp);
212 ASSERT_INT_EQ(r, 0);
213 ASSERT_PTR_NE(dp, NULL);
214 *dp = 0xff;
215 cdp = sshbuf_ptr(p1);
216 ASSERT_PTR_NE(cdp, NULL);
217 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
218 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
219 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
220 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
221 sshbuf_free(p1);
222 TEST_DONE();
223
224 TEST_START("reset buffer");
225 p1 = sshbuf_new();
226 ASSERT_PTR_NE(p1, NULL);
227 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
228 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
229 r = sshbuf_reserve(p1, 1223, &dp);
230 ASSERT_INT_EQ(r, 0);
231 ASSERT_PTR_NE(dp, NULL);
232 memset(dp, 0xd7, 1223);
233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
234 sshbuf_reset(p1);
235 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
236 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
237 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
238 sshbuf_free(p1);
239 TEST_DONE();
240}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fixed.c b/regress/unittests/sshbuf/test_sshbuf_fixed.c
new file mode 100644
index 000000000..df4925f7c
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fixed.c
@@ -0,0 +1,126 @@
1/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#define SSHBUF_INTERNAL 1 /* access internals for testing */
9#include "includes.h"
10
11#include <sys/types.h>
12#include <sys/param.h>
13#include <stdio.h>
14#ifdef HAVE_STDINT_H
15# include <stdint.h>
16#endif
17#include <stdlib.h>
18#include <string.h>
19
20#include "../test_helper/test_helper.h"
21
22#include "sshbuf.h"
23#include "ssherr.h"
24
25void sshbuf_fixed(void);
26
27const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello";
28
29void
30sshbuf_fixed(void)
31{
32 struct sshbuf *p1, *p2, *p3;
33 u_char c;
34 char *s;
35 u_int i;
36 size_t l;
37
38 TEST_START("sshbuf_from");
39 p1 = sshbuf_from(test_buf, sizeof(test_buf));
40 ASSERT_PTR_NE(p1, NULL);
41 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
42 ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY);
43 ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY);
44 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY);
45 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY);
46 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
47 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
48 sshbuf_free(p1);
49 TEST_DONE();
50
51 TEST_START("sshbuf_from data");
52 p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1);
53 ASSERT_PTR_NE(p1, NULL);
54 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
55 ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0);
56 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1);
57 ASSERT_U8_EQ(c, 1);
58 ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0);
59 ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5);
60 ASSERT_U32_EQ(i, 0x12345678);
61 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0);
62 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
63 ASSERT_STRING_EQ(s, "hello");
64 ASSERT_SIZE_T_EQ(l, 5);
65 sshbuf_free(p1);
66 free(s);
67 TEST_DONE();
68
69 TEST_START("sshbuf_fromb ");
70 p1 = sshbuf_new();
71 ASSERT_PTR_NE(p1, NULL);
72 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
73 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
74 ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0);
75 p2 = sshbuf_fromb(p1);
76 ASSERT_PTR_NE(p2, NULL);
77 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2);
78 ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
79 ASSERT_PTR_EQ(sshbuf_parent(p2), p1);
80 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1));
81 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
82 ASSERT_PTR_NE(sshbuf_ptr(p2), NULL);
83 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
84 ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2));
86 ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0);
87 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1);
88 ASSERT_U8_EQ(c, 1);
89 ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0);
90 ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5);
91 ASSERT_U32_EQ(i, 0x12345678);
92 ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0);
93 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
94 ASSERT_STRING_EQ(s, "hello");
95 ASSERT_SIZE_T_EQ(l, 5);
96 sshbuf_free(p1);
97 ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
98 sshbuf_free(p2);
99 free(s);
100 TEST_DONE();
101
102 TEST_START("sshbuf_froms");
103 p1 = sshbuf_new();
104 ASSERT_PTR_NE(p1, NULL);
105 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0);
106 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
107 ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0);
108 p2 = sshbuf_new();
109 ASSERT_PTR_NE(p2, NULL);
110 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1);
111 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
112 ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1);
113 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0);
114 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
115 ASSERT_PTR_NE(p3, NULL);
116 ASSERT_PTR_NE(sshbuf_ptr(p3), NULL);
117 ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1);
118 ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1);
119 sshbuf_free(p3);
120 ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
121 ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0);
122 ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE);
123 ASSERT_PTR_EQ(p3, NULL);
124 sshbuf_free(p2);
125 sshbuf_free(p1);
126}
diff --git a/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
new file mode 100644
index 000000000..c52376b53
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_fuzz.c
@@ -0,0 +1,127 @@
1/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "ssherr.h"
22#include "sshbuf.h"
23
24#define NUM_FUZZ_TESTS (1 << 18)
25
26void sshbuf_fuzz_tests(void);
27
28void
29sshbuf_fuzz_tests(void)
30{
31 struct sshbuf *p1;
32 u_char *dp;
33 size_t sz, sz2, i;
34 u_int32_t r;
35 int ret;
36
37 /* NB. uses sshbuf internals */
38 TEST_START("fuzz alloc/dealloc");
39 p1 = sshbuf_new();
40 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
41 ASSERT_PTR_NE(p1, NULL);
42 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
43 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
44 for (i = 0; i < NUM_FUZZ_TESTS; i++) {
45 r = arc4random_uniform(10);
46 if (r == 0) {
47 /* 10% chance: small reserve */
48 r = arc4random_uniform(10);
49 fuzz_reserve:
50 sz = sshbuf_avail(p1);
51 sz2 = sshbuf_len(p1);
52 ret = sshbuf_reserve(p1, r, &dp);
53 if (ret < 0) {
54 ASSERT_PTR_EQ(dp, NULL);
55 ASSERT_SIZE_T_LT(sz, r);
56 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
57 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
58 } else {
59 ASSERT_PTR_NE(dp, NULL);
60 ASSERT_SIZE_T_GE(sz, r);
61 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
62 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
63 memset(dp, arc4random_uniform(255) + 1, r);
64 }
65 } else if (r < 3) {
66 /* 20% chance: big reserve */
67 r = arc4random_uniform(8 * 1024);
68 goto fuzz_reserve;
69 } else if (r == 3) {
70 /* 10% chance: small consume */
71 r = arc4random_uniform(10);
72 fuzz_consume:
73 sz = sshbuf_avail(p1);
74 sz2 = sshbuf_len(p1);
75 /* 50% change consume from end, otherwise start */
76 ret = ((arc4random() & 1) ?
77 sshbuf_consume : sshbuf_consume_end)(p1, r);
78 if (ret < 0) {
79 ASSERT_SIZE_T_LT(sz2, r);
80 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
82 } else {
83 ASSERT_SIZE_T_GE(sz2, r);
84 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
86 }
87 } else if (r < 8) {
88 /* 40% chance: big consume */
89 r = arc4random_uniform(2 * 1024);
90 goto fuzz_consume;
91 } else if (r == 8) {
92 /* 10% chance: reset max size */
93 r = arc4random_uniform(16 * 1024);
94 sz = sshbuf_max_size(p1);
95 if (sshbuf_set_max_size(p1, r) < 0)
96 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
97 else
98 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
99 } else {
100 if (arc4random_uniform(8192) == 0) {
101 /* tiny chance: new buffer */
102 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
103 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
104 sshbuf_free(p1);
105 p1 = sshbuf_new();
106 ASSERT_PTR_NE(p1, NULL);
107 ASSERT_INT_EQ(sshbuf_set_max_size(p1,
108 16 * 1024), 0);
109 } else {
110 /* Almost 10%: giant reserve */
111 /* use arc4random_buf for r > 2^32 on 64 bit */
112 arc4random_buf(&r, sizeof(r));
113 while (r < SSHBUF_SIZE_MAX / 2) {
114 r <<= 1;
115 r |= arc4random() & 1;
116 }
117 goto fuzz_reserve;
118 }
119 }
120 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
121 ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
122 }
123 ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
124 ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
125 sshbuf_free(p1);
126 TEST_DONE();
127}
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
new file mode 100644
index 000000000..966e8432b
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
@@ -0,0 +1,484 @@
1/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20#include "ssherr.h"
21#include "sshbuf.h"
22
23void sshbuf_getput_basic_tests(void);
24
25void
26sshbuf_getput_basic_tests(void)
27{
28 struct sshbuf *p1, *p2;
29 const u_char *cd;
30 u_char *d, d2[32], x[] = {
31 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99
32 };
33 u_int64_t v64;
34 u_int32_t v32;
35 u_int16_t v16;
36 u_char v8;
37 size_t s;
38 char *s2;
39 int r;
40 u_char bn1[] = { 0x00, 0x00, 0x00 };
41 u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 };
42 u_char bn3[] = { 0x00, 0x80, 0x09 };
43 u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 };
44 u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 };
45 u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 };
46
47 TEST_START("PEEK_U64");
48 ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL);
49 TEST_DONE();
50
51 TEST_START("PEEK_U32");
52 ASSERT_U32_EQ(PEEK_U32(x), 0x11223344);
53 TEST_DONE();
54
55 TEST_START("PEEK_U16");
56 ASSERT_U16_EQ(PEEK_U16(x), 0x1122);
57 TEST_DONE();
58
59 TEST_START("POKE_U64");
60 bzero(d2, sizeof(d2));
61 POKE_U64(d2, 0x1122334455667788ULL);
62 ASSERT_MEM_EQ(d2, x, 8);
63 TEST_DONE();
64
65 TEST_START("POKE_U32");
66 bzero(d2, sizeof(d2));
67 POKE_U32(d2, 0x11223344);
68 ASSERT_MEM_EQ(d2, x, 4);
69 TEST_DONE();
70
71 TEST_START("POKE_U16");
72 bzero(d2, sizeof(d2));
73 POKE_U16(d2, 0x1122);
74 ASSERT_MEM_EQ(d2, x, 2);
75 TEST_DONE();
76
77 TEST_START("sshbuf_put");
78 p1 = sshbuf_new();
79 ASSERT_PTR_NE(p1, NULL);
80 ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0);
81 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
82 cd = sshbuf_ptr(p1);
83 ASSERT_PTR_NE(cd, NULL);
84 ASSERT_U8_EQ(cd[0], 0x11);
85 ASSERT_U8_EQ(cd[1], 0x22);
86 ASSERT_U8_EQ(cd[2], 0x33);
87 ASSERT_U8_EQ(cd[3], 0x44);
88 ASSERT_U8_EQ(cd[4], 0x55);
89 TEST_DONE();
90
91 TEST_START("sshbuf_get");
92 ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0);
93 ASSERT_MEM_EQ(d2, x, 4);
94 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
95 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
96 TEST_DONE();
97
98 TEST_START("sshbuf_get truncated");
99 r = sshbuf_get(p1, d2, 4);
100 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
101 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
102 ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
103 TEST_DONE();
104
105 TEST_START("sshbuf_put truncated");
106 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
107 r = sshbuf_put(p1, x, 5);
108 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
110 sshbuf_free(p1);
111 TEST_DONE();
112
113 TEST_START("sshbuf_get_u64");
114 p1 = sshbuf_new();
115 ASSERT_PTR_NE(p1, NULL);
116 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
117 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
118 ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0);
119 ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
121 TEST_DONE();
122
123 TEST_START("sshbuf_get_u64 truncated");
124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
125 r = sshbuf_get_u64(p1, &v64);
126 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
127 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
128 sshbuf_free(p1);
129 TEST_DONE();
130
131 TEST_START("sshbuf_get_u32");
132 p1 = sshbuf_new();
133 ASSERT_PTR_NE(p1, NULL);
134 ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
135 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
136 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
137 ASSERT_U32_EQ(v32, 0x11223344);
138 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6);
139 ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
140 ASSERT_U32_EQ(v32, 0x55667788);
141 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
142 TEST_DONE();
143
144 TEST_START("sshbuf_get_u32 truncated");
145 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
146 r = sshbuf_get_u32(p1, &v32);
147 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
148 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
149 sshbuf_free(p1);
150 TEST_DONE();
151
152 TEST_START("sshbuf_get_u16");
153 p1 = sshbuf_new();
154 ASSERT_PTR_NE(p1, NULL);
155 ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0);
156 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9);
157 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
158 ASSERT_U16_EQ(v16, 0x1122);
159 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7);
160 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
161 ASSERT_U16_EQ(v16, 0x3344);
162 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
163 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
164 ASSERT_U16_EQ(v16, 0x5566);
165 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
166 ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
167 ASSERT_U16_EQ(v16, 0x7788);
168 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
169 TEST_DONE();
170
171 TEST_START("sshbuf_get_u16 truncated");
172 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
173 r = sshbuf_get_u16(p1, &v16);
174 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
175 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
176 sshbuf_free(p1);
177 TEST_DONE();
178
179 TEST_START("sshbuf_get_u8");
180 p1 = sshbuf_new();
181 ASSERT_PTR_NE(p1, NULL);
182 ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0);
183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
184 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
185 ASSERT_U8_EQ(v8, 0x11);
186 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
187 ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
188 ASSERT_U8_EQ(v8, 0x22);
189 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
190 TEST_DONE();
191
192 TEST_START("sshbuf_get_u8 truncated");
193 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
194 r = sshbuf_get_u8(p1, &v8);
195 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
196 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
197 sshbuf_free(p1);
198 TEST_DONE();
199
200 TEST_START("sshbuf_put_u64");
201 p1 = sshbuf_new();
202 ASSERT_PTR_NE(p1, NULL);
203 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
205 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
206 sshbuf_free(p1);
207 TEST_DONE();
208
209 TEST_START("sshbuf_put_u64 exact");
210 p1 = sshbuf_new();
211 ASSERT_PTR_NE(p1, NULL);
212 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0);
213 ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
214 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
215 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
216 sshbuf_free(p1);
217 TEST_DONE();
218
219 TEST_START("sshbuf_put_u64 limited");
220 p1 = sshbuf_new();
221 ASSERT_PTR_NE(p1, NULL);
222 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0);
223 r = sshbuf_put_u64(p1, 0x1122334455667788ULL);
224 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
225 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
226 sshbuf_free(p1);
227 TEST_DONE();
228
229 TEST_START("sshbuf_put_u32");
230 p1 = sshbuf_new();
231 ASSERT_PTR_NE(p1, NULL);
232 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
234 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
235 sshbuf_free(p1);
236 TEST_DONE();
237
238 TEST_START("sshbuf_put_u32 exact");
239 p1 = sshbuf_new();
240 ASSERT_PTR_NE(p1, NULL);
241 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
242 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
243 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
244 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
245 sshbuf_free(p1);
246 TEST_DONE();
247
248 TEST_START("sshbuf_put_u32 limited");
249 p1 = sshbuf_new();
250 ASSERT_PTR_NE(p1, NULL);
251 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0);
252 r = sshbuf_put_u32(p1, 0x11223344);
253 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
254 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
255 sshbuf_free(p1);
256 TEST_DONE();
257
258 TEST_START("sshbuf_put_u16");
259 p1 = sshbuf_new();
260 ASSERT_PTR_NE(p1, NULL);
261 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
262 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
263 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
264 sshbuf_free(p1);
265 TEST_DONE();
266
267 TEST_START("sshbuf_put_u16");
268 p1 = sshbuf_new();
269 ASSERT_PTR_NE(p1, NULL);
270 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0);
271 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
272 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
273 ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
274 sshbuf_free(p1);
275 TEST_DONE();
276
277 TEST_START("sshbuf_put_u16 limited");
278 p1 = sshbuf_new();
279 ASSERT_PTR_NE(p1, NULL);
280 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0);
281 r = sshbuf_put_u16(p1, 0x1122);
282 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
283 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
284 sshbuf_free(p1);
285 TEST_DONE();
286
287 TEST_START("sshbuf_get_string");
288 p1 = sshbuf_new();
289 ASSERT_PTR_NE(p1, NULL);
290 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
291 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
292 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
293 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4);
294 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
295 ASSERT_SIZE_T_EQ(s, sizeof(x));
296 ASSERT_MEM_EQ(d, x, sizeof(x));
297 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
298 free(d);
299 sshbuf_free(p1);
300 TEST_DONE();
301
302 TEST_START("sshbuf_get_string exact");
303 p1 = sshbuf_new();
304 ASSERT_PTR_NE(p1, NULL);
305 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0);
306 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
307 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
308 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
309 ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
310 ASSERT_SIZE_T_EQ(s, sizeof(x));
311 ASSERT_MEM_EQ(d, x, sizeof(x));
312 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
313 free(d);
314 sshbuf_free(p1);
315 TEST_DONE();
316
317 TEST_START("sshbuf_get_string truncated");
318 p1 = sshbuf_new();
319 ASSERT_PTR_NE(p1, NULL);
320 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
321 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
322 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
323 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
324 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
325 r = sshbuf_get_string(p1, &d, &s);
326 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
327 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
328 sshbuf_free(p1);
329 TEST_DONE();
330
331 TEST_START("sshbuf_get_string giant");
332 p1 = sshbuf_new();
333 ASSERT_PTR_NE(p1, NULL);
334 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
335 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
336 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
337 r = sshbuf_get_string(p1, &d, &s);
338 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
339 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
340 sshbuf_free(p1);
341 TEST_DONE();
342
343 TEST_START("sshbuf_get_cstring giant");
344 p1 = sshbuf_new();
345 ASSERT_PTR_NE(p1, NULL);
346 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
347 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
348 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
349 r = sshbuf_get_cstring(p1, &s2, &s);
350 ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
351 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
352 sshbuf_free(p1);
353 TEST_DONE();
354
355 TEST_START("sshbuf_get_cstring embedded \\0");
356 p1 = sshbuf_new();
357 ASSERT_PTR_NE(p1, NULL);
358 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
359 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
360 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
361 r = sshbuf_get_cstring(p1, &s2, NULL);
362 ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT);
363 sshbuf_free(p1);
364 TEST_DONE();
365
366 TEST_START("sshbuf_get_cstring trailing \\0");
367 p1 = sshbuf_new();
368 ASSERT_PTR_NE(p1, NULL);
369 ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0);
370 ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0);
371 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1);
372 ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0);
373 ASSERT_SIZE_T_EQ(s, sizeof(x) - 1);
374 ASSERT_MEM_EQ(s2, x, s);
375 free(s2);
376 sshbuf_free(p1);
377 TEST_DONE();
378
379 TEST_START("sshbuf_put_string");
380 p1 = sshbuf_new();
381 ASSERT_PTR_NE(p1, NULL);
382 ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0);
383 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
384 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x));
385 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x));
386 sshbuf_free(p1);
387 TEST_DONE();
388
389 TEST_START("sshbuf_put_string limited");
390 p1 = sshbuf_new();
391 ASSERT_PTR_NE(p1, NULL);
392 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0);
393 r = sshbuf_put_string(p1, x, sizeof(x));
394 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
395 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
396 sshbuf_free(p1);
397 TEST_DONE();
398
399 TEST_START("sshbuf_put_string giant");
400 p1 = sshbuf_new();
401 ASSERT_PTR_NE(p1, NULL);
402 r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc);
403 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
404 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
405 sshbuf_free(p1);
406 TEST_DONE();
407
408 TEST_START("sshbuf_putf");
409 p1 = sshbuf_new();
410 ASSERT_PTR_NE(p1, NULL);
411 r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f);
412 ASSERT_INT_EQ(r, 0);
413 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11);
414 ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11);
415 sshbuf_free(p1);
416 TEST_DONE();
417
418 TEST_START("sshbuf_putb");
419 p1 = sshbuf_new();
420 ASSERT_PTR_NE(p1, NULL);
421 p2 = sshbuf_new();
422 ASSERT_PTR_NE(p2, NULL);
423 ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0);
424 ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0);
425 sshbuf_free(p1);
426 ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12);
427 ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12);
428 sshbuf_free(p2);
429 TEST_DONE();
430
431 TEST_START("sshbuf_put_bignum2_bytes empty buf");
432 p1 = sshbuf_new();
433 ASSERT_PTR_NE(p1, NULL);
434 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0);
435 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
436 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
437 sshbuf_free(p1);
438 TEST_DONE();
439
440 TEST_START("sshbuf_put_bignum2_bytes all zeroes");
441 p1 = sshbuf_new();
442 ASSERT_PTR_NE(p1, NULL);
443 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0);
444 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
445 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
446 sshbuf_free(p1);
447 TEST_DONE();
448
449 TEST_START("sshbuf_put_bignum2_bytes simple");
450 p1 = sshbuf_new();
451 ASSERT_PTR_NE(p1, NULL);
452 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0);
453 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
454 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
455 sshbuf_free(p1);
456 TEST_DONE();
457
458 TEST_START("sshbuf_put_bignum2_bytes leading zero");
459 p1 = sshbuf_new();
460 ASSERT_PTR_NE(p1, NULL);
461 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0);
462 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
463 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
464 sshbuf_free(p1);
465 TEST_DONE();
466
467 TEST_START("sshbuf_put_bignum2_bytes neg");
468 p1 = sshbuf_new();
469 ASSERT_PTR_NE(p1, NULL);
470 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0);
471 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
472 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
473 sshbuf_free(p1);
474 TEST_DONE();
475
476 TEST_START("sshbuf_put_bignum2_bytes neg and leading zero");
477 p1 = sshbuf_new();
478 ASSERT_PTR_NE(p1, NULL);
479 ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0);
480 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
481 ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
482 sshbuf_free(p1);
483 TEST_DONE();
484}
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
new file mode 100644
index 000000000..0c4c71ecd
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -0,0 +1,409 @@
1/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20#include <openssl/objects.h>
21#ifdef OPENSSL_HAS_NISTP256
22# include <openssl/ec.h>
23#endif
24
25#include "../test_helper/test_helper.h"
26#include "ssherr.h"
27#include "sshbuf.h"
28
29void sshbuf_getput_crypto_tests(void);
30
31void
32sshbuf_getput_crypto_tests(void)
33{
34 struct sshbuf *p1;
35 const u_char *d;
36 size_t s;
37 BIGNUM *bn, *bn2;
38 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
39 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
40 /* This one has MSB set to test bignum2 encoding negative-avoidance */
41 const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
42 u_char expbn1[] = {
43 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
44 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
45 };
46 u_char expbn2[] = {
47 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
48 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
49 0x7f, 0xff, 0x11
50 };
51#ifdef OPENSSL_HAS_NISTP256
52 BIGNUM *bn_x, *bn_y;
53 int ec256_nid = NID_X9_62_prime256v1;
54 char *ec256_x = "0C828004839D0106AA59575216191357"
55 "34B451459DADB586677EF9DF55784999";
56 char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
57 "C8F9A35E42BDD047550F69D80EC23CD4";
58 u_char expec256[] = {
59 0x04,
60 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
61 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
62 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
63 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
64 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
65 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
66 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
67 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
68 };
69 EC_KEY *eck;
70 EC_POINT *ecp;
71#endif
72 int r;
73
74#define MKBN(b, bnn) \
75 do { \
76 bnn = NULL; \
77 ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
78 } while (0)
79
80 TEST_START("sshbuf_put_bignum1");
81 MKBN(hexbn1, bn);
82 p1 = sshbuf_new();
83 ASSERT_PTR_NE(p1, NULL);
84 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
86 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
87 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
88 BN_free(bn);
89 sshbuf_free(p1);
90 TEST_DONE();
91
92 TEST_START("sshbuf_put_bignum1 limited");
93 MKBN(hexbn1, bn);
94 p1 = sshbuf_new();
95 ASSERT_PTR_NE(p1, NULL);
96 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
97 r = sshbuf_put_bignum1(p1, bn);
98 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
99 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
100 BN_free(bn);
101 sshbuf_free(p1);
102 TEST_DONE();
103
104 TEST_START("sshbuf_put_bignum1 bn2");
105 MKBN(hexbn2, bn);
106 p1 = sshbuf_new();
107 ASSERT_PTR_NE(p1, NULL);
108 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
110 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
111 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
112 BN_free(bn);
113 sshbuf_free(p1);
114 TEST_DONE();
115
116 TEST_START("sshbuf_put_bignum1 bn2 limited");
117 MKBN(hexbn2, bn);
118 p1 = sshbuf_new();
119 ASSERT_PTR_NE(p1, NULL);
120 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
121 r = sshbuf_put_bignum1(p1, bn);
122 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
124 BN_free(bn);
125 sshbuf_free(p1);
126 TEST_DONE();
127
128 TEST_START("sshbuf_put_bignum2");
129 MKBN(hexbn1, bn);
130 p1 = sshbuf_new();
131 ASSERT_PTR_NE(p1, NULL);
132 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
133 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
134 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
135 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
136 BN_free(bn);
137 sshbuf_free(p1);
138 TEST_DONE();
139
140 TEST_START("sshbuf_put_bignum2 limited");
141 MKBN(hexbn1, bn);
142 p1 = sshbuf_new();
143 ASSERT_PTR_NE(p1, NULL);
144 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
145 r = sshbuf_put_bignum2(p1, bn);
146 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
148 BN_free(bn);
149 sshbuf_free(p1);
150 TEST_DONE();
151
152 TEST_START("sshbuf_put_bignum2 bn2");
153 MKBN(hexbn2, bn);
154 p1 = sshbuf_new();
155 ASSERT_PTR_NE(p1, NULL);
156 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
157 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
158 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
159 ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
160 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
161 BN_free(bn);
162 sshbuf_free(p1);
163 TEST_DONE();
164
165 TEST_START("sshbuf_put_bignum2 bn2 limited");
166 MKBN(hexbn2, bn);
167 p1 = sshbuf_new();
168 ASSERT_PTR_NE(p1, NULL);
169 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
170 r = sshbuf_put_bignum2(p1, bn);
171 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
172 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
173 BN_free(bn);
174 sshbuf_free(p1);
175 TEST_DONE();
176
177 TEST_START("sshbuf_get_bignum1");
178 MKBN(hexbn1, bn);
179 p1 = sshbuf_new();
180 ASSERT_PTR_NE(p1, NULL);
181 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
182 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
184 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
185 bn2 = BN_new();
186 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
187 ASSERT_BIGNUM_EQ(bn, bn2);
188 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
189 BN_free(bn);
190 BN_free(bn2);
191 sshbuf_free(p1);
192 TEST_DONE();
193
194 TEST_START("sshbuf_get_bignum1 truncated");
195 MKBN(hexbn1, bn);
196 p1 = sshbuf_new();
197 ASSERT_PTR_NE(p1, NULL);
198 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
199 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
200 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
201 bn2 = BN_new();
202 r = sshbuf_get_bignum1(p1, bn2);
203 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
205 BN_free(bn);
206 BN_free(bn2);
207 sshbuf_free(p1);
208 TEST_DONE();
209
210 TEST_START("sshbuf_get_bignum1 giant");
211 MKBN(hexbn1, bn);
212 p1 = sshbuf_new();
213 ASSERT_PTR_NE(p1, NULL);
214 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
215 ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
216 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
217 bn2 = BN_new();
218 r = sshbuf_get_bignum1(p1, bn2);
219 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
220 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
221 BN_free(bn);
222 BN_free(bn2);
223 sshbuf_free(p1);
224 TEST_DONE();
225
226 TEST_START("sshbuf_get_bignum1 bn2");
227 MKBN(hexbn2, bn);
228 p1 = sshbuf_new();
229 ASSERT_PTR_NE(p1, NULL);
230 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
231 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
232 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
233 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
234 bn2 = BN_new();
235 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
236 ASSERT_BIGNUM_EQ(bn, bn2);
237 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
238 BN_free(bn);
239 BN_free(bn2);
240 sshbuf_free(p1);
241 TEST_DONE();
242
243 TEST_START("sshbuf_get_bignum1 bn2 truncated");
244 MKBN(hexbn2, bn);
245 p1 = sshbuf_new();
246 ASSERT_PTR_NE(p1, NULL);
247 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
248 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
249 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
250 bn2 = BN_new();
251 r = sshbuf_get_bignum1(p1, bn2);
252 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
253 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
254 BN_free(bn);
255 BN_free(bn2);
256 sshbuf_free(p1);
257 TEST_DONE();
258
259 TEST_START("sshbuf_get_bignum2");
260 MKBN(hexbn1, bn);
261 p1 = sshbuf_new();
262 ASSERT_PTR_NE(p1, NULL);
263 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
264 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
265 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
266 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
267 bn2 = BN_new();
268 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
269 ASSERT_BIGNUM_EQ(bn, bn2);
270 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
271 BN_free(bn);
272 BN_free(bn2);
273 sshbuf_free(p1);
274 TEST_DONE();
275
276 TEST_START("sshbuf_get_bignum2 truncated");
277 MKBN(hexbn1, bn);
278 p1 = sshbuf_new();
279 ASSERT_PTR_NE(p1, NULL);
280 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
281 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
282 bn2 = BN_new();
283 r = sshbuf_get_bignum2(p1, bn2);
284 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
285 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
286 BN_free(bn);
287 BN_free(bn2);
288 sshbuf_free(p1);
289 TEST_DONE();
290
291 TEST_START("sshbuf_get_bignum2 giant");
292 MKBN(hexbn1, bn);
293 p1 = sshbuf_new();
294 ASSERT_PTR_NE(p1, NULL);
295 ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
296 ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
297 bn2 = BN_new();
298 r = sshbuf_get_bignum2(p1, bn2);
299 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
300 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
301 BN_free(bn);
302 BN_free(bn2);
303 sshbuf_free(p1);
304 TEST_DONE();
305
306 TEST_START("sshbuf_get_bignum2 bn2");
307 MKBN(hexbn2, bn);
308 p1 = sshbuf_new();
309 ASSERT_PTR_NE(p1, NULL);
310 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
311 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
312 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
313 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
314 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
315 bn2 = BN_new();
316 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
317 ASSERT_BIGNUM_EQ(bn, bn2);
318 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
319 BN_free(bn);
320 BN_free(bn2);
321 sshbuf_free(p1);
322 TEST_DONE();
323
324 TEST_START("sshbuf_get_bignum2 bn2 truncated");
325 MKBN(hexbn2, bn);
326 p1 = sshbuf_new();
327 ASSERT_PTR_NE(p1, NULL);
328 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
329 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
330 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
331 bn2 = BN_new();
332 r = sshbuf_get_bignum2(p1, bn2);
333 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
334 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
335 BN_free(bn);
336 BN_free(bn2);
337 sshbuf_free(p1);
338 TEST_DONE();
339
340 TEST_START("sshbuf_get_bignum2 bn2 negative");
341 MKBN(hexbn2, bn);
342 p1 = sshbuf_new();
343 ASSERT_PTR_NE(p1, NULL);
344 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
345 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
346 bn2 = BN_new();
347 r = sshbuf_get_bignum2(p1, bn2);
348 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
349 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
350 BN_free(bn);
351 BN_free(bn2);
352 sshbuf_free(p1);
353 TEST_DONE();
354
355#ifdef OPENSSL_HAS_NISTP256
356 TEST_START("sshbuf_put_ec");
357 eck = EC_KEY_new_by_curve_name(ec256_nid);
358 ASSERT_PTR_NE(eck, NULL);
359 ecp = EC_POINT_new(EC_KEY_get0_group(eck));
360 ASSERT_PTR_NE(ecp, NULL);
361 MKBN(ec256_x, bn_x);
362 MKBN(ec256_y, bn_y);
363 ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
364 EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
365 ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
366 BN_free(bn_x);
367 BN_free(bn_y);
368 EC_POINT_free(ecp);
369 p1 = sshbuf_new();
370 ASSERT_PTR_NE(p1, NULL);
371 ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
372 ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
373 ASSERT_SIZE_T_EQ(s, sizeof(expec256));
374 ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
375 sshbuf_free(p1);
376 EC_KEY_free(eck);
377 TEST_DONE();
378
379 TEST_START("sshbuf_get_ec");
380 eck = EC_KEY_new_by_curve_name(ec256_nid);
381 ASSERT_PTR_NE(eck, NULL);
382 p1 = sshbuf_new();
383 ASSERT_PTR_NE(p1, NULL);
384 ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
385 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
386 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
387 ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
388 bn_x = BN_new();
389 bn_y = BN_new();
390 ASSERT_PTR_NE(bn_x, NULL);
391 ASSERT_PTR_NE(bn_y, NULL);
392 ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
393 EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
394 bn_x, bn_y, NULL), 1);
395 MKBN(ec256_x, bn);
396 MKBN(ec256_y, bn2);
397 ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
398 ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
399 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
400 sshbuf_free(p1);
401 EC_KEY_free(eck);
402 BN_free(bn_x);
403 BN_free(bn_y);
404 BN_free(bn);
405 BN_free(bn2);
406 TEST_DONE();
407#endif
408}
409
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
new file mode 100644
index 000000000..8c3269b13
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -0,0 +1,130 @@
1/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20#include <openssl/objects.h>
21#ifdef OPENSSL_HAS_NISTP256
22# include <openssl/ec.h>
23#endif
24
25#include "../test_helper/test_helper.h"
26#include "ssherr.h"
27#include "sshbuf.h"
28
29void sshbuf_getput_fuzz_tests(void);
30
31static void
32attempt_parse_blob(u_char *blob, size_t len)
33{
34 struct sshbuf *p1;
35 BIGNUM *bn;
36#ifdef OPENSSL_HAS_NISTP256
37 EC_KEY *eck;
38#endif
39 u_char *s;
40 size_t l;
41 u_int8_t u8;
42 u_int16_t u16;
43 u_int32_t u32;
44 u_int64_t u64;
45
46 p1 = sshbuf_new();
47 ASSERT_PTR_NE(p1, NULL);
48 ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
49 sshbuf_get_u8(p1, &u8);
50 sshbuf_get_u16(p1, &u16);
51 sshbuf_get_u32(p1, &u32);
52 sshbuf_get_u64(p1, &u64);
53 if (sshbuf_get_string(p1, &s, &l) == 0) {
54 bzero(s, l);
55 free(s);
56 }
57 bn = BN_new();
58 sshbuf_get_bignum1(p1, bn);
59 BN_clear_free(bn);
60 bn = BN_new();
61 sshbuf_get_bignum2(p1, bn);
62 BN_clear_free(bn);
63#ifdef OPENSSL_HAS_NISTP256
64 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
65 ASSERT_PTR_NE(eck, NULL);
66 sshbuf_get_eckey(p1, eck);
67 EC_KEY_free(eck);
68#endif
69 sshbuf_free(p1);
70}
71
72
73static void
74onerror(void *fuzz)
75{
76 fprintf(stderr, "Failed during fuzz:\n");
77 fuzz_dump((struct fuzz *)fuzz);
78}
79
80void
81sshbuf_getput_fuzz_tests(void)
82{
83 u_char blob[] = {
84 /* u8 */
85 0xd0,
86 /* u16 */
87 0xc0, 0xde,
88 /* u32 */
89 0xfa, 0xce, 0xde, 0xad,
90 /* u64 */
91 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
92 /* string */
93 0x00, 0x00, 0x00, 0x09,
94 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
95 /* bignum1 */
96 0x79,
97 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
98 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
99 /* bignum2 */
100 0x00, 0x00, 0x00, 0x14,
101 0x00,
102 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
103 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
104 0x7f, 0xff, 0x11,
105 /* EC point (NIST-256 curve) */
106 0x00, 0x00, 0x00, 0x41,
107 0x04,
108 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
109 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
110 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
111 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
112 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
113 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
114 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
115 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
116 };
117 struct fuzz *fuzz;
118
119 TEST_START("fuzz blob parsing");
120 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
121 FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
122 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
123 TEST_ONERROR(onerror, fuzz);
124 for(; !fuzz_done(fuzz); fuzz_next(fuzz))
125 attempt_parse_blob(blob, sizeof(blob));
126 fuzz_cleanup(fuzz);
127 TEST_DONE();
128 TEST_ONERROR(NULL, NULL);
129}
130
diff --git a/regress/unittests/sshbuf/test_sshbuf_misc.c b/regress/unittests/sshbuf/test_sshbuf_misc.c
new file mode 100644
index 000000000..f155491a0
--- /dev/null
+++ b/regress/unittests/sshbuf/test_sshbuf_misc.c
@@ -0,0 +1,138 @@
1/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14# include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include "../test_helper/test_helper.h"
20
21#include "sshbuf.h"
22
23void sshbuf_misc_tests(void);
24
25void
26sshbuf_misc_tests(void)
27{
28 struct sshbuf *p1;
29 char tmp[512], *p;
30 FILE *out;
31 size_t sz;
32
33 TEST_START("sshbuf_dump");
34 out = tmpfile();
35 ASSERT_PTR_NE(out, NULL);
36 p1 = sshbuf_new();
37 ASSERT_PTR_NE(p1, NULL);
38 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
39 sshbuf_dump(p1, out);
40 fflush(out);
41 rewind(out);
42 sz = fread(tmp, 1, sizeof(tmp), out);
43 ASSERT_INT_EQ(ferror(out), 0);
44 ASSERT_INT_NE(feof(out), 0);
45 ASSERT_SIZE_T_GT(sz, 0);
46 tmp[sz] = '\0';
47 ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
48 fclose(out);
49 sshbuf_free(p1);
50 TEST_DONE();
51
52 TEST_START("sshbuf_dtob16");
53 p1 = sshbuf_new();
54 ASSERT_PTR_NE(p1, NULL);
55 ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
56 p = sshbuf_dtob16(p1);
57 ASSERT_PTR_NE(p, NULL);
58 ASSERT_STRING_EQ(p, "12345678");
59 free(p);
60 sshbuf_free(p1);
61 TEST_DONE();
62
63 TEST_START("sshbuf_dtob64 len 1");
64 p1 = sshbuf_new();
65 ASSERT_PTR_NE(p1, NULL);
66 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
67 p = sshbuf_dtob64(p1);
68 ASSERT_PTR_NE(p, NULL);
69 ASSERT_STRING_EQ(p, "EQ==");
70 free(p);
71 sshbuf_free(p1);
72 TEST_DONE();
73
74 TEST_START("sshbuf_dtob64 len 2");
75 p1 = sshbuf_new();
76 ASSERT_PTR_NE(p1, NULL);
77 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
78 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
79 p = sshbuf_dtob64(p1);
80 ASSERT_PTR_NE(p, NULL);
81 ASSERT_STRING_EQ(p, "ESI=");
82 free(p);
83 sshbuf_free(p1);
84 TEST_DONE();
85
86 TEST_START("sshbuf_dtob64 len 3");
87 p1 = sshbuf_new();
88 ASSERT_PTR_NE(p1, NULL);
89 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
90 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
91 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
92 p = sshbuf_dtob64(p1);
93 ASSERT_PTR_NE(p, NULL);
94 ASSERT_STRING_EQ(p, "ESIz");
95 free(p);
96 sshbuf_free(p1);
97 TEST_DONE();
98
99 TEST_START("sshbuf_dtob64 len 8191");
100 p1 = sshbuf_new();
101 ASSERT_PTR_NE(p1, NULL);
102 ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
103 bzero(sshbuf_mutable_ptr(p1), 8192);
104 p = sshbuf_dtob64(p1);
105 ASSERT_PTR_NE(p, NULL);
106 ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
107 free(p);
108 sshbuf_free(p1);
109 TEST_DONE();
110
111 TEST_START("sshbuf_b64tod len 1");
112 p1 = sshbuf_new();
113 ASSERT_PTR_NE(p1, NULL);
114 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
115 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
116 ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
117 sshbuf_free(p1);
118 TEST_DONE();
119
120 TEST_START("sshbuf_b64tod len 2");
121 p1 = sshbuf_new();
122 ASSERT_PTR_NE(p1, NULL);
123 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
125 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
126 sshbuf_free(p1);
127 TEST_DONE();
128
129 TEST_START("sshbuf_b64tod len 4");
130 p1 = sshbuf_new();
131 ASSERT_PTR_NE(p1, NULL);
132 ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
133 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
134 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
135 sshbuf_free(p1);
136 TEST_DONE();
137}
138
diff --git a/regress/unittests/sshbuf/tests.c b/regress/unittests/sshbuf/tests.c
new file mode 100644
index 000000000..1557e4342
--- /dev/null
+++ b/regress/unittests/sshbuf/tests.c
@@ -0,0 +1,28 @@
1/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "../test_helper/test_helper.h"
9
10void sshbuf_tests(void);
11void sshbuf_getput_basic_tests(void);
12void sshbuf_getput_crypto_tests(void);
13void sshbuf_misc_tests(void);
14void sshbuf_fuzz_tests(void);
15void sshbuf_getput_fuzz_tests(void);
16void sshbuf_fixed(void);
17
18void
19tests(void)
20{
21 sshbuf_tests();
22 sshbuf_getput_basic_tests();
23 sshbuf_getput_crypto_tests();
24 sshbuf_misc_tests();
25 sshbuf_fuzz_tests();
26 sshbuf_getput_fuzz_tests();
27 sshbuf_fixed();
28}
diff --git a/regress/unittests/sshkey/Makefile b/regress/unittests/sshkey/Makefile
new file mode 100644
index 000000000..1bcd26676
--- /dev/null
+++ b/regress/unittests/sshkey/Makefile
@@ -0,0 +1,13 @@
1# $OpenBSD: Makefile,v 1.1 2014/06/24 01:14:18 djm Exp $
2
3TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
4
5PROG=test_sshkey
6SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c
7REGRESS_TARGETS=run-regress-${PROG}
8
9run-regress-${PROG}: ${PROG}
10 env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
11
12.include <bsd.regress.mk>
13
diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c
new file mode 100644
index 000000000..0a4b3a90c
--- /dev/null
+++ b/regress/unittests/sshkey/common.c
@@ -0,0 +1,84 @@
1/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Helpers for key API tests
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <sys/stat.h>
13#include <fcntl.h>
14#include <stdio.h>
15#ifdef HAVE_STDINT_H
16#include <stdint.h>
17#endif
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21
22#include <openssl/bn.h>
23#include <openssl/rsa.h>
24#include <openssl/dsa.h>
25#include <openssl/objects.h>
26#ifdef OPENSSL_HAS_NISTP256
27# include <openssl/ec.h>
28#endif
29
30#include "../test_helper/test_helper.h"
31
32#include "ssherr.h"
33#include "authfile.h"
34#include "sshkey.h"
35#include "sshbuf.h"
36
37#include "common.h"
38
39struct sshbuf *
40load_file(const char *name)
41{
42 int fd;
43 struct sshbuf *ret;
44
45 ASSERT_PTR_NE(ret = sshbuf_new(), NULL);
46 ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1);
47 ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0);
48 close(fd);
49 return ret;
50}
51
52struct sshbuf *
53load_text_file(const char *name)
54{
55 struct sshbuf *ret = load_file(name);
56 const u_char *p;
57
58 /* Trim whitespace at EOL */
59 for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) {
60 if (p[sshbuf_len(ret) - 1] == '\r' ||
61 p[sshbuf_len(ret) - 1] == '\t' ||
62 p[sshbuf_len(ret) - 1] == ' ' ||
63 p[sshbuf_len(ret) - 1] == '\n')
64 ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0);
65 else
66 break;
67 }
68 /* \0 terminate */
69 ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0);
70 return ret;
71}
72
73BIGNUM *
74load_bignum(const char *name)
75{
76 BIGNUM *ret = NULL;
77 struct sshbuf *buf;
78
79 buf = load_text_file(name);
80 ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0);
81 sshbuf_free(buf);
82 return ret;
83}
84
diff --git a/regress/unittests/sshkey/common.h b/regress/unittests/sshkey/common.h
new file mode 100644
index 000000000..bf7d19dce
--- /dev/null
+++ b/regress/unittests/sshkey/common.h
@@ -0,0 +1,16 @@
1/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Helpers for key API tests
4 *
5 * Placed in the public domain
6 */
7
8/* Load a binary file into a buffer */
9struct sshbuf *load_file(const char *name);
10
11/* Load a text file into a buffer */
12struct sshbuf *load_text_file(const char *name);
13
14/* Load a bignum from a file */
15BIGNUM *load_bignum(const char *name);
16
diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh
new file mode 100755
index 000000000..ee1fe3962
--- /dev/null
+++ b/regress/unittests/sshkey/mktestdata.sh
@@ -0,0 +1,190 @@
1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $
3
4PW=mekmitasdigoat
5
6rsa1_params() {
7 _in="$1"
8 _outbase="$2"
9 set -e
10 ssh-keygen -f $_in -e -m pkcs8 | \
11 openssl rsa -noout -text -pubin | \
12 awk '/^Modulus:$/,/^Exponent:/' | \
13 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
14 # XXX need conversion support in ssh-keygen for the other params
15 for x in n ; do
16 echo "" >> ${_outbase}.$x
17 echo ============ ${_outbase}.$x
18 cat ${_outbase}.$x
19 echo ============
20 done
21}
22
23rsa_params() {
24 _in="$1"
25 _outbase="$2"
26 set -e
27 openssl rsa -noout -text -in $_in | \
28 awk '/^modulus:$/,/^publicExponent:/' | \
29 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
30 openssl rsa -noout -text -in $_in | \
31 awk '/^prime1:$/,/^prime2:/' | \
32 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.p
33 openssl rsa -noout -text -in $_in | \
34 awk '/^prime2:$/,/^exponent1:/' | \
35 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.q
36 for x in n p q ; do
37 echo "" >> ${_outbase}.$x
38 echo ============ ${_outbase}.$x
39 cat ${_outbase}.$x
40 echo ============
41 done
42}
43
44dsa_params() {
45 _in="$1"
46 _outbase="$2"
47 set -e
48 openssl dsa -noout -text -in $_in | \
49 awk '/^priv:$/,/^pub:/' | \
50 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
51 openssl dsa -noout -text -in $_in | \
52 awk '/^pub:/,/^P:/' | #\
53 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
54 openssl dsa -noout -text -in $_in | \
55 awk '/^G:/,0' | \
56 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g
57 for x in priv pub g ; do
58 echo "" >> ${_outbase}.$x
59 echo ============ ${_outbase}.$x
60 cat ${_outbase}.$x
61 echo ============
62 done
63}
64
65ecdsa_params() {
66 _in="$1"
67 _outbase="$2"
68 set -e
69 openssl ec -noout -text -in $_in | \
70 awk '/^priv:$/,/^pub:/' | \
71 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
72 openssl ec -noout -text -in $_in | \
73 awk '/^pub:/,/^ASN1 OID:/' | #\
74 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
75 openssl ec -noout -text -in $_in | \
76 grep "ASN1 OID:" | tr -d '\n' | \
77 sed 's/.*: //;s/ *$//' > ${_outbase}.curve
78 for x in priv pub curve ; do
79 echo "" >> ${_outbase}.$x
80 echo ============ ${_outbase}.$x
81 cat ${_outbase}.$x
82 echo ============
83 done
84}
85
86set -ex
87
88cd testdata
89
90rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1
91rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2
92rm -f rsa_n dsa_n ecdsa_n # new-format keys
93rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw
94rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw
95rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb
96
97ssh-keygen -t rsa1 -b 768 -C "RSA1 test key #1" -N "" -f rsa1_1
98ssh-keygen -t rsa -b 768 -C "RSA test key #1" -N "" -f rsa_1
99ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1
100ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1
101ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1
102
103ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2
104ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2
105ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2
106ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2
107ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_2
108
109cp rsa_1 rsa_n
110cp dsa_1 dsa_n
111cp ecdsa_1 ecdsa_n
112
113cp rsa1_1 rsa1_1_pw
114cp rsa_1 rsa_1_pw
115cp dsa_1 dsa_1_pw
116cp ecdsa_1 ecdsa_1_pw
117cp ed25519_1 ed25519_1_pw
118cp rsa_1 rsa_n_pw
119cp dsa_1 dsa_n_pw
120cp ecdsa_1 ecdsa_n_pw
121
122ssh-keygen -pf rsa1_1_pw -N "$PW"
123ssh-keygen -pf rsa_1_pw -N "$PW"
124ssh-keygen -pf dsa_1_pw -N "$PW"
125ssh-keygen -pf ecdsa_1_pw -N "$PW"
126ssh-keygen -pf ed25519_1_pw -N "$PW"
127ssh-keygen -opf rsa_n_pw -N "$PW"
128ssh-keygen -opf dsa_n_pw -N "$PW"
129ssh-keygen -opf ecdsa_n_pw -N "$PW"
130
131rsa1_params rsa1_1 rsa1_1.param
132rsa1_params rsa1_2 rsa1_2.param
133rsa_params rsa_1 rsa_1.param
134rsa_params rsa_2 rsa_2.param
135dsa_params dsa_1 dsa_1.param
136dsa_params dsa_1 dsa_1.param
137ecdsa_params ecdsa_1 ecdsa_1.param
138ecdsa_params ecdsa_2 ecdsa_2.param
139# XXX ed25519 params
140
141ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
142 -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
143 -V 19990101:20110101 -z 1 rsa_1.pub
144ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
145 -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
146 -V 19990101:20110101 -z 2 dsa_1.pub
147ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
148 -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
149 -V 19990101:20110101 -z 3 ecdsa_1.pub
150ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
151 -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
152 -V 19990101:20110101 -z 4 ed25519_1.pub
153
154ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
155 -V 19990101:20110101 -z 5 rsa_1.pub
156ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
157 -V 19990101:20110101 -z 6 dsa_1.pub
158ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
159 -V 19990101:20110101 -z 7 ecdsa_1.pub
160ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
161 -V 19990101:20110101 -z 8 ed25519_1.pub
162
163ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp
164ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp
165ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp
166ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp
167ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp
168ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp
169ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp
170ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp
171ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp
172ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp
173
174ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp
175ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp
176ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp
177ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp
178
179ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb
180ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb
181ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb
182ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb
183ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb
184ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb
185ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb
186ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
188ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
189
190echo "$PW" > pw
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
new file mode 100644
index 000000000..764f7fb76
--- /dev/null
+++ b/regress/unittests/sshkey/test_file.c
@@ -0,0 +1,457 @@
1/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Regress test for sshkey.h key management API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <sys/stat.h>
13#include <fcntl.h>
14#include <stdio.h>
15#ifdef HAVE_STDINT_H
16#include <stdint.h>
17#endif
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21
22#include <openssl/bn.h>
23#include <openssl/rsa.h>
24#include <openssl/dsa.h>
25#include <openssl/objects.h>
26#ifdef OPENSSL_HAS_NISTP256
27# include <openssl/ec.h>
28#endif
29
30#include "../test_helper/test_helper.h"
31
32#include "ssherr.h"
33#include "authfile.h"
34#include "sshkey.h"
35#include "sshbuf.h"
36
37#include "common.h"
38
39void sshkey_file_tests(void);
40
41void
42sshkey_file_tests(void)
43{
44 struct sshkey *k1, *k2;
45 struct sshbuf *buf, *pw;
46 BIGNUM *a, *b, *c;
47 char *cp;
48
49 TEST_START("load passphrase");
50 pw = load_text_file("pw");
51 TEST_DONE();
52
53 TEST_START("parse RSA1 from private");
54 buf = load_file("rsa1_1");
55 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
56 &k1, NULL), 0);
57 sshbuf_free(buf);
58 ASSERT_PTR_NE(k1, NULL);
59 a = load_bignum("rsa1_1.param.n");
60 ASSERT_BIGNUM_EQ(k1->rsa->n, a);
61 BN_free(a);
62 TEST_DONE();
63
64 TEST_START("parse RSA1 from private w/ passphrase");
65 buf = load_file("rsa1_1_pw");
66 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
67 (const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0);
68 sshbuf_free(buf);
69 ASSERT_PTR_NE(k2, NULL);
70 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
71 sshkey_free(k2);
72 TEST_DONE();
73
74 TEST_START("load RSA1 from public");
75 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2,
76 NULL), 0);
77 ASSERT_PTR_NE(k2, NULL);
78 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
79 sshkey_free(k2);
80 TEST_DONE();
81
82 TEST_START("RSA1 key hex fingerprint");
83 buf = load_text_file("rsa1_1.fp");
84 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
85 ASSERT_PTR_NE(cp, NULL);
86 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
87 sshbuf_free(buf);
88 free(cp);
89 TEST_DONE();
90
91 TEST_START("RSA1 key bubblebabble fingerprint");
92 buf = load_text_file("rsa1_1.fp.bb");
93 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
94 ASSERT_PTR_NE(cp, NULL);
95 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
96 sshbuf_free(buf);
97 free(cp);
98 TEST_DONE();
99
100 sshkey_free(k1);
101
102 TEST_START("parse RSA from private");
103 buf = load_file("rsa_1");
104 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1",
105 &k1, NULL), 0);
106 sshbuf_free(buf);
107 ASSERT_PTR_NE(k1, NULL);
108 a = load_bignum("rsa_1.param.n");
109 b = load_bignum("rsa_1.param.p");
110 c = load_bignum("rsa_1.param.q");
111 ASSERT_BIGNUM_EQ(k1->rsa->n, a);
112 ASSERT_BIGNUM_EQ(k1->rsa->p, b);
113 ASSERT_BIGNUM_EQ(k1->rsa->q, c);
114 BN_free(a);
115 BN_free(b);
116 BN_free(c);
117 TEST_DONE();
118
119 TEST_START("parse RSA from private w/ passphrase");
120 buf = load_file("rsa_1_pw");
121 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
122 (const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0);
123 sshbuf_free(buf);
124 ASSERT_PTR_NE(k2, NULL);
125 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
126 sshkey_free(k2);
127 TEST_DONE();
128
129 TEST_START("parse RSA from new-format");
130 buf = load_file("rsa_n");
131 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
132 "", "rsa_n", &k2, NULL), 0);
133 sshbuf_free(buf);
134 ASSERT_PTR_NE(k2, NULL);
135 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
136 sshkey_free(k2);
137 TEST_DONE();
138
139 TEST_START("parse RSA from new-format w/ passphrase");
140 buf = load_file("rsa_n_pw");
141 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
142 (const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0);
143 sshbuf_free(buf);
144 ASSERT_PTR_NE(k2, NULL);
145 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
146 sshkey_free(k2);
147 TEST_DONE();
148
149 TEST_START("load RSA from public");
150 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
151 NULL), 0);
152 ASSERT_PTR_NE(k2, NULL);
153 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
154 sshkey_free(k2);
155 TEST_DONE();
156
157 TEST_START("load RSA cert");
158 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0);
159 ASSERT_PTR_NE(k2, NULL);
160 ASSERT_INT_EQ(k2->type, KEY_RSA_CERT);
161 ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
162 ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
163 TEST_DONE();
164
165 TEST_START("RSA key hex fingerprint");
166 buf = load_text_file("rsa_1.fp");
167 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
168 ASSERT_PTR_NE(cp, NULL);
169 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
170 sshbuf_free(buf);
171 free(cp);
172 TEST_DONE();
173
174 TEST_START("RSA cert hex fingerprint");
175 buf = load_text_file("rsa_1-cert.fp");
176 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
177 ASSERT_PTR_NE(cp, NULL);
178 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
179 sshbuf_free(buf);
180 free(cp);
181 sshkey_free(k2);
182 TEST_DONE();
183
184 TEST_START("RSA key bubblebabble fingerprint");
185 buf = load_text_file("rsa_1.fp.bb");
186 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
187 ASSERT_PTR_NE(cp, NULL);
188 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
189 sshbuf_free(buf);
190 free(cp);
191 TEST_DONE();
192
193 sshkey_free(k1);
194
195 TEST_START("parse DSA from private");
196 buf = load_file("dsa_1");
197 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1",
198 &k1, NULL), 0);
199 sshbuf_free(buf);
200 ASSERT_PTR_NE(k1, NULL);
201 a = load_bignum("dsa_1.param.g");
202 b = load_bignum("dsa_1.param.priv");
203 c = load_bignum("dsa_1.param.pub");
204 ASSERT_BIGNUM_EQ(k1->dsa->g, a);
205 ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
206 ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
207 BN_free(a);
208 BN_free(b);
209 BN_free(c);
210 TEST_DONE();
211
212 TEST_START("parse DSA from private w/ passphrase");
213 buf = load_file("dsa_1_pw");
214 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
215 (const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0);
216 sshbuf_free(buf);
217 ASSERT_PTR_NE(k2, NULL);
218 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
219 sshkey_free(k2);
220 TEST_DONE();
221
222 TEST_START("parse DSA from new-format");
223 buf = load_file("dsa_n");
224 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
225 "", "dsa_n", &k2, NULL), 0);
226 sshbuf_free(buf);
227 ASSERT_PTR_NE(k2, NULL);
228 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
229 sshkey_free(k2);
230 TEST_DONE();
231
232 TEST_START("parse DSA from new-format w/ passphrase");
233 buf = load_file("dsa_n_pw");
234 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
235 (const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0);
236 sshbuf_free(buf);
237 ASSERT_PTR_NE(k2, NULL);
238 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
239 sshkey_free(k2);
240 TEST_DONE();
241
242 TEST_START("load DSA from public");
243 ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2,
244 NULL), 0);
245 ASSERT_PTR_NE(k2, NULL);
246 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
247 sshkey_free(k2);
248 TEST_DONE();
249
250 TEST_START("load DSA cert");
251 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0);
252 ASSERT_PTR_NE(k2, NULL);
253 ASSERT_INT_EQ(k2->type, KEY_DSA_CERT);
254 ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
255 ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
256 TEST_DONE();
257
258 TEST_START("DSA key hex fingerprint");
259 buf = load_text_file("dsa_1.fp");
260 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
261 ASSERT_PTR_NE(cp, NULL);
262 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
263 sshbuf_free(buf);
264 free(cp);
265 TEST_DONE();
266
267 TEST_START("DSA cert hex fingerprint");
268 buf = load_text_file("dsa_1-cert.fp");
269 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
270 ASSERT_PTR_NE(cp, NULL);
271 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
272 sshbuf_free(buf);
273 free(cp);
274 sshkey_free(k2);
275 TEST_DONE();
276
277 TEST_START("DSA key bubblebabble fingerprint");
278 buf = load_text_file("dsa_1.fp.bb");
279 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
280 ASSERT_PTR_NE(cp, NULL);
281 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
282 sshbuf_free(buf);
283 free(cp);
284 TEST_DONE();
285
286 sshkey_free(k1);
287
288#ifdef OPENSSL_HAS_ECC
289 TEST_START("parse ECDSA from private");
290 buf = load_file("ecdsa_1");
291 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1",
292 &k1, NULL), 0);
293 sshbuf_free(buf);
294 ASSERT_PTR_NE(k1, NULL);
295 buf = load_text_file("ecdsa_1.param.curve");
296 ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf),
297 OBJ_nid2sn(k1->ecdsa_nid));
298 sshbuf_free(buf);
299 a = load_bignum("ecdsa_1.param.priv");
300 b = load_bignum("ecdsa_1.param.pub");
301 c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa),
302 EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED,
303 NULL, NULL);
304 ASSERT_PTR_NE(c, NULL);
305 ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a);
306 ASSERT_BIGNUM_EQ(b, c);
307 BN_free(a);
308 BN_free(b);
309 BN_free(c);
310 TEST_DONE();
311
312 TEST_START("parse ECDSA from private w/ passphrase");
313 buf = load_file("ecdsa_1_pw");
314 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
315 (const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0);
316 sshbuf_free(buf);
317 ASSERT_PTR_NE(k2, NULL);
318 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
319 sshkey_free(k2);
320 TEST_DONE();
321
322 TEST_START("parse ECDSA from new-format");
323 buf = load_file("ecdsa_n");
324 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
325 "", "ecdsa_n", &k2, NULL), 0);
326 sshbuf_free(buf);
327 ASSERT_PTR_NE(k2, NULL);
328 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
329 sshkey_free(k2);
330 TEST_DONE();
331
332 TEST_START("parse ECDSA from new-format w/ passphrase");
333 buf = load_file("ecdsa_n_pw");
334 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
335 (const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0);
336 sshbuf_free(buf);
337 ASSERT_PTR_NE(k2, NULL);
338 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
339 sshkey_free(k2);
340 TEST_DONE();
341
342 TEST_START("load ECDSA from public");
343 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2,
344 NULL), 0);
345 ASSERT_PTR_NE(k2, NULL);
346 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
347 sshkey_free(k2);
348 TEST_DONE();
349
350 TEST_START("load ECDSA cert");
351 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0);
352 ASSERT_PTR_NE(k2, NULL);
353 ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT);
354 ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
355 ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
356 TEST_DONE();
357
358 TEST_START("ECDSA key hex fingerprint");
359 buf = load_text_file("ecdsa_1.fp");
360 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
361 ASSERT_PTR_NE(cp, NULL);
362 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
363 sshbuf_free(buf);
364 free(cp);
365 TEST_DONE();
366
367 TEST_START("ECDSA cert hex fingerprint");
368 buf = load_text_file("ecdsa_1-cert.fp");
369 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
370 ASSERT_PTR_NE(cp, NULL);
371 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
372 sshbuf_free(buf);
373 free(cp);
374 sshkey_free(k2);
375 TEST_DONE();
376
377 TEST_START("ECDSA key bubblebabble fingerprint");
378 buf = load_text_file("ecdsa_1.fp.bb");
379 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
380 ASSERT_PTR_NE(cp, NULL);
381 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
382 sshbuf_free(buf);
383 free(cp);
384 TEST_DONE();
385
386 sshkey_free(k1);
387#endif /* OPENSSL_HAS_ECC */
388
389 TEST_START("parse Ed25519 from private");
390 buf = load_file("ed25519_1");
391 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1",
392 &k1, NULL), 0);
393 sshbuf_free(buf);
394 ASSERT_PTR_NE(k1, NULL);
395 ASSERT_INT_EQ(k1->type, KEY_ED25519);
396 /* XXX check key contents */
397 TEST_DONE();
398
399 TEST_START("parse Ed25519 from private w/ passphrase");
400 buf = load_file("ed25519_1_pw");
401 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
402 (const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0);
403 sshbuf_free(buf);
404 ASSERT_PTR_NE(k2, NULL);
405 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
406 sshkey_free(k2);
407 TEST_DONE();
408
409 TEST_START("load Ed25519 from public");
410 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2,
411 NULL), 0);
412 ASSERT_PTR_NE(k2, NULL);
413 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
414 sshkey_free(k2);
415 TEST_DONE();
416
417 TEST_START("load Ed25519 cert");
418 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0);
419 ASSERT_PTR_NE(k2, NULL);
420 ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT);
421 ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
422 ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
423 TEST_DONE();
424
425 TEST_START("Ed25519 key hex fingerprint");
426 buf = load_text_file("ed25519_1.fp");
427 cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
428 ASSERT_PTR_NE(cp, NULL);
429 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
430 sshbuf_free(buf);
431 free(cp);
432 TEST_DONE();
433
434 TEST_START("Ed25519 cert hex fingerprint");
435 buf = load_text_file("ed25519_1-cert.fp");
436 cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
437 ASSERT_PTR_NE(cp, NULL);
438 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
439 sshbuf_free(buf);
440 free(cp);
441 sshkey_free(k2);
442 TEST_DONE();
443
444 TEST_START("Ed25519 key bubblebabble fingerprint");
445 buf = load_text_file("ed25519_1.fp.bb");
446 cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
447 ASSERT_PTR_NE(cp, NULL);
448 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
449 sshbuf_free(buf);
450 free(cp);
451 TEST_DONE();
452
453 sshkey_free(k1);
454
455 sshbuf_free(pw);
456
457}
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c
new file mode 100644
index 000000000..a3f61a6df
--- /dev/null
+++ b/regress/unittests/sshkey/test_fuzz.c
@@ -0,0 +1,406 @@
1/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Fuzz tests for key parsing
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <sys/stat.h>
13#include <fcntl.h>
14#include <stdio.h>
15#ifdef HAVE_STDINT_H
16#include <stdint.h>
17#endif
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21
22#include <openssl/bn.h>
23#include <openssl/rsa.h>
24#include <openssl/dsa.h>
25#include <openssl/objects.h>
26#ifdef OPENSSL_HAS_NISTP256
27# include <openssl/ec.h>
28#endif
29
30#include "../test_helper/test_helper.h"
31
32#include "ssherr.h"
33#include "authfile.h"
34#include "sshkey.h"
35#include "sshbuf.h"
36
37#include "common.h"
38
39void sshkey_fuzz_tests(void);
40
41static void
42onerror(void *fuzz)
43{
44 fprintf(stderr, "Failed during fuzz:\n");
45 fuzz_dump((struct fuzz *)fuzz);
46}
47
48static void
49public_fuzz(struct sshkey *k)
50{
51 struct sshkey *k1;
52 struct sshbuf *buf;
53 struct fuzz *fuzz;
54
55 ASSERT_PTR_NE(buf = sshbuf_new(), NULL);
56 ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0);
57 /* XXX need a way to run the tests in "slow, but complete" mode */
58 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */
59 FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */
60 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
61 sshbuf_mutable_ptr(buf), sshbuf_len(buf));
62 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf),
63 &k1), 0);
64 sshkey_free(k1);
65 sshbuf_free(buf);
66 TEST_ONERROR(onerror, fuzz);
67 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
68 if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0)
69 sshkey_free(k1);
70 }
71 fuzz_cleanup(fuzz);
72}
73
74static void
75sig_fuzz(struct sshkey *k)
76{
77 struct fuzz *fuzz;
78 u_char *sig, c[] = "some junk to be signed";
79 size_t l;
80
81 ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0);
82 ASSERT_SIZE_T_GT(l, 0);
83 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */
84 FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
85 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l);
86 ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0);
87 free(sig);
88 TEST_ONERROR(onerror, fuzz);
89 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
90 sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
91 c, sizeof(c), 0);
92 }
93 fuzz_cleanup(fuzz);
94}
95
96void
97sshkey_fuzz_tests(void)
98{
99 struct sshkey *k1;
100 struct sshbuf *buf, *fuzzed;
101 struct fuzz *fuzz;
102 int r;
103
104 TEST_START("fuzz RSA1 private");
105 buf = load_file("rsa1_1");
106 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
107 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
108 sshbuf_mutable_ptr(buf), sshbuf_len(buf));
109 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
110 &k1, NULL), 0);
111 sshkey_free(k1);
112 sshbuf_free(buf);
113 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
114 TEST_ONERROR(onerror, fuzz);
115 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
116 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
117 ASSERT_INT_EQ(r, 0);
118 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
119 &k1, NULL) == 0)
120 sshkey_free(k1);
121 sshbuf_reset(fuzzed);
122 }
123 sshbuf_free(fuzzed);
124 fuzz_cleanup(fuzz);
125 TEST_DONE();
126
127 TEST_START("fuzz RSA1 public");
128 buf = load_file("rsa1_1_pw");
129 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
130 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
131 sshbuf_mutable_ptr(buf), sshbuf_len(buf));
132 ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0);
133 sshkey_free(k1);
134 sshbuf_free(buf);
135 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
136 TEST_ONERROR(onerror, fuzz);
137 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
138 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
139 ASSERT_INT_EQ(r, 0);
140 if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0)
141 sshkey_free(k1);
142 sshbuf_reset(fuzzed);
143 }
144 sshbuf_free(fuzzed);
145 fuzz_cleanup(fuzz);
146 TEST_DONE();
147
148 TEST_START("fuzz RSA private");
149 buf = load_file("rsa_1");
150 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
151 sshbuf_len(buf));
152 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
153 &k1, NULL), 0);
154 sshkey_free(k1);
155 sshbuf_free(buf);
156 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
157 TEST_ONERROR(onerror, fuzz);
158 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
159 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
160 ASSERT_INT_EQ(r, 0);
161 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
162 &k1, NULL) == 0)
163 sshkey_free(k1);
164 sshbuf_reset(fuzzed);
165 }
166 sshbuf_free(fuzzed);
167 fuzz_cleanup(fuzz);
168 TEST_DONE();
169
170 TEST_START("fuzz RSA new-format private");
171 buf = load_file("rsa_n");
172 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
173 sshbuf_len(buf));
174 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
175 &k1, NULL), 0);
176 sshkey_free(k1);
177 sshbuf_free(buf);
178 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
179 TEST_ONERROR(onerror, fuzz);
180 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
181 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
182 ASSERT_INT_EQ(r, 0);
183 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
184 &k1, NULL) == 0)
185 sshkey_free(k1);
186 sshbuf_reset(fuzzed);
187 }
188 sshbuf_free(fuzzed);
189 fuzz_cleanup(fuzz);
190 TEST_DONE();
191
192 TEST_START("fuzz DSA private");
193 buf = load_file("dsa_1");
194 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
195 sshbuf_len(buf));
196 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
197 &k1, NULL), 0);
198 sshkey_free(k1);
199 sshbuf_free(buf);
200 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
201 TEST_ONERROR(onerror, fuzz);
202 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
203 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
204 ASSERT_INT_EQ(r, 0);
205 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
206 &k1, NULL) == 0)
207 sshkey_free(k1);
208 sshbuf_reset(fuzzed);
209 }
210 sshbuf_free(fuzzed);
211 fuzz_cleanup(fuzz);
212 TEST_DONE();
213
214 TEST_START("fuzz DSA new-format private");
215 buf = load_file("dsa_n");
216 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
217 sshbuf_len(buf));
218 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
219 &k1, NULL), 0);
220 sshkey_free(k1);
221 sshbuf_free(buf);
222 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
223 TEST_ONERROR(onerror, fuzz);
224 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
225 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
226 ASSERT_INT_EQ(r, 0);
227 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
228 &k1, NULL) == 0)
229 sshkey_free(k1);
230 sshbuf_reset(fuzzed);
231 }
232 sshbuf_free(fuzzed);
233 fuzz_cleanup(fuzz);
234 TEST_DONE();
235
236#ifdef OPENSSL_HAS_ECC
237 TEST_START("fuzz ECDSA private");
238 buf = load_file("ecdsa_1");
239 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
240 sshbuf_len(buf));
241 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
242 &k1, NULL), 0);
243 sshkey_free(k1);
244 sshbuf_free(buf);
245 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
246 TEST_ONERROR(onerror, fuzz);
247 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
248 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
249 ASSERT_INT_EQ(r, 0);
250 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
251 &k1, NULL) == 0)
252 sshkey_free(k1);
253 sshbuf_reset(fuzzed);
254 }
255 sshbuf_free(fuzzed);
256 fuzz_cleanup(fuzz);
257 TEST_DONE();
258
259 TEST_START("fuzz ECDSA new-format private");
260 buf = load_file("ecdsa_n");
261 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
262 sshbuf_len(buf));
263 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
264 &k1, NULL), 0);
265 sshkey_free(k1);
266 sshbuf_free(buf);
267 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
268 TEST_ONERROR(onerror, fuzz);
269 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
270 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
271 ASSERT_INT_EQ(r, 0);
272 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
273 &k1, NULL) == 0)
274 sshkey_free(k1);
275 sshbuf_reset(fuzzed);
276 }
277 sshbuf_free(fuzzed);
278 fuzz_cleanup(fuzz);
279 TEST_DONE();
280#endif
281
282 TEST_START("fuzz Ed25519 private");
283 buf = load_file("ed25519_1");
284 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
285 sshbuf_len(buf));
286 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
287 &k1, NULL), 0);
288 sshkey_free(k1);
289 sshbuf_free(buf);
290 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
291 TEST_ONERROR(onerror, fuzz);
292 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
293 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
294 ASSERT_INT_EQ(r, 0);
295 if (sshkey_parse_private_fileblob(fuzzed, "", "key",
296 &k1, NULL) == 0)
297 sshkey_free(k1);
298 sshbuf_reset(fuzzed);
299 }
300 sshbuf_free(fuzzed);
301 fuzz_cleanup(fuzz);
302 TEST_DONE();
303
304 TEST_START("fuzz RSA public");
305 buf = load_file("rsa_1");
306 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
307 &k1, NULL), 0);
308 sshbuf_free(buf);
309 public_fuzz(k1);
310 sshkey_free(k1);
311 TEST_DONE();
312
313 TEST_START("fuzz RSA cert");
314 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
315 public_fuzz(k1);
316 sshkey_free(k1);
317 TEST_DONE();
318
319 TEST_START("fuzz DSA public");
320 buf = load_file("dsa_1");
321 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
322 &k1, NULL), 0);
323 sshbuf_free(buf);
324 public_fuzz(k1);
325 sshkey_free(k1);
326 TEST_DONE();
327
328 TEST_START("fuzz DSA cert");
329 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0);
330 public_fuzz(k1);
331 sshkey_free(k1);
332 TEST_DONE();
333
334#ifdef OPENSSL_HAS_ECC
335 TEST_START("fuzz ECDSA public");
336 buf = load_file("ecdsa_1");
337 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
338 &k1, NULL), 0);
339 sshbuf_free(buf);
340 public_fuzz(k1);
341 sshkey_free(k1);
342 TEST_DONE();
343
344 TEST_START("fuzz ECDSA cert");
345 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0);
346 public_fuzz(k1);
347 sshkey_free(k1);
348 TEST_DONE();
349#endif
350
351 TEST_START("fuzz Ed25519 public");
352 buf = load_file("ed25519_1");
353 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
354 &k1, NULL), 0);
355 sshbuf_free(buf);
356 public_fuzz(k1);
357 sshkey_free(k1);
358 TEST_DONE();
359
360 TEST_START("fuzz Ed25519 cert");
361 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0);
362 public_fuzz(k1);
363 sshkey_free(k1);
364 TEST_DONE();
365
366 TEST_START("fuzz RSA sig");
367 buf = load_file("rsa_1");
368 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
369 &k1, NULL), 0);
370 sshbuf_free(buf);
371 sig_fuzz(k1);
372 sshkey_free(k1);
373 TEST_DONE();
374
375 TEST_START("fuzz DSA sig");
376 buf = load_file("dsa_1");
377 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
378 &k1, NULL), 0);
379 sshbuf_free(buf);
380 sig_fuzz(k1);
381 sshkey_free(k1);
382 TEST_DONE();
383
384#ifdef OPENSSL_HAS_ECC
385 TEST_START("fuzz ECDSA sig");
386 buf = load_file("ecdsa_1");
387 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
388 &k1, NULL), 0);
389 sshbuf_free(buf);
390 sig_fuzz(k1);
391 sshkey_free(k1);
392 TEST_DONE();
393#endif
394
395 TEST_START("fuzz Ed25519 sig");
396 buf = load_file("ed25519_1");
397 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
398 &k1, NULL), 0);
399 sshbuf_free(buf);
400 sig_fuzz(k1);
401 sshkey_free(k1);
402 TEST_DONE();
403
404/* XXX fuzz decoded new-format blobs too */
405
406}
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
new file mode 100644
index 000000000..ef0c67956
--- /dev/null
+++ b/regress/unittests/sshkey/test_sshkey.c
@@ -0,0 +1,357 @@
1/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Regress test for sshkey.h key management API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <sys/param.h>
12#include <stdio.h>
13#ifdef HAVE_STDINT_H
14#include <stdint.h>
15#endif
16#include <stdlib.h>
17#include <string.h>
18
19#include <openssl/bn.h>
20#include <openssl/rsa.h>
21#include <openssl/dsa.h>
22#ifdef OPENSSL_HAS_NISTP256
23# include <openssl/ec.h>
24#endif
25
26#include "../test_helper/test_helper.h"
27
28#include "ssherr.h"
29#include "sshbuf.h"
30#define SSHBUF_INTERNAL 1 /* access internals for testing */
31#include "sshkey.h"
32
33#include "authfile.h"
34#include "common.h"
35#include "ssh2.h"
36
37void sshkey_tests(void);
38
39static void
40build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
41 const struct sshkey *sign_key, const struct sshkey *ca_key)
42{
43 struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
44 u_char *sigblob;
45 size_t siglen;
46
47 ca_buf = sshbuf_new();
48 ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
49
50 /*
51 * Get the public key serialisation by rendering the key and skipping
52 * the type string. This is a bit of a hack :/
53 */
54 pk = sshbuf_new();
55 ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
56 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
57
58 principals = sshbuf_new();
59 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
60 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
61
62 critopts = sshbuf_new();
63 /* XXX fill this in */
64
65 exts = sshbuf_new();
66 /* XXX fill this in */
67
68 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
69 ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
70 ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */
71 ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */
72 ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */
73 ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */
74 ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */
75 ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */
76 ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */
77 ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */
78 ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */
79 ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
80 ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
81 ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
82 sshbuf_ptr(b), sshbuf_len(b), 0), 0);
83 ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
84
85 free(sigblob);
86 sshbuf_free(ca_buf);
87 sshbuf_free(exts);
88 sshbuf_free(critopts);
89 sshbuf_free(principals);
90 sshbuf_free(pk);
91}
92
93void
94sshkey_tests(void)
95{
96 struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf;
97 struct sshbuf *b;
98
99 TEST_START("new invalid");
100 k1 = sshkey_new(-42);
101 ASSERT_PTR_EQ(k1, NULL);
102 TEST_DONE();
103
104 TEST_START("new/free KEY_UNSPEC");
105 k1 = sshkey_new(KEY_UNSPEC);
106 ASSERT_PTR_NE(k1, NULL);
107 sshkey_free(k1);
108 TEST_DONE();
109
110 TEST_START("new/free KEY_RSA1");
111 k1 = sshkey_new(KEY_RSA1);
112 ASSERT_PTR_NE(k1, NULL);
113 ASSERT_PTR_NE(k1->rsa, NULL);
114 ASSERT_PTR_NE(k1->rsa->n, NULL);
115 ASSERT_PTR_NE(k1->rsa->e, NULL);
116 ASSERT_PTR_EQ(k1->rsa->p, NULL);
117 sshkey_free(k1);
118 TEST_DONE();
119
120 TEST_START("new/free KEY_RSA");
121 k1 = sshkey_new(KEY_RSA);
122 ASSERT_PTR_NE(k1, NULL);
123 ASSERT_PTR_NE(k1->rsa, NULL);
124 ASSERT_PTR_NE(k1->rsa->n, NULL);
125 ASSERT_PTR_NE(k1->rsa->e, NULL);
126 ASSERT_PTR_EQ(k1->rsa->p, NULL);
127 sshkey_free(k1);
128 TEST_DONE();
129
130 TEST_START("new/free KEY_DSA");
131 k1 = sshkey_new(KEY_DSA);
132 ASSERT_PTR_NE(k1, NULL);
133 ASSERT_PTR_NE(k1->dsa, NULL);
134 ASSERT_PTR_NE(k1->dsa->g, NULL);
135 ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
136 sshkey_free(k1);
137 TEST_DONE();
138
139 TEST_START("new/free KEY_ECDSA");
140 k1 = sshkey_new(KEY_ECDSA);
141 ASSERT_PTR_NE(k1, NULL);
142 ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
143 sshkey_free(k1);
144 TEST_DONE();
145
146 TEST_START("new/free KEY_ED25519");
147 k1 = sshkey_new(KEY_ED25519);
148 ASSERT_PTR_NE(k1, NULL);
149 /* These should be blank until key loaded or generated */
150 ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
151 ASSERT_PTR_EQ(k1->ed25519_pk, NULL);
152 sshkey_free(k1);
153 TEST_DONE();
154
155 TEST_START("new_private KEY_RSA");
156 k1 = sshkey_new_private(KEY_RSA);
157 ASSERT_PTR_NE(k1, NULL);
158 ASSERT_PTR_NE(k1->rsa, NULL);
159 ASSERT_PTR_NE(k1->rsa->n, NULL);
160 ASSERT_PTR_NE(k1->rsa->e, NULL);
161 ASSERT_PTR_NE(k1->rsa->p, NULL);
162 ASSERT_INT_EQ(sshkey_add_private(k1), 0);
163 sshkey_free(k1);
164 TEST_DONE();
165
166 TEST_START("new_private KEY_DSA");
167 k1 = sshkey_new_private(KEY_DSA);
168 ASSERT_PTR_NE(k1, NULL);
169 ASSERT_PTR_NE(k1->dsa, NULL);
170 ASSERT_PTR_NE(k1->dsa->g, NULL);
171 ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
172 ASSERT_INT_EQ(sshkey_add_private(k1), 0);
173 sshkey_free(k1);
174 TEST_DONE();
175
176 TEST_START("generate KEY_RSA too small modulus");
177 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
178 SSH_ERR_INVALID_ARGUMENT);
179 ASSERT_PTR_EQ(k1, NULL);
180 TEST_DONE();
181
182 TEST_START("generate KEY_RSA too large modulus");
183 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
184 SSH_ERR_INVALID_ARGUMENT);
185 ASSERT_PTR_EQ(k1, NULL);
186 TEST_DONE();
187
188 TEST_START("generate KEY_DSA wrong bits");
189 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
190 SSH_ERR_INVALID_ARGUMENT);
191 ASSERT_PTR_EQ(k1, NULL);
192 sshkey_free(k1);
193 TEST_DONE();
194
195 TEST_START("generate KEY_ECDSA wrong bits");
196 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
197 SSH_ERR_INVALID_ARGUMENT);
198 ASSERT_PTR_EQ(k1, NULL);
199 sshkey_free(k1);
200 TEST_DONE();
201
202 TEST_START("generate KEY_RSA");
203 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0);
204 ASSERT_PTR_NE(kr, NULL);
205 ASSERT_PTR_NE(kr->rsa, NULL);
206 ASSERT_PTR_NE(kr->rsa->n, NULL);
207 ASSERT_PTR_NE(kr->rsa->e, NULL);
208 ASSERT_PTR_NE(kr->rsa->p, NULL);
209 ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768);
210 TEST_DONE();
211
212 TEST_START("generate KEY_DSA");
213 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
214 ASSERT_PTR_NE(kd, NULL);
215 ASSERT_PTR_NE(kd->dsa, NULL);
216 ASSERT_PTR_NE(kd->dsa->g, NULL);
217 ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
218 TEST_DONE();
219
220#ifdef OPENSSL_HAS_ECC
221 TEST_START("generate KEY_ECDSA");
222 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
223 ASSERT_PTR_NE(ke, NULL);
224 ASSERT_PTR_NE(ke->ecdsa, NULL);
225 ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
226 ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL);
227 TEST_DONE();
228#endif
229
230 TEST_START("generate KEY_ED25519");
231 ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
232 ASSERT_PTR_NE(kf, NULL);
233 ASSERT_INT_EQ(kf->type, KEY_ED25519);
234 ASSERT_PTR_NE(kf->ed25519_pk, NULL);
235 ASSERT_PTR_NE(kf->ed25519_sk, NULL);
236 TEST_DONE();
237
238 TEST_START("demote KEY_RSA");
239 ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0);
240 ASSERT_PTR_NE(k1, NULL);
241 ASSERT_PTR_NE(kr, k1);
242 ASSERT_INT_EQ(k1->type, KEY_RSA);
243 ASSERT_PTR_NE(k1->rsa, NULL);
244 ASSERT_PTR_NE(k1->rsa->n, NULL);
245 ASSERT_PTR_NE(k1->rsa->e, NULL);
246 ASSERT_PTR_EQ(k1->rsa->p, NULL);
247 TEST_DONE();
248
249 TEST_START("equal KEY_RSA/demoted KEY_RSA");
250 ASSERT_INT_EQ(sshkey_equal(kr, k1), 1);
251 sshkey_free(k1);
252 TEST_DONE();
253
254 TEST_START("demote KEY_DSA");
255 ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0);
256 ASSERT_PTR_NE(k1, NULL);
257 ASSERT_PTR_NE(kd, k1);
258 ASSERT_INT_EQ(k1->type, KEY_DSA);
259 ASSERT_PTR_NE(k1->dsa, NULL);
260 ASSERT_PTR_NE(k1->dsa->g, NULL);
261 ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
262 TEST_DONE();
263
264 TEST_START("equal KEY_DSA/demoted KEY_DSA");
265 ASSERT_INT_EQ(sshkey_equal(kd, k1), 1);
266 sshkey_free(k1);
267 TEST_DONE();
268
269#ifdef OPENSSL_HAS_ECC
270 TEST_START("demote KEY_ECDSA");
271 ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0);
272 ASSERT_PTR_NE(k1, NULL);
273 ASSERT_PTR_NE(ke, k1);
274 ASSERT_INT_EQ(k1->type, KEY_ECDSA);
275 ASSERT_PTR_NE(k1->ecdsa, NULL);
276 ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
277 ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
278 ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL);
279 TEST_DONE();
280
281 TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");
282 ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
283 sshkey_free(k1);
284 TEST_DONE();
285#endif
286
287 TEST_START("demote KEY_ED25519");
288 ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0);
289 ASSERT_PTR_NE(k1, NULL);
290 ASSERT_PTR_NE(kf, k1);
291 ASSERT_INT_EQ(k1->type, KEY_ED25519);
292 ASSERT_PTR_NE(k1->ed25519_pk, NULL);
293 ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
294 TEST_DONE();
295
296 TEST_START("equal KEY_ED25519/demoted KEY_ED25519");
297 ASSERT_INT_EQ(sshkey_equal(kf, k1), 1);
298 sshkey_free(k1);
299 TEST_DONE();
300
301 TEST_START("equal mismatched key types");
302 ASSERT_INT_EQ(sshkey_equal(kd, kr), 0);
303#ifdef OPENSSL_HAS_ECC
304 ASSERT_INT_EQ(sshkey_equal(kd, ke), 0);
305 ASSERT_INT_EQ(sshkey_equal(kr, ke), 0);
306 ASSERT_INT_EQ(sshkey_equal(ke, kf), 0);
307#endif
308 ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
309 TEST_DONE();
310
311 TEST_START("equal different keys");
312 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0);
313 ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
314 sshkey_free(k1);
315 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0);
316 ASSERT_INT_EQ(sshkey_equal(kd, k1), 0);
317 sshkey_free(k1);
318#ifdef OPENSSL_HAS_ECC
319 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
320 ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
321 sshkey_free(k1);
322#endif
323 ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
324 ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
325 sshkey_free(k1);
326 TEST_DONE();
327
328 sshkey_free(kr);
329 sshkey_free(kd);
330#ifdef OPENSSL_HAS_ECC
331 sshkey_free(ke);
332#endif
333 sshkey_free(kf);
334
335/* XXX certify test */
336/* XXX sign test */
337/* XXX verify test */
338
339 TEST_START("nested certificate");
340 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
341 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
342 NULL), 0);
343 b = load_file("rsa_2");
344 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
345 &k3, NULL), 0);
346 sshbuf_reset(b);
347 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
348 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
349 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
350 ASSERT_PTR_EQ(k4, NULL);
351 sshbuf_free(b);
352 sshkey_free(k1);
353 sshkey_free(k2);
354 sshkey_free(k3);
355 TEST_DONE();
356
357}
diff --git a/regress/unittests/sshkey/testdata/dsa_1 b/regress/unittests/sshkey/testdata/dsa_1
new file mode 100644
index 000000000..34346869f
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1
@@ -0,0 +1,12 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBuwIBAAKBgQCxBNwH8TmLXqiZa0b9pxC6W+zS4Voqp8S+QwecYpNPTmhjaUYI
3E/aJWAzFVtdbysLM89ukvw/z8qBkbMSefdypKmjUtgv51ZD4nfV4Wxb+G+1QExHr
4M+kowOOL3XbcsdbPLUt8vxDJbBlQRch4zyai7CWjQR3JFXpR8sevUFJxSQIVAIdE
5oncp2DEY2U/ZZnIyGCwApCzfAoGARW+eewZTv1Eosxv3ANKx372pf5+fQKwnWizI
6j5z/GY3w3xobRCP9FiL4K3Nip2FvHLTGpRrlfm19RWYAg77VsNgztC4V9C8QrKWc
7WJdkUkoQpZ3VoO25rO13hmIelkal3omKCF4ZE/edeF3d2B8DlzYs0aBcjTCMDrub
8/CJILcYCgYEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
94hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1
10/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gCFBl7Lc6V
11hmTiTuhLXjoRdCZS/p/m
12-----END DSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/unittests/sshkey/testdata/dsa_1-cert.fp
new file mode 100644
index 000000000..56ee1f89b
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1-cert.fp
@@ -0,0 +1 @@
5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.pub b/regress/unittests/sshkey/testdata/dsa_1-cert.pub
new file mode 100644
index 000000000..023edf136
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1-cert.pub
@@ -0,0 +1 @@
ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgj8zueN51MSQ7jW3fFwqyJWA3DycAAavQ8WgMHqcUG7YAAACBALEE3AfxOYteqJlrRv2nELpb7NLhWiqnxL5DB5xik09OaGNpRggT9olYDMVW11vKwszz26S/D/PyoGRsxJ593KkqaNS2C/nVkPid9XhbFv4b7VATEesz6SjA44vddtyx1s8tS3y/EMlsGVBFyHjPJqLsJaNBHckVelHyx69QUnFJAAAAFQCHRKJ3KdgxGNlP2WZyMhgsAKQs3wAAAIBFb557BlO/USizG/cA0rHfval/n59ArCdaLMiPnP8ZjfDfGhtEI/0WIvgrc2KnYW8ctMalGuV+bX1FZgCDvtWw2DO0LhX0LxCspZxYl2RSShClndWg7bms7XeGYh6WRqXeiYoIXhkT9514Xd3YHwOXNizRoFyNMIwOu5v8IkgtxgAAAIEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j4hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gAAAAAAAAABgAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bcLSB4073R7d0aAvR8gJrPvnV0D3MQAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEA6qftqozw0ah9PG9obAg8iOPwQv6AsT9t/1G69eArSd9Am85OKIhAvYguI1Xtr9rw78X/Xk+6HtyAOF3QemaQD dsa_1.pub
diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp b/regress/unittests/sshkey/testdata/dsa_1.fp
new file mode 100644
index 000000000..56ee1f89b
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.fp
@@ -0,0 +1 @@
5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74
diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp.bb b/regress/unittests/sshkey/testdata/dsa_1.fp.bb
new file mode 100644
index 000000000..07dd9b418
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.fp.bb
@@ -0,0 +1 @@
xosat-baneh-gocad-relek-kepur-mibip-motog-bykyb-hisug-mysus-tuxix
diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.g b/regress/unittests/sshkey/testdata/dsa_1.param.g
new file mode 100644
index 000000000..4b09f6d18
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.param.g
@@ -0,0 +1 @@
456f9e7b0653bf5128b31bf700d2b1dfbda97f9f9f40ac275a2cc88f9cff198df0df1a1b4423fd1622f82b7362a7616f1cb4c6a51ae57e6d7d45660083bed5b0d833b42e15f42f10aca59c589764524a10a59dd5a0edb9aced7786621e9646a5de898a085e1913f79d785dddd81f0397362cd1a05c8d308c0ebb9bfc22482dc6
diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.priv b/regress/unittests/sshkey/testdata/dsa_1.param.priv
new file mode 100644
index 000000000..2dd737cbe
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.param.priv
@@ -0,0 +1 @@
197b2dce958664e24ee84b5e3a11742652fe9fe6
diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.pub b/regress/unittests/sshkey/testdata/dsa_1.param.pub
new file mode 100644
index 000000000..b23d7207f
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.param.pub
@@ -0,0 +1 @@
00809b7d8de7c6422e1297917c8778d8a39d8bca013cb0d632bab12530a566ca1152289d487e2f63e21369da3673bbb8e96568589dd5283da1ba81b441edf2f7a79927951a373f60f39ddeaee8d01d86b003596f895fd9f5fc430a52fd21f2b44523fddbf516351d55730501fb577b0d27a89e907f09a8ecb596208c68cca5c388
diff --git a/regress/unittests/sshkey/testdata/dsa_1.pub b/regress/unittests/sshkey/testdata/dsa_1.pub
new file mode 100644
index 000000000..89681970c
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1.pub
@@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBALEE3AfxOYteqJlrRv2nELpb7NLhWiqnxL5DB5xik09OaGNpRggT9olYDMVW11vKwszz26S/D/PyoGRsxJ593KkqaNS2C/nVkPid9XhbFv4b7VATEesz6SjA44vddtyx1s8tS3y/EMlsGVBFyHjPJqLsJaNBHckVelHyx69QUnFJAAAAFQCHRKJ3KdgxGNlP2WZyMhgsAKQs3wAAAIBFb557BlO/USizG/cA0rHfval/n59ArCdaLMiPnP8ZjfDfGhtEI/0WIvgrc2KnYW8ctMalGuV+bX1FZgCDvtWw2DO0LhX0LxCspZxYl2RSShClndWg7bms7XeGYh6WRqXeiYoIXhkT9514Xd3YHwOXNizRoFyNMIwOu5v8IkgtxgAAAIEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j4hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4g= DSA test key #1
diff --git a/regress/unittests/sshkey/testdata/dsa_1_pw b/regress/unittests/sshkey/testdata/dsa_1_pw
new file mode 100644
index 000000000..1402153a0
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_1_pw
@@ -0,0 +1,15 @@
1-----BEGIN DSA PRIVATE KEY-----
2Proc-Type: 4,ENCRYPTED
3DEK-Info: AES-128-CBC,9E668E24E7B9D658E3E7D0446B32B376
4
5hDjDLbfCAQutblxLuyNzSLxISSgXTgyzq8St9GE0lUtEc7i0xGNWwoWpFSbtD9y1
6yTG5UkhATQt56SY1ABfXZ21wieYuEEQeSJi0gwUQNNt2SwwITx4EdzDedWiHjikt
7jbzH3v33agp/odw2X9wY6zu75y9CeW9o7SszRl286DliWIHJmhMlbb8r7jRqu62H
8s5YYxD0xS1ipWauxklmIXMWNZHcARo8ZiJOuNdLshrSrl8DUW9P6F89FvxclQzKr
944u3OBm7KbgPvPURDFLgNP6uCGBjzHvhHTpzVBxmQzCl3aGgsTKXiwJ1eupNjntB
10ji0EnbznvoxR6qhXxw/WQ+MnWlWqTXka/2qaB6m3oJv+Zn7cPCJ5kvHnhr2JmNMl
11igTh4Ov4LZLyNgO0Lbec4KyxW9QInRV5CY4Pu5lhqHteiPmOIGMWFtuh8Bb8Kg2q
12VvXnPo5I3FjqV7UhDduO1Wn558sBZWQPqRbHVPN6wXJuM3HGkBl+aNjn0qddv9tr
13VFJd/xdly2Ne81g3CB8jysE+3WEOrV9kdybocp/EhSOzP4i6pjWlyWdR5+CgbvRm
14TUIeIaQbmPIB5251o5YK+Q==
15-----END DSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/dsa_2 b/regress/unittests/sshkey/testdata/dsa_2
new file mode 100644
index 000000000..b189dc821
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_2
@@ -0,0 +1,12 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBuwIBAAKBgQDoMxCTyBnLPSO7CRU3RyfJLANLKBZ3/LdcsyNaARctaRA5gzRb
3XdTFFU+rWKfxv+otm0KyCOepLtWy8tjKRYb7Ni46USlGwtM0Adx/3vR4iWNfipDP
4K2V4O97JyMe3wsbF7siC01U4b8Ki+J44iFG9nuRnOTHqUWI615mraQRwlQIVAMsX
5nsPGH8QrU11F1ScAIfZC165dAoGACCXyOHFkxABpJDtJs6AE7Hl3XjI4dnlim/XH
6Y60W6gcO7gHSE2r2ljCubJqoUXmxd5mLKgnu91jIG/4URwDM4V7pb2k99sXpAi8I
7L52eQl88C0bRD9+lEJfR4PMT39EccDRPB4+E055RoYQZ/McIyad8sF3Qwt084Eq+
8IkUt2coCgYEAxZRpCY82sM9Mu4B0EcH6O8seRqIRScmelljhUtKxuvf2PChwIWkR
9HK9lORHBE3iKyurC5Muf3abuHKwMFjrOjHKOTqXBRrDZ7RgLQA0aUAQD3lWc9OTP
10NShjphpq5xr0HZB31eJg3/Mo6KxYlRpzMXbTyenZP0XLICSSAywvTDoCFG5whl2k
11Y2FLGfi9V6ylUVH6jKgE
12-----END DSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp b/regress/unittests/sshkey/testdata/dsa_2.fp
new file mode 100644
index 000000000..ba9de82a8
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_2.fp
@@ -0,0 +1 @@
72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a
diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp.bb b/regress/unittests/sshkey/testdata/dsa_2.fp.bb
new file mode 100644
index 000000000..37a5221a7
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_2.fp.bb
@@ -0,0 +1 @@
xesoh-mebaf-feced-lenuz-sicam-pevok-bosak-nogaz-ligen-fekef-fixex
diff --git a/regress/unittests/sshkey/testdata/dsa_2.pub b/regress/unittests/sshkey/testdata/dsa_2.pub
new file mode 100644
index 000000000..6ed2736b1
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_2.pub
@@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAOgzEJPIGcs9I7sJFTdHJ8ksA0soFnf8t1yzI1oBFy1pEDmDNFtd1MUVT6tYp/G/6i2bQrII56ku1bLy2MpFhvs2LjpRKUbC0zQB3H/e9HiJY1+KkM8rZXg73snIx7fCxsXuyILTVThvwqL4njiIUb2e5Gc5MepRYjrXmatpBHCVAAAAFQDLF57Dxh/EK1NdRdUnACH2QteuXQAAAIAIJfI4cWTEAGkkO0mzoATseXdeMjh2eWKb9cdjrRbqBw7uAdITavaWMK5smqhRebF3mYsqCe73WMgb/hRHAMzhXulvaT32xekCLwgvnZ5CXzwLRtEP36UQl9Hg8xPf0RxwNE8Hj4TTnlGhhBn8xwjJp3ywXdDC3TzgSr4iRS3ZygAAAIEAxZRpCY82sM9Mu4B0EcH6O8seRqIRScmelljhUtKxuvf2PChwIWkRHK9lORHBE3iKyurC5Muf3abuHKwMFjrOjHKOTqXBRrDZ7RgLQA0aUAQD3lWc9OTPNShjphpq5xr0HZB31eJg3/Mo6KxYlRpzMXbTyenZP0XLICSSAywvTDo= DSA test key #2
diff --git a/regress/unittests/sshkey/testdata/dsa_n b/regress/unittests/sshkey/testdata/dsa_n
new file mode 100644
index 000000000..34346869f
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_n
@@ -0,0 +1,12 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBuwIBAAKBgQCxBNwH8TmLXqiZa0b9pxC6W+zS4Voqp8S+QwecYpNPTmhjaUYI
3E/aJWAzFVtdbysLM89ukvw/z8qBkbMSefdypKmjUtgv51ZD4nfV4Wxb+G+1QExHr
4M+kowOOL3XbcsdbPLUt8vxDJbBlQRch4zyai7CWjQR3JFXpR8sevUFJxSQIVAIdE
5oncp2DEY2U/ZZnIyGCwApCzfAoGARW+eewZTv1Eosxv3ANKx372pf5+fQKwnWizI
6j5z/GY3w3xobRCP9FiL4K3Nip2FvHLTGpRrlfm19RWYAg77VsNgztC4V9C8QrKWc
7WJdkUkoQpZ3VoO25rO13hmIelkal3omKCF4ZE/edeF3d2B8DlzYs0aBcjTCMDrub
8/CJILcYCgYEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
94hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1
10/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gCFBl7Lc6V
11hmTiTuhLXjoRdCZS/p/m
12-----END DSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/dsa_n_pw b/regress/unittests/sshkey/testdata/dsa_n_pw
new file mode 100644
index 000000000..42f70dd23
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/dsa_n_pw
@@ -0,0 +1,22 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABD5nB+Nkw
3LNoPtAG7C3IdXmAAAAEAAAAAEAAAGyAAAAB3NzaC1kc3MAAACBALEE3AfxOYteqJlrRv2n
4ELpb7NLhWiqnxL5DB5xik09OaGNpRggT9olYDMVW11vKwszz26S/D/PyoGRsxJ593KkqaN
5S2C/nVkPid9XhbFv4b7VATEesz6SjA44vddtyx1s8tS3y/EMlsGVBFyHjPJqLsJaNBHckV
6elHyx69QUnFJAAAAFQCHRKJ3KdgxGNlP2WZyMhgsAKQs3wAAAIBFb557BlO/USizG/cA0r
7Hfval/n59ArCdaLMiPnP8ZjfDfGhtEI/0WIvgrc2KnYW8ctMalGuV+bX1FZgCDvtWw2DO0
8LhX0LxCspZxYl2RSShClndWg7bms7XeGYh6WRqXeiYoIXhkT9514Xd3YHwOXNizRoFyNMI
9wOu5v8IkgtxgAAAIEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
104hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1/EMKUv
110h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gAAAHw8P1DtkBulOGv85qf
12P+md2+LL+NKufVzHl9k2UKQFjeqY6uqs4HSDqvhXe7oiXd5mz6I7orxjtKU9hGjNF4ABUD
13OawVGe/GCRUQ4WgpAgDnqQLeFcdIwtMSIrRZU6xjs314EI7TM7IIiG26JEuXDfZI1e7C3y
14Cc38ZsP3zmg/UjgcCQar5c4n++vhOmeO36+fcUyZ1QlR05SaEtFYJA+otP3RmKTiDwob8Q
15zRMr8Y57i2NTTtFjkmnnnQCibP62yz7N22Dve7RTOH8jiaW7p02Vn/6WmCarevN1rxtLLR
16lkuWtPoKY8z/Ktcev8YE9f2+9H2TfXDRKYqIEfxgZLCJ4yP2gxDe6zurabS0hAO1CP+ej5
17htdJM3/rTqHAIevXX5uhIDmMvRHnLGldaIX1xux8TIJvSfMkYNIwscIP4kx7BGMk04vXtW
185DLm6IZhzw9T3hjr8R0kBugmT6/h9vD5iN1D+wiHIhHYzQKMU9nOeFNsMBFWgJjU0l8VlF
19gEjEMgAEfwynnmIoKB1iA/0em1tdU3naS59DBK+buE0trxUpTAAB5z8yPhAm6DdqrPE8cA
20N3HlMoWrbCuak2A0uyOlEJjPg4UJUnv12ve2c9pAMsAu/4CAszCEM0prR+qd/RA4nn4M5u
21Xrny2wNtt/DybCkA==
22-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1 b/regress/unittests/sshkey/testdata/ecdsa_1
new file mode 100644
index 000000000..aec73dd61
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1
@@ -0,0 +1,5 @@
1-----BEGIN EC PRIVATE KEY-----
2MHcCAQEEIFghsFR1K95tz8qOl3+tX6fv8a/O6AfNbxOSFZX3ihxooAoGCCqGSM49
3AwEHoUQDQgAEalpgP0BOePHtTw0Pus4tdhTb8P9yWUZluvLf1D8vrHImT+G4vr/W
4xo5iXGKQVEifuUVyLkAW2kDrq8J/szeRiQ==
5-----END EC PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
new file mode 100644
index 000000000..a56dbc8d0
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
@@ -0,0 +1 @@
f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub b/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub
new file mode 100644
index 000000000..29b06a4dd
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgjpoHehzmM54xz776HOiTOLPhkOwSWyXOMYeqDhDEcLgAAAAIbmlzdHAyNTYAAABBBGpaYD9ATnjx7U8ND7rOLXYU2/D/cllGZbry39Q/L6xyJk/huL6/1saOYlxikFRIn7lFci5AFtpA66vCf7M3kYkAAAAAAAAABwAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGpaYD9ATnjx7U8ND7rOLXYU2/D/cllGZbry39Q/L6xyJk/huL6/1saOYlxikFRIn7lFci5AFtpA66vCf7M3kYkAAABjAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABIAAAAIFZM1PXlXf0a3VuGs7MVdWSealDXprT1nN5hQTg+m+EYAAAAIGN1yNXWEY5V315NhOD3mBuh/xCpfDn5rZjF4YntA7du ecdsa_1.pub
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.fp b/regress/unittests/sshkey/testdata/ecdsa_1.fp
new file mode 100644
index 000000000..a56dbc8d0
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.fp
@@ -0,0 +1 @@
f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb b/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb
new file mode 100644
index 000000000..f01a5dd44
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb
@@ -0,0 +1 @@
xotah-hecal-zibyb-nadug-romuc-hator-venum-hobip-ruluh-ripus-naxix
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.param.curve b/regress/unittests/sshkey/testdata/ecdsa_1.param.curve
new file mode 100644
index 000000000..fa0400467
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.param.curve
@@ -0,0 +1 @@
prime256v1
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.param.priv b/regress/unittests/sshkey/testdata/ecdsa_1.param.priv
new file mode 100644
index 000000000..3475f1fe9
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.param.priv
@@ -0,0 +1 @@
5821b054752bde6dcfca8e977fad5fa7eff1afcee807cd6f13921595f78a1c68
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.param.pub b/regress/unittests/sshkey/testdata/ecdsa_1.param.pub
new file mode 100644
index 000000000..11847a394
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.param.pub
@@ -0,0 +1 @@
046a5a603f404e78f1ed4f0d0fbace2d7614dbf0ff72594665baf2dfd43f2fac72264fe1b8bebfd6c68e625c629054489fb945722e4016da40ebabc27fb3379189
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.pub b/regress/unittests/sshkey/testdata/ecdsa_1.pub
new file mode 100644
index 000000000..eca1620bc
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGpaYD9ATnjx7U8ND7rOLXYU2/D/cllGZbry39Q/L6xyJk/huL6/1saOYlxikFRIn7lFci5AFtpA66vCf7M3kYk= ECDSA test key #1
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1_pw b/regress/unittests/sshkey/testdata/ecdsa_1_pw
new file mode 100644
index 000000000..071154ab2
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_1_pw
@@ -0,0 +1,8 @@
1-----BEGIN EC PRIVATE KEY-----
2Proc-Type: 4,ENCRYPTED
3DEK-Info: AES-128-CBC,74C8AEA5BFAFCC2B1C8B13DE671F5610
4
5vUsgOvCqezxPmcZcFqrSy9Y1MMlVguY0h9cfSPFC7gUrRr+45uCOYX5bOwEXecKn
6/9uCXZtlBwwqDS9iK5IPoUrjEHvzI5rVbHWUxDrEOVbsfiDuCxrQM19It6QIqC1v
7OSQEdXuBWR5WmhKNc3dqLbWsU8u2s60YwKQmZrj9nM4=
8-----END EC PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2 b/regress/unittests/sshkey/testdata/ecdsa_2
new file mode 100644
index 000000000..76ae07ad4
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2
@@ -0,0 +1,7 @@
1-----BEGIN EC PRIVATE KEY-----
2MIHcAgEBBEIBg4kVxUfoo/RE/78/QBRqG6PZuHZ82eLnhmZVzBa7XREUiYI/Jw7r
3Qwp4FTBVfXL76Pt5AyBMf+52aVeOUlLRERSgBwYFK4EEACOhgYkDgYYABACNTJ5O
4uNo5dNgIQRLHzKU91m7immKFiutJ6BlDbkRkKr+Envj13J6HOgYvOTm0n7SPlKHS
5STZ4/T36d/rzQOAbIwEnbbwD9HMj6IzE4WH9lJzH7Zy7Tcyu6dOM8L7nOxCp3DUk
6F3aAnPSFJhD7NN0jBWOFsD6uy1OmaTklPfRAnCt1MQ==
7-----END EC PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.fp b/regress/unittests/sshkey/testdata/ecdsa_2.fp
new file mode 100644
index 000000000..eb4bbdf03
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.fp
@@ -0,0 +1 @@
51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb b/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb
new file mode 100644
index 000000000..267bc63fd
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb
@@ -0,0 +1 @@
xuzaz-zuzuk-virop-vypah-zumel-gylak-selih-fevad-varag-zynif-haxox
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.param.curve b/regress/unittests/sshkey/testdata/ecdsa_2.param.curve
new file mode 100644
index 000000000..617ea2fb8
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.param.curve
@@ -0,0 +1 @@
secp521r1
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.param.priv b/regress/unittests/sshkey/testdata/ecdsa_2.param.priv
new file mode 100644
index 000000000..537cdaac3
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.param.priv
@@ -0,0 +1 @@
01838915c547e8a3f444ffbf3f40146a1ba3d9b8767cd9e2e7866655cc16bb5d111489823f270eeb430a781530557d72fbe8fb7903204c7fee7669578e5252d11114
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.param.pub b/regress/unittests/sshkey/testdata/ecdsa_2.param.pub
new file mode 100644
index 000000000..3352ac769
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.param.pub
@@ -0,0 +1 @@
04008d4c9e4eb8da3974d8084112c7cca53dd66ee29a62858aeb49e819436e44642abf849ef8f5dc9e873a062f3939b49fb48f94a1d2493678fd3dfa77faf340e01b2301276dbc03f47323e88cc4e161fd949cc7ed9cbb4dccaee9d38cf0bee73b10a9dc35241776809cf4852610fb34dd23056385b03eaecb53a66939253df4409c2b7531
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.pub b/regress/unittests/sshkey/testdata/ecdsa_2.pub
new file mode 100644
index 000000000..34e1881dd
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_2.pub
@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACNTJ5OuNo5dNgIQRLHzKU91m7immKFiutJ6BlDbkRkKr+Envj13J6HOgYvOTm0n7SPlKHSSTZ4/T36d/rzQOAbIwEnbbwD9HMj6IzE4WH9lJzH7Zy7Tcyu6dOM8L7nOxCp3DUkF3aAnPSFJhD7NN0jBWOFsD6uy1OmaTklPfRAnCt1MQ== ECDSA test key #2
diff --git a/regress/unittests/sshkey/testdata/ecdsa_n b/regress/unittests/sshkey/testdata/ecdsa_n
new file mode 100644
index 000000000..aec73dd61
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_n
@@ -0,0 +1,5 @@
1-----BEGIN EC PRIVATE KEY-----
2MHcCAQEEIFghsFR1K95tz8qOl3+tX6fv8a/O6AfNbxOSFZX3ihxooAoGCCqGSM49
3AwEHoUQDQgAEalpgP0BOePHtTw0Pus4tdhTb8P9yWUZluvLf1D8vrHImT+G4vr/W
4xo5iXGKQVEifuUVyLkAW2kDrq8J/szeRiQ==
5-----END EC PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ecdsa_n_pw b/regress/unittests/sshkey/testdata/ecdsa_n_pw
new file mode 100644
index 000000000..75d585908
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ecdsa_n_pw
@@ -0,0 +1,9 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBXqI6Z6o
3uRM+jAwdhnDoIMAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz
4dHAyNTYAAABBBGpaYD9ATnjx7U8ND7rOLXYU2/D/cllGZbry39Q/L6xyJk/huL6/1saOYl
5xikFRIn7lFci5AFtpA66vCf7M3kYkAAACwYMnoCTqvUTG0ktSSMNsOZLCdal5J4avEpM1L
6sV9SL/RVcwo3ChprhwsnQsaAtMiJCRcHerKgD9qy1MNNaE5VNfVJ0Ih/7ut04cbFKed8p6
70V+w8WP7WvFffBPoHn+GGbQd1FDGzHhXUB61pH8Qzd1bI/sld/XEtMk7iYjNGQe9Rt0RaK
8Wi8trwaA0Fb2w/EFnrdsFFxrIhQEqYBdEQJo782IqAsMG9OwUaM0vy+8bcI=
9-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ed25519_1 b/regress/unittests/sshkey/testdata/ed25519_1
new file mode 100644
index 000000000..a537ae13d
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1
@@ -0,0 +1,7 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
3QyNTUxOQAAACC5PeVeSdyylcfG3C0geNO90e3dGgL0fICaz751dA9zEAAAAJglsAcYJbAH
4GAAAAAtzc2gtZWQyNTUxOQAAACC5PeVeSdyylcfG3C0geNO90e3dGgL0fICaz751dA9zEA
5AAAED6HJ8Bh8tdQvhMd5o8IxtIwBv8/FV48FpBFWAbYdsIsLk95V5J3LKVx8bcLSB4073R
67d0aAvR8gJrPvnV0D3MQAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
7-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
new file mode 100644
index 000000000..e6d23d0b8
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
@@ -0,0 +1 @@
19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
diff --git a/regress/unittests/sshkey/testdata/ed25519_1-cert.pub b/regress/unittests/sshkey/testdata/ed25519_1-cert.pub
new file mode 100644
index 000000000..ad0b9a888
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1-cert.pub
@@ -0,0 +1 @@
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIHmdL66MkkOvncpc0W4MdvlJZMfQthHiOUv+XKm7gvzOAAAAILk95V5J3LKVx8bcLSB4073R7d0aAvR8gJrPvnV0D3MQAAAAAAAAAAgAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANouDYAAAAABNHeHgAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACC5PeVeSdyylcfG3C0geNO90e3dGgL0fICaz751dA9zEAAAAFMAAAALc3NoLWVkMjU1MTkAAABAsUStKm1z3Rtvwy3eXE1DrgVp6kix2iEQXfB66IHX2UpAj5yl0eQGXWTSEDIxHDIb0SJvUH43OWX0PrEeAs0mAA== ed25519_1.pub
diff --git a/regress/unittests/sshkey/testdata/ed25519_1.fp b/regress/unittests/sshkey/testdata/ed25519_1.fp
new file mode 100644
index 000000000..e6d23d0b8
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1.fp
@@ -0,0 +1 @@
19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f
diff --git a/regress/unittests/sshkey/testdata/ed25519_1.fp.bb b/regress/unittests/sshkey/testdata/ed25519_1.fp.bb
new file mode 100644
index 000000000..591a711b4
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1.fp.bb
@@ -0,0 +1 @@
xofip-nuhoh-botam-cypeg-panig-tunef-bimav-numeb-nikic-gocyf-paxax
diff --git a/regress/unittests/sshkey/testdata/ed25519_1.pub b/regress/unittests/sshkey/testdata/ed25519_1.pub
new file mode 100644
index 000000000..633e05077
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bcLSB4073R7d0aAvR8gJrPvnV0D3MQ ED25519 test key #1
diff --git a/regress/unittests/sshkey/testdata/ed25519_1_pw b/regress/unittests/sshkey/testdata/ed25519_1_pw
new file mode 100644
index 000000000..9fc635208
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_1_pw
@@ -0,0 +1,8 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAlT1eewp
39gl0gue+sSrBWKAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bc
4LSB4073R7d0aAvR8gJrPvnV0D3MQAAAAoMrL9ixIQHoJ86DcKMGt26+bCeaoyGjW5hha2Y
5IxAZ+rRvNjUuv3MGvbUxtUpPZkTP/vk2fVSCuCD9St5Lbt/LKdIk2MfWIFbjZ6iEfdzxz0
6DHmsSDMps8dbePqqIPULR8av447jEzQEkUc8GSR6WqFSJOjJ8OvrJat1KcEK7V2tjZnLS1
7GoLMqVAtCVhuXwUkeJiRQE/JRl172hxB+LAVw=
8-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ed25519_2 b/regress/unittests/sshkey/testdata/ed25519_2
new file mode 100644
index 000000000..a6e5f0040
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_2
@@ -0,0 +1,7 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
3QyNTUxOQAAACBXUfO5Kid+jhRnyVt+1r9wj2FN/mZ6RfgGdySeYoq4WAAAAJjGeKsZxnir
4GQAAAAtzc2gtZWQyNTUxOQAAACBXUfO5Kid+jhRnyVt+1r9wj2FN/mZ6RfgGdySeYoq4WA
5AAAEB+gn4gGClQl2WMeOkikY+w0A0kSw1KH4Oyami7hlypsFdR87kqJ36OFGfJW37Wv3CP
6YU3+ZnpF+AZ3JJ5iirhYAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
7-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/ed25519_2.fp b/regress/unittests/sshkey/testdata/ed25519_2.fp
new file mode 100644
index 000000000..02c684f36
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_2.fp
@@ -0,0 +1 @@
5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9
diff --git a/regress/unittests/sshkey/testdata/ed25519_2.fp.bb b/regress/unittests/sshkey/testdata/ed25519_2.fp.bb
new file mode 100644
index 000000000..ebe782e2c
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_2.fp.bb
@@ -0,0 +1 @@
xenoz-tovup-zecyt-hohar-motam-sugid-fecyz-tutyk-gosom-ginar-kixux
diff --git a/regress/unittests/sshkey/testdata/ed25519_2.pub b/regress/unittests/sshkey/testdata/ed25519_2.pub
new file mode 100644
index 000000000..37b93352a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/ed25519_2.pub
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdR87kqJ36OFGfJW37Wv3CPYU3+ZnpF+AZ3JJ5iirhY ED25519 test key #1
diff --git a/regress/unittests/sshkey/testdata/pw b/regress/unittests/sshkey/testdata/pw
new file mode 100644
index 000000000..8a1dff98a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/pw
@@ -0,0 +1 @@
mekmitasdigoat
diff --git a/regress/unittests/sshkey/testdata/rsa1_1 b/regress/unittests/sshkey/testdata/rsa1_1
new file mode 100644
index 000000000..d22014e88
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1
Binary files differ
diff --git a/regress/unittests/sshkey/testdata/rsa1_1.fp b/regress/unittests/sshkey/testdata/rsa1_1.fp
new file mode 100644
index 000000000..782ece0db
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1.fp
@@ -0,0 +1 @@
a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80
diff --git a/regress/unittests/sshkey/testdata/rsa1_1.fp.bb b/regress/unittests/sshkey/testdata/rsa1_1.fp.bb
new file mode 100644
index 000000000..caaf9511a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1.fp.bb
@@ -0,0 +1 @@
xukib-cymuf-mylib-kecih-rogyb-sorid-belys-kytem-dinin-cicil-kyxex
diff --git a/regress/unittests/sshkey/testdata/rsa1_1.param.n b/regress/unittests/sshkey/testdata/rsa1_1.param.n
new file mode 100644
index 000000000..4ceb37362
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1.param.n
@@ -0,0 +1 @@
00cf68059e5c7743318d740d3ebb55eb577891c9c3098817703f4c3157285055c2daa50102509ebdcade324e541c965e2931fd3459052fe65d013722da805d7ec8ef5b97cc006789d0566c5578b23e7aaa5be2b055d85798030cdead2eb2cc4eb3
diff --git a/regress/unittests/sshkey/testdata/rsa1_1.pub b/regress/unittests/sshkey/testdata/rsa1_1.pub
new file mode 100644
index 000000000..56cf30d30
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1.pub
@@ -0,0 +1 @@
768 65537 1257820658919101781627826212425999371251377782154008557690434337796299274692579921603319269571889066123773172648045269780061837011867522525764583065919572648969392756890567918758763032103894830246827894023662422727333291801518558899 RSA1 test key #1
diff --git a/regress/unittests/sshkey/testdata/rsa1_1_pw b/regress/unittests/sshkey/testdata/rsa1_1_pw
new file mode 100644
index 000000000..3113dbc0f
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_1_pw
Binary files differ
diff --git a/regress/unittests/sshkey/testdata/rsa1_2 b/regress/unittests/sshkey/testdata/rsa1_2
new file mode 100644
index 000000000..e75e665ff
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_2
Binary files differ
diff --git a/regress/unittests/sshkey/testdata/rsa1_2.fp b/regress/unittests/sshkey/testdata/rsa1_2.fp
new file mode 100644
index 000000000..c3325371d
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_2.fp
@@ -0,0 +1 @@
c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c
diff --git a/regress/unittests/sshkey/testdata/rsa1_2.fp.bb b/regress/unittests/sshkey/testdata/rsa1_2.fp.bb
new file mode 100644
index 000000000..cd8037140
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_2.fp.bb
@@ -0,0 +1 @@
xifad-vevot-sozyl-fapeb-meryf-kylut-cydiv-firik-gavyb-lanad-kaxox
diff --git a/regress/unittests/sshkey/testdata/rsa1_2.param.n b/regress/unittests/sshkey/testdata/rsa1_2.param.n
new file mode 100644
index 000000000..f8143a4b9
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_2.param.n
@@ -0,0 +1 @@
00b08a9fa386aceaab2ec3e9cdc7e6cb4eac9e98620279eed6762e1f513739a417ac8a86231fad3b8727a9de994973a7aae674a132547341984ade91aa1c22f01d2f0204ea7fa121969c367a5d04bda384066cf94e0b56d1efc47f50ca28e90603547df41c0676550d82d369f699b457d4f0f077999d9e76ab679fbf4206d418dbabed1823f14e4ddf3aac987686e6b006f8a23ea6af13b4c0e5b1fb5b1eb4db2f47b229422c450574cae9c64db5dcfce050836b6bdfa8fb541b4d426444a5ea20ad51a25d3048414ced2e199da2997968273e8beb10f3a351e98a57b00dadfa8f00a39bb55be94dae898fda6021d728f32b2ec93edd16e51073be3ac7511e5085
diff --git a/regress/unittests/sshkey/testdata/rsa1_2.pub b/regress/unittests/sshkey/testdata/rsa1_2.pub
new file mode 100644
index 000000000..de1afbb8b
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa1_2.pub
@@ -0,0 +1 @@
2048 65537 22286299513474010485021611215236051675183880694440075228245854420062562171290421803318459093678819161498086077099067169041536315773126601869537036602014639497662916952995546870691495931205282427606841521014293638607226118353743812583642616889028731910222603216563207637006843580936568089467160095319593442255227365472917576488012409542775346105980501967996562422764758836868135158147777193940857952623773420292946843206784104932927528915610322518810753953608862466374219925252817405397507396462117715293725218947744085154122395590957537510003558169729949140038634486299736757269280065662263306737701939154762092925061 RSA1 test key #2
diff --git a/regress/unittests/sshkey/testdata/rsa_1 b/regress/unittests/sshkey/testdata/rsa_1
new file mode 100644
index 000000000..09e79a72e
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1
@@ -0,0 +1,12 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIIBywIBAAJhAM/6MDmVVm/uNQmZpOcthoAAgMDUg7G4H6ZLLyPEhboKaBBHvIdw
3ZdDmB+0LDf3D1aWXyUd2/pCkCysiBzqd/523zAzjY7HayqL6A940AxKBBbWLn+X6
4i2yJR7dTOYkk6QIDAQABAmAgKanBjfWzE5yCIo+c7K5rJyjCKVtAZaAHYIMmveKM
5VcWoFt/x9hDY0GoTX21HfDxLX8oDxnsmhsOrnvSmgUChFwkm45eSETqeVDWwIVFA
6FGL1s38xQsciWZWBFNppAIECMQD7nslReAxwz/Ad++ACXswfJg1l2wUQ1gJA3zh3
7jln6a4s3aV1zxbKlIn8iqBv0BZkCMQDTmO4WqyNnin73XCZs0DWu7GsfcuaH8QnD
8wqPjJgrclTZXedxHkeqO2oyZW4mLC9ECMBb/blsZ49kzyDiVWuYcj/+Q1MyodhAR
932bagCi9RBAVYEYSRU5dlXRucLxULSnikQIxAJ5teY5Vcru6kZfJUifUuO0QrKAu
10WnbcPVBqMmUHfchsm/RhFFIt6W4uKmlEhTYrkQIxAMAStb7QCU3yU6ZkN7uL22Zs
11498i4jY6y+VEXv+L9O09VdlEnXhbUisOhy1bhyS3yg==
12-----END RSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/regress/unittests/sshkey/testdata/rsa_1-cert.fp
new file mode 100644
index 000000000..bf9c2e362
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1-cert.fp
@@ -0,0 +1 @@
be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
diff --git a/regress/unittests/sshkey/testdata/rsa_1-cert.pub b/regress/unittests/sshkey/testdata/rsa_1-cert.pub
new file mode 100644
index 000000000..51b1ce0dd
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1-cert.pub
@@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg1i9Ueveqg9sFSGsEYmsQqlI+dpC3nqhucPfwBVo3DtcAAAADAQABAAAAYQDP+jA5lVZv7jUJmaTnLYaAAIDA1IOxuB+mSy8jxIW6CmgQR7yHcGXQ5gftCw39w9Wll8lHdv6QpAsrIgc6nf+dt8wM42Ox2sqi+gPeNAMSgQW1i5/l+otsiUe3UzmJJOkAAAAAAAAABQAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2i4NgAAAAAE0d4eAAAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bcLSB4073R7d0aAvR8gJrPvnV0D3MQAAAAUwAAAAtzc2gtZWQyNTUxOQAAAED0TLf2Mv2F9TBt1Skf/1vviUgt7bt9xvL5HqugnVDfKaEg+RNKgfa5Rtpteb39EODkH8v4FJPWlmNG0F9w0cYF rsa_1.pub
diff --git a/regress/unittests/sshkey/testdata/rsa_1.fp b/regress/unittests/sshkey/testdata/rsa_1.fp
new file mode 100644
index 000000000..bf9c2e362
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.fp
@@ -0,0 +1 @@
be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b
diff --git a/regress/unittests/sshkey/testdata/rsa_1.fp.bb b/regress/unittests/sshkey/testdata/rsa_1.fp.bb
new file mode 100644
index 000000000..448133bad
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.fp.bb
@@ -0,0 +1 @@
xetif-zuvul-nylyc-vykor-lumac-gyhyv-bacih-cimyk-sycen-gikym-pixax
diff --git a/regress/unittests/sshkey/testdata/rsa_1.param.n b/regress/unittests/sshkey/testdata/rsa_1.param.n
new file mode 100644
index 000000000..2ffc2ba7e
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.param.n
@@ -0,0 +1 @@
00cffa303995566fee350999a4e72d86800080c0d483b1b81fa64b2f23c485ba0a681047bc877065d0e607ed0b0dfdc3d5a597c94776fe90a40b2b22073a9dff9db7cc0ce363b1dacaa2fa03de3403128105b58b9fe5fa8b6c8947b753398924e9
diff --git a/regress/unittests/sshkey/testdata/rsa_1.param.p b/regress/unittests/sshkey/testdata/rsa_1.param.p
new file mode 100644
index 000000000..4fcf148c3
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.param.p
@@ -0,0 +1 @@
00fb9ec951780c70cff01dfbe0025ecc1f260d65db0510d60240df38778e59fa6b8b37695d73c5b2a5227f22a81bf40599
diff --git a/regress/unittests/sshkey/testdata/rsa_1.param.q b/regress/unittests/sshkey/testdata/rsa_1.param.q
new file mode 100644
index 000000000..3473f5144
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.param.q
@@ -0,0 +1 @@
00d398ee16ab23678a7ef75c266cd035aeec6b1f72e687f109c3c2a3e3260adc95365779dc4791ea8eda8c995b898b0bd1
diff --git a/regress/unittests/sshkey/testdata/rsa_1.pub b/regress/unittests/sshkey/testdata/rsa_1.pub
new file mode 100644
index 000000000..889fdae86
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1.pub
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDP+jA5lVZv7jUJmaTnLYaAAIDA1IOxuB+mSy8jxIW6CmgQR7yHcGXQ5gftCw39w9Wll8lHdv6QpAsrIgc6nf+dt8wM42Ox2sqi+gPeNAMSgQW1i5/l+otsiUe3UzmJJOk= RSA test key #1
diff --git a/regress/unittests/sshkey/testdata/rsa_1_pw b/regress/unittests/sshkey/testdata/rsa_1_pw
new file mode 100644
index 000000000..71637a59b
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_1_pw
@@ -0,0 +1,15 @@
1-----BEGIN RSA PRIVATE KEY-----
2Proc-Type: 4,ENCRYPTED
3DEK-Info: AES-128-CBC,1E851A01F12A49FDC256E7A665C61D4B
4
5+sfWU7kg3idmHL6vShby5LXnfF4bZDPhJjv89uldae7qPEgEW8qS8o0Ssokxf7Au
6/vTQnbSB+gy/qZaUOykOzqiV1YL7UfkbOkM2QYnzzrVeGzI5RZ0G9iH8HBn2owQ+
7Ejf1UKDUVZEea5X0IwQRfE0zaZqFS4tyEex0iKz8dI4FvyabKLZsCs1DBGO7A3ml
8LgP947mh10yKWTP2fbq8LOhDUEWCXrh2NzuH6Rl5nNyC4MNQEkLzK1wL7J/WCNaL
9sciYmuqEQRDikDDQQFZw2wjBD638fhK+IhuN3VGegiXFnu5C+p9kzUvqVk4X9g2r
10BMmlP0pceFv/fEwtNNaeI2Tt7mIsWsZTmCqdzOUAYqGIiNjzykWw64nMO3TpVpbA
11i4854RhblbeiyjENbMVPU6BAk4fx7OJvDElLxwN43CS3U0MldbI7A4uG3B3RTSCj
121rGxRNAHWC3q3zzrn6gLwrUVje4iTedaKItLIHQeo1A091Tr8AqQdZi/Ck2Ju0Hl
134Qdwzjw1Y5n1Akm+EWh31ydxtUQ0YBOz/W6DKwTNA1D8oH9bZBG4f0pnvVhtttAO
14WKj+DUqMa+f3OOmQ9UXlitk2pEgjeMngTgfQnhZiCts=
15-----END RSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/rsa_2 b/regress/unittests/sshkey/testdata/rsa_2
new file mode 100644
index 000000000..058cf777a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2
@@ -0,0 +1,27 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIIEowIBAAKCAQEAlDS/ygeFfsR/mhZK/XMHU/gzRogPuMQIYUd17WDjMprA6dQb
3ckTDrNm/mrf09I6YAhjgooEL16oWM1z6cesDE0KwaJsy6uTmXFMLO+Ha4mtFHhmu
4tiyJcQ9MKKr0vC64384WQZygZk0OlVz7x9WSPiGXzal5MzsX4TYq5B05o2Cb+epA
5FxK0c8cdYZD0Sy57gWRpRA3yJq4zh/hks98jzn0XA3HAJA39MKhUG5tf5e6z5BeP
6Yi5FvdnDQ9WcasRiEvkmHbg59pbgg/Lbsl6OgZQruS8hKiJ3YBARt2euCCeg7qAF
7KbXRR9TMwfphH3Ai4Oi/w6HPRAhdrwooA/gKkQIDAQABAoIBAH22OLB/rMaYmrvz
8COzvM1oQgD3lj6Bj98+8M9WEh3MXPWeaGSXWGjx1/0aXn1oJ0fqFa5Wr7IWkqmwr
9A+y5McSWntg8PPZt7tCFSFQlAetonhooIsA4CuUx2qHsUOeGoh6EyvAgkRX1atdb
10Jd6d1AyLph43EK1aBKltrvgLqiZfs7mcuwyvKtN9ktdKY2FDhn6DHpm9pE9MEHJV
11Xv1isNc6a0qNoRlKqxrSZHNEN4fbjLw31wBySzmmnIog5wVEwaHeASwLJT6TmuIZ
12eZxnd7/jMwRZWH8ZIGKvkTMp4fYzK9QkehO7A2HFD3FPDBVrkSJjqRdkujF8vu1C
130RwrD1kCgYEAxFXUoE1ero6vp9akvR/mw94kYjXE/YOz1yi0KTkZUs6gURc8Kzsm
14MzlEZ31rnngE4jQHYAvuPEfiqcnUgylW3QuevMgo2hCLYO7aG5C0fk8TeOiuvnrF
15YPO8rSJWk/BgdrPtzu45P7jmWsjkHn+y+t8cKvq1sZY40sn2YgIhYK8CgYEAwT6j
165tReI6sxpHltPUbvOdpD04eL6ggBAKwzb5aBoa/Dj+sU1zg5uyY8diggQEEznlBW
17iWTQmmmfy1ef9i6YAwNuZveKOrVwNMcdubQJ2X26XoFrmA59PjsbLtr1bdUb02gz
186P5x6pcw5qzEq0mddgvHiU3RhL24xdc1LW8nmL8CgYEAmgaT1macPuklmNBlURGz
194jll5b41GoW2EreWDzkCStpbHwLRa0DuCQWGSoI0aY/SlPsoRgtWDOiAQ59ZHsTR
20pnw1PfjxQ5HzJkp7xWBSmTzEE/jHDhwWuKa+gD0OGuVbaARkLhDpzLnrzZEIlXyt
21Fu7tlDI3VGh7j7Jtnhn5wXUCgYBKmPbGfcaVeFmih2lfFUn2CEbUmmetgUd5zf/R
22HMWP9/zDStlxt3e5winm5tiEVWcqvxKY2T0Zzppr8biDXTs7NpDg2MAYp7/X7+GO
23tWxz8/AE2WsCeN1qL4Dv1oCV1IV4V6pqUAcDqzeqZJlLEhDh5+wwGcU+u8pfPRN/
24JYCgmwKBgDa+kXPqzcc6vzD9cwEEk4ftn9/Vk2yBx0XOu8RdEkRhXj1QXGJckCqh
25FkXzVbuurFhsBt+H0B4arw+51T9fVCZqfcaU34u+Qa/FQvTod4OJUSRxYUaDqygs
26VTyuP+zGZlIw7JWktxjVazENsM/ef5wBH0Nf839OZbPVDLfn7K0j
27-----END RSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/rsa_2.fp b/regress/unittests/sshkey/testdata/rsa_2.fp
new file mode 100644
index 000000000..53939f413
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.fp
@@ -0,0 +1 @@
fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0
diff --git a/regress/unittests/sshkey/testdata/rsa_2.fp.bb b/regress/unittests/sshkey/testdata/rsa_2.fp.bb
new file mode 100644
index 000000000..e90a3571a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.fp.bb
@@ -0,0 +1 @@
xepev-gupub-vuvyg-femiv-gonat-defiv-hirak-betub-pahut-veryd-hexix
diff --git a/regress/unittests/sshkey/testdata/rsa_2.param.n b/regress/unittests/sshkey/testdata/rsa_2.param.n
new file mode 100644
index 000000000..389de4226
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.param.n
@@ -0,0 +1 @@
009434bfca07857ec47f9a164afd730753f83346880fb8c408614775ed60e3329ac0e9d41b7244c3acd9bf9ab7f4f48e980218e0a2810bd7aa16335cfa71eb031342b0689b32eae4e65c530b3be1dae26b451e19aeb62c89710f4c28aaf4bc2eb8dfce16419ca0664d0e955cfbc7d5923e2197cda979333b17e1362ae41d39a3609bf9ea401712b473c71d6190f44b2e7b816469440df226ae3387f864b3df23ce7d170371c0240dfd30a8541b9b5fe5eeb3e4178f622e45bdd9c343d59c6ac46212f9261db839f696e083f2dbb25e8e81942bb92f212a2277601011b767ae0827a0eea00529b5d147d4ccc1fa611f7022e0e8bfc3a1cf44085daf0a2803f80a91
diff --git a/regress/unittests/sshkey/testdata/rsa_2.param.p b/regress/unittests/sshkey/testdata/rsa_2.param.p
new file mode 100644
index 000000000..c3c9a130a
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.param.p
@@ -0,0 +1 @@
00c455d4a04d5eae8eafa7d6a4bd1fe6c3de246235c4fd83b3d728b429391952cea051173c2b3b26333944677d6b9e7804e23407600bee3c47e2a9c9d4832956dd0b9ebcc828da108b60eeda1b90b47e4f1378e8aebe7ac560f3bcad225693f06076b3edceee393fb8e65ac8e41e7fb2fadf1c2afab5b19638d2c9f662022160af
diff --git a/regress/unittests/sshkey/testdata/rsa_2.param.q b/regress/unittests/sshkey/testdata/rsa_2.param.q
new file mode 100644
index 000000000..728c474b0
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.param.q
@@ -0,0 +1 @@
00c13ea3e6d45e23ab31a4796d3d46ef39da43d3878bea080100ac336f9681a1afc38feb14d73839bb263c7628204041339e50568964d09a699fcb579ff62e9803036e66f78a3ab57034c71db9b409d97dba5e816b980e7d3e3b1b2edaf56dd51bd36833e8fe71ea9730e6acc4ab499d760bc7894dd184bdb8c5d7352d6f2798bf
diff --git a/regress/unittests/sshkey/testdata/rsa_2.pub b/regress/unittests/sshkey/testdata/rsa_2.pub
new file mode 100644
index 000000000..ed9f78cad
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_2.pub
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUNL/KB4V+xH+aFkr9cwdT+DNGiA+4xAhhR3XtYOMymsDp1BtyRMOs2b+at/T0jpgCGOCigQvXqhYzXPpx6wMTQrBomzLq5OZcUws74dria0UeGa62LIlxD0woqvS8LrjfzhZBnKBmTQ6VXPvH1ZI+IZfNqXkzOxfhNirkHTmjYJv56kAXErRzxx1hkPRLLnuBZGlEDfImrjOH+GSz3yPOfRcDccAkDf0wqFQbm1/l7rPkF49iLkW92cND1ZxqxGIS+SYduDn2luCD8tuyXo6BlCu5LyEqIndgEBG3Z64IJ6DuoAUptdFH1MzB+mEfcCLg6L/Doc9ECF2vCigD+AqR RSA test key #2
diff --git a/regress/unittests/sshkey/testdata/rsa_n b/regress/unittests/sshkey/testdata/rsa_n
new file mode 100644
index 000000000..09e79a72e
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_n
@@ -0,0 +1,12 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIIBywIBAAJhAM/6MDmVVm/uNQmZpOcthoAAgMDUg7G4H6ZLLyPEhboKaBBHvIdw
3ZdDmB+0LDf3D1aWXyUd2/pCkCysiBzqd/523zAzjY7HayqL6A940AxKBBbWLn+X6
4i2yJR7dTOYkk6QIDAQABAmAgKanBjfWzE5yCIo+c7K5rJyjCKVtAZaAHYIMmveKM
5VcWoFt/x9hDY0GoTX21HfDxLX8oDxnsmhsOrnvSmgUChFwkm45eSETqeVDWwIVFA
6FGL1s38xQsciWZWBFNppAIECMQD7nslReAxwz/Ad++ACXswfJg1l2wUQ1gJA3zh3
7jln6a4s3aV1zxbKlIn8iqBv0BZkCMQDTmO4WqyNnin73XCZs0DWu7GsfcuaH8QnD
8wqPjJgrclTZXedxHkeqO2oyZW4mLC9ECMBb/blsZ49kzyDiVWuYcj/+Q1MyodhAR
932bagCi9RBAVYEYSRU5dlXRucLxULSnikQIxAJ5teY5Vcru6kZfJUifUuO0QrKAu
10WnbcPVBqMmUHfchsm/RhFFIt6W4uKmlEhTYrkQIxAMAStb7QCU3yU6ZkN7uL22Zs
11498i4jY6y+VEXv+L9O09VdlEnXhbUisOhy1bhyS3yg==
12-----END RSA PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/testdata/rsa_n_pw b/regress/unittests/sshkey/testdata/rsa_n_pw
new file mode 100644
index 000000000..0166fd5f1
--- /dev/null
+++ b/regress/unittests/sshkey/testdata/rsa_n_pw
@@ -0,0 +1,14 @@
1-----BEGIN OPENSSH PRIVATE KEY-----
2b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABClELgtaZ
3qAmMwESpqXDN0uAAAAEAAAAAEAAAB3AAAAB3NzaC1yc2EAAAADAQABAAAAYQDP+jA5lVZv
47jUJmaTnLYaAAIDA1IOxuB+mSy8jxIW6CmgQR7yHcGXQ5gftCw39w9Wll8lHdv6QpAsrIg
5c6nf+dt8wM42Ox2sqi+gPeNAMSgQW1i5/l+otsiUe3UzmJJOkAAAGgwJpHy/nshQa9+Jbw
6yomvgNMYvuuoD7Ll7iCY/RFFGXivTkki27C9q0qx3afauSLQQWFanGhjeJn7JPy98lMcVl
7qnn5XOE5+xxZqA8ONOBD8eH0KBcTH17DH1A1z94p5zZ1VJKIWsBZ0krxgHIXcdv9ucAckj
8N0vAEBm+0wsfy2TTOtuqXvcj65wFwknpyy/SSvU0QTr99FiYe9PIhIslBHO6wlqxfKj+Tm
9E/nCb75dAVu6gTtS2P0pdOqV/V7VHX5C0z3BROqpKDJJcVeoc7vRkEl+MWfvvQrG66IPEW
10luohFXPDPDrxu1zDduyRsmNwpBHChi2rFhxtsjxNK0svMwESeCCKAWmPxnzLJfvMbTCv00
11SpaCr7WhtzsGt73axqSkeOdynp5NNrN7MEdwruMZFirF4BcI2z2H9ugpS+qbLPuE2H5vln
12h7NSwBUNwmZ+4TC8MXFH9KIpRg8dNhf66OU610LYiN4+ZfOYCmfQfgQuBGhMTYFMY6O4SB
13NCdIavvWY6rDSBq7QC1f4rHpwiXxpkiE43Rd8fM32TaPlBPtA=
14-----END OPENSSH PRIVATE KEY-----
diff --git a/regress/unittests/sshkey/tests.c b/regress/unittests/sshkey/tests.c
new file mode 100644
index 000000000..13f265cdb
--- /dev/null
+++ b/regress/unittests/sshkey/tests.c
@@ -0,0 +1,27 @@
1/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <openssl/evp.h>
11
12#include "../test_helper/test_helper.h"
13
14void sshkey_tests(void);
15void sshkey_file_tests(void);
16void sshkey_fuzz_tests(void);
17
18void
19tests(void)
20{
21 OpenSSL_add_all_algorithms();
22 ERR_load_CRYPTO_strings();
23
24 sshkey_tests();
25 sshkey_file_tests();
26 sshkey_fuzz_tests();
27}
diff --git a/regress/unittests/test_helper/Makefile b/regress/unittests/test_helper/Makefile
new file mode 100644
index 000000000..3e90903ef
--- /dev/null
+++ b/regress/unittests/test_helper/Makefile
@@ -0,0 +1,13 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
2
3LIB= test_helper
4SRCS= test_helper.c fuzz.c
5
6DEBUGLIBS= no
7NOPROFILE= yes
8NOPIC= yes
9
10install:
11 @echo -n
12
13.include <bsd.lib.mk>
diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c
new file mode 100644
index 000000000..77c6e7cad
--- /dev/null
+++ b/regress/unittests/test_helper/fuzz.c
@@ -0,0 +1,378 @@
1/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for fuzz tests */
19
20#include "includes.h"
21
22#include <sys/types.h>
23
24#include <assert.h>
25#include <ctype.h>
26#include <stdio.h>
27#ifdef HAVE_STDINT_H
28# include <stdint.h>
29#endif
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33
34#include "test_helper.h"
35
36/* #define FUZZ_DEBUG */
37
38#ifdef FUZZ_DEBUG
39# define FUZZ_DBG(x) do { \
40 printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
41 printf x; \
42 printf("\n"); \
43 fflush(stdout); \
44 } while (0)
45#else
46# define FUZZ_DBG(x)
47#endif
48
49/* For brevity later */
50typedef unsigned long long fuzz_ullong;
51
52/* For base-64 fuzzing */
53static const char fuzz_b64chars[] =
54 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
55
56struct fuzz {
57 /* Fuzz method currently in use */
58 int strategy;
59
60 /* Fuzz methods remaining */
61 int strategies;
62
63 /* Original seed data blob */
64 void *seed;
65 size_t slen;
66
67 /* Current working copy of seed with fuzz mutations applied */
68 u_char *fuzzed;
69
70 /* Used by fuzz methods */
71 size_t o1, o2;
72};
73
74static const char *
75fuzz_ntop(u_int n)
76{
77 switch (n) {
78 case 0:
79 return "NONE";
80 case FUZZ_1_BIT_FLIP:
81 return "FUZZ_1_BIT_FLIP";
82 case FUZZ_2_BIT_FLIP:
83 return "FUZZ_2_BIT_FLIP";
84 case FUZZ_1_BYTE_FLIP:
85 return "FUZZ_1_BYTE_FLIP";
86 case FUZZ_2_BYTE_FLIP:
87 return "FUZZ_2_BYTE_FLIP";
88 case FUZZ_TRUNCATE_START:
89 return "FUZZ_TRUNCATE_START";
90 case FUZZ_TRUNCATE_END:
91 return "FUZZ_TRUNCATE_END";
92 case FUZZ_BASE64:
93 return "FUZZ_BASE64";
94 default:
95 abort();
96 }
97}
98
99void
100fuzz_dump(struct fuzz *fuzz)
101{
102 u_char *p = fuzz_ptr(fuzz);
103 size_t i, j, len = fuzz_len(fuzz);
104
105 switch (fuzz->strategy) {
106 case FUZZ_1_BIT_FLIP:
107 fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n",
108 fuzz_ntop(fuzz->strategy),
109 fuzz->o1, fuzz->slen * 8, fuzz->o1);
110 break;
111 case FUZZ_2_BIT_FLIP:
112 fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n",
113 fuzz_ntop(fuzz->strategy),
114 (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
115 ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
116 fuzz->o1, fuzz->o2);
117 break;
118 case FUZZ_1_BYTE_FLIP:
119 fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n",
120 fuzz_ntop(fuzz->strategy),
121 fuzz->o1, fuzz->slen, fuzz->o1);
122 break;
123 case FUZZ_2_BYTE_FLIP:
124 fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n",
125 fuzz_ntop(fuzz->strategy),
126 (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
127 ((fuzz_ullong)fuzz->slen) * fuzz->slen,
128 fuzz->o1, fuzz->o2);
129 break;
130 case FUZZ_TRUNCATE_START:
131 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
132 fuzz_ntop(fuzz->strategy),
133 fuzz->o1, fuzz->slen, fuzz->o1);
134 break;
135 case FUZZ_TRUNCATE_END:
136 fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
137 fuzz_ntop(fuzz->strategy),
138 fuzz->o1, fuzz->slen, fuzz->o1);
139 break;
140 case FUZZ_BASE64:
141 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
142 fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n",
143 fuzz_ntop(fuzz->strategy),
144 (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
145 fuzz->slen * (fuzz_ullong)64, fuzz->o1,
146 fuzz_b64chars[fuzz->o2]);
147 break;
148 default:
149 abort();
150 }
151
152 fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
153 for (i = 0; i < len; i += 16) {
154 fprintf(stderr, "%.4zd: ", i);
155 for (j = i; j < i + 16; j++) {
156 if (j < len)
157 fprintf(stderr, "%02x ", p[j]);
158 else
159 fprintf(stderr, " ");
160 }
161 fprintf(stderr, " ");
162 for (j = i; j < i + 16; j++) {
163 if (j < len) {
164 if (isascii(p[j]) && isprint(p[j]))
165 fprintf(stderr, "%c", p[j]);
166 else
167 fprintf(stderr, ".");
168 }
169 }
170 fprintf(stderr, "\n");
171 }
172}
173
174struct fuzz *
175fuzz_begin(u_int strategies, const void *p, size_t l)
176{
177 struct fuzz *ret = calloc(sizeof(*ret), 1);
178
179 assert(p != NULL);
180 assert(ret != NULL);
181 ret->seed = malloc(l);
182 assert(ret->seed != NULL);
183 memcpy(ret->seed, p, l);
184 ret->slen = l;
185 ret->strategies = strategies;
186
187 assert(ret->slen < SIZE_MAX / 8);
188 assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1)));
189
190 FUZZ_DBG(("begin, ret = %p", ret));
191
192 fuzz_next(ret);
193 return ret;
194}
195
196void
197fuzz_cleanup(struct fuzz *fuzz)
198{
199 FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
200 assert(fuzz != NULL);
201 assert(fuzz->seed != NULL);
202 assert(fuzz->fuzzed != NULL);
203 free(fuzz->seed);
204 free(fuzz->fuzzed);
205 free(fuzz);
206}
207
208static int
209fuzz_strategy_done(struct fuzz *fuzz)
210{
211 FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu",
212 fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen));
213
214 switch (fuzz->strategy) {
215 case FUZZ_1_BIT_FLIP:
216 return fuzz->o1 >= fuzz->slen * 8;
217 case FUZZ_2_BIT_FLIP:
218 return fuzz->o2 >= fuzz->slen * 8;
219 case FUZZ_2_BYTE_FLIP:
220 return fuzz->o2 >= fuzz->slen;
221 case FUZZ_1_BYTE_FLIP:
222 case FUZZ_TRUNCATE_START:
223 case FUZZ_TRUNCATE_END:
224 case FUZZ_BASE64:
225 return fuzz->o1 >= fuzz->slen;
226 default:
227 abort();
228 }
229}
230
231void
232fuzz_next(struct fuzz *fuzz)
233{
234 u_int i;
235
236 FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, "
237 "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
238 (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
239
240 if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) {
241 /* If we are just starting out, we need to allocate too */
242 if (fuzz->fuzzed == NULL) {
243 FUZZ_DBG(("alloc"));
244 fuzz->fuzzed = calloc(fuzz->slen, 1);
245 }
246 /* Pick next strategy */
247 FUZZ_DBG(("advance"));
248 for (i = 1; i <= FUZZ_MAX; i <<= 1) {
249 if ((fuzz->strategies & i) != 0) {
250 fuzz->strategy = i;
251 break;
252 }
253 }
254 FUZZ_DBG(("selected = %u", fuzz->strategy));
255 if (fuzz->strategy == 0) {
256 FUZZ_DBG(("done, no more strategies"));
257 return;
258 }
259 fuzz->strategies &= ~(fuzz->strategy);
260 fuzz->o1 = fuzz->o2 = 0;
261 }
262
263 assert(fuzz->fuzzed != NULL);
264
265 switch (fuzz->strategy) {
266 case FUZZ_1_BIT_FLIP:
267 assert(fuzz->o1 / 8 < fuzz->slen);
268 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
269 fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
270 fuzz->o1++;
271 break;
272 case FUZZ_2_BIT_FLIP:
273 assert(fuzz->o1 / 8 < fuzz->slen);
274 assert(fuzz->o2 / 8 < fuzz->slen);
275 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
276 fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
277 fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8);
278 fuzz->o1++;
279 if (fuzz->o1 >= fuzz->slen * 8) {
280 fuzz->o1 = 0;
281 fuzz->o2++;
282 }
283 break;
284 case FUZZ_1_BYTE_FLIP:
285 assert(fuzz->o1 < fuzz->slen);
286 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
287 fuzz->fuzzed[fuzz->o1] ^= 0xff;
288 fuzz->o1++;
289 break;
290 case FUZZ_2_BYTE_FLIP:
291 assert(fuzz->o1 < fuzz->slen);
292 assert(fuzz->o2 < fuzz->slen);
293 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
294 fuzz->fuzzed[fuzz->o1] ^= 0xff;
295 fuzz->fuzzed[fuzz->o2] ^= 0xff;
296 fuzz->o1++;
297 if (fuzz->o1 >= fuzz->slen) {
298 fuzz->o1 = 0;
299 fuzz->o2++;
300 }
301 break;
302 case FUZZ_TRUNCATE_START:
303 case FUZZ_TRUNCATE_END:
304 assert(fuzz->o1 < fuzz->slen);
305 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
306 fuzz->o1++;
307 break;
308 case FUZZ_BASE64:
309 assert(fuzz->o1 < fuzz->slen);
310 assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
311 memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
312 fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2];
313 fuzz->o2++;
314 if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) {
315 fuzz->o2 = 0;
316 fuzz->o1++;
317 }
318 break;
319 default:
320 abort();
321 }
322
323 FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, "
324 "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
325 (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
326}
327
328int
329fuzz_done(struct fuzz *fuzz)
330{
331 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
332 (u_long)fuzz->strategies));
333
334 return fuzz_strategy_done(fuzz) && fuzz->strategies == 0;
335}
336
337size_t
338fuzz_len(struct fuzz *fuzz)
339{
340 assert(fuzz->fuzzed != NULL);
341 switch (fuzz->strategy) {
342 case FUZZ_1_BIT_FLIP:
343 case FUZZ_2_BIT_FLIP:
344 case FUZZ_1_BYTE_FLIP:
345 case FUZZ_2_BYTE_FLIP:
346 case FUZZ_BASE64:
347 return fuzz->slen;
348 case FUZZ_TRUNCATE_START:
349 case FUZZ_TRUNCATE_END:
350 assert(fuzz->o1 <= fuzz->slen);
351 return fuzz->slen - fuzz->o1;
352 default:
353 abort();
354 }
355}
356
357u_char *
358fuzz_ptr(struct fuzz *fuzz)
359{
360 assert(fuzz->fuzzed != NULL);
361 switch (fuzz->strategy) {
362 case FUZZ_1_BIT_FLIP:
363 case FUZZ_2_BIT_FLIP:
364 case FUZZ_1_BYTE_FLIP:
365 case FUZZ_2_BYTE_FLIP:
366 case FUZZ_BASE64:
367 return fuzz->fuzzed;
368 case FUZZ_TRUNCATE_START:
369 assert(fuzz->o1 <= fuzz->slen);
370 return fuzz->fuzzed + fuzz->o1;
371 case FUZZ_TRUNCATE_END:
372 assert(fuzz->o1 <= fuzz->slen);
373 return fuzz->fuzzed;
374 default:
375 abort();
376 }
377}
378
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c
new file mode 100644
index 000000000..d0bc67833
--- /dev/null
+++ b/regress/unittests/test_helper/test_helper.c
@@ -0,0 +1,471 @@
1/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for regress tests */
19
20#include "includes.h"
21
22#include <sys/types.h>
23#include <sys/param.h>
24
25#include <fcntl.h>
26#include <stdio.h>
27#ifdef HAVE_STDINT_H
28# include <stdint.h>
29#endif
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33#include <unistd.h>
34
35#include <openssl/bn.h>
36
37#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
38# include <vis.h>
39#endif
40
41#include "test_helper.h"
42
43#define TEST_CHECK_INT(r, pred) do { \
44 switch (pred) { \
45 case TEST_EQ: \
46 if (r == 0) \
47 return; \
48 break; \
49 case TEST_NE: \
50 if (r != 0) \
51 return; \
52 break; \
53 case TEST_LT: \
54 if (r < 0) \
55 return; \
56 break; \
57 case TEST_LE: \
58 if (r <= 0) \
59 return; \
60 break; \
61 case TEST_GT: \
62 if (r > 0) \
63 return; \
64 break; \
65 case TEST_GE: \
66 if (r >= 0) \
67 return; \
68 break; \
69 default: \
70 abort(); \
71 } \
72 } while (0)
73
74#define TEST_CHECK(x1, x2, pred) do { \
75 switch (pred) { \
76 case TEST_EQ: \
77 if (x1 == x2) \
78 return; \
79 break; \
80 case TEST_NE: \
81 if (x1 != x2) \
82 return; \
83 break; \
84 case TEST_LT: \
85 if (x1 < x2) \
86 return; \
87 break; \
88 case TEST_LE: \
89 if (x1 <= x2) \
90 return; \
91 break; \
92 case TEST_GT: \
93 if (x1 > x2) \
94 return; \
95 break; \
96 case TEST_GE: \
97 if (x1 >= x2) \
98 return; \
99 break; \
100 default: \
101 abort(); \
102 } \
103 } while (0)
104
105extern char *__progname;
106
107static int verbose_mode = 0;
108static int quiet_mode = 0;
109static char *active_test_name = NULL;
110static u_int test_number = 0;
111static test_onerror_func_t *test_onerror = NULL;
112static void *onerror_ctx = NULL;
113static const char *data_dir = NULL;
114
115int
116main(int argc, char **argv)
117{
118 int ch;
119
120 /* Handle systems without __progname */
121 if (__progname == NULL) {
122 __progname = strrchr(argv[0], '/');
123 if (__progname == NULL || __progname[1] == '\0')
124 __progname = argv[0];
125 else
126 __progname++;
127 if ((__progname = strdup(__progname)) == NULL) {
128 fprintf(stderr, "strdup failed\n");
129 exit(1);
130 }
131 }
132
133 while ((ch = getopt(argc, argv, "vqd:")) != -1) {
134 switch (ch) {
135 case 'd':
136 data_dir = optarg;
137 break;
138 case 'q':
139 verbose_mode = 0;
140 quiet_mode = 1;
141 break;
142 case 'v':
143 verbose_mode = 1;
144 quiet_mode = 0;
145 break;
146 default:
147 fprintf(stderr, "Unrecognised command line option\n");
148 fprintf(stderr, "Usage: %s [-v]\n", __progname);
149 exit(1);
150 }
151 }
152 setvbuf(stdout, NULL, _IONBF, 0);
153 if (!quiet_mode)
154 printf("%s: ", __progname);
155 if (verbose_mode)
156 printf("\n");
157
158 tests();
159
160 if (!quiet_mode)
161 printf(" %u tests ok\n", test_number);
162 return 0;
163}
164
165const char *
166test_data_file(const char *name)
167{
168 static char ret[PATH_MAX];
169
170 if (data_dir != NULL)
171 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
172 else
173 strlcpy(ret, name, sizeof(ret));
174 if (access(ret, F_OK) != 0) {
175 fprintf(stderr, "Cannot access data file %s: %s\n",
176 ret, strerror(errno));
177 exit(1);
178 }
179 return ret;
180}
181
182void
183test_start(const char *n)
184{
185 assert(active_test_name == NULL);
186 assert((active_test_name = strdup(n)) != NULL);
187 if (verbose_mode)
188 printf("test %u - \"%s\": ", test_number, active_test_name);
189 test_number++;
190}
191
192void
193set_onerror_func(test_onerror_func_t *f, void *ctx)
194{
195 test_onerror = f;
196 onerror_ctx = ctx;
197}
198
199void
200test_done(void)
201{
202 assert(active_test_name != NULL);
203 free(active_test_name);
204 active_test_name = NULL;
205 if (verbose_mode)
206 printf("OK\n");
207 else if (!quiet_mode) {
208 printf(".");
209 fflush(stdout);
210 }
211}
212
213void
214ssl_err_check(const char *file, int line)
215{
216 long openssl_error = ERR_get_error();
217
218 if (openssl_error == 0)
219 return;
220
221 fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
222 file, line, ERR_error_string(openssl_error, NULL));
223 abort();
224}
225
226static const char *
227pred_name(enum test_predicate p)
228{
229 switch (p) {
230 case TEST_EQ:
231 return "EQ";
232 case TEST_NE:
233 return "NE";
234 case TEST_LT:
235 return "LT";
236 case TEST_LE:
237 return "LE";
238 case TEST_GT:
239 return "GT";
240 case TEST_GE:
241 return "GE";
242 default:
243 return "UNKNOWN";
244 }
245}
246
247static void
248test_die(void)
249{
250 if (test_onerror != NULL)
251 test_onerror(onerror_ctx);
252 abort();
253}
254
255static void
256test_header(const char *file, int line, const char *a1, const char *a2,
257 const char *name, enum test_predicate pred)
258{
259 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
260 file, line, test_number, active_test_name);
261 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
262 name, pred_name(pred), a1,
263 a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
264}
265
266void
267assert_bignum(const char *file, int line, const char *a1, const char *a2,
268 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
269{
270 int r = BN_cmp(aa1, aa2);
271
272 TEST_CHECK_INT(r, pred);
273 test_header(file, line, a1, a2, "BIGNUM", pred);
274 fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
275 fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
276 test_die();
277}
278
279void
280assert_string(const char *file, int line, const char *a1, const char *a2,
281 const char *aa1, const char *aa2, enum test_predicate pred)
282{
283 int r = strcmp(aa1, aa2);
284
285 TEST_CHECK_INT(r, pred);
286 test_header(file, line, a1, a2, "STRING", pred);
287 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
288 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
289 test_die();
290}
291
292static char *
293tohex(const void *_s, size_t l)
294{
295 u_int8_t *s = (u_int8_t *)_s;
296 size_t i, j;
297 const char *hex = "0123456789abcdef";
298 char *r = malloc((l * 2) + 1);
299
300 assert(r != NULL);
301 for (i = j = 0; i < l; i++) {
302 r[j++] = hex[(s[i] >> 4) & 0xf];
303 r[j++] = hex[s[i] & 0xf];
304 }
305 r[j] = '\0';
306 return r;
307}
308
309void
310assert_mem(const char *file, int line, const char *a1, const char *a2,
311 const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
312{
313 int r = memcmp(aa1, aa2, l);
314
315 TEST_CHECK_INT(r, pred);
316 test_header(file, line, a1, a2, "STRING", pred);
317 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
318 fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
319 test_die();
320}
321
322static int
323memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
324{
325 size_t i;
326
327 for (i = 0; i < l; i++) {
328 if (s[i] != v) {
329 *where = i;
330 return 1;
331 }
332 }
333 return 0;
334}
335
336void
337assert_mem_filled(const char *file, int line, const char *a1,
338 const void *aa1, u_char v, size_t l, enum test_predicate pred)
339{
340 size_t where = -1;
341 int r = memvalcmp(aa1, v, l, &where);
342 char tmp[64];
343
344 if (l == 0)
345 return;
346 TEST_CHECK_INT(r, pred);
347 test_header(file, line, a1, NULL, "MEM_ZERO", pred);
348 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
349 tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
350 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
351 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
352 ((u_char *)aa1)[where], v);
353 test_die();
354}
355
356void
357assert_int(const char *file, int line, const char *a1, const char *a2,
358 int aa1, int aa2, enum test_predicate pred)
359{
360 TEST_CHECK(aa1, aa2, pred);
361 test_header(file, line, a1, a2, "INT", pred);
362 fprintf(stderr, "%12s = %d\n", a1, aa1);
363 fprintf(stderr, "%12s = %d\n", a2, aa2);
364 test_die();
365}
366
367void
368assert_size_t(const char *file, int line, const char *a1, const char *a2,
369 size_t aa1, size_t aa2, enum test_predicate pred)
370{
371 TEST_CHECK(aa1, aa2, pred);
372 test_header(file, line, a1, a2, "SIZE_T", pred);
373 fprintf(stderr, "%12s = %zu\n", a1, aa1);
374 fprintf(stderr, "%12s = %zu\n", a2, aa2);
375 test_die();
376}
377
378void
379assert_u_int(const char *file, int line, const char *a1, const char *a2,
380 u_int aa1, u_int aa2, enum test_predicate pred)
381{
382 TEST_CHECK(aa1, aa2, pred);
383 test_header(file, line, a1, a2, "U_INT", pred);
384 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
385 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
386 test_die();
387}
388
389void
390assert_long_long(const char *file, int line, const char *a1, const char *a2,
391 long long aa1, long long aa2, enum test_predicate pred)
392{
393 TEST_CHECK(aa1, aa2, pred);
394 test_header(file, line, a1, a2, "LONG LONG", pred);
395 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
396 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
397 test_die();
398}
399
400void
401assert_char(const char *file, int line, const char *a1, const char *a2,
402 char aa1, char aa2, enum test_predicate pred)
403{
404 char buf[8];
405
406 TEST_CHECK(aa1, aa2, pred);
407 test_header(file, line, a1, a2, "CHAR", pred);
408 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
409 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
410 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
411 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
412 test_die();
413}
414
415void
416assert_u8(const char *file, int line, const char *a1, const char *a2,
417 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
418{
419 TEST_CHECK(aa1, aa2, pred);
420 test_header(file, line, a1, a2, "U8", pred);
421 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
422 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
423 test_die();
424}
425
426void
427assert_u16(const char *file, int line, const char *a1, const char *a2,
428 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
429{
430 TEST_CHECK(aa1, aa2, pred);
431 test_header(file, line, a1, a2, "U16", pred);
432 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
433 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
434 test_die();
435}
436
437void
438assert_u32(const char *file, int line, const char *a1, const char *a2,
439 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
440{
441 TEST_CHECK(aa1, aa2, pred);
442 test_header(file, line, a1, a2, "U32", pred);
443 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
444 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
445 test_die();
446}
447
448void
449assert_u64(const char *file, int line, const char *a1, const char *a2,
450 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
451{
452 TEST_CHECK(aa1, aa2, pred);
453 test_header(file, line, a1, a2, "U64", pred);
454 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
455 (unsigned long long)aa1, (unsigned long long)aa1);
456 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
457 (unsigned long long)aa2, (unsigned long long)aa2);
458 test_die();
459}
460
461void
462assert_ptr(const char *file, int line, const char *a1, const char *a2,
463 const void *aa1, const void *aa2, enum test_predicate pred)
464{
465 TEST_CHECK(aa1, aa2, pred);
466 test_header(file, line, a1, a2, "PTR", pred);
467 fprintf(stderr, "%12s = %p\n", a1, aa1);
468 fprintf(stderr, "%12s = %p\n", a2, aa2);
469 test_die();
470}
471
diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h
new file mode 100644
index 000000000..a398c615f
--- /dev/null
+++ b/regress/unittests/test_helper/test_helper.h
@@ -0,0 +1,292 @@
1/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* Utility functions/framework for regress tests */
19
20#ifndef _TEST_HELPER_H
21#define _TEST_HELPER_H
22
23#include "includes.h"
24
25#include <sys/types.h>
26#ifdef HAVE_STDINT_H
27# include <stdint.h>
28#endif
29
30#include <openssl/bn.h>
31#include <openssl/err.h>
32
33enum test_predicate {
34 TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE
35};
36typedef void (test_onerror_func_t)(void *);
37
38/* Supplied by test suite */
39void tests(void);
40
41const char *test_data_file(const char *name);
42void test_start(const char *n);
43void set_onerror_func(test_onerror_func_t *f, void *ctx);
44void test_done(void);
45void ssl_err_check(const char *file, int line);
46void assert_bignum(const char *file, int line,
47 const char *a1, const char *a2,
48 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred);
49void assert_string(const char *file, int line,
50 const char *a1, const char *a2,
51 const char *aa1, const char *aa2, enum test_predicate pred);
52void assert_mem(const char *file, int line,
53 const char *a1, const char *a2,
54 const void *aa1, const void *aa2, size_t l, enum test_predicate pred);
55void assert_mem_filled(const char *file, int line,
56 const char *a1,
57 const void *aa1, u_char v, size_t l, enum test_predicate pred);
58void assert_int(const char *file, int line,
59 const char *a1, const char *a2,
60 int aa1, int aa2, enum test_predicate pred);
61void assert_size_t(const char *file, int line,
62 const char *a1, const char *a2,
63 size_t aa1, size_t aa2, enum test_predicate pred);
64void assert_u_int(const char *file, int line,
65 const char *a1, const char *a2,
66 u_int aa1, u_int aa2, enum test_predicate pred);
67void assert_long_long(const char *file, int line,
68 const char *a1, const char *a2,
69 long long aa1, long long aa2, enum test_predicate pred);
70void assert_char(const char *file, int line,
71 const char *a1, const char *a2,
72 char aa1, char aa2, enum test_predicate pred);
73void assert_ptr(const char *file, int line,
74 const char *a1, const char *a2,
75 const void *aa1, const void *aa2, enum test_predicate pred);
76void assert_u8(const char *file, int line,
77 const char *a1, const char *a2,
78 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred);
79void assert_u16(const char *file, int line,
80 const char *a1, const char *a2,
81 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred);
82void assert_u32(const char *file, int line,
83 const char *a1, const char *a2,
84 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred);
85void assert_u64(const char *file, int line,
86 const char *a1, const char *a2,
87 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred);
88
89#define TEST_START(n) test_start(n)
90#define TEST_DONE() test_done()
91#define TEST_ONERROR(f, c) set_onerror_func(f, c)
92#define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__)
93
94#define ASSERT_BIGNUM_EQ(a1, a2) \
95 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
96#define ASSERT_STRING_EQ(a1, a2) \
97 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
98#define ASSERT_MEM_EQ(a1, a2, l) \
99 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ)
100#define ASSERT_MEM_FILLED_EQ(a1, c, l) \
101 assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ)
102#define ASSERT_MEM_ZERO_EQ(a1, l) \
103 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ)
104#define ASSERT_INT_EQ(a1, a2) \
105 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
106#define ASSERT_SIZE_T_EQ(a1, a2) \
107 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
108#define ASSERT_U_INT_EQ(a1, a2) \
109 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
110#define ASSERT_LONG_LONG_EQ(a1, a2) \
111 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
112#define ASSERT_CHAR_EQ(a1, a2) \
113 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
114#define ASSERT_PTR_EQ(a1, a2) \
115 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
116#define ASSERT_U8_EQ(a1, a2) \
117 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
118#define ASSERT_U16_EQ(a1, a2) \
119 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
120#define ASSERT_U32_EQ(a1, a2) \
121 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
122#define ASSERT_U64_EQ(a1, a2) \
123 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
124
125#define ASSERT_BIGNUM_NE(a1, a2) \
126 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
127#define ASSERT_STRING_NE(a1, a2) \
128 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
129#define ASSERT_MEM_NE(a1, a2, l) \
130 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE)
131#define ASSERT_MEM_ZERO_NE(a1, l) \
132 assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE)
133#define ASSERT_INT_NE(a1, a2) \
134 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
135#define ASSERT_SIZE_T_NE(a1, a2) \
136 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
137#define ASSERT_U_INT_NE(a1, a2) \
138 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
139#define ASSERT_LONG_LONG_NE(a1, a2) \
140 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
141#define ASSERT_CHAR_NE(a1, a2) \
142 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
143#define ASSERT_PTR_NE(a1, a2) \
144 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
145#define ASSERT_U8_NE(a1, a2) \
146 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
147#define ASSERT_U16_NE(a1, a2) \
148 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
149#define ASSERT_U32_NE(a1, a2) \
150 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
151#define ASSERT_U64_NE(a1, a2) \
152 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
153
154#define ASSERT_BIGNUM_LT(a1, a2) \
155 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
156#define ASSERT_STRING_LT(a1, a2) \
157 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
158#define ASSERT_MEM_LT(a1, a2, l) \
159 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT)
160#define ASSERT_INT_LT(a1, a2) \
161 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
162#define ASSERT_SIZE_T_LT(a1, a2) \
163 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
164#define ASSERT_U_INT_LT(a1, a2) \
165 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
166#define ASSERT_LONG_LONG_LT(a1, a2) \
167 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
168#define ASSERT_CHAR_LT(a1, a2) \
169 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
170#define ASSERT_PTR_LT(a1, a2) \
171 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
172#define ASSERT_U8_LT(a1, a2) \
173 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
174#define ASSERT_U16_LT(a1, a2) \
175 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
176#define ASSERT_U32_LT(a1, a2) \
177 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
178#define ASSERT_U64_LT(a1, a2) \
179 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
180
181#define ASSERT_BIGNUM_LE(a1, a2) \
182 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
183#define ASSERT_STRING_LE(a1, a2) \
184 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
185#define ASSERT_MEM_LE(a1, a2, l) \
186 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE)
187#define ASSERT_INT_LE(a1, a2) \
188 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
189#define ASSERT_SIZE_T_LE(a1, a2) \
190 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
191#define ASSERT_U_INT_LE(a1, a2) \
192 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
193#define ASSERT_LONG_LONG_LE(a1, a2) \
194 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
195#define ASSERT_CHAR_LE(a1, a2) \
196 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
197#define ASSERT_PTR_LE(a1, a2) \
198 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
199#define ASSERT_U8_LE(a1, a2) \
200 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
201#define ASSERT_U16_LE(a1, a2) \
202 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
203#define ASSERT_U32_LE(a1, a2) \
204 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
205#define ASSERT_U64_LE(a1, a2) \
206 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
207
208#define ASSERT_BIGNUM_GT(a1, a2) \
209 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
210#define ASSERT_STRING_GT(a1, a2) \
211 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
212#define ASSERT_MEM_GT(a1, a2, l) \
213 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT)
214#define ASSERT_INT_GT(a1, a2) \
215 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
216#define ASSERT_SIZE_T_GT(a1, a2) \
217 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
218#define ASSERT_U_INT_GT(a1, a2) \
219 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
220#define ASSERT_LONG_LONG_GT(a1, a2) \
221 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
222#define ASSERT_CHAR_GT(a1, a2) \
223 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
224#define ASSERT_PTR_GT(a1, a2) \
225 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
226#define ASSERT_U8_GT(a1, a2) \
227 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
228#define ASSERT_U16_GT(a1, a2) \
229 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
230#define ASSERT_U32_GT(a1, a2) \
231 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
232#define ASSERT_U64_GT(a1, a2) \
233 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
234
235#define ASSERT_BIGNUM_GE(a1, a2) \
236 assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
237#define ASSERT_STRING_GE(a1, a2) \
238 assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
239#define ASSERT_MEM_GE(a1, a2, l) \
240 assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE)
241#define ASSERT_INT_GE(a1, a2) \
242 assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
243#define ASSERT_SIZE_T_GE(a1, a2) \
244 assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
245#define ASSERT_U_INT_GE(a1, a2) \
246 assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
247#define ASSERT_LONG_LONG_GE(a1, a2) \
248 assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
249#define ASSERT_CHAR_GE(a1, a2) \
250 assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
251#define ASSERT_PTR_GE(a1, a2) \
252 assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
253#define ASSERT_U8_GE(a1, a2) \
254 assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
255#define ASSERT_U16_GE(a1, a2) \
256 assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
257#define ASSERT_U32_GE(a1, a2) \
258 assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
259#define ASSERT_U64_GE(a1, a2) \
260 assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
261
262/* Fuzzing support */
263
264struct fuzz;
265#define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */
266#define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */
267#define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */
268#define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */
269#define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */
270#define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */
271#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */
272#define FUZZ_MAX FUZZ_BASE64
273
274/* Start fuzzing a blob of data with selected strategies (bitmask) */
275struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l);
276
277/* Free a fuzz context */
278void fuzz_cleanup(struct fuzz *fuzz);
279
280/* Prepare the next fuzz case in the series */
281void fuzz_next(struct fuzz *fuzz);
282
283/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
284int fuzz_done(struct fuzz *fuzz);
285
286/* Return the length and a pointer to the current fuzzed case */
287size_t fuzz_len(struct fuzz *fuzz);
288u_char *fuzz_ptr(struct fuzz *fuzz);
289
290/* Dump the current fuzz case to stderr */
291void fuzz_dump(struct fuzz *fuzz);
292#endif /* _TEST_HELPER_H */