summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/regress
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/regress')
-rw-r--r--crypto/openssh/regress/Makefile190
-rw-r--r--crypto/openssh/regress/README.regress104
-rwxr-xr-xcrypto/openssh/regress/addrmatch.sh56
-rw-r--r--crypto/openssh/regress/agent-getpeereid.sh45
-rwxr-xr-xcrypto/openssh/regress/agent-pkcs11.sh69
-rw-r--r--crypto/openssh/regress/agent-ptrace.sh61
-rw-r--r--crypto/openssh/regress/agent-timeout.sh36
-rw-r--r--crypto/openssh/regress/agent.sh81
-rw-r--r--crypto/openssh/regress/banner.sh44
-rw-r--r--crypto/openssh/regress/broken-pipe.sh15
-rw-r--r--crypto/openssh/regress/brokenkeys.sh23
-rwxr-xr-xcrypto/openssh/regress/cert-hostkey.sh244
-rwxr-xr-xcrypto/openssh/regress/cert-userkey.sh358
-rw-r--r--crypto/openssh/regress/cfgmatch.sh126
-rw-r--r--crypto/openssh/regress/cipher-speed.sh47
-rwxr-xr-xcrypto/openssh/regress/conch-ciphers.sh28
-rw-r--r--crypto/openssh/regress/connect-privsep.sh36
-rw-r--r--crypto/openssh/regress/connect.sh13
-rwxr-xr-xcrypto/openssh/regress/dhgex.sh58
-rw-r--r--crypto/openssh/regress/dsa_ssh2.prv14
-rw-r--r--crypto/openssh/regress/dsa_ssh2.pub13
-rw-r--r--crypto/openssh/regress/dynamic-forward.sh59
-rw-r--r--crypto/openssh/regress/envpass.sh60
-rw-r--r--crypto/openssh/regress/exit-status.sh24
-rw-r--r--crypto/openssh/regress/forcecommand.sh42
-rwxr-xr-xcrypto/openssh/regress/forward-control.sh168
-rw-r--r--crypto/openssh/regress/forwarding.sh137
-rwxr-xr-xcrypto/openssh/regress/host-expand.sh19
-rwxr-xr-xcrypto/openssh/regress/integrity.sh75
-rwxr-xr-xcrypto/openssh/regress/kextype.sh25
-rwxr-xr-xcrypto/openssh/regress/key-options.sh71
-rw-r--r--crypto/openssh/regress/keygen-change.sh23
-rwxr-xr-xcrypto/openssh/regress/keygen-convert.sh33
-rwxr-xr-xcrypto/openssh/regress/keys-command.sh39
-rw-r--r--crypto/openssh/regress/keyscan.sh19
-rwxr-xr-xcrypto/openssh/regress/keytype.sh61
-rwxr-xr-xcrypto/openssh/regress/krl.sh163
-rwxr-xr-xcrypto/openssh/regress/localcommand.sh15
-rw-r--r--crypto/openssh/regress/login-timeout.sh32
-rwxr-xr-xcrypto/openssh/regress/modpipe.c175
-rw-r--r--crypto/openssh/regress/multiplex.sh203
-rwxr-xr-xcrypto/openssh/regress/portnum.sh34
-rw-r--r--crypto/openssh/regress/proto-mismatch.sh19
-rw-r--r--crypto/openssh/regress/proto-version.sh34
-rw-r--r--crypto/openssh/regress/proxy-connect.sh31
-rwxr-xr-xcrypto/openssh/regress/putty-ciphers.sh26
-rwxr-xr-xcrypto/openssh/regress/putty-kex.sh23
-rwxr-xr-xcrypto/openssh/regress/putty-transfer.sh41
-rw-r--r--crypto/openssh/regress/reconfigure.sh36
-rw-r--r--crypto/openssh/regress/reexec.sh73
-rw-r--r--crypto/openssh/regress/rekey.sh150
-rw-r--r--crypto/openssh/regress/rsa_openssh.prv15
-rw-r--r--crypto/openssh/regress/rsa_openssh.pub1
-rw-r--r--crypto/openssh/regress/rsa_ssh2.prv16
-rw-r--r--crypto/openssh/regress/scp-ssh-wrapper.sh59
-rw-r--r--crypto/openssh/regress/scp.sh126
-rw-r--r--crypto/openssh/regress/setuid-allowed.c57
-rw-r--r--crypto/openssh/regress/sftp-badcmds.sh65
-rw-r--r--crypto/openssh/regress/sftp-batch.sh55
-rwxr-xr-xcrypto/openssh/regress/sftp-chroot.sh26
-rw-r--r--crypto/openssh/regress/sftp-cmds.sh232
-rw-r--r--crypto/openssh/regress/sftp-glob.sh75
-rw-r--r--crypto/openssh/regress/sftp-perm.sh269
-rw-r--r--crypto/openssh/regress/sftp.sh32
-rw-r--r--crypto/openssh/regress/ssh-com-client.sh130
-rw-r--r--crypto/openssh/regress/ssh-com-keygen.sh74
-rw-r--r--crypto/openssh/regress/ssh-com-sftp.sh65
-rw-r--r--crypto/openssh/regress/ssh-com.sh119
-rwxr-xr-xcrypto/openssh/regress/ssh2putty.sh34
-rw-r--r--crypto/openssh/regress/sshd-log-wrapper.sh13
-rw-r--r--crypto/openssh/regress/stderr-after-eof.sh24
-rw-r--r--crypto/openssh/regress/stderr-data.sh29
-rw-r--r--crypto/openssh/regress/t4.ok1
-rw-r--r--crypto/openssh/regress/t5.ok1
-rw-r--r--crypto/openssh/regress/test-exec.sh494
-rw-r--r--crypto/openssh/regress/transfer.sh26
-rw-r--r--crypto/openssh/regress/try-ciphers.sh38
-rw-r--r--crypto/openssh/regress/unittests/Makefile5
-rw-r--r--crypto/openssh/regress/unittests/Makefile.inc59
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/Makefile14
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c240
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c126
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c127
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c484
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c409
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c130
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c138
-rw-r--r--crypto/openssh/regress/unittests/sshbuf/tests.c28
-rw-r--r--crypto/openssh/regress/unittests/sshkey/Makefile13
-rw-r--r--crypto/openssh/regress/unittests/sshkey/common.c84
-rw-r--r--crypto/openssh/regress/unittests/sshkey/common.h16
-rwxr-xr-xcrypto/openssh/regress/unittests/sshkey/mktestdata.sh190
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_file.c457
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_fuzz.c406
-rw-r--r--crypto/openssh/regress/unittests/sshkey/test_sshkey.c357
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_112
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.g1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.priv1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_1_pw15
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_212
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_n12
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/dsa_n_pw22
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_15
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.curve1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.priv1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1_pw8
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_27
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.curve1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.priv1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n5
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n_pw9
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_17
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw8
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_27
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/pw1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1bin0 -> 421 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pwbin0 -> 421 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2bin0 -> 981 bytes
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_112
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.p1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.q1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_1_pw15
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_227
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp.bb1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.n1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.p1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.q1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.pub1
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_n12
-rw-r--r--crypto/openssh/regress/unittests/sshkey/testdata/rsa_n_pw14
-rw-r--r--crypto/openssh/regress/unittests/sshkey/tests.c27
-rw-r--r--crypto/openssh/regress/unittests/test_helper/Makefile13
-rw-r--r--crypto/openssh/regress/unittests/test_helper/fuzz.c378
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.c471
-rw-r--r--crypto/openssh/regress/unittests/test_helper/test_helper.h292
-rw-r--r--crypto/openssh/regress/yes-head.sh15
178 files changed, 10391 insertions, 0 deletions
diff --git a/crypto/openssh/regress/Makefile b/crypto/openssh/regress/Makefile
new file mode 100644
index 0000000..3feb7a9
--- /dev/null
+++ b/crypto/openssh/regress/Makefile
@@ -0,0 +1,190 @@
+# $OpenBSD: Makefile,v 1.70 2014/06/24 01:14:17 djm Exp $
+
+REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec
+tests: $(REGRESS_TARGETS)
+
+# Interop tests are not run by default
+interop interop-tests: t-exec-interop
+
+clean:
+ for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
+ test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN}
+ rm -rf $(OBJ).putty
+
+distclean: clean
+
+LTESTS= connect \
+ proxy-connect \
+ connect-privsep \
+ proto-version \
+ proto-mismatch \
+ exit-status \
+ envpass \
+ transfer \
+ banner \
+ rekey \
+ stderr-data \
+ stderr-after-eof \
+ broken-pipe \
+ try-ciphers \
+ yes-head \
+ login-timeout \
+ agent \
+ agent-getpeereid \
+ agent-timeout \
+ agent-ptrace \
+ keyscan \
+ keygen-change \
+ keygen-convert \
+ key-options \
+ scp \
+ sftp \
+ sftp-chroot \
+ sftp-cmds \
+ sftp-badcmds \
+ sftp-batch \
+ sftp-glob \
+ sftp-perm \
+ reconfigure \
+ dynamic-forward \
+ forwarding \
+ multiplex \
+ reexec \
+ brokenkeys \
+ cfgmatch \
+ addrmatch \
+ localcommand \
+ forcecommand \
+ portnum \
+ keytype \
+ kextype \
+ cert-hostkey \
+ cert-userkey \
+ host-expand \
+ keys-command \
+ forward-control \
+ integrity \
+ krl
+# dhgex \
+
+INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
+#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
+
+#LTESTS= cipher-speed
+
+USER!= id -un
+CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
+ t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \
+ authorized_keys_${USER} known_hosts pidfile testdata \
+ ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \
+ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \
+ rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \
+ ls.copy banner.in banner.out empty.in \
+ scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \
+ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \
+ known_hosts-cert host_ca_key* cert_host_key* cert_user_key* \
+ putty.rsa2 sshd_proxy_orig ssh_proxy_bak \
+ key.rsa-* key.dsa-* key.ecdsa-* \
+ authorized_principals_${USER} expect actual ready \
+ sshd_proxy.* authorized_keys_${USER}.* modpipe revoked-* krl-* \
+ ssh.log failed-ssh.log sshd.log failed-sshd.log \
+ regress.log failed-regress.log ssh-log-wrapper.sh \
+ sftp-server.sh sftp-server.log sftp.log setuid-allowed \
+ data ed25519-agent ed25519-agent.pub key.ed25519-512 \
+ key.ed25519-512.pub
+
+SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER}
+
+# Enable all malloc(3) randomisations and checks
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+TEST_SSH_SSHKEYGEN?=ssh-keygen
+
+CPPFLAGS=-I..
+
+t1:
+ ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
+ tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv
+ ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv
+ awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv
+ ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv
+
+t2:
+ cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out
+ chmod 600 $(OBJ)/t2.out
+ ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub
+
+t3:
+ ${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out
+ ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub
+
+t4:
+ ${TEST_SSH_SSHKEYGEN} -lf ${.CURDIR}/rsa_openssh.pub |\
+ awk '{print $$2}' | diff - ${.CURDIR}/t4.ok
+
+t5:
+ ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\
+ awk '{print $$2}' | diff - ${.CURDIR}/t5.ok
+
+t6:
+ ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1
+ ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2
+ chmod 600 $(OBJ)/t6.out1
+ ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2
+
+$(OBJ)/t7.out:
+ ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@
+
+t7: $(OBJ)/t7.out
+ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null
+ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null
+
+$(OBJ)/t8.out:
+ ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@
+
+t8: $(OBJ)/t8.out
+ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null
+ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null
+
+$(OBJ)/t9.out:
+ test "${TEST_SSH_ECC}" != yes || \
+ ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@
+
+t9: $(OBJ)/t9.out
+ test "${TEST_SSH_ECC}" != yes || \
+ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null
+ test "${TEST_SSH_ECC}" != yes || \
+ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null
+
+
+$(OBJ)/t10.out:
+ ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -f $@
+
+t10: $(OBJ)/t10.out
+ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null
+ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null
+
+t-exec: ${LTESTS:=.sh}
+ @if [ "x$?" = "x" ]; then exit 0; fi; \
+ for TEST in ""$?; do \
+ echo "run test $${TEST}" ... 1>&2; \
+ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+ done
+
+t-exec-interop: ${INTEROP_TESTS:=.sh}
+ @if [ "x$?" = "x" ]; then exit 0; fi; \
+ for TEST in ""$?; do \
+ echo "run test $${TEST}" ... 1>&2; \
+ (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
+ done
+
+# Not run by default
+interop: ${INTEROP_TARGETS}
+
+# Unit tests, built by top-level Makefile
+unit:
+ set -e ; if test -z "${SKIP_UNIT}" ; then \
+ ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \
+ ${.OBJDIR}/unittests/sshkey/test_sshkey \
+ -d ${.CURDIR}//unittests/sshkey/testdata ; \
+ fi
diff --git a/crypto/openssh/regress/README.regress b/crypto/openssh/regress/README.regress
new file mode 100644
index 0000000..82e4cc7
--- /dev/null
+++ b/crypto/openssh/regress/README.regress
@@ -0,0 +1,104 @@
+Overview.
+
+$ ./configure && make tests
+
+You'll see some progress info. A failure will cause either the make to
+abort or the driver script to report a "FATAL" failure.
+
+The test consists of 2 parts. The first is the file-based tests which is
+driven by the Makefile, and the second is a set of network or proxycommand
+based tests, which are driven by a driver script (test-exec.sh) which is
+called multiple times by the Makefile.
+
+Failures in the first part will cause the Makefile to return an error.
+Failures in the second part will print a "FATAL" message for the failed
+test and continue.
+
+OpenBSD has a system-wide regression test suite. OpenSSH Portable's test
+suite is based on OpenBSD's with modifications.
+
+
+Environment variables.
+
+SUDO: path to sudo command, if desired. Note that some systems (notably
+ systems using PAM) require sudo to execute some tests.
+TEST_SSH_TRACE: set to "yes" for verbose output from tests
+TEST_SSH_QUIET: set to "yes" to suppress non-fatal output.
+TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD
+ SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER
+OBJ: used by test scripts to access build dir.
+TEST_SHELL: shell used for running the test scripts.
+TEST_SSH_PORT: TCP port to be used for the listening tests.
+TEST_SSH_SSH_CONFOPTS: Configuration directives to be added to ssh_config
+ before running each test.
+TEST_SSH_SSHD_CONFOTPS: Configuration directives to be added to sshd_config
+ before running each test.
+
+
+Individual tests.
+
+You can run an individual test from the top-level Makefile, eg:
+$ make tests LTESTS=agent-timeout
+
+If you need to manipulate the environment more you can invoke test-exec.sh
+directly if you set up the path to find the binaries under test and the
+test scripts themselves, for example:
+
+$ cd regress
+$ PATH=`pwd`/..:$PATH:. TEST_SHELL=/bin/sh sh test-exec.sh `pwd` \
+ agent-timeout.sh
+ok agent timeout test
+
+
+Files.
+
+test-exec.sh: the main test driver. Sets environment, creates config files
+and keys and runs the specified test.
+
+At the time of writing, the individual tests are:
+agent-timeout.sh: agent timeout test
+agent.sh: simple agent test
+broken-pipe.sh: broken pipe test
+connect-privsep.sh: proxy connect with privsep
+connect.sh: simple connect
+exit-status.sh: remote exit status
+forwarding.sh: local and remote forwarding
+keygen-change.sh: change passphrase for key
+keyscan.sh: keyscan
+proto-mismatch.sh: protocol version mismatch
+proto-version.sh: sshd version with different protocol combinations
+proxy-connect.sh: proxy connect
+sftp.sh: basic sftp put/get
+ssh-com-client.sh: connect with ssh.com client
+ssh-com-keygen.sh: ssh.com key import
+ssh-com-sftp.sh: basic sftp put/get with ssh.com server
+ssh-com.sh: connect to ssh.com server
+stderr-after-eof.sh: stderr data after eof
+stderr-data.sh: stderr data transfer
+transfer.sh: transfer data
+try-ciphers.sh: try ciphers
+yes-head.sh: yes pipe head
+
+
+Problems?
+
+Run the failing test with shell tracing (-x) turned on:
+$ PATH=`pwd`/..:$PATH:. sh -x test-exec.sh `pwd` agent-timeout.sh
+
+Failed tests can be difficult to diagnose. Suggestions:
+- run the individual test via ./test-exec.sh `pwd` [testname]
+- set LogLevel to VERBOSE in test-exec.sh and enable syslogging of
+ auth.debug (eg to /var/log/authlog).
+
+
+Known Issues.
+
+- Similarly, if you do not have "scp" in your system's $PATH then the
+ multiplex scp tests will fail (since the system's shell startup scripts
+ will determine where the shell started by sshd will look for scp).
+
+- Recent GNU coreutils deprecate "head -[n]": this will cause the yes-head
+ test to fail. The old behaviour can be restored by setting (and
+ exporting) _POSIX2_VERSION=199209 before running the tests.
+
+$Id: README.regress,v 1.12 2011/05/05 03:48:42 djm Exp $
diff --git a/crypto/openssh/regress/addrmatch.sh b/crypto/openssh/regress/addrmatch.sh
new file mode 100755
index 0000000..1584bd4
--- /dev/null
+++ b/crypto/openssh/regress/addrmatch.sh
@@ -0,0 +1,56 @@
+# $OpenBSD: addrmatch.sh,v 1.4 2012/05/13 01:42:32 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="address match"
+
+mv $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+run_trial()
+{
+ user="$1"; addr="$2"; host="$3"; laddr="$4"; lport="$5"
+ expected="$6"; descr="$7"
+
+ verbose "test $descr for $user $addr $host"
+ result=`${SSHD} -f $OBJ/sshd_proxy -T \
+ -C user=${user},addr=${addr},host=${host},laddr=${laddr},lport=${lport} | \
+ awk '/^forcecommand/ {print $2}'`
+ if [ "$result" != "$expected" ]; then
+ fail "failed '$descr' expected $expected got $result"
+ fi
+}
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >>$OBJ/sshd_proxy <<EOD
+ForceCommand nomatch
+Match Address 192.168.0.0/16,!192.168.30.0/24,10.0.0.0/8,host.example.com
+ ForceCommand match1
+Match Address 1.1.1.1,::1,!::3,2000::/16
+ ForceCommand match2
+Match LocalAddress 127.0.0.1,::1
+ ForceCommand match3
+Match LocalPort 5678
+ ForceCommand match4
+EOD
+
+run_trial user 192.168.0.1 somehost 1.2.3.4 1234 match1 "first entry"
+run_trial user 192.168.30.1 somehost 1.2.3.4 1234 nomatch "negative match"
+run_trial user 19.0.0.1 somehost 1.2.3.4 1234 nomatch "no match"
+run_trial user 10.255.255.254 somehost 1.2.3.4 1234 match1 "list middle"
+run_trial user 192.168.30.1 192.168.0.1 1.2.3.4 1234 nomatch "faked IP in hostname"
+run_trial user 1.1.1.1 somehost.example.com 1.2.3.4 1234 match2 "bare IP4 address"
+run_trial user 19.0.0.1 somehost 127.0.0.1 1234 match3 "localaddress"
+run_trial user 19.0.0.1 somehost 1.2.3.4 5678 match4 "localport"
+
+if test "$TEST_SSH_IPV6" != "no"; then
+run_trial user ::1 somehost.example.com ::2 1234 match2 "bare IP6 address"
+run_trial user ::2 somehost.exaple.com ::2 1234 nomatch "deny IPv6"
+run_trial user ::3 somehost ::2 1234 nomatch "IP6 negated"
+run_trial user ::4 somehost ::2 1234 nomatch "IP6 no match"
+run_trial user 2000::1 somehost ::2 1234 match2 "IP6 network"
+run_trial user 2001::1 somehost ::2 1234 nomatch "IP6 network"
+run_trial user ::5 somehost ::1 1234 match3 "IP6 localaddress"
+run_trial user ::5 somehost ::2 5678 match4 "IP6 localport"
+fi
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+rm $OBJ/sshd_proxy_bak
diff --git a/crypto/openssh/regress/agent-getpeereid.sh b/crypto/openssh/regress/agent-getpeereid.sh
new file mode 100644
index 0000000..d5ae2d6
--- /dev/null
+++ b/crypto/openssh/regress/agent-getpeereid.sh
@@ -0,0 +1,45 @@
+# $OpenBSD: agent-getpeereid.sh,v 1.5 2013/05/17 10:33:09 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="disallow agent attach from other uid"
+
+UNPRIV=nobody
+ASOCK=${OBJ}/agent
+SSH_AUTH_SOCK=/nonexistent
+
+if config_defined HAVE_GETPEEREID HAVE_GETPEERUCRED HAVE_SO_PEERCRED ; then
+ :
+else
+ echo "skipped (not supported on this platform)"
+ exit 0
+fi
+if [ -z "$SUDO" ]; then
+ echo "skipped: need SUDO to switch to uid $UNPRIV"
+ exit 0
+fi
+
+trace "start agent"
+eval `${SSHAGENT} -s -a ${ASOCK}` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fail "could not start ssh-agent: exit code $r"
+else
+ chmod 644 ${SSH_AUTH_SOCK}
+
+ ssh-add -l > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 1 ]; then
+ fail "ssh-add failed with $r != 1"
+ fi
+
+ < /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l 2>/dev/null
+ r=$?
+ if [ $r -lt 2 ]; then
+ fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
+ fi
+
+ trace "kill agent"
+ ${SSHAGENT} -k > /dev/null
+fi
+
+rm -f ${OBJ}/agent
diff --git a/crypto/openssh/regress/agent-pkcs11.sh b/crypto/openssh/regress/agent-pkcs11.sh
new file mode 100755
index 0000000..db33ab3
--- /dev/null
+++ b/crypto/openssh/regress/agent-pkcs11.sh
@@ -0,0 +1,69 @@
+# $OpenBSD: agent-pkcs11.sh,v 1.1 2010/02/08 10:52:47 markus Exp $
+# Placed in the Public Domain.
+
+tid="pkcs11 agent test"
+
+TEST_SSH_PIN=""
+TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0
+
+# setup environment for soft-pkcs11 token
+SOFTPKCS11RC=$OBJ/pkcs11.info
+export SOFTPKCS11RC
+# prevent ssh-agent from calling ssh-askpass
+SSH_ASKPASS=/usr/bin/true
+export SSH_ASKPASS
+unset DISPLAY
+
+# start command w/o tty, so ssh-add accepts pin from stdin
+notty() {
+ perl -e 'use POSIX; POSIX::setsid();
+ if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@"
+}
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fail "could not start ssh-agent: exit code $r"
+else
+ trace "generating key/cert"
+ rm -f $OBJ/pkcs11.key $OBJ/pkcs11.crt
+ openssl genrsa -out $OBJ/pkcs11.key 2048 > /dev/null 2>&1
+ chmod 600 $OBJ/pkcs11.key
+ openssl req -key $OBJ/pkcs11.key -new -x509 \
+ -out $OBJ/pkcs11.crt -text -subj '/CN=pkcs11 test' > /dev/null
+ printf "a\ta\t$OBJ/pkcs11.crt\t$OBJ/pkcs11.key" > $SOFTPKCS11RC
+ # add to authorized keys
+ ${SSHKEYGEN} -y -f $OBJ/pkcs11.key > $OBJ/authorized_keys_$USER
+
+ trace "add pkcs11 key to agent"
+ echo ${TEST_SSH_PIN} | notty ${SSHADD} -s ${TEST_SSH_PKCS11} > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -s failed: exit code $r"
+ fi
+
+ trace "pkcs11 list via agent"
+ ${SSHADD} -l > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -l failed: exit code $r"
+ fi
+
+ trace "pkcs11 connect via agent"
+ ${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5
+ r=$?
+ if [ $r -ne 5 ]; then
+ fail "ssh connect failed (exit code $r)"
+ fi
+
+ trace "remove pkcs11 keys"
+ echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -e failed: exit code $r"
+ fi
+
+ trace "kill agent"
+ ${SSHAGENT} -k > /dev/null
+fi
diff --git a/crypto/openssh/regress/agent-ptrace.sh b/crypto/openssh/regress/agent-ptrace.sh
new file mode 100644
index 0000000..1912ca8
--- /dev/null
+++ b/crypto/openssh/regress/agent-ptrace.sh
@@ -0,0 +1,61 @@
+# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $
+# Placed in the Public Domain.
+
+tid="disallow agent ptrace attach"
+
+if have_prog uname ; then
+ case `uname` in
+ AIX|CYGWIN*|OSF1)
+ echo "skipped (not supported on this platform)"
+ exit 0
+ ;;
+ esac
+fi
+
+if have_prog gdb ; then
+ : ok
+else
+ echo "skipped (gdb not found)"
+ exit 0
+fi
+
+if $OBJ/setuid-allowed ${SSHAGENT} ; then
+ : ok
+else
+ echo "skipped (${SSHAGENT} is mounted on a no-setuid filesystem)"
+ exit 0
+fi
+
+if test -z "$SUDO" ; then
+ echo "skipped (SUDO not set)"
+ exit 0
+else
+ $SUDO chown 0 ${SSHAGENT}
+ $SUDO chgrp 0 ${SSHAGENT}
+ $SUDO chmod 2755 ${SSHAGENT}
+fi
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fail "could not start ssh-agent: exit code $r"
+else
+ # ls -l ${SSH_AUTH_SOCK}
+ gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF
+ quit
+EOF
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "gdb failed: exit code $r"
+ fi
+ egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out
+ r=$?
+ rm -f ${OBJ}/gdb.out
+ if [ $r -ne 0 ]; then
+ fail "ptrace succeeded?: exit code $r"
+ fi
+
+ trace "kill agent"
+ ${SSHAGENT} -k > /dev/null
+fi
diff --git a/crypto/openssh/regress/agent-timeout.sh b/crypto/openssh/regress/agent-timeout.sh
new file mode 100644
index 0000000..6882659
--- /dev/null
+++ b/crypto/openssh/regress/agent-timeout.sh
@@ -0,0 +1,36 @@
+# $OpenBSD: agent-timeout.sh,v 1.2 2013/05/17 01:16:09 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="agent timeout test"
+
+SSHAGENT_TIMEOUT=10
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fail "could not start ssh-agent: exit code $r"
+else
+ trace "add keys with timeout"
+ for t in rsa rsa1; do
+ ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh-add did succeed exit code 0"
+ fi
+ done
+ n=`${SSHADD} -l 2> /dev/null | wc -l`
+ trace "agent has $n keys"
+ if [ $n -ne 2 ]; then
+ fail "ssh-add -l did not return 2 keys: $n"
+ fi
+ trace "sleeping 2*${SSHAGENT_TIMEOUT} seconds"
+ sleep ${SSHAGENT_TIMEOUT}
+ sleep ${SSHAGENT_TIMEOUT}
+ ${SSHADD} -l 2> /dev/null | grep 'The agent has no identities.' >/dev/null
+ if [ $? -ne 0 ]; then
+ fail "ssh-add -l still returns keys after timeout"
+ fi
+
+ trace "kill agent"
+ ${SSHAGENT} -k > /dev/null
+fi
diff --git a/crypto/openssh/regress/agent.sh b/crypto/openssh/regress/agent.sh
new file mode 100644
index 0000000..caad3c8
--- /dev/null
+++ b/crypto/openssh/regress/agent.sh
@@ -0,0 +1,81 @@
+# $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $
+# Placed in the Public Domain.
+
+tid="simple agent test"
+
+SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
+if [ $? -ne 2 ]; then
+ fail "ssh-add -l did not fail with exit code 2"
+fi
+
+trace "start agent"
+eval `${SSHAGENT} -s` > /dev/null
+r=$?
+if [ $r -ne 0 ]; then
+ fail "could not start ssh-agent: exit code $r"
+else
+ ${SSHADD} -l > /dev/null 2>&1
+ if [ $? -ne 1 ]; then
+ fail "ssh-add -l did not fail with exit code 1"
+ fi
+ trace "overwrite authorized keys"
+ printf '' > $OBJ/authorized_keys_$USER
+ for t in ed25519 rsa rsa1; do
+ # generate user key for agent
+ rm -f $OBJ/$t-agent
+ ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\
+ fail "ssh-keygen for $t-agent failed"
+ # add to authorized keys
+ cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER
+ # add privat key to agent
+ ${SSHADD} $OBJ/$t-agent > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh-add did succeed exit code 0"
+ fi
+ done
+ ${SSHADD} -l > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -l failed: exit code $r"
+ fi
+ # the same for full pubkey output
+ ${SSHADD} -L > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -L failed: exit code $r"
+ fi
+
+ trace "simple connect via agent"
+ for p in 1 2; do
+ ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p
+ r=$?
+ if [ $r -ne 5$p ]; then
+ fail "ssh connect with protocol $p failed (exit code $r)"
+ fi
+ done
+
+ trace "agent forwarding"
+ for p in 1 2; do
+ ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -l via agent fwd proto $p failed (exit code $r)"
+ fi
+ ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \
+ "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p"
+ r=$?
+ if [ $r -ne 5$p ]; then
+ fail "agent fwd proto $p failed (exit code $r)"
+ fi
+ done
+
+ trace "delete all agent keys"
+ ${SSHADD} -D > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-add -D failed: exit code $r"
+ fi
+
+ trace "kill agent"
+ ${SSHAGENT} -k > /dev/null
+fi
diff --git a/crypto/openssh/regress/banner.sh b/crypto/openssh/regress/banner.sh
new file mode 100644
index 0000000..0b9c950
--- /dev/null
+++ b/crypto/openssh/regress/banner.sh
@@ -0,0 +1,44 @@
+# $OpenBSD: banner.sh,v 1.2 2003/10/11 11:49:49 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="banner"
+echo "Banner $OBJ/banner.in" >> $OBJ/sshd_proxy
+
+rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in
+touch $OBJ/empty.in
+
+trace "test missing banner file"
+verbose "test $tid: missing banner file"
+( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
+ cmp $OBJ/empty.in $OBJ/banner.out ) || \
+ fail "missing banner file"
+
+for s in 0 10 100 1000 10000 100000 ; do
+ if [ "$s" = "0" ]; then
+ # create empty banner
+ touch $OBJ/banner.in
+ elif [ "$s" = "10" ]; then
+ # create 10-byte banner file
+ echo "abcdefghi" >$OBJ/banner.in
+ else
+ # increase size 10x
+ cp $OBJ/banner.in $OBJ/banner.out
+ for i in 0 1 2 3 4 5 6 7 8 ; do
+ cat $OBJ/banner.out >> $OBJ/banner.in
+ done
+ fi
+
+ trace "test banner size $s"
+ verbose "test $tid: size $s"
+ ( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
+ cmp $OBJ/banner.in $OBJ/banner.out ) || \
+ fail "banner size $s mismatch"
+done
+
+trace "test suppress banner (-q)"
+verbose "test $tid: suppress banner (-q)"
+( ${SSH} -q -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
+ cmp $OBJ/empty.in $OBJ/banner.out ) || \
+ fail "suppress banner (-q)"
+
+rm -f $OBJ/banner.out $OBJ/banner.in $OBJ/empty.in
diff --git a/crypto/openssh/regress/broken-pipe.sh b/crypto/openssh/regress/broken-pipe.sh
new file mode 100644
index 0000000..c08c849
--- /dev/null
+++ b/crypto/openssh/regress/broken-pipe.sh
@@ -0,0 +1,15 @@
+# $OpenBSD: broken-pipe.sh,v 1.4 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="broken pipe test"
+
+for p in 1 2; do
+ trace "protocol $p"
+ for i in 1 2 3 4; do
+ ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "broken pipe returns $r for protocol $p"
+ fi
+ done
+done
diff --git a/crypto/openssh/regress/brokenkeys.sh b/crypto/openssh/regress/brokenkeys.sh
new file mode 100644
index 0000000..3e70c34
--- /dev/null
+++ b/crypto/openssh/regress/brokenkeys.sh
@@ -0,0 +1,23 @@
+# $OpenBSD: brokenkeys.sh,v 1.1 2004/10/29 23:59:22 djm Exp $
+# Placed in the Public Domain.
+
+tid="broken keys"
+
+KEYS="$OBJ/authorized_keys_${USER}"
+
+start_sshd
+
+mv ${KEYS} ${KEYS}.bak
+
+# Truncated key
+echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS
+cat ${KEYS}.bak >> ${KEYS}
+cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
+
+${SSH} -2 -F $OBJ/ssh_config somehost true
+if [ $? -ne 0 ]; then
+ fail "ssh connect with protocol $p failed"
+fi
+
+mv ${KEYS}.bak ${KEYS}
+
diff --git a/crypto/openssh/regress/cert-hostkey.sh b/crypto/openssh/regress/cert-hostkey.sh
new file mode 100755
index 0000000..1d9e0ed
--- /dev/null
+++ b/crypto/openssh/regress/cert-hostkey.sh
@@ -0,0 +1,244 @@
+# $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $
+# Placed in the Public Domain.
+
+tid="certified host keys"
+
+rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+HOSTS='localhost-with-alias,127.0.0.1,::1'
+
+# Create a CA key and add it to known hosts
+${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\
+ fail "ssh-keygen of host_ca_key failed"
+(
+ printf '@cert-authority '
+ printf "$HOSTS "
+ cat $OBJ/host_ca_key.pub
+) > $OBJ/known_hosts-cert
+
+PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
+
+type_has_legacy() {
+ case $1 in
+ ed25519*|ecdsa*) return 1 ;;
+ esac
+ return 0
+}
+
+# Generate and sign host keys
+for ktype in $PLAIN_TYPES ; do
+ verbose "$tid: sign host ${ktype} cert"
+ # Generate and sign a host key
+ ${SSHKEYGEN} -q -N '' -t ${ktype} \
+ -f $OBJ/cert_host_key_${ktype} || \
+ fail "ssh-keygen of cert_host_key_${ktype} failed"
+ ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${ktype} ||
+ fail "couldn't sign cert_host_key_${ktype}"
+ type_has_legacy $ktype || continue
+ cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00
+ cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub
+ verbose "$tid: sign host ${ktype}_v00 cert"
+ ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 ||
+ fail "couldn't sign cert_host_key_${ktype}_v00"
+done
+
+# Basic connect tests
+for privsep in yes no ; do
+ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do
+ verbose "$tid: host ${ktype} cert connect privsep $privsep"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${ktype}
+ echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
+ echo UsePrivilegeSeparation $privsep
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
+done
+
+# Revoked certificates with key present
+(
+ printf '@cert-authority '
+ printf "$HOSTS "
+ cat $OBJ/host_ca_key.pub
+ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do
+ test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey"
+ printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n"
+ done
+) > $OBJ/known_hosts-cert
+for privsep in yes no ; do
+ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do
+ verbose "$tid: host ${ktype} revoked cert privsep $privsep"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${ktype}
+ echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
+ echo UsePrivilegeSeparation $privsep
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+ done
+done
+
+# Revoked CA
+(
+ printf '@cert-authority '
+ printf "$HOSTS "
+ cat $OBJ/host_ca_key.pub
+ printf '@revoked '
+ printf "* "
+ cat $OBJ/host_ca_key.pub
+) > $OBJ/known_hosts-cert
+for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do
+ verbose "$tid: host ${ktype} revoked cert"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${ktype}
+ echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
+ ) > $OBJ/sshd_proxy
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+done
+
+# Create a CA key and add it to known hosts
+(
+ printf '@cert-authority '
+ printf "$HOSTS "
+ cat $OBJ/host_ca_key.pub
+) > $OBJ/known_hosts-cert
+
+test_one() {
+ ident=$1
+ result=$2
+ sign_opts=$3
+
+ for kt in rsa rsa_v00 ; do
+ case $kt in
+ *_v00) args="-t v00" ;;
+ *) args="" ;;
+ esac
+
+ verbose "$tid: host cert connect $ident $kt expect $result"
+ ${SSHKEYGEN} -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ $sign_opts $args \
+ $OBJ/cert_host_key_${kt} ||
+ fail "couldn't sign cert_host_key_${kt}"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${kt}
+ echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ rc=$?
+ if [ "x$result" = "xsuccess" ] ; then
+ if [ $rc -ne 0 ]; then
+ fail "ssh cert connect $ident failed unexpectedly"
+ fi
+ else
+ if [ $rc -eq 0 ]; then
+ fail "ssh cert connect $ident succeeded unexpectedly"
+ fi
+ fi
+ done
+}
+
+test_one "user-certificate" failure "-n $HOSTS"
+test_one "empty principals" success "-h"
+test_one "wrong principals" failure "-h -n foo"
+test_one "cert not yet valid" failure "-h -V20200101:20300101"
+test_one "cert expired" failure "-h -V19800101:19900101"
+test_one "cert valid interval" success "-h -V-1w:+2w"
+test_one "cert has constraints" failure "-h -Oforce-command=false"
+
+# Check downgrade of cert to raw key when no CA found
+for v in v01 v00 ; do
+ for ktype in $PLAIN_TYPES ; do
+ type_has_legacy $ktype || continue
+ rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
+ verbose "$tid: host ${ktype} ${v} cert downgrade to raw key"
+ # Generate and sign a host key
+ ${SSHKEYGEN} -q -N '' -t ${ktype} \
+ -f $OBJ/cert_host_key_${ktype} || \
+ fail "ssh-keygen of cert_host_key_${ktype} failed"
+ ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${ktype} ||
+ fail "couldn't sign cert_host_key_${ktype}"
+ (
+ printf "$HOSTS "
+ cat $OBJ/cert_host_key_${ktype}.pub
+ ) > $OBJ/known_hosts-cert
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${ktype}
+ echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
+done
+
+# Wrong certificate
+(
+ printf '@cert-authority '
+ printf "$HOSTS "
+ cat $OBJ/host_ca_key.pub
+) > $OBJ/known_hosts-cert
+for v in v01 v00 ; do
+ for kt in $PLAIN_TYPES ; do
+ type_has_legacy $kt || continue
+ rm -f $OBJ/cert_host_key*
+ # Self-sign key
+ ${SSHKEYGEN} -q -N '' -t ${kt} \
+ -f $OBJ/cert_host_key_${kt} || \
+ fail "ssh-keygen of cert_host_key_${kt} failed"
+ ${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \
+ -I "regress host key for $USER" \
+ -n $HOSTS $OBJ/cert_host_key_${kt} ||
+ fail "couldn't sign cert_host_key_${kt}"
+ verbose "$tid: host ${kt} connect wrong cert"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/cert_host_key_${kt}
+ echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
+ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
+ -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect $ident succeeded unexpectedly"
+ fi
+ done
+done
+
+rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
diff --git a/crypto/openssh/regress/cert-userkey.sh b/crypto/openssh/regress/cert-userkey.sh
new file mode 100755
index 0000000..b093a91
--- /dev/null
+++ b/crypto/openssh/regress/cert-userkey.sh
@@ -0,0 +1,358 @@
+# $OpenBSD: cert-userkey.sh,v 1.12 2013/12/06 13:52:46 markus Exp $
+# Placed in the Public Domain.
+
+tid="certified user keys"
+
+rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
+
+type_has_legacy() {
+ case $1 in
+ ed25519*|ecdsa*) return 1 ;;
+ esac
+ return 0
+}
+
+# Create a CA key
+${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\
+ fail "ssh-keygen of user_ca_key failed"
+
+# Generate and sign user keys
+for ktype in $PLAIN_TYPES ; do
+ verbose "$tid: sign user ${ktype} cert"
+ ${SSHKEYGEN} -q -N '' -t ${ktype} \
+ -f $OBJ/cert_user_key_${ktype} || \
+ fail "ssh-keygen of cert_user_key_${ktype} failed"
+ ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
+ -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
+ fail "couldn't sign cert_user_key_${ktype}"
+ type_has_legacy $ktype || continue
+ cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00
+ cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub
+ verbose "$tid: sign host ${ktype}_v00 cert"
+ ${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \
+ "regress user key for $USER" \
+ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 ||
+ fatal "couldn't sign cert_user_key_${ktype}_v00"
+done
+
+# Test explicitly-specified principals
+for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do
+ for privsep in yes no ; do
+ _prefix="${ktype} privsep $privsep"
+
+ # Setup for AuthorizedPrincipalsFile
+ rm -f $OBJ/authorized_keys_$USER
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ echo "AuthorizedPrincipalsFile " \
+ "$OBJ/authorized_principals_%u"
+ echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
+ ) > $OBJ/sshd_proxy
+
+ # Missing authorized_principals
+ verbose "$tid: ${_prefix} missing authorized_principals"
+ rm -f $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Empty authorized_principals
+ verbose "$tid: ${_prefix} empty authorized_principals"
+ echo > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Wrong authorized_principals
+ verbose "$tid: ${_prefix} wrong authorized_principals"
+ echo gregorsamsa > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Correct authorized_principals
+ verbose "$tid: ${_prefix} correct authorized_principals"
+ echo mekmitasdigoat > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+
+ # authorized_principals with bad key option
+ verbose "$tid: ${_prefix} authorized_principals bad key opt"
+ echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # authorized_principals with command=false
+ verbose "$tid: ${_prefix} authorized_principals command=false"
+ echo 'command="false" mekmitasdigoat' > \
+ $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+
+ # authorized_principals with command=true
+ verbose "$tid: ${_prefix} authorized_principals command=true"
+ echo 'command="true" mekmitasdigoat' > \
+ $OBJ/authorized_principals_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+
+ # Setup for principals= key option
+ rm -f $OBJ/authorized_principals_$USER
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ ) > $OBJ/sshd_proxy
+
+ # Wrong principals list
+ verbose "$tid: ${_prefix} wrong principals key option"
+ (
+ printf 'cert-authority,principals="gregorsamsa" '
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpectedly"
+ fi
+
+ # Correct principals list
+ verbose "$tid: ${_prefix} correct principals key option"
+ (
+ printf 'cert-authority,principals="mekmitasdigoat" '
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
+done
+
+basic_tests() {
+ auth=$1
+ if test "x$auth" = "xauthorized_keys" ; then
+ # Add CA to authorized_keys
+ (
+ printf 'cert-authority '
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ else
+ echo > $OBJ/authorized_keys_$USER
+ extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
+ fi
+
+ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do
+ for privsep in yes no ; do
+ _prefix="${ktype} privsep $privsep $auth"
+ # Simple connect
+ verbose "$tid: ${_prefix} connect"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ echo "$extra_sshd"
+ ) > $OBJ/sshd_proxy
+
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+
+ # Revoked keys
+ verbose "$tid: ${_prefix} revoked key"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "UsePrivilegeSeparation $privsep"
+ echo "RevokedKeys $OBJ/cert_user_key_revoked"
+ echo "$extra_sshd"
+ ) > $OBJ/sshd_proxy
+ cp $OBJ/cert_user_key_${ktype}.pub \
+ $OBJ/cert_user_key_revoked
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpecedly"
+ fi
+ verbose "$tid: ${_prefix} revoked via KRL"
+ rm $OBJ/cert_user_key_revoked
+ ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \
+ $OBJ/cert_user_key_${ktype}.pub
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpecedly"
+ fi
+ verbose "$tid: ${_prefix} empty KRL"
+ ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "ssh cert connect failed"
+ fi
+ done
+
+ # Revoked CA
+ verbose "$tid: ${ktype} $auth revoked CA key"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "RevokedKeys $OBJ/user_ca_key.pub"
+ echo "$extra_sshd"
+ ) > $OBJ/sshd_proxy
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
+ somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect succeeded unexpecedly"
+ fi
+ done
+
+ verbose "$tid: $auth CA does not authenticate"
+ (
+ cat $OBJ/sshd_proxy_bak
+ echo "$extra_sshd"
+ ) > $OBJ/sshd_proxy
+ verbose "$tid: ensure CA key does not authenticate user"
+ ${SSH} -2i $OBJ/user_ca_key \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect with CA key succeeded unexpectedly"
+ fi
+}
+
+basic_tests authorized_keys
+basic_tests TrustedUserCAKeys
+
+test_one() {
+ ident=$1
+ result=$2
+ sign_opts=$3
+ auth_choice=$4
+ auth_opt=$5
+
+ if test "x$auth_choice" = "x" ; then
+ auth_choice="authorized_keys TrustedUserCAKeys"
+ fi
+
+ for auth in $auth_choice ; do
+ for ktype in rsa rsa_v00 ; do
+ case $ktype in
+ *_v00) keyv="-t v00" ;;
+ *) keyv="" ;;
+ esac
+
+ cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
+ if test "x$auth" = "xauthorized_keys" ; then
+ # Add CA to authorized_keys
+ (
+ printf "cert-authority${auth_opt} "
+ cat $OBJ/user_ca_key.pub
+ ) > $OBJ/authorized_keys_$USER
+ else
+ echo > $OBJ/authorized_keys_$USER
+ echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
+ >> $OBJ/sshd_proxy
+ if test "x$auth_opt" != "x" ; then
+ echo $auth_opt >> $OBJ/sshd_proxy
+ fi
+ fi
+
+ verbose "$tid: $ident auth $auth expect $result $ktype"
+ ${SSHKEYGEN} -q -s $OBJ/user_ca_key \
+ -I "regress user key for $USER" \
+ $sign_opts $keyv \
+ $OBJ/cert_user_key_${ktype} ||
+ fail "couldn't sign cert_user_key_${ktype}"
+
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} \
+ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
+ rc=$?
+ if [ "x$result" = "xsuccess" ] ; then
+ if [ $rc -ne 0 ]; then
+ fail "$ident failed unexpectedly"
+ fi
+ else
+ if [ $rc -eq 0 ]; then
+ fail "$ident succeeded unexpectedly"
+ fi
+ fi
+ done
+ done
+}
+
+test_one "correct principal" success "-n ${USER}"
+test_one "host-certificate" failure "-n ${USER} -h"
+test_one "wrong principals" failure "-n foo"
+test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101"
+test_one "cert expired" failure "-n ${USER} -V19800101:19900101"
+test_one "cert valid interval" success "-n ${USER} -V-1w:+2w"
+test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8"
+test_one "force-command" failure "-n ${USER} -Oforce-command=false"
+
+# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals
+test_one "empty principals" success "" authorized_keys
+test_one "empty principals" failure "" TrustedUserCAKeys
+
+# Check explicitly-specified principals: an empty principals list in the cert
+# should always be refused.
+
+# AuthorizedPrincipalsFile
+rm -f $OBJ/authorized_keys_$USER
+echo mekmitasdigoat > $OBJ/authorized_principals_$USER
+test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \
+ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
+test_one "AuthorizedPrincipalsFile no principals" failure "" \
+ TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
+
+# principals= key option
+rm -f $OBJ/authorized_principals_$USER
+test_one "principals key option principals" success "-n mekmitasdigoat" \
+ authorized_keys ',principals="mekmitasdigoat"'
+test_one "principals key option no principals" failure "" \
+ authorized_keys ',principals="mekmitasdigoat"'
+
+# Wrong certificate
+cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
+for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do
+ case $ktype in
+ *_v00) args="-t v00" ;;
+ *) args="" ;;
+ esac
+ # Self-sign
+ ${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \
+ "regress user key for $USER" \
+ -n $USER $OBJ/cert_user_key_${ktype} ||
+ fail "couldn't sign cert_user_key_${ktype}"
+ verbose "$tid: user ${ktype} connect wrong cert"
+ ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
+ somehost true >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ fail "ssh cert connect $ident succeeded unexpectedly"
+ fi
+done
+
+rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
+rm -f $OBJ/authorized_principals_$USER
+
diff --git a/crypto/openssh/regress/cfgmatch.sh b/crypto/openssh/regress/cfgmatch.sh
new file mode 100644
index 0000000..80cf229
--- /dev/null
+++ b/crypto/openssh/regress/cfgmatch.sh
@@ -0,0 +1,126 @@
+# $OpenBSD: cfgmatch.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="sshd_config match"
+
+pidfile=$OBJ/remote_pid
+fwdport=3301
+fwd="-L $fwdport:127.0.0.1:$PORT"
+
+echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_config
+echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy
+
+start_client()
+{
+ rm -f $pidfile
+ ${SSH} -q -$p $fwd "$@" somehost \
+ exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \
+ >>$TEST_REGRESS_LOGFILE 2>&1 &
+ client_pid=$!
+ # Wait for remote end
+ n=0
+ while test ! -f $pidfile ; do
+ sleep 1
+ n=`expr $n + 1`
+ if test $n -gt 60; then
+ kill $client_pid
+ fatal "timeout waiting for background ssh"
+ fi
+ done
+}
+
+stop_client()
+{
+ pid=`cat $pidfile`
+ if [ ! -z "$pid" ]; then
+ kill $pid
+ fi
+ wait
+}
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_config
+echo "Match Address 127.0.0.1" >>$OBJ/sshd_config
+echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_config
+
+grep -v AuthorizedKeysFile $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
+echo "AuthorizedKeysFile /dev/null" >>$OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:1" >>$OBJ/sshd_proxy
+echo "Match user $USER" >>$OBJ/sshd_proxy
+echo "AuthorizedKeysFile /dev/null $OBJ/authorized_keys_%u" >>$OBJ/sshd_proxy
+echo "Match Address 127.0.0.1" >>$OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:$PORT" >>$OBJ/sshd_proxy
+
+start_sshd
+
+#set -x
+
+# Test Match + PermitOpen in sshd_config. This should be permitted
+for p in 1 2; do
+ trace "match permitopen localhost proto $p"
+ start_client -F $OBJ/ssh_config
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
+ fail "match permitopen permit proto $p"
+ stop_client
+done
+
+# Same but from different source. This should not be permitted
+for p in 1 2; do
+ trace "match permitopen proxy proto $p"
+ start_client -F $OBJ/ssh_proxy
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
+ fail "match permitopen deny proto $p"
+ stop_client
+done
+
+# Retry previous with key option, should also be denied.
+printf 'permitopen="127.0.0.1:'$PORT'" ' >$OBJ/authorized_keys_$USER
+cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER
+printf 'permitopen="127.0.0.1:'$PORT'" ' >>$OBJ/authorized_keys_$USER
+cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER
+for p in 1 2; do
+ trace "match permitopen proxy w/key opts proto $p"
+ start_client -F $OBJ/ssh_proxy
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
+ fail "match permitopen deny w/key opt proto $p"
+ stop_client
+done
+
+# Test both sshd_config and key options permitting the same dst/port pair.
+# Should be permitted.
+for p in 1 2; do
+ trace "match permitopen localhost proto $p"
+ start_client -F $OBJ/ssh_config
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
+ fail "match permitopen permit proto $p"
+ stop_client
+done
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
+echo "Match User $USER" >>$OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
+
+# Test that a Match overrides a PermitOpen in the global section
+for p in 1 2; do
+ trace "match permitopen proxy w/key opts proto $p"
+ start_client -F $OBJ/ssh_proxy
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
+ fail "match override permitopen proto $p"
+ stop_client
+done
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
+echo "Match User NoSuchUser" >>$OBJ/sshd_proxy
+echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
+
+# Test that a rule that doesn't match doesn't override, plus test a
+# PermitOpen entry that's not at the start of the list
+for p in 1 2; do
+ trace "nomatch permitopen proxy w/key opts proto $p"
+ start_client -F $OBJ/ssh_proxy
+ ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
+ fail "nomatch override permitopen proto $p"
+ stop_client
+done
diff --git a/crypto/openssh/regress/cipher-speed.sh b/crypto/openssh/regress/cipher-speed.sh
new file mode 100644
index 0000000..a6d53a7
--- /dev/null
+++ b/crypto/openssh/regress/cipher-speed.sh
@@ -0,0 +1,47 @@
+# $OpenBSD: cipher-speed.sh,v 1.11 2013/11/21 03:18:51 djm Exp $
+# Placed in the Public Domain.
+
+tid="cipher speed"
+
+getbytes ()
+{
+ sed -n -e '/transferred/s/.*secs (\(.* bytes.sec\).*/\1/p' \
+ -e '/copied/s/.*s, \(.* MB.s\).*/\1/p'
+}
+
+tries="1 2"
+
+for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
+ trace "proto 2 cipher $c mac $m"
+ for x in $tries; do
+ printf "%-60s" "$c/$m:"
+ ( ${SSH} -o 'compression no' \
+ -F $OBJ/ssh_proxy -2 -m $m -c $c somehost \
+ exec sh -c \'"dd of=/dev/null obs=32k"\' \
+ < ${DATA} ) 2>&1 | getbytes
+
+ if [ $? -ne 0 ]; then
+ fail "ssh -2 failed with mac $m cipher $c"
+ fi
+ done
+ # No point trying all MACs for AEAD ciphers since they are ignored.
+ if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then
+ break
+ fi
+ n=`expr $n + 1`
+done; done
+
+ciphers="3des blowfish"
+for c in $ciphers; do
+ trace "proto 1 cipher $c"
+ for x in $tries; do
+ printf "%-60s" "$c:"
+ ( ${SSH} -o 'compression no' \
+ -F $OBJ/ssh_proxy -1 -c $c somehost \
+ exec sh -c \'"dd of=/dev/null obs=32k"\' \
+ < ${DATA} ) 2>&1 | getbytes
+ if [ $? -ne 0 ]; then
+ fail "ssh -1 failed with cipher $c"
+ fi
+ done
+done
diff --git a/crypto/openssh/regress/conch-ciphers.sh b/crypto/openssh/regress/conch-ciphers.sh
new file mode 100755
index 0000000..199d863
--- /dev/null
+++ b/crypto/openssh/regress/conch-ciphers.sh
@@ -0,0 +1,28 @@
+# $OpenBSD: conch-ciphers.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="conch ciphers"
+
+if test "x$REGRESS_INTEROP_CONCH" != "xyes" ; then
+ echo "conch interop tests not enabled"
+ exit 0
+fi
+
+start_sshd
+
+for c in aes256-ctr aes256-cbc aes192-ctr aes192-cbc aes128-ctr aes128-cbc \
+ cast128-cbc blowfish 3des-cbc ; do
+ verbose "$tid: cipher $c"
+ rm -f ${COPY}
+ # XXX the 2nd "cat" seems to be needed because of buggy FD handling
+ # in conch
+ ${CONCH} --identity $OBJ/rsa --port $PORT --user $USER -e none \
+ --known-hosts $OBJ/known_hosts --notty --noagent --nox11 -n \
+ 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+done
+rm -f ${COPY}
+
diff --git a/crypto/openssh/regress/connect-privsep.sh b/crypto/openssh/regress/connect-privsep.sh
new file mode 100644
index 0000000..41cb7af
--- /dev/null
+++ b/crypto/openssh/regress/connect-privsep.sh
@@ -0,0 +1,36 @@
+# $OpenBSD: connect-privsep.sh,v 1.5 2014/05/04 10:40:59 logan Exp $
+# Placed in the Public Domain.
+
+tid="proxy connect with privsep"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy
+
+for p in 1 2; do
+ ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
+ if [ $? -ne 0 ]; then
+ fail "ssh privsep+proxyconnect protocol $p failed"
+ fi
+done
+
+cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
+echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
+
+for p in 1 2; do
+ ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
+ if [ $? -ne 0 ]; then
+ # XXX replace this with fail once sandbox has stabilised
+ warn "ssh privsep/sandbox+proxyconnect protocol $p failed"
+ fi
+done
+
+# Because sandbox is sensitive to changes in libc, especially malloc, retest
+# with every malloc.conf option (and none).
+for m in '' A F G H J P R S X '<' '>'; do
+ for p in 1 2; do
+ env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
+ if [ $? -ne 0 ]; then
+ fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed"
+ fi
+ done
+done
diff --git a/crypto/openssh/regress/connect.sh b/crypto/openssh/regress/connect.sh
new file mode 100644
index 0000000..2186fa6
--- /dev/null
+++ b/crypto/openssh/regress/connect.sh
@@ -0,0 +1,13 @@
+# $OpenBSD: connect.sh,v 1.4 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="simple connect"
+
+start_sshd
+
+for p in 1 2; do
+ ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh connect with protocol $p failed"
+ fi
+done
diff --git a/crypto/openssh/regress/dhgex.sh b/crypto/openssh/regress/dhgex.sh
new file mode 100755
index 0000000..57fca4a
--- /dev/null
+++ b/crypto/openssh/regress/dhgex.sh
@@ -0,0 +1,58 @@
+# $OpenBSD: dhgex.sh,v 1.2 2014/04/21 22:15:37 djm Exp $
+# Placed in the Public Domain.
+
+tid="dhgex"
+
+LOG=${TEST_SSH_LOGFILE}
+rm -f ${LOG}
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange`
+
+ssh_test_dhgex()
+{
+ bits="$1"; shift
+ cipher="$1"; shift
+ kex="$1"; shift
+
+ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+ echo "KexAlgorithms=$kex" >> $OBJ/sshd_proxy
+ echo "Ciphers=$cipher" >> $OBJ/sshd_proxy
+ rm -f ${LOG}
+ opts="-oKexAlgorithms=$kex -oCiphers=$cipher"
+ groupsz="1024<$bits<8192"
+ verbose "$tid bits $bits $kex $cipher"
+ ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh failed ($@)"
+ fi
+ # check what we request
+ grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null
+ if [ $? != 0 ]; then
+ got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}`
+ fail "$tid unexpected GEX sizes, expected $groupsz, got $got"
+ fi
+ # check what we got (depends on contents of system moduli file)
+ gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`"
+ if [ "$gotbits" -lt "$bits" ]; then
+ fatal "$tid expected $bits bit group, got $gotbits"
+ fi
+}
+
+check()
+{
+ bits="$1"; shift
+
+ for c in $@; do
+ for k in $kexs; do
+ ssh_test_dhgex $bits $c $k
+ done
+ done
+}
+
+#check 2048 3des-cbc
+check 3072 `${SSH} -Q cipher | grep 128`
+check 3072 arcfour blowfish-cbc
+check 7680 `${SSH} -Q cipher | grep 192`
+check 8192 `${SSH} -Q cipher | grep 256`
+check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com
diff --git a/crypto/openssh/regress/dsa_ssh2.prv b/crypto/openssh/regress/dsa_ssh2.prv
new file mode 100644
index 0000000..c93b403
--- /dev/null
+++ b/crypto/openssh/regress/dsa_ssh2.prv
@@ -0,0 +1,14 @@
+---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
+Subject: ssh-keygen test
+Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100"
+P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA
+AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR
+Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg
+x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv
+MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt
+F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1
+kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik
+ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6
+75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV
+zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A==
+---- END SSH2 ENCRYPTED PRIVATE KEY ----
diff --git a/crypto/openssh/regress/dsa_ssh2.pub b/crypto/openssh/regress/dsa_ssh2.pub
new file mode 100644
index 0000000..215d73ba
--- /dev/null
+++ b/crypto/openssh/regress/dsa_ssh2.pub
@@ -0,0 +1,13 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Subject: ssh-keygen test
+Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100"
+AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8
+NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l
+ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo
+0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE
+MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk
+JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC
+eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv
+JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1
+ixaVivLt8RgTwGF99uI=
+---- END SSH2 PUBLIC KEY ----
diff --git a/crypto/openssh/regress/dynamic-forward.sh b/crypto/openssh/regress/dynamic-forward.sh
new file mode 100644
index 0000000..42fa8ac
--- /dev/null
+++ b/crypto/openssh/regress/dynamic-forward.sh
@@ -0,0 +1,59 @@
+# $OpenBSD: dynamic-forward.sh,v 1.10 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="dynamic forwarding"
+
+FWDPORT=`expr $PORT + 1`
+
+if have_prog nc && nc -h 2>&1 | grep "proxy address" >/dev/null; then
+ proxycmd="nc -x 127.0.0.1:$FWDPORT -X"
+elif have_prog connect; then
+ proxycmd="connect -S 127.0.0.1:$FWDPORT -"
+else
+ echo "skipped (no suitable ProxyCommand found)"
+ exit 0
+fi
+trace "will use ProxyCommand $proxycmd"
+
+start_sshd
+
+for p in 1 2; do
+ n=0
+ error="1"
+ trace "start dynamic forwarding, fork to background"
+ while [ "$error" -ne 0 -a "$n" -lt 3 ]; do
+ n=`expr $n + 1`
+ ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q \
+ -oExitOnForwardFailure=yes somehost exec sh -c \
+ \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\'
+ error=$?
+ if [ "$error" -ne 0 ]; then
+ trace "forward failed proto $p attempt $n err $error"
+ sleep $n
+ fi
+ done
+ if [ "$error" -ne 0 ]; then
+ fatal "failed to start dynamic forwarding proto $p"
+ fi
+
+ for s in 4 5; do
+ for h in 127.0.0.1 localhost; do
+ trace "testing ssh protocol $p socks version $s host $h"
+ ${SSH} -F $OBJ/ssh_config \
+ -o "ProxyCommand ${proxycmd}${s} $h $PORT" \
+ somehost cat $DATA > $OBJ/ls.copy
+ test -f $OBJ/ls.copy || fail "failed copy $DATA"
+ cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA"
+ done
+ done
+
+ if [ -f $OBJ/remote_pid ]; then
+ remote=`cat $OBJ/remote_pid`
+ trace "terminate remote shell, pid $remote"
+ if [ $remote -gt 1 ]; then
+ kill -HUP $remote
+ fi
+ else
+ fail "no pid file: $OBJ/remote_pid"
+ fi
+done
diff --git a/crypto/openssh/regress/envpass.sh b/crypto/openssh/regress/envpass.sh
new file mode 100644
index 0000000..af7eafe
--- /dev/null
+++ b/crypto/openssh/regress/envpass.sh
@@ -0,0 +1,60 @@
+# $OpenBSD: envpass.sh,v 1.4 2005/03/04 08:48:46 djm Exp $
+# Placed in the Public Domain.
+
+tid="environment passing"
+
+# NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST)
+
+# Prepare a custom config to test for a configuration parsing bug fixed in 4.0
+cat << EOF > $OBJ/ssh_proxy_envpass
+Host test-sendenv-confparse-bug
+ SendEnv *
+EOF
+cat $OBJ/ssh_proxy >> $OBJ/ssh_proxy_envpass
+
+trace "pass env, don't accept"
+verbose "test $tid: pass env, don't accept"
+_TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy_envpass otherhost \
+ sh << 'EOF'
+ test -z "$_TEST_ENV"
+EOF
+r=$?
+if [ $r -ne 0 ]; then
+ fail "environment found"
+fi
+
+trace "don't pass env, accept"
+verbose "test $tid: don't pass env, accept"
+_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -F $OBJ/ssh_proxy_envpass otherhost \
+ sh << 'EOF'
+ test -z "$_XXX_TEST_A" && test -z "$_XXX_TEST_B"
+EOF
+r=$?
+if [ $r -ne 0 ]; then
+ fail "environment found"
+fi
+
+trace "pass single env, accept single env"
+verbose "test $tid: pass single env, accept single env"
+_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy_envpass \
+ otherhost sh << 'EOF'
+ test X"$_XXX_TEST" = X"blah"
+EOF
+r=$?
+if [ $r -ne 0 ]; then
+ fail "environment not found"
+fi
+
+trace "pass multiple env, accept multiple env"
+verbose "test $tid: pass multiple env, accept multiple env"
+_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \
+ -F $OBJ/ssh_proxy_envpass otherhost \
+ sh << 'EOF'
+ test X"$_XXX_TEST_A" = X"1" -a X"$_XXX_TEST_B" = X"2"
+EOF
+r=$?
+if [ $r -ne 0 ]; then
+ fail "environment not found"
+fi
+
+rm -f $OBJ/ssh_proxy_envpass
diff --git a/crypto/openssh/regress/exit-status.sh b/crypto/openssh/regress/exit-status.sh
new file mode 100644
index 0000000..56b78a6
--- /dev/null
+++ b/crypto/openssh/regress/exit-status.sh
@@ -0,0 +1,24 @@
+# $OpenBSD: exit-status.sh,v 1.6 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="remote exit status"
+
+for p in 1 2; do
+ for s in 0 1 4 5 44; do
+ trace "proto $p status $s"
+ verbose "test $tid: proto $p status $s"
+ ${SSH} -$p -F $OBJ/ssh_proxy otherhost exit $s
+ r=$?
+ if [ $r -ne $s ]; then
+ fail "exit code mismatch for protocol $p: $r != $s"
+ fi
+
+ # same with early close of stdout/err
+ ${SSH} -$p -F $OBJ/ssh_proxy -n otherhost \
+ exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
+ r=$?
+ if [ $r -ne $s ]; then
+ fail "exit code (with sleep) mismatch for protocol $p: $r != $s"
+ fi
+ done
+done
diff --git a/crypto/openssh/regress/forcecommand.sh b/crypto/openssh/regress/forcecommand.sh
new file mode 100644
index 0000000..44d2b7f
--- /dev/null
+++ b/crypto/openssh/regress/forcecommand.sh
@@ -0,0 +1,42 @@
+# $OpenBSD: forcecommand.sh,v 1.2 2013/05/17 00:37:40 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="forced command"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+printf 'command="true" ' >$OBJ/authorized_keys_$USER
+cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER
+printf 'command="true" ' >>$OBJ/authorized_keys_$USER
+cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER
+
+for p in 1 2; do
+ trace "forced command in key option proto $p"
+ ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
+ fail "forced command in key proto $p"
+done
+
+printf 'command="false" ' >$OBJ/authorized_keys_$USER
+cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER
+printf 'command="false" ' >>$OBJ/authorized_keys_$USER
+cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+echo "ForceCommand true" >> $OBJ/sshd_proxy
+
+for p in 1 2; do
+ trace "forced command in sshd_config overrides key option proto $p"
+ ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
+ fail "forced command in key proto $p"
+done
+
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+echo "ForceCommand false" >> $OBJ/sshd_proxy
+echo "Match User $USER" >> $OBJ/sshd_proxy
+echo " ForceCommand true" >> $OBJ/sshd_proxy
+
+for p in 1 2; do
+ trace "forced command with match proto $p"
+ ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
+ fail "forced command in key proto $p"
+done
diff --git a/crypto/openssh/regress/forward-control.sh b/crypto/openssh/regress/forward-control.sh
new file mode 100755
index 0000000..7f7d105
--- /dev/null
+++ b/crypto/openssh/regress/forward-control.sh
@@ -0,0 +1,168 @@
+# $OpenBSD: forward-control.sh,v 1.2 2013/11/18 05:09:32 naddy Exp $
+# Placed in the Public Domain.
+
+tid="sshd control of local and remote forwarding"
+
+LFWD_PORT=3320
+RFWD_PORT=3321
+CTL=$OBJ/ctl-sock
+READY=$OBJ/ready
+
+wait_for_file_to_appear() {
+ _path=$1
+ _n=0
+ while test ! -f $_path ; do
+ test $_n -eq 1 && trace "waiting for $_path to appear"
+ _n=`expr $_n + 1`
+ test $_n -ge 20 && return 1
+ sleep 1
+ done
+ return 0
+}
+
+wait_for_process_to_exit() {
+ _pid=$1
+ _n=0
+ while kill -0 $_pid 2>/dev/null ; do
+ test $_n -eq 1 && trace "waiting for $_pid to exit"
+ _n=`expr $_n + 1`
+ test $_n -ge 20 && return 1
+ sleep 1
+ done
+ return 0
+}
+
+# usage: check_lfwd protocol Y|N message
+check_lfwd() {
+ _proto=$1
+ _expected=$2
+ _message=$3
+ rm -f $READY
+ ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \
+ -L$LFWD_PORT:127.0.0.1:$PORT \
+ -o ExitOnForwardFailure=yes \
+ -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
+ >/dev/null 2>&1 &
+ _sshpid=$!
+ wait_for_file_to_appear $READY || \
+ fatal "check_lfwd ssh fail: $_message"
+ ${SSH} -F $OBJ/ssh_config -p $LFWD_PORT \
+ -oConnectionAttempts=4 host true >/dev/null 2>&1
+ _result=$?
+ kill $_sshpid `cat $READY` 2>/dev/null
+ wait_for_process_to_exit $_sshpid
+ if test "x$_expected" = "xY" -a $_result -ne 0 ; then
+ fail "check_lfwd failed (expecting success): $_message"
+ elif test "x$_expected" = "xN" -a $_result -eq 0 ; then
+ fail "check_lfwd succeeded (expecting failure): $_message"
+ elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then
+ fatal "check_lfwd invalid argument \"$_expected\""
+ else
+ verbose "check_lfwd done (expecting $_expected): $_message"
+ fi
+}
+
+# usage: check_rfwd protocol Y|N message
+check_rfwd() {
+ _proto=$1
+ _expected=$2
+ _message=$3
+ rm -f $READY
+ ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \
+ -R$RFWD_PORT:127.0.0.1:$PORT \
+ -o ExitOnForwardFailure=yes \
+ -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
+ >/dev/null 2>&1 &
+ _sshpid=$!
+ wait_for_file_to_appear $READY
+ _result=$?
+ if test $_result -eq 0 ; then
+ ${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \
+ -oConnectionAttempts=4 host true >/dev/null 2>&1
+ _result=$?
+ kill $_sshpid `cat $READY` 2>/dev/null
+ wait_for_process_to_exit $_sshpid
+ fi
+ if test "x$_expected" = "xY" -a $_result -ne 0 ; then
+ fail "check_rfwd failed (expecting success): $_message"
+ elif test "x$_expected" = "xN" -a $_result -eq 0 ; then
+ fail "check_rfwd succeeded (expecting failure): $_message"
+ elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then
+ fatal "check_rfwd invalid argument \"$_expected\""
+ else
+ verbose "check_rfwd done (expecting $_expected): $_message"
+ fi
+}
+
+start_sshd
+cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak
+cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak
+
+# Sanity check: ensure the default config allows forwarding
+for p in 1 2 ; do
+ check_lfwd $p Y "proto $p, default configuration"
+ check_rfwd $p Y "proto $p, default configuration"
+done
+
+# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N
+all_tests() {
+ _tcpfwd=$1
+ _plain_lfwd=$2
+ _plain_rfwd=$3
+ _nopermit_lfwd=$4
+ _nopermit_rfwd=$5
+ _permit_lfwd=$6
+ _permit_rfwd=$7
+ _badfwd=127.0.0.1:22
+ _goodfwd=127.0.0.1:${PORT}
+ for _proto in 1 2 ; do
+ cp ${OBJ}/authorized_keys_${USER}.bak \
+ ${OBJ}/authorized_keys_${USER}
+ _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd"
+ # No PermitOpen
+ ( cat ${OBJ}/sshd_proxy.bak ;
+ echo "AllowTcpForwarding $_tcpfwd" ) \
+ > ${OBJ}/sshd_proxy
+ check_lfwd $_proto $_plain_lfwd "$_prefix"
+ check_rfwd $_proto $_plain_rfwd "$_prefix"
+ # PermitOpen via sshd_config that doesn't match
+ ( cat ${OBJ}/sshd_proxy.bak ;
+ echo "AllowTcpForwarding $_tcpfwd" ;
+ echo "PermitOpen $_badfwd" ) \
+ > ${OBJ}/sshd_proxy
+ check_lfwd $_proto $_nopermit_lfwd "$_prefix, !PermitOpen"
+ check_rfwd $_proto $_nopermit_rfwd "$_prefix, !PermitOpen"
+ # PermitOpen via sshd_config that does match
+ ( cat ${OBJ}/sshd_proxy.bak ;
+ echo "AllowTcpForwarding $_tcpfwd" ;
+ echo "PermitOpen $_badfwd $_goodfwd" ) \
+ > ${OBJ}/sshd_proxy
+ # NB. permitopen via authorized_keys should have same
+ # success/fail as via sshd_config
+ # permitopen via authorized_keys that doesn't match
+ sed "s/^/permitopen=\"$_badfwd\" /" \
+ < ${OBJ}/authorized_keys_${USER}.bak \
+ > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail"
+ ( cat ${OBJ}/sshd_proxy.bak ;
+ echo "AllowTcpForwarding $_tcpfwd" ) \
+ > ${OBJ}/sshd_proxy
+ check_lfwd $_proto $_nopermit_lfwd "$_prefix, !permitopen"
+ check_rfwd $_proto $_nopermit_rfwd "$_prefix, !permitopen"
+ # permitopen via authorized_keys that does match
+ sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \
+ < ${OBJ}/authorized_keys_${USER}.bak \
+ > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail"
+ ( cat ${OBJ}/sshd_proxy.bak ;
+ echo "AllowTcpForwarding $_tcpfwd" ) \
+ > ${OBJ}/sshd_proxy
+ check_lfwd $_proto $_permit_lfwd "$_prefix, permitopen"
+ check_rfwd $_proto $_permit_rfwd "$_prefix, permitopen"
+ done
+}
+
+# no-permitopen mismatch-permitopen match-permitopen
+# AllowTcpForwarding local remote local remote local remote
+all_tests yes Y Y N Y Y Y
+all_tests local Y N N N Y N
+all_tests remote N Y N Y N Y
+all_tests no N N N N N N
diff --git a/crypto/openssh/regress/forwarding.sh b/crypto/openssh/regress/forwarding.sh
new file mode 100644
index 0000000..f799d49
--- /dev/null
+++ b/crypto/openssh/regress/forwarding.sh
@@ -0,0 +1,137 @@
+# $OpenBSD: forwarding.sh,v 1.12 2014/07/15 15:54:15 millert Exp $
+# Placed in the Public Domain.
+
+tid="local and remote forwarding"
+
+DATA=/bin/ls${EXEEXT}
+
+start_sshd
+
+base=33
+last=$PORT
+fwd=""
+for j in 0 1 2; do
+ for i in 0 1 2; do
+ a=$base$j$i
+ b=`expr $a + 50`
+ c=$last
+ # fwd chain: $a -> $b -> $c
+ fwd="$fwd -L$a:127.0.0.1:$b -R$b:127.0.0.1:$c"
+ last=$a
+ done
+done
+for p in 1 2; do
+ q=`expr 3 - $p`
+ trace "start forwarding, fork to background"
+ ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10
+
+ trace "transfer over forwarded channels and check result"
+ ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \
+ somehost cat ${DATA} > ${COPY}
+ test -s ${COPY} || fail "failed copy of ${DATA}"
+ cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
+
+ sleep 10
+done
+
+for p in 1 2; do
+for d in L R; do
+ trace "exit on -$d forward failure, proto $p"
+
+ # this one should succeed
+ ${SSH} -$p -F $OBJ/ssh_config \
+ -$d ${base}01:127.0.0.1:$PORT \
+ -$d ${base}02:127.0.0.1:$PORT \
+ -$d ${base}03:127.0.0.1:$PORT \
+ -$d ${base}04:127.0.0.1:$PORT \
+ -oExitOnForwardFailure=yes somehost true
+ if [ $? != 0 ]; then
+ fail "connection failed, should not"
+ else
+ # this one should fail
+ ${SSH} -q -$p -F $OBJ/ssh_config \
+ -$d ${base}01:127.0.0.1:$PORT \
+ -$d ${base}02:127.0.0.1:$PORT \
+ -$d ${base}03:127.0.0.1:$PORT \
+ -$d ${base}01:127.0.0.1:$PORT \
+ -$d ${base}04:127.0.0.1:$PORT \
+ -oExitOnForwardFailure=yes somehost true
+ r=$?
+ if [ $r != 255 ]; then
+ fail "connection not termintated, but should ($r)"
+ fi
+ fi
+done
+done
+
+for p in 1 2; do
+ trace "simple clear forwarding proto $p"
+ ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true
+
+ trace "clear local forward proto $p"
+ ${SSH} -$p -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \
+ -oClearAllForwardings=yes somehost sleep 10
+ if [ $? != 0 ]; then
+ fail "connection failed with cleared local forwarding"
+ else
+ # this one should fail
+ ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \
+ >>$TEST_REGRESS_LOGFILE 2>&1 && \
+ fail "local forwarding not cleared"
+ fi
+ sleep 10
+
+ trace "clear remote forward proto $p"
+ ${SSH} -$p -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \
+ -oClearAllForwardings=yes somehost sleep 10
+ if [ $? != 0 ]; then
+ fail "connection failed with cleared remote forwarding"
+ else
+ # this one should fail
+ ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 true \
+ >>$TEST_REGRESS_LOGFILE 2>&1 && \
+ fail "remote forwarding not cleared"
+ fi
+ sleep 10
+done
+
+for p in 2; do
+ trace "stdio forwarding proto $p"
+ cmd="${SSH} -$p -F $OBJ/ssh_config"
+ $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \
+ somehost true
+ if [ $? != 0 ]; then
+ fail "stdio forwarding proto $p"
+ fi
+done
+
+echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config
+echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config
+for p in 1 2; do
+ trace "config file: start forwarding, fork to background"
+ ${SSH} -$p -F $OBJ/ssh_config -f somehost sleep 10
+
+ trace "config file: transfer over forwarded channels and check result"
+ ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
+ somehost cat ${DATA} > ${COPY}
+ test -s ${COPY} || fail "failed copy of ${DATA}"
+ cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
+
+ wait
+done
+
+for p in 2; do
+ trace "transfer over chained unix domain socket forwards and check result"
+ rm -f $OBJ/unix-[123].fwd
+ ${SSH} -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10
+ ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10
+ ${SSH} -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10
+ ${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10
+ ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \
+ somehost cat ${DATA} > ${COPY}
+ test -s ${COPY} || fail "failed copy ${DATA}"
+ cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
+
+ #wait
+ sleep 10
+done
diff --git a/crypto/openssh/regress/host-expand.sh b/crypto/openssh/regress/host-expand.sh
new file mode 100755
index 0000000..6cc0e60
--- /dev/null
+++ b/crypto/openssh/regress/host-expand.sh
@@ -0,0 +1,19 @@
+# $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $
+# Placed in the Public Domain.
+
+tid="expand %h and %n"
+
+echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy
+printf 'LocalCommand printf "%%%%s\\n" "%%n" "%%h"\n' >> $OBJ/ssh_proxy
+
+cat >$OBJ/expect <<EOE
+somehost
+127.0.0.1
+EOE
+
+for p in 1 2; do
+ verbose "test $tid: proto $p"
+ ${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual
+ diff $OBJ/expect $OBJ/actual || fail "$tid proto $p"
+done
+
diff --git a/crypto/openssh/regress/integrity.sh b/crypto/openssh/regress/integrity.sh
new file mode 100755
index 0000000..d3a489f
--- /dev/null
+++ b/crypto/openssh/regress/integrity.sh
@@ -0,0 +1,75 @@
+# $OpenBSD: integrity.sh,v 1.14 2014/05/21 07:04:21 djm Exp $
+# Placed in the Public Domain.
+
+tid="integrity"
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+# start at byte 2900 (i.e. after kex) and corrupt at different offsets
+# XXX the test hangs if we modify the low bytes of the packet length
+# XXX and ssh tries to read...
+tries=10
+startoffset=2900
+macs=`${SSH} -Q mac`
+# The following are not MACs, but ciphers with integrated integrity. They are
+# handled specially below.
+macs="$macs `${SSH} -Q cipher-auth`"
+
+# avoid DH group exchange as the extra traffic makes it harder to get the
+# offset into the stream right.
+echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \
+ >> $OBJ/ssh_proxy
+
+# sshd-command for proxy (see test-exec.sh)
+cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy"
+
+for m in $macs; do
+ trace "test $tid: mac $m"
+ elen=0
+ epad=0
+ emac=0
+ ecnt=0
+ skip=0
+ for off in `jot $tries $startoffset`; do
+ skip=`expr $skip - 1`
+ if [ $skip -gt 0 ]; then
+ # avoid modifying the high bytes of the length
+ continue
+ fi
+ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+ # modify output from sshd at offset $off
+ pxy="proxycommand=$cmd | $OBJ/modpipe -wm xor:$off:1"
+ if ssh -Q cipher-auth | grep "^${m}\$" >/dev/null 2>&1 ; then
+ echo "Ciphers=$m" >> $OBJ/sshd_proxy
+ macopt="-c $m"
+ else
+ echo "Ciphers=aes128-ctr" >> $OBJ/sshd_proxy
+ echo "MACs=$m" >> $OBJ/sshd_proxy
+ macopt="-m $m -c aes128-ctr"
+ fi
+ verbose "test $tid: $m @$off"
+ ${SSH} $macopt -2F $OBJ/ssh_proxy -o "$pxy" \
+ -oServerAliveInterval=1 -oServerAliveCountMax=30 \
+ 999.999.999.999 'printf "%4096s" " "' >/dev/null
+ if [ $? -eq 0 ]; then
+ fail "ssh -m $m succeeds with bit-flip at $off"
+ fi
+ ecnt=`expr $ecnt + 1`
+ out=$(tail -2 $TEST_SSH_LOGFILE | egrep -v "^debug" | \
+ tr -s '\r\n' '.')
+ case "$out" in
+ Bad?packet*) elen=`expr $elen + 1`; skip=3;;
+ Corrupted?MAC* | Decryption?integrity?check?failed*)
+ emac=`expr $emac + 1`; skip=0;;
+ padding*) epad=`expr $epad + 1`; skip=0;;
+ *) fail "unexpected error mac $m at $off: $out";;
+ esac
+ done
+ verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen"
+ if [ $emac -eq 0 ]; then
+ fail "$m: no mac errors"
+ fi
+ expect=`expr $ecnt - $epad - $elen`
+ if [ $emac -ne $expect ]; then
+ fail "$m: expected $expect mac errors, got $emac"
+ fi
+done
diff --git a/crypto/openssh/regress/kextype.sh b/crypto/openssh/regress/kextype.sh
new file mode 100755
index 0000000..6f952f4
--- /dev/null
+++ b/crypto/openssh/regress/kextype.sh
@@ -0,0 +1,25 @@
+# $OpenBSD: kextype.sh,v 1.5 2014/04/21 22:15:37 djm Exp $
+# Placed in the Public Domain.
+
+tid="login with different key exchange algorithms"
+
+TIME=/usr/bin/time
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
+
+# Make server accept all key exchanges.
+ALLKEX=`ssh -Q kex`
+KEXOPT=`echo $ALLKEX | tr ' ' ,`
+echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy
+
+tries="1 2 3 4"
+for k in `${SSH} -Q kex`; do
+ verbose "kex $k"
+ for i in $tries; do
+ ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true
+ if [ $? -ne 0 ]; then
+ fail "ssh kex $k"
+ fi
+ done
+done
+
diff --git a/crypto/openssh/regress/key-options.sh b/crypto/openssh/regress/key-options.sh
new file mode 100755
index 0000000..f98d78b
--- /dev/null
+++ b/crypto/openssh/regress/key-options.sh
@@ -0,0 +1,71 @@
+# $OpenBSD: key-options.sh,v 1.2 2008/06/30 08:07:34 djm Exp $
+# Placed in the Public Domain.
+
+tid="key options"
+
+origkeys="$OBJ/authkeys_orig"
+authkeys="$OBJ/authorized_keys_${USER}"
+cp $authkeys $origkeys
+
+# Test command= forced command
+for p in 1 2; do
+ for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do
+ sed "s/.*/$c &/" $origkeys >$authkeys
+ verbose "key option proto $p $c"
+ r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost echo foo`
+ if [ "$r" = "foo" ]; then
+ fail "key option forced command not restricted"
+ fi
+ if [ "$r" != "bar" ]; then
+ fail "key option forced command not executed"
+ fi
+ done
+done
+
+# Test no-pty
+sed 's/.*/no-pty &/' $origkeys >$authkeys
+for p in 1 2; do
+ verbose "key option proto $p no-pty"
+ r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty`
+ if [ -f "$r" ]; then
+ fail "key option failed proto $p no-pty (pty $r)"
+ fi
+done
+
+# Test environment=
+echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy
+sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys
+for p in 1 2; do
+ verbose "key option proto $p environment"
+ r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'`
+ if [ "$r" != "bar" ]; then
+ fail "key option environment not set"
+ fi
+done
+
+# Test from= restriction
+start_sshd
+for p in 1 2; do
+ for f in 127.0.0.1 '127.0.0.0\/8'; do
+ cat $origkeys >$authkeys
+ ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "key option proto $p failed without restriction"
+ fi
+
+ sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys
+ from=`head -1 $authkeys | cut -f1 -d ' '`
+ verbose "key option proto $p $from"
+ r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo true'`
+ if [ "$r" = "true" ]; then
+ fail "key option proto $p $from not restricted"
+ fi
+
+ r=`${SSH} -$p -q -F $OBJ/ssh_config somehost 'echo true'`
+ if [ "$r" != "true" ]; then
+ fail "key option proto $p $from not allowed but should be"
+ fi
+ done
+done
+
+rm -f "$origkeys"
diff --git a/crypto/openssh/regress/keygen-change.sh b/crypto/openssh/regress/keygen-change.sh
new file mode 100644
index 0000000..08d3590
--- /dev/null
+++ b/crypto/openssh/regress/keygen-change.sh
@@ -0,0 +1,23 @@
+# $OpenBSD: keygen-change.sh,v 1.2 2002/07/16 09:15:55 markus Exp $
+# Placed in the Public Domain.
+
+tid="change passphrase for key"
+
+S1="secret1"
+S2="2secret"
+
+for t in rsa dsa rsa1; do
+ # generate user key for agent
+ trace "generating $t key"
+ rm -f $OBJ/$t-key
+ ${SSHKEYGEN} -q -N ${S1} -t $t -f $OBJ/$t-key
+ if [ $? -eq 0 ]; then
+ ${SSHKEYGEN} -p -P ${S1} -N ${S2} -f $OBJ/$t-key > /dev/null
+ if [ $? -ne 0 ]; then
+ fail "ssh-keygen -p failed for $t-key"
+ fi
+ else
+ fail "ssh-keygen for $t-key failed"
+ fi
+ rm -f $OBJ/$t-key $OBJ/$t-key.pub
+done
diff --git a/crypto/openssh/regress/keygen-convert.sh b/crypto/openssh/regress/keygen-convert.sh
new file mode 100755
index 0000000..ad0e9c6
--- /dev/null
+++ b/crypto/openssh/regress/keygen-convert.sh
@@ -0,0 +1,33 @@
+# $OpenBSD: keygen-convert.sh,v 1.1 2009/11/09 04:20:04 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="convert keys"
+
+for t in rsa dsa; do
+ # generate user key for agent
+ trace "generating $t key"
+ rm -f $OBJ/$t-key
+ ${SSHKEYGEN} -q -N "" -t $t -f $OBJ/$t-key
+
+ trace "export $t private to rfc4716 public"
+ ${SSHKEYGEN} -q -e -f $OBJ/$t-key >$OBJ/$t-key-rfc || \
+ fail "export $t private to rfc4716 public"
+
+ trace "export $t public to rfc4716 public"
+ ${SSHKEYGEN} -q -e -f $OBJ/$t-key.pub >$OBJ/$t-key-rfc.pub || \
+ fail "$t public to rfc4716 public"
+
+ cmp $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub || \
+ fail "$t rfc4716 exports differ between public and private"
+
+ trace "import $t rfc4716 public"
+ ${SSHKEYGEN} -q -i -f $OBJ/$t-key-rfc >$OBJ/$t-rfc-imported || \
+ fail "$t import rfc4716 public"
+
+ cut -f1,2 -d " " $OBJ/$t-key.pub >$OBJ/$t-key-nocomment.pub
+ cmp $OBJ/$t-key-nocomment.pub $OBJ/$t-rfc-imported || \
+ fail "$t imported differs from original"
+
+ rm -f $OBJ/$t-key $OBJ/$t-key.pub $OBJ/$t-key-rfc $OBJ/$t-key-rfc.pub \
+ $OBJ/$t-rfc-imported $OBJ/$t-key-nocomment.pub
+done
diff --git a/crypto/openssh/regress/keys-command.sh b/crypto/openssh/regress/keys-command.sh
new file mode 100755
index 0000000..b595a43
--- /dev/null
+++ b/crypto/openssh/regress/keys-command.sh
@@ -0,0 +1,39 @@
+# $OpenBSD: keys-command.sh,v 1.2 2012/12/06 06:06:54 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="authorized keys from command"
+
+if test -z "$SUDO" ; then
+ echo "skipped (SUDO not set)"
+ echo "need SUDO to create file in /var/run, test won't work without"
+ exit 0
+fi
+
+# Establish a AuthorizedKeysCommand in /var/run where it will have
+# acceptable directory permissions.
+KEY_COMMAND="/var/run/keycommand_${LOGNAME}"
+cat << _EOF | $SUDO sh -c "cat > '$KEY_COMMAND'"
+#!/bin/sh
+test "x\$1" != "x${LOGNAME}" && exit 1
+exec cat "$OBJ/authorized_keys_${LOGNAME}"
+_EOF
+$SUDO chmod 0755 "$KEY_COMMAND"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak
+(
+ grep -vi AuthorizedKeysFile $OBJ/sshd_proxy.bak
+ echo AuthorizedKeysFile none
+ echo AuthorizedKeysCommand $KEY_COMMAND
+ echo AuthorizedKeysCommandUser ${LOGNAME}
+) > $OBJ/sshd_proxy
+
+if [ -x $KEY_COMMAND ]; then
+ ${SSH} -F $OBJ/ssh_proxy somehost true
+ if [ $? -ne 0 ]; then
+ fail "connect failed"
+ fi
+else
+ echo "SKIPPED: $KEY_COMMAND not executable (/var/run mounted noexec?)"
+fi
+
+$SUDO rm -f $KEY_COMMAND
diff --git a/crypto/openssh/regress/keyscan.sh b/crypto/openssh/regress/keyscan.sh
new file mode 100644
index 0000000..33f14f0
--- /dev/null
+++ b/crypto/openssh/regress/keyscan.sh
@@ -0,0 +1,19 @@
+# $OpenBSD: keyscan.sh,v 1.3 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="keyscan"
+
+# remove DSA hostkey
+rm -f ${OBJ}/host.dsa
+
+start_sshd
+
+for t in rsa1 rsa dsa; do
+ trace "keyscan type $t"
+ ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \
+ > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh-keyscan -t $t failed with: $r"
+ fi
+done
diff --git a/crypto/openssh/regress/keytype.sh b/crypto/openssh/regress/keytype.sh
new file mode 100755
index 0000000..9752acb
--- /dev/null
+++ b/crypto/openssh/regress/keytype.sh
@@ -0,0 +1,61 @@
+# $OpenBSD: keytype.sh,v 1.3 2013/12/06 13:52:46 markus Exp $
+# Placed in the Public Domain.
+
+tid="login with different key types"
+
+TIME=`which time 2>/dev/null`
+if test ! -x "$TIME"; then
+ TIME=""
+fi
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
+
+# Traditional and builtin key types.
+ktypes="dsa-1024 rsa-2048 rsa-3072 ed25519-512"
+# Types not present in all OpenSSL versions.
+for i in `$SSH -Q key`; do
+ case "$i" in
+ ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;;
+ ecdsa-sha2-nistp384) ktypes="$ktypes ecdsa-384" ;;
+ ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;;
+ esac
+done
+
+for kt in $ktypes; do
+ rm -f $OBJ/key.$kt
+ bits=`echo ${kt} | awk -F- '{print $2}'`
+ type=`echo ${kt} | awk -F- '{print $1}'`
+ printf "keygen $type, $bits bits:\t"
+ ${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\
+ fail "ssh-keygen for type $type, $bits bits failed"
+done
+
+tries="1 2 3"
+for ut in $ktypes; do
+ htypes=$ut
+ #htypes=$ktypes
+ for ht in $htypes; do
+ trace "ssh connect, userkey $ut, hostkey $ht"
+ (
+ grep -v HostKey $OBJ/sshd_proxy_bak
+ echo HostKey $OBJ/key.$ht
+ ) > $OBJ/sshd_proxy
+ (
+ grep -v IdentityFile $OBJ/ssh_proxy_bak
+ echo IdentityFile $OBJ/key.$ut
+ ) > $OBJ/ssh_proxy
+ (
+ printf 'localhost-with-alias,127.0.0.1,::1 '
+ cat $OBJ/key.$ht.pub
+ ) > $OBJ/known_hosts
+ cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER
+ for i in $tries; do
+ printf "userkey $ut, hostkey ${ht}:\t"
+ ${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
+ if [ $? -ne 0 ]; then
+ fail "ssh userkey $ut, hostkey $ht failed"
+ fi
+ done
+ done
+done
diff --git a/crypto/openssh/regress/krl.sh b/crypto/openssh/regress/krl.sh
new file mode 100755
index 0000000..287384b
--- /dev/null
+++ b/crypto/openssh/regress/krl.sh
@@ -0,0 +1,163 @@
+# $OpenBSD: krl.sh,v 1.3 2014/06/24 01:04:43 djm Exp $
+# Placed in the Public Domain.
+
+tid="key revocation lists"
+
+# If we don't support ecdsa keys then this tell will be much slower.
+ECDSA=ecdsa
+if test "x$TEST_SSH_ECC" != "xyes"; then
+ ECDSA=rsa
+fi
+
+# Do most testing with ssh-keygen; it uses the same verification code as sshd.
+
+# Old keys will interfere with ssh-keygen.
+rm -f $OBJ/revoked-* $OBJ/krl-*
+
+# Generate a CA key
+$SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null ||
+ fatal "$SSHKEYGEN CA failed"
+
+# A specification that revokes some certificates by serial numbers
+# The serial pattern is chosen to ensure the KRL includes list, range and
+# bitmap sections.
+cat << EOF >> $OBJ/revoked-serials
+serial: 1-4
+serial: 10
+serial: 15
+serial: 30
+serial: 50
+serial: 999
+# The following sum to 500-799
+serial: 500
+serial: 501
+serial: 502
+serial: 503-600
+serial: 700-797
+serial: 798
+serial: 799
+serial: 599-701
+# Some multiple consecutive serial number ranges
+serial: 10000-20000
+serial: 30000-40000
+EOF
+
+# A specification that revokes some certificated by key ID.
+touch $OBJ/revoked-keyid
+for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do
+ # Fill in by-ID revocation spec.
+ echo "id: revoked $n" >> $OBJ/revoked-keyid
+done
+
+keygen() {
+ N=$1
+ f=$OBJ/revoked-`printf "%04d" $N`
+ # Vary the keytype. We use mostly ECDSA since this is fastest by far.
+ keytype=$ECDSA
+ case $N in
+ 2 | 10 | 510 | 1001) keytype=rsa;;
+ 4 | 30 | 520 | 1002) keytype=dsa;;
+ esac
+ $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \
+ || fatal "$SSHKEYGEN failed"
+ # Sign cert
+ $SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \
+ || fatal "$SSHKEYGEN sign failed"
+ echo $f
+}
+
+# Generate some keys.
+verbose "$tid: generating test keys"
+REVOKED_SERIALS="1 4 10 50 500 510 520 799 999"
+for n in $REVOKED_SERIALS ; do
+ f=`keygen $n`
+ REVOKED_KEYS="$REVOKED_KEYS ${f}.pub"
+ REVOKED_CERTS="$REVOKED_CERTS ${f}-cert.pub"
+done
+NOTREVOKED_SERIALS="5 9 14 16 29 30 49 51 499 800 1000 1001"
+NOTREVOKED=""
+for n in $NOTREVOKED_SERIALS ; do
+ NOTREVOKED_KEYS="$NOTREVOKED_KEYS ${f}.pub"
+ NOTREVOKED_CERTS="$NOTREVOKED_CERTS ${f}-cert.pub"
+done
+
+genkrls() {
+ OPTS=$1
+$SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $REVOKED_KEYS \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $REVOKED_CERTS \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-all $REVOKED_KEYS $REVOKED_CERTS \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+# KRLs from serial/key-id spec need the CA specified.
+$SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \
+ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \
+ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca $OBJ/revoked-serials \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub $OBJ/revoked-keyid \
+ >/dev/null || fatal "$SSHKEYGEN KRL failed"
+}
+
+## XXX dump with trace and grep for set cert serials
+## XXX test ranges near (u64)-1, etc.
+
+verbose "$tid: generating KRLs"
+genkrls
+
+check_krl() {
+ KEY=$1
+ KRL=$2
+ EXPECT_REVOKED=$3
+ TAG=$4
+ $SSHKEYGEN -Qf $KRL $KEY >/dev/null
+ result=$?
+ if test "x$EXPECT_REVOKED" = "xyes" -a $result -eq 0 ; then
+ fatal "key $KEY not revoked by KRL $KRL: $TAG"
+ elif test "x$EXPECT_REVOKED" = "xno" -a $result -ne 0 ; then
+ fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG"
+ fi
+}
+test_all() {
+ FILES=$1
+ TAG=$2
+ KEYS_RESULT=$3
+ ALL_RESULT=$4
+ SERIAL_RESULT=$5
+ KEYID_RESULT=$6
+ CERTS_RESULT=$7
+ CA_RESULT=$8
+ verbose "$tid: checking revocations for $TAG"
+ for f in $FILES ; do
+ check_krl $f $OBJ/krl-empty no "$TAG"
+ check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG"
+ check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG"
+ check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG"
+ check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG"
+ check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG"
+ check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG"
+ done
+}
+# keys all serial keyid certs CA
+test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no
+test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no
+test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes
+test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes
+
+# Check update. Results should be identical.
+verbose "$tid: testing KRL update"
+for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \
+ $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid ; do
+ cp -f $OBJ/krl-empty $f
+ genkrls -u
+done
+# keys all serial keyid certs CA
+test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no
+test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no
+test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes
+test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes
diff --git a/crypto/openssh/regress/localcommand.sh b/crypto/openssh/regress/localcommand.sh
new file mode 100755
index 0000000..8a9b569
--- /dev/null
+++ b/crypto/openssh/regress/localcommand.sh
@@ -0,0 +1,15 @@
+# $OpenBSD: localcommand.sh,v 1.2 2013/05/17 10:24:48 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="localcommand"
+
+echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy
+echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy
+
+for p in 1 2; do
+ verbose "test $tid: proto $p localcommand"
+ a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true`
+ if [ "$a" != "foo" ] ; then
+ fail "$tid proto $p"
+ fi
+done
diff --git a/crypto/openssh/regress/login-timeout.sh b/crypto/openssh/regress/login-timeout.sh
new file mode 100644
index 0000000..eb76f55
--- /dev/null
+++ b/crypto/openssh/regress/login-timeout.sh
@@ -0,0 +1,32 @@
+# $OpenBSD: login-timeout.sh,v 1.7 2014/03/13 20:44:49 djm Exp $
+# Placed in the Public Domain.
+
+tid="connect after login grace timeout"
+
+trace "test login grace with privsep"
+cp $OBJ/sshd_config $OBJ/sshd_config.orig
+grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config
+echo "LoginGraceTime 10s" >> $OBJ/sshd_config
+echo "MaxStartups 1" >> $OBJ/sshd_config
+start_sshd
+
+(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
+sleep 15
+${SSH} -F $OBJ/ssh_config somehost true
+if [ $? -ne 0 ]; then
+ fail "ssh connect after login grace timeout failed with privsep"
+fi
+
+$SUDO kill `$SUDO cat $PIDFILE`
+
+trace "test login grace without privsep"
+echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
+start_sshd
+sleep 1
+
+(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
+sleep 15
+${SSH} -F $OBJ/ssh_config somehost true
+if [ $? -ne 0 ]; then
+ fail "ssh connect after login grace timeout failed without privsep"
+fi
diff --git a/crypto/openssh/regress/modpipe.c b/crypto/openssh/regress/modpipe.c
new file mode 100755
index 0000000..e854f9e
--- /dev/null
+++ b/crypto/openssh/regress/modpipe.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "openbsd-compat/getopt_long.c"
+
+static void err(int, const char *, ...) __attribute__((format(printf, 2, 3)));
+static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3)));
+
+static void
+err(int r, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ fprintf(stderr, "%s: ", strerror(errno));
+ vfprintf(stderr, fmt, args);
+ fputc('\n', stderr);
+ va_end(args);
+ exit(r);
+}
+
+static void
+errx(int r, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fputc('\n', stderr);
+ va_end(args);
+ exit(r);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: modpipe -w [-m modspec ...] < in > out\n");
+ fprintf(stderr, "modspec is one of:\n");
+ fprintf(stderr, " xor:offset:value - XOR \"value\" at \"offset\"\n");
+ fprintf(stderr, " andor:offset:val1:val2 - AND \"val1\" then OR \"val2\" at \"offset\"\n");
+ exit(1);
+}
+
+#define MAX_MODIFICATIONS 256
+struct modification {
+ enum { MOD_XOR, MOD_AND_OR } what;
+ unsigned long long offset;
+ u_int8_t m1, m2;
+};
+
+static void
+parse_modification(const char *s, struct modification *m)
+{
+ char what[16+1];
+ int n, m1, m2;
+
+ bzero(m, sizeof(*m));
+ if ((n = sscanf(s, "%16[^:]%*[:]%llu%*[:]%i%*[:]%i",
+ what, &m->offset, &m1, &m2)) < 3)
+ errx(1, "Invalid modification spec \"%s\"", s);
+ if (strcasecmp(what, "xor") == 0) {
+ if (n > 3)
+ errx(1, "Invalid modification spec \"%s\"", s);
+ if (m1 < 0 || m1 > 0xff)
+ errx(1, "Invalid XOR modification value");
+ m->what = MOD_XOR;
+ m->m1 = m1;
+ } else if (strcasecmp(what, "andor") == 0) {
+ if (n != 4)
+ errx(1, "Invalid modification spec \"%s\"", s);
+ if (m1 < 0 || m1 > 0xff)
+ errx(1, "Invalid AND modification value");
+ if (m2 < 0 || m2 > 0xff)
+ errx(1, "Invalid OR modification value");
+ m->what = MOD_AND_OR;
+ m->m1 = m1;
+ m->m2 = m2;
+ } else
+ errx(1, "Invalid modification type \"%s\"", what);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+ u_char buf[8192];
+ size_t total;
+ ssize_t r, s, o;
+ struct modification mods[MAX_MODIFICATIONS];
+ u_int i, wflag = 0, num_mods = 0;
+
+ while ((ch = getopt(argc, argv, "wm:")) != -1) {
+ switch (ch) {
+ case 'm':
+ if (num_mods >= MAX_MODIFICATIONS)
+ errx(1, "Too many modifications");
+ parse_modification(optarg, &(mods[num_mods++]));
+ break;
+ case 'w':
+ wflag = 1;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+ for (total = 0;;) {
+ r = s = read(STDIN_FILENO, buf, sizeof(buf));
+ if (r == 0)
+ break;
+ if (r < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ err(1, "read");
+ }
+ for (i = 0; i < num_mods; i++) {
+ if (mods[i].offset < total ||
+ mods[i].offset >= total + s)
+ continue;
+ switch (mods[i].what) {
+ case MOD_XOR:
+ buf[mods[i].offset - total] ^= mods[i].m1;
+ break;
+ case MOD_AND_OR:
+ buf[mods[i].offset - total] &= mods[i].m1;
+ buf[mods[i].offset - total] |= mods[i].m2;
+ break;
+ }
+ }
+ for (o = 0; o < s; o += r) {
+ r = write(STDOUT_FILENO, buf, s - o);
+ if (r == 0)
+ break;
+ if (r < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ err(1, "write");
+ }
+ }
+ total += s;
+ }
+ /* Warn if modifications not reached in input stream */
+ r = 0;
+ for (i = 0; wflag && i < num_mods; i++) {
+ if (mods[i].offset < total)
+ continue;
+ r = 1;
+ fprintf(stderr, "modpipe: warning - mod %u not reached\n", i);
+ }
+ return r;
+}
diff --git a/crypto/openssh/regress/multiplex.sh b/crypto/openssh/regress/multiplex.sh
new file mode 100644
index 0000000..8ee140b
--- /dev/null
+++ b/crypto/openssh/regress/multiplex.sh
@@ -0,0 +1,203 @@
+# $OpenBSD: multiplex.sh,v 1.25 2014/07/22 01:32:12 djm Exp $
+# Placed in the Public Domain.
+
+CTL=/tmp/openssh.regress.ctl-sock.$$
+
+tid="connection multiplexing"
+
+if have_prog nc ; then
+ if nc -h 2>&1 | grep -- -N >/dev/null; then
+ NC="nc -N";
+ elif nc -h 2>&1 | grep -- "-U.*Use UNIX" >/dev/null ; then
+ NC="nc"
+ else
+ echo "nc is incompatible"
+ fi
+fi
+
+if test -z "$NC" ; then
+ echo "skipped (no compatible nc found)"
+ exit 0
+fi
+
+trace "will use ProxyCommand $proxycmd"
+if config_defined DISABLE_FD_PASSING ; then
+ echo "skipped (not supported on this platform)"
+ exit 0
+fi
+
+P=3301 # test port
+
+wait_for_mux_master_ready()
+{
+ for i in 1 2 3 4 5; do
+ ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \
+ >/dev/null 2>&1 && return 0
+ sleep $i
+ done
+ fatal "mux master never becomes ready"
+}
+
+start_sshd
+
+start_mux_master()
+{
+ trace "start master, fork to background"
+ ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \
+ -E $TEST_REGRESS_LOGFILE 2>&1 &
+ # NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors.
+ SSH_PID=$!
+ wait_for_mux_master_ready
+}
+
+start_mux_master
+
+verbose "test $tid: envpass"
+trace "env passing over multiplexed connection"
+_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF'
+ test X"$_XXX_TEST" = X"blah"
+EOF
+if [ $? -ne 0 ]; then
+ fail "environment not found"
+fi
+
+verbose "test $tid: transfer"
+rm -f ${COPY}
+trace "ssh transfer over multiplexed connection and check result"
+${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY}
+test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}"
+cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}"
+
+rm -f ${COPY}
+trace "ssh transfer over multiplexed connection and check result"
+${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY}
+test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}"
+cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}"
+
+rm -f ${COPY}
+trace "sftp transfer over multiplexed connection and check result"
+echo "get ${DATA} ${COPY}" | \
+ ${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1
+test -f ${COPY} || fail "sftp: failed copy ${DATA}"
+cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}"
+
+rm -f ${COPY}
+trace "scp transfer over multiplexed connection and check result"
+${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1
+test -f ${COPY} || fail "scp: failed copy ${DATA}"
+cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}"
+
+rm -f ${COPY}
+verbose "test $tid: forward"
+trace "forward over TCP/IP and check result"
+$NC -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} &
+netcat_pid=$!
+${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
+$NC -d 127.0.0.1 $((${PORT} + 2)) > ${COPY} < /dev/null
+cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
+kill $netcat_pid 2>/dev/null
+rm -f ${COPY} $OBJ/unix-[123].fwd
+
+trace "forward over UNIX and check result"
+$NC -Ul $OBJ/unix-1.fwd < ${DATA} &
+netcat_pid=$!
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
+$NC -d -U $OBJ/unix-3.fwd > ${COPY} </dev/null
+cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
+kill $netcat_pid 2>/dev/null
+rm -f ${COPY} $OBJ/unix-[123].fwd
+
+for s in 0 1 4 5 44; do
+ trace "exit status $s over multiplexed connection"
+ verbose "test $tid: status $s"
+ ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s
+ r=$?
+ if [ $r -ne $s ]; then
+ fail "exit code mismatch for protocol $p: $r != $s"
+ fi
+
+ # same with early close of stdout/err
+ trace "exit status $s with early close over multiplexed connection"
+ ${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \
+ exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
+ r=$?
+ if [ $r -ne $s ]; then
+ fail "exit code (with sleep) mismatch for protocol $p: $r != $s"
+ fi
+done
+
+verbose "test $tid: cmd check"
+${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
+ || fail "check command failed"
+
+verbose "test $tid: cmd forward local (TCP)"
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \
+ || fail "request local forward failed"
+${SSH} -F $OBJ/ssh_config -p$P otherhost true \
+ || fail "connect to local forward port failed"
+${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \
+ || fail "cancel local forward failed"
+${SSH} -F $OBJ/ssh_config -p$P otherhost true \
+ && fail "local forward port still listening"
+
+verbose "test $tid: cmd forward remote (TCP)"
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \
+ || fail "request remote forward failed"
+${SSH} -F $OBJ/ssh_config -p$P otherhost true \
+ || fail "connect to remote forwarded port failed"
+${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \
+ || fail "cancel remote forward failed"
+${SSH} -F $OBJ/ssh_config -p$P otherhost true \
+ && fail "remote forward port still listening"
+
+verbose "test $tid: cmd forward local (UNIX)"
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
+ || fail "request local forward failed"
+echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \
+ || fail "connect to local forward path failed"
+${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
+ || fail "cancel local forward failed"
+N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
+test ${N} -eq 0 || fail "local forward path still listening"
+rm -f $OBJ/unix-1.fwd
+
+verbose "test $tid: cmd forward remote (UNIX)"
+${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
+ || fail "request remote forward failed"
+echo "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \
+ || fail "connect to remote forwarded path failed"
+${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
+ || fail "cancel remote forward failed"
+N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
+test ${N} -eq 0 || fail "remote forward path still listening"
+rm -f $OBJ/unix-1.fwd
+
+verbose "test $tid: cmd exit"
+${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
+ || fail "send exit command failed"
+
+# Wait for master to exit
+wait $SSH_PID
+kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed"
+
+# Restart master and test -O stop command with master using -N
+verbose "test $tid: cmd stop"
+trace "restart master, fork to background"
+start_mux_master
+
+# start a long-running command then immediately request a stop
+${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \
+ >>$TEST_REGRESS_LOGFILE 2>&1 &
+SLEEP_PID=$!
+${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
+ || fail "send stop command failed"
+
+# wait until both long-running command and master have exited.
+wait $SLEEP_PID
+[ $! != 0 ] || fail "waiting for concurrent command"
+wait $SSH_PID
+[ $! != 0 ] || fail "waiting for master stop"
+kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed"
+SSH_PID="" # Already gone, so don't kill in cleanup
+
diff --git a/crypto/openssh/regress/portnum.sh b/crypto/openssh/regress/portnum.sh
new file mode 100755
index 0000000..c56b869
--- /dev/null
+++ b/crypto/openssh/regress/portnum.sh
@@ -0,0 +1,34 @@
+# $OpenBSD: portnum.sh,v 1.2 2013/05/17 10:34:30 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="port number parsing"
+
+badport() {
+ port=$1
+ verbose "$tid: invalid port $port"
+ if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then
+ fail "$tid accepted invalid port $port"
+ fi
+}
+goodport() {
+ port=$1
+ verbose "$tid: valid port $port"
+ if ${SSH} -F $OBJ/ssh_proxy -p $port somehost true 2>/dev/null ; then
+ :
+ else
+ fail "$tid rejected valid port $port"
+ fi
+}
+
+badport 0
+badport 65536
+badport 131073
+badport 2000blah
+badport blah2000
+
+goodport 1
+goodport 22
+goodport 2222
+goodport 22222
+goodport 65535
+
diff --git a/crypto/openssh/regress/proto-mismatch.sh b/crypto/openssh/regress/proto-mismatch.sh
new file mode 100644
index 0000000..fb521f2
--- /dev/null
+++ b/crypto/openssh/regress/proto-mismatch.sh
@@ -0,0 +1,19 @@
+# $OpenBSD: proto-mismatch.sh,v 1.3 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="protocol version mismatch"
+
+mismatch ()
+{
+ server=$1
+ client=$2
+ banner=`echo ${client} | ${SSHD} -o "Protocol=${server}" -i -f ${OBJ}/sshd_proxy`
+ r=$?
+ trace "sshd prints ${banner}"
+ if [ $r -ne 255 ]; then
+ fail "sshd prints ${banner} and accepts connect with version ${client}"
+ fi
+}
+
+mismatch 2 SSH-1.5-HALLO
+mismatch 1 SSH-2.0-HALLO
diff --git a/crypto/openssh/regress/proto-version.sh b/crypto/openssh/regress/proto-version.sh
new file mode 100644
index 0000000..b876dd7
--- /dev/null
+++ b/crypto/openssh/regress/proto-version.sh
@@ -0,0 +1,34 @@
+# $OpenBSD: proto-version.sh,v 1.4 2013/05/17 00:37:40 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="sshd version with different protocol combinations"
+
+# we just start sshd in inetd mode and check the banner
+check_version ()
+{
+ version=$1
+ expect=$2
+ banner=`printf '' | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy`
+ case ${banner} in
+ SSH-1.99-*)
+ proto=199
+ ;;
+ SSH-2.0-*)
+ proto=20
+ ;;
+ SSH-1.5-*)
+ proto=15
+ ;;
+ *)
+ proto=0
+ ;;
+ esac
+ if [ ${expect} -ne ${proto} ]; then
+ fail "wrong protocol version ${banner} for ${version}"
+ fi
+}
+
+check_version 2,1 199
+check_version 1,2 199
+check_version 2 20
+check_version 1 15
diff --git a/crypto/openssh/regress/proxy-connect.sh b/crypto/openssh/regress/proxy-connect.sh
new file mode 100644
index 0000000..023ba73
--- /dev/null
+++ b/crypto/openssh/regress/proxy-connect.sh
@@ -0,0 +1,31 @@
+# $OpenBSD: proxy-connect.sh,v 1.7 2014/05/03 18:46:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="proxy connect"
+
+mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+
+for ps in no yes; do
+ cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
+ echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
+
+ for p in 1 2; do
+ for c in no yes; do
+ verbose "plain username protocol $p privsep=$ps comp=$c"
+ opts="-$p -oCompression=$c -F $OBJ/ssh_proxy"
+ SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
+ if [ $? -ne 0 ]; then
+ fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed"
+ fi
+ if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
+ fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c"
+ fi
+ done
+ done
+done
+
+for p in 1 2; do
+ verbose "username with style protocol $p"
+ ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \
+ fail "ssh proxyconnect protocol $p failed"
+done
diff --git a/crypto/openssh/regress/putty-ciphers.sh b/crypto/openssh/regress/putty-ciphers.sh
new file mode 100755
index 0000000..724a98c
--- /dev/null
+++ b/crypto/openssh/regress/putty-ciphers.sh
@@ -0,0 +1,26 @@
+# $OpenBSD: putty-ciphers.sh,v 1.4 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="putty ciphers"
+
+if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
+ echo "putty interop tests not enabled"
+ exit 0
+fi
+
+for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do
+ verbose "$tid: cipher $c"
+ cp ${OBJ}/.putty/sessions/localhost_proxy \
+ ${OBJ}/.putty/sessions/cipher_$c
+ echo "Cipher=$c" >> ${OBJ}/.putty/sessions/cipher_$c
+
+ rm -f ${COPY}
+ env HOME=$PWD ${PLINK} -load cipher_$c -batch -i putty.rsa2 \
+ 127.0.0.1 cat ${DATA} > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+done
+rm -f ${COPY}
+
diff --git a/crypto/openssh/regress/putty-kex.sh b/crypto/openssh/regress/putty-kex.sh
new file mode 100755
index 0000000..1844d65
--- /dev/null
+++ b/crypto/openssh/regress/putty-kex.sh
@@ -0,0 +1,23 @@
+# $OpenBSD: putty-kex.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="putty KEX"
+
+if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
+ echo "putty interop tests not enabled"
+ exit 0
+fi
+
+for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do
+ verbose "$tid: kex $k"
+ cp ${OBJ}/.putty/sessions/localhost_proxy \
+ ${OBJ}/.putty/sessions/kex_$k
+ echo "KEX=$k" >> ${OBJ}/.putty/sessions/kex_$k
+
+ env HOME=$PWD ${PLINK} -load kex_$k -batch -i putty.rsa2 \
+ 127.0.0.1 true
+ if [ $? -ne 0 ]; then
+ fail "KEX $k failed"
+ fi
+done
+
diff --git a/crypto/openssh/regress/putty-transfer.sh b/crypto/openssh/regress/putty-transfer.sh
new file mode 100755
index 0000000..aec0e04
--- /dev/null
+++ b/crypto/openssh/regress/putty-transfer.sh
@@ -0,0 +1,41 @@
+# $OpenBSD: putty-transfer.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="putty transfer data"
+
+if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
+ echo "putty interop tests not enabled"
+ exit 0
+fi
+
+# XXX support protocol 1 too
+for p in 2; do
+ for c in 0 1 ; do
+ verbose "$tid: proto $p compression $c"
+ rm -f ${COPY}
+ cp ${OBJ}/.putty/sessions/localhost_proxy \
+ ${OBJ}/.putty/sessions/compression_$c
+ echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k
+ env HOME=$PWD ${PLINK} -load compression_$c -batch \
+ -i putty.rsa$p 127.0.0.1 cat ${DATA} > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+ for s in 10 100 1k 32k 64k 128k 256k; do
+ trace "proto $p compression $c dd-size ${s}"
+ rm -f ${COPY}
+ dd if=$DATA obs=${s} 2> /dev/null | \
+ env HOME=$PWD ${PLINK} -load compression_$c \
+ -batch -i putty.rsa$p 127.0.0.1 \
+ "cat > ${COPY}"
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp $DATA ${COPY} || fail "corrupted copy"
+ done
+ done
+done
+rm -f ${COPY}
+
diff --git a/crypto/openssh/regress/reconfigure.sh b/crypto/openssh/regress/reconfigure.sh
new file mode 100644
index 0000000..9fd2895
--- /dev/null
+++ b/crypto/openssh/regress/reconfigure.sh
@@ -0,0 +1,36 @@
+# $OpenBSD: reconfigure.sh,v 1.2 2003/06/21 09:14:05 markus Exp $
+# Placed in the Public Domain.
+
+tid="simple connect after reconfigure"
+
+# we need the full path to sshd for -HUP
+case $SSHD in
+/*)
+ # full path is OK
+ ;;
+*)
+ # otherwise make fully qualified
+ SSHD=$OBJ/$SSHD
+esac
+
+start_sshd
+
+PID=`$SUDO cat $PIDFILE`
+rm -f $PIDFILE
+$SUDO kill -HUP $PID
+
+trace "wait for sshd to restart"
+i=0;
+while [ ! -f $PIDFILE -a $i -lt 10 ]; do
+ i=`expr $i + 1`
+ sleep $i
+done
+
+test -f $PIDFILE || fatal "sshd did not restart"
+
+for p in 1 2; do
+ ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh connect with protocol $p failed after reconfigure"
+ fi
+done
diff --git a/crypto/openssh/regress/reexec.sh b/crypto/openssh/regress/reexec.sh
new file mode 100644
index 0000000..433573f
--- /dev/null
+++ b/crypto/openssh/regress/reexec.sh
@@ -0,0 +1,73 @@
+# $OpenBSD: reexec.sh,v 1.7 2013/05/17 10:23:52 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="reexec tests"
+
+SSHD_ORIG=$SSHD
+SSHD_COPY=$OBJ/sshd
+
+# Start a sshd and then delete it
+start_sshd_copy ()
+{
+ cp $SSHD_ORIG $SSHD_COPY
+ SSHD=$SSHD_COPY
+ start_sshd
+ SSHD=$SSHD_ORIG
+}
+
+# Do basic copy tests
+copy_tests ()
+{
+ rm -f ${COPY}
+ for p in 1 2; do
+ verbose "$tid: proto $p"
+ ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \
+ cat ${DATA} > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+ rm -f ${COPY}
+ done
+}
+
+verbose "test config passing"
+
+cp $OBJ/sshd_config $OBJ/sshd_config.orig
+start_sshd
+echo "InvalidXXX=no" >> $OBJ/sshd_config
+
+copy_tests
+
+$SUDO kill `$SUDO cat $PIDFILE`
+rm -f $PIDFILE
+
+cp $OBJ/sshd_config.orig $OBJ/sshd_config
+
+# cygwin can't fork a deleted binary
+if [ "$os" != "cygwin" ]; then
+
+verbose "test reexec fallback"
+
+start_sshd_copy
+rm -f $SSHD_COPY
+
+copy_tests
+
+$SUDO kill `$SUDO cat $PIDFILE`
+rm -f $PIDFILE
+
+verbose "test reexec fallback without privsep"
+
+cp $OBJ/sshd_config.orig $OBJ/sshd_config
+echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config
+
+start_sshd_copy
+rm -f $SSHD_COPY
+
+copy_tests
+
+$SUDO kill `$SUDO cat $PIDFILE`
+rm -f $PIDFILE
+
+fi
diff --git a/crypto/openssh/regress/rekey.sh b/crypto/openssh/regress/rekey.sh
new file mode 100644
index 0000000..fd452b0
--- /dev/null
+++ b/crypto/openssh/regress/rekey.sh
@@ -0,0 +1,150 @@
+# $OpenBSD: rekey.sh,v 1.15 2014/04/21 22:15:37 djm Exp $
+# Placed in the Public Domain.
+
+tid="rekey"
+
+LOG=${TEST_SSH_LOGFILE}
+
+rm -f ${LOG}
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+# Test rekeying based on data volume only.
+# Arguments will be passed to ssh.
+ssh_data_rekeying()
+{
+ _kexopt=$1 ; shift
+ _opts="$@"
+ if ! test -z "$_kexopts" ; then
+ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+ echo "$_kexopt" >> $OBJ/sshd_proxy
+ _opts="$_opts -o$_kexopt"
+ fi
+ rm -f ${COPY} ${LOG}
+ _opts="$_opts -oCompression=no"
+ ${SSH} <${DATA} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}"
+ if [ $? -ne 0 ]; then
+ fail "ssh failed ($@)"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy ($@)"
+ n=`grep 'NEWKEYS sent' ${LOG} | wc -l`
+ n=`expr $n - 1`
+ trace "$n rekeying(s)"
+ if [ $n -lt 1 ]; then
+ fail "no rekeying occured ($@)"
+ fi
+}
+
+increase_datafile_size 300
+
+opts=""
+for i in `${SSH} -Q kex`; do
+ opts="$opts KexAlgorithms=$i"
+done
+for i in `${SSH} -Q cipher`; do
+ opts="$opts Ciphers=$i"
+done
+for i in `${SSH} -Q mac`; do
+ opts="$opts MACs=$i"
+done
+
+for opt in $opts; do
+ verbose "client rekey $opt"
+ ssh_data_rekeying "$opt" -oRekeyLimit=256k
+done
+
+# AEAD ciphers are magical so test with all KexAlgorithms
+if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then
+ for c in `${SSH} -Q cipher-auth`; do
+ for kex in `${SSH} -Q kex`; do
+ verbose "client rekey $c $kex"
+ ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c
+ done
+ done
+fi
+
+for s in 16 1k 128k 256k; do
+ verbose "client rekeylimit ${s}"
+ ssh_data_rekeying "" -oCompression=no -oRekeyLimit=$s
+done
+
+for s in 5 10; do
+ verbose "client rekeylimit default ${s}"
+ rm -f ${COPY} ${LOG}
+ ${SSH} < ${DATA} -oCompression=no -oRekeyLimit="default $s" -F \
+ $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 3"
+ if [ $? -ne 0 ]; then
+ fail "ssh failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+ n=`grep 'NEWKEYS sent' ${LOG} | wc -l`
+ n=`expr $n - 1`
+ trace "$n rekeying(s)"
+ if [ $n -lt 1 ]; then
+ fail "no rekeying occured"
+ fi
+done
+
+for s in 5 10; do
+ verbose "client rekeylimit default ${s} no data"
+ rm -f ${COPY} ${LOG}
+ ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \
+ $OBJ/ssh_proxy somehost "sleep $s;sleep 3"
+ if [ $? -ne 0 ]; then
+ fail "ssh failed"
+ fi
+ n=`grep 'NEWKEYS sent' ${LOG} | wc -l`
+ n=`expr $n - 1`
+ trace "$n rekeying(s)"
+ if [ $n -lt 1 ]; then
+ fail "no rekeying occured"
+ fi
+done
+
+echo "rekeylimit default 5" >>$OBJ/sshd_proxy
+for s in 5 10; do
+ verbose "server rekeylimit default ${s} no data"
+ rm -f ${COPY} ${LOG}
+ ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3"
+ if [ $? -ne 0 ]; then
+ fail "ssh failed"
+ fi
+ n=`grep 'NEWKEYS sent' ${LOG} | wc -l`
+ n=`expr $n - 1`
+ trace "$n rekeying(s)"
+ if [ $n -lt 1 ]; then
+ fail "no rekeying occured"
+ fi
+done
+
+verbose "rekeylimit parsing"
+for size in 16 1k 1K 1m 1M 1g 1G; do
+ for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do
+ case $size in
+ 16) bytes=16 ;;
+ 1k|1K) bytes=1024 ;;
+ 1m|1M) bytes=1048576 ;;
+ 1g|1G) bytes=1073741824 ;;
+ esac
+ case $time in
+ 1) seconds=1 ;;
+ 1m|1M) seconds=60 ;;
+ 1h|1H) seconds=3600 ;;
+ 1d|1D) seconds=86400 ;;
+ 1w|1W) seconds=604800 ;;
+ esac
+
+ b=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \
+ awk '/rekeylimit/{print $2}'`
+ s=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \
+ awk '/rekeylimit/{print $3}'`
+
+ if [ "$bytes" != "$b" ]; then
+ fatal "rekeylimit size: expected $bytes bytes got $b"
+ fi
+ if [ "$seconds" != "$s" ]; then
+ fatal "rekeylimit time: expected $time seconds got $s"
+ fi
+ done
+done
+
+rm -f ${COPY} ${DATA}
diff --git a/crypto/openssh/regress/rsa_openssh.prv b/crypto/openssh/regress/rsa_openssh.prv
new file mode 100644
index 0000000..2675555
--- /dev/null
+++ b/crypto/openssh/regress/rsa_openssh.prv
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWgIBAAKBgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko
++dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3
+xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQIDAQAB
+An8nH5VzvHkMbSqJ6eOYDsVwomRvYbH5IEaYl1x6VATITNvAu9kUdQ4NsSpuMc+7
+Jj9gKZvmO1y2YCKc0P/iO+i/eV0L+yQh1Rw18jQZll+12T+LZrKRav03YNvMx0gN
+wqWY48Kt6hv2/N/ebQzKRe79+D0t2cTh92hT7xENFLIBAkEBGnoGKFjAUkJCwO1V
+mzpUqMHpRZVOrqP9hUmPjzNJ5oBPFGe4+h1hoSRFOAzaNuZt8ssbqaLCkzB8bfzj
+qhZqAQJBANZekuUpp8iBLeLSagw5FkcPwPzq6zfExbhvsZXb8Bo/4SflNs4JHXwI
+7SD9Z8aJLvM4uQ/5M70lblDMQ40i3o0CQQDIJvBYBFL5tlOgakq/O7yi+wt0L5BZ
+9H79w5rCSAA0IHRoK/qI1urHiHC3f3vbbLk5UStfrqEaND/mm0shyNIBAkBLsYdC
+/ctt5Bc0wUGK4Vl5bBmj9LtrrMJ4FpBpLwj/69BwCuKoK9XKZ0h73p6XHveCEGRg
+PIlFX4MtaoLrwgU9AkBV2k4dgIws+X8YX65EsyyFjnlDqX4x0nSOjQB1msIKfHBr
+dh5XLDBTTCxnKhMJ0Yx/opgOvf09XHBFwaQntR5i
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/rsa_openssh.pub b/crypto/openssh/regress/rsa_openssh.pub
new file mode 100644
index 0000000..b504730
--- /dev/null
+++ b/crypto/openssh/regress/rsa_openssh.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko+dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQ==
diff --git a/crypto/openssh/regress/rsa_ssh2.prv b/crypto/openssh/regress/rsa_ssh2.prv
new file mode 100644
index 0000000..1ece3d7
--- /dev/null
+++ b/crypto/openssh/regress/rsa_ssh2.prv
@@ -0,0 +1,16 @@
+---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
+Subject: ssh-keygen test
+Comment: "1024-bit rsa, Sat Jun 23 2001 12:21:26 -0400"
+P2/56wAAAi4AAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS
+1wa2NzMXYyLW9hZXB9fQAAAARub25lAAAB3wAAAdsAAAARAQABAAAD9icflXO8eQxtKonp
+45gOxXCiZG9hsfkgRpiXXHpUBMhM28C72RR1Dg2xKm4xz7smP2Apm+Y7XLZgIpzQ/+I76L
+95XQv7JCHVHDXyNBmWX7XZP4tmspFq/Tdg28zHSA3CpZjjwq3qG/b8395tDMpF7v34PS3Z
+xOH3aFPvEQ0UsgEAAAQA7IpcCnGijesEjDXdVoEPfh0akBJA9JAk1bba2sxrtDoQVN1JKP
+nRQ9SKdAsXV5jduSUFsTmBe4fznLvD948790U1/O8SkdGM5V0y1/ki7Rf8knm0t8Vj65X0
+VA4YdN4UeVfvMcb78vcInT2CsP6CLcBkrnjrBKtS03Mwg79nQI0AAAH/VdpOHYCMLPl/GF
++uRLMshY55Q6l+MdJ0jo0AdZrCCnxwa3YeVywwU0wsZyoTCdGMf6KYDr39PVxwRcGkJ7Ue
+YgAAAgDWXpLlKafIgS3i0moMORZHD8D86us3xMW4b7GV2/AaP+En5TbOCR18CO0g/WfGiS
+7zOLkP+TO9JW5QzEONIt6NAAACAQEaegYoWMBSQkLA7VWbOlSowelFlU6uo/2FSY+PM0nm
+gE8UZ7j6HWGhJEU4DNo25m3yyxuposKTMHxt/OOqFmoB
+---- END SSH2 ENCRYPTED PRIVATE KEY ----
+---
diff --git a/crypto/openssh/regress/scp-ssh-wrapper.sh b/crypto/openssh/regress/scp-ssh-wrapper.sh
new file mode 100644
index 0000000..59f1ff6
--- /dev/null
+++ b/crypto/openssh/regress/scp-ssh-wrapper.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+# $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $
+# Placed in the Public Domain.
+
+printname () {
+ NAME=$1
+ save_IFS=$IFS
+ IFS=/
+ set -- `echo "$NAME"`
+ IFS="$save_IFS"
+ while [ $# -ge 1 ] ; do
+ if [ "x$1" != "x" ]; then
+ echo "D0755 0 $1"
+ fi
+ shift;
+ done
+}
+
+# Discard all but last argument. We use arg later.
+while test "x$1" != "x"; do
+ arg="$1"
+ shift
+done
+
+BAD="../../../../../../../../../../../../../${DIR}/dotpathdir"
+
+case "$SCPTESTMODE" in
+badserver_0)
+ echo "D0755 0 /${DIR}/rootpathdir"
+ echo "C755 2 rootpathfile"
+ echo "X"
+ ;;
+badserver_1)
+ echo "D0755 0 $BAD"
+ echo "C755 2 file"
+ echo "X"
+ ;;
+badserver_2)
+ echo "D0755 0 $BAD"
+ echo "C755 2 file"
+ echo "X"
+ ;;
+badserver_3)
+ printname $BAD
+ echo "C755 2 file"
+ echo "X"
+ ;;
+badserver_4)
+ printname $BAD
+ echo "D0755 0 .."
+ echo "C755 2 file"
+ echo "X"
+ ;;
+*)
+ set -- $arg
+ shift
+ exec $SCP "$@"
+ ;;
+esac
diff --git a/crypto/openssh/regress/scp.sh b/crypto/openssh/regress/scp.sh
new file mode 100644
index 0000000..57cc770
--- /dev/null
+++ b/crypto/openssh/regress/scp.sh
@@ -0,0 +1,126 @@
+# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $
+# Placed in the Public Domain.
+
+tid="scp"
+
+#set -x
+
+# Figure out if diff understands "-N"
+if diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then
+ DIFFOPT="-rN"
+else
+ DIFFOPT="-r"
+fi
+
+COPY2=${OBJ}/copy2
+DIR=${COPY}.dd
+DIR2=${COPY}.dd2
+
+SRC=`dirname ${SCRIPT}`
+cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp
+chmod 755 ${OBJ}/scp-ssh-wrapper.scp
+scpopts="-q -S ${OBJ}/scp-ssh-wrapper.scp"
+export SCP # used in scp-ssh-wrapper.scp
+
+scpclean() {
+ rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
+ mkdir ${DIR} ${DIR2}
+}
+
+verbose "$tid: simple copy local file to local file"
+scpclean
+$SCP $scpopts ${DATA} ${COPY} || fail "copy failed"
+cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+verbose "$tid: simple copy local file to remote file"
+scpclean
+$SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed"
+cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+verbose "$tid: simple copy remote file to local file"
+scpclean
+$SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed"
+cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+verbose "$tid: simple copy local file to remote dir"
+scpclean
+cp ${DATA} ${COPY}
+$SCP $scpopts ${COPY} somehost:${DIR} || fail "copy failed"
+cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+
+verbose "$tid: simple copy local file to local dir"
+scpclean
+cp ${DATA} ${COPY}
+$SCP $scpopts ${COPY} ${DIR} || fail "copy failed"
+cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+
+verbose "$tid: simple copy remote file to local dir"
+scpclean
+cp ${DATA} ${COPY}
+$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed"
+cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
+
+verbose "$tid: recursive local dir to remote dir"
+scpclean
+rm -rf ${DIR2}
+cp ${DATA} ${DIR}/copy
+$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed"
+diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+
+verbose "$tid: recursive local dir to local dir"
+scpclean
+rm -rf ${DIR2}
+cp ${DATA} ${DIR}/copy
+$SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed"
+diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+
+verbose "$tid: recursive remote dir to local dir"
+scpclean
+rm -rf ${DIR2}
+cp ${DATA} ${DIR}/copy
+$SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed"
+diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+
+verbose "$tid: shell metacharacters"
+scpclean
+(cd ${DIR} && \
+touch '`touch metachartest`' && \
+$SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \
+[ ! -f metachartest ] ) || fail "shell metacharacters"
+
+if [ ! -z "$SUDO" ]; then
+ verbose "$tid: skipped file after scp -p with failed chown+utimes"
+ scpclean
+ cp -p ${DATA} ${DIR}/copy
+ cp -p ${DATA} ${DIR}/copy2
+ cp ${DATA} ${DIR2}/copy
+ chmod 660 ${DIR2}/copy
+ $SUDO chown root ${DIR2}/copy
+ $SCP -p $scpopts somehost:${DIR}/\* ${DIR2} >/dev/null 2>&1
+ $SUDO diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+ $SUDO rm ${DIR2}/copy
+fi
+
+for i in 0 1 2 3 4; do
+ verbose "$tid: disallow bad server #$i"
+ SCPTESTMODE=badserver_$i
+ export DIR SCPTESTMODE
+ scpclean
+ $SCP $scpopts somehost:${DATA} ${DIR} >/dev/null 2>/dev/null
+ [ -d {$DIR}/rootpathdir ] && fail "allows dir relative to root dir"
+ [ -d ${DIR}/dotpathdir ] && fail "allows dir creation in non-recursive mode"
+
+ scpclean
+ $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
+ [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir"
+done
+
+verbose "$tid: detect non-directory target"
+scpclean
+echo a > ${COPY}
+echo b > ${COPY2}
+$SCP $scpopts ${DATA} ${COPY} ${COPY2}
+cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target"
+
+scpclean
+rm -f ${OBJ}/scp-ssh-wrapper.scp
diff --git a/crypto/openssh/regress/setuid-allowed.c b/crypto/openssh/regress/setuid-allowed.c
new file mode 100644
index 0000000..676d266
--- /dev/null
+++ b/crypto/openssh/regress/setuid-allowed.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $OpenBSD$ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_STATVFS_H
+# include <sys/statvfs.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+void
+usage(void)
+{
+ fprintf(stderr, "check-setuid [path]\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *path = ".";
+ struct statvfs sb;
+
+ if (argc > 2)
+ usage();
+ else if (argc == 2)
+ path = argv[1];
+
+ if (statvfs(path, &sb) != 0) {
+ /* Don't return an error if the host doesn't support statvfs */
+ if (errno == ENOSYS)
+ return 0;
+ fprintf(stderr, "statvfs for \"%s\" failed: %s\n",
+ path, strerror(errno));
+ }
+ return (sb.f_flag & ST_NOSUID) ? 1 : 0;
+}
+
+
diff --git a/crypto/openssh/regress/sftp-badcmds.sh b/crypto/openssh/regress/sftp-badcmds.sh
new file mode 100644
index 0000000..7f85c4f
--- /dev/null
+++ b/crypto/openssh/regress/sftp-badcmds.sh
@@ -0,0 +1,65 @@
+# $OpenBSD: sftp-badcmds.sh,v 1.6 2013/05/17 10:26:26 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="sftp invalid commands"
+
+DATA2=/bin/sh${EXEEXT}
+NONEXIST=/NONEXIST.$$
+GLOBFILES=`(cd /bin;echo l*)`
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd
+
+rm -f ${COPY}
+verbose "$tid: get nonexistent"
+echo "get $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get nonexistent failed"
+test -f ${COPY} && fail "existing copy after get nonexistent"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob get to nonexistent directory"
+echo "get /bin/l* $NONEXIST" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get nonexistent failed"
+for x in $GLOBFILES; do
+ test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent"
+done
+
+rm -f ${COPY}
+verbose "$tid: put nonexistent"
+echo "put $NONEXIST $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put nonexistent failed"
+test -f ${COPY} && fail "existing copy after put nonexistent"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob put to nonexistent directory"
+echo "put /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put nonexistent failed"
+for x in $GLOBFILES; do
+ test -f ${COPY}.dd/$x && fail "existing copy after nonexistent"
+done
+
+rm -f ${COPY}
+verbose "$tid: rename nonexistent"
+echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "rename nonexist failed"
+test -f ${COPY}.1 && fail "file exists after rename nonexistent"
+
+rm -rf ${COPY} ${COPY}.dd
+cp $DATA $COPY
+mkdir ${COPY}.dd
+verbose "$tid: rename target exists (directory)"
+echo "rename $COPY ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "rename target exists (directory) failed"
+test -f ${COPY} || fail "oldname missing after rename target exists (directory)"
+test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)"
+cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists (directory)"
+
+rm -f ${COPY}.dd/*
+rm -rf ${COPY}
+cp ${DATA2} ${COPY}
+verbose "$tid: glob put files to local file"
+echo "put /bin/l* $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1
+cmp ${DATA2} ${COPY} || fail "put successed when it should have failed"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd
+
+
diff --git a/crypto/openssh/regress/sftp-batch.sh b/crypto/openssh/regress/sftp-batch.sh
new file mode 100644
index 0000000..4101154
--- /dev/null
+++ b/crypto/openssh/regress/sftp-batch.sh
@@ -0,0 +1,55 @@
+# $OpenBSD: sftp-batch.sh,v 1.5 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="sftp batchfile"
+
+BATCH=${OBJ}/sftp.bb
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+cat << EOF > ${BATCH}.pass.1
+ get $DATA $COPY
+ put ${COPY} ${COPY}.1
+ rm ${COPY}
+ -put ${COPY} ${COPY}.2
+EOF
+
+cat << EOF > ${BATCH}.pass.2
+ # This is a comment
+
+ # That was a blank line
+ ls
+EOF
+
+cat << EOF > ${BATCH}.fail.1
+ get $DATA $COPY
+ put ${COPY} ${COPY}.3
+ rm ${COPY}.*
+ # The next command should fail
+ put ${COPY}.3 ${COPY}.4
+EOF
+
+cat << EOF > ${BATCH}.fail.2
+ # The next command should fail
+ jajajajaja
+EOF
+
+verbose "$tid: good commands"
+${SFTP} -b ${BATCH}.pass.1 -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "good commands failed"
+
+verbose "$tid: bad commands"
+${SFTP} -b ${BATCH}.fail.1 -D ${SFTPSERVER} >/dev/null 2>&1 \
+ && fail "bad commands succeeded"
+
+verbose "$tid: comments and blanks"
+${SFTP} -b ${BATCH}.pass.2 -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "comments & blanks failed"
+
+verbose "$tid: junk command"
+${SFTP} -b ${BATCH}.fail.2 -D ${SFTPSERVER} >/dev/null 2>&1 \
+ && fail "junk command succeeded"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.*
+
+
diff --git a/crypto/openssh/regress/sftp-chroot.sh b/crypto/openssh/regress/sftp-chroot.sh
new file mode 100755
index 0000000..23f7456
--- /dev/null
+++ b/crypto/openssh/regress/sftp-chroot.sh
@@ -0,0 +1,26 @@
+# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="sftp in chroot"
+
+CHROOT=/var/run
+FILENAME=testdata_${USER}
+PRIVDATA=${CHROOT}/${FILENAME}
+
+if [ -z "$SUDO" ]; then
+ echo "skipped: need SUDO to create file in /var/run, test won't work without"
+ exit 0
+fi
+
+$SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \
+ fatal "create $PRIVDATA failed"
+
+start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /"
+
+verbose "test $tid: get"
+${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \
+ >>$TEST_REGRESS_LOGFILE 2>&1 || \
+ fatal "Fetch ${FILENAME} failed"
+cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ"
+
+$SUDO rm $PRIVDATA
diff --git a/crypto/openssh/regress/sftp-cmds.sh b/crypto/openssh/regress/sftp-cmds.sh
new file mode 100644
index 0000000..aad7fca
--- /dev/null
+++ b/crypto/openssh/regress/sftp-cmds.sh
@@ -0,0 +1,232 @@
+# $OpenBSD: sftp-cmds.sh,v 1.14 2013/06/21 02:26:26 djm Exp $
+# Placed in the Public Domain.
+
+# XXX - TODO:
+# - chmod / chown / chgrp
+# - -p flag for get & put
+
+tid="sftp commands"
+
+# test that these files are readable!
+for i in `(cd /bin;echo l*)`
+do
+ if [ -r $i ]; then
+ GLOBFILES="$GLOBFILES $i"
+ fi
+done
+
+# Path with embedded quote
+QUOTECOPY=${COPY}".\"blah\""
+QUOTECOPY_ARG=${COPY}'.\"blah\"'
+# File with spaces
+SPACECOPY="${COPY} this has spaces.txt"
+SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt"
+# File with glob metacharacters
+GLOBMETACOPY="${COPY} [metachar].txt"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2
+mkdir ${COPY}.dd
+
+verbose "$tid: lls"
+(echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -D ${SFTPSERVER} 2>&1 | \
+ grep copy.dd >/dev/null 2>&1 || fail "lls failed"
+
+verbose "$tid: lls w/path"
+echo "lls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \
+ grep copy.dd >/dev/null 2>&1 || fail "lls w/path failed"
+
+verbose "$tid: ls"
+echo "ls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "ls failed"
+# XXX always successful
+
+verbose "$tid: shell"
+echo "!echo hi there" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "shell failed"
+# XXX always successful
+
+verbose "$tid: pwd"
+echo "pwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "pwd failed"
+# XXX always successful
+
+verbose "$tid: lpwd"
+echo "lpwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "lpwd failed"
+# XXX always successful
+
+verbose "$tid: quit"
+echo "quit" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "quit failed"
+# XXX always successful
+
+verbose "$tid: help"
+echo "help" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "help failed"
+# XXX always successful
+
+rm -f ${COPY}
+verbose "$tid: get"
+echo "get $DATA $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp $DATA ${COPY} || fail "corrupted copy after get"
+
+rm -f ${COPY}
+verbose "$tid: get quoted"
+echo "get \"$DATA\" $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp $DATA ${COPY} || fail "corrupted copy after get"
+
+if [ "$os" != "cygwin" ]; then
+rm -f ${QUOTECOPY}
+cp $DATA ${QUOTECOPY}
+verbose "$tid: get filename with quotes"
+echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes"
+rm -f ${QUOTECOPY} ${COPY}
+fi
+
+rm -f "$SPACECOPY" ${COPY}
+cp $DATA "$SPACECOPY"
+verbose "$tid: get filename with spaces"
+echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces"
+
+rm -f "$GLOBMETACOPY" ${COPY}
+cp $DATA "$GLOBMETACOPY"
+verbose "$tid: get filename with glob metacharacters"
+echo "get \"${GLOBMETACOPY}\" ${COPY}" | \
+ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed"
+cmp ${COPY} "$GLOBMETACOPY" || \
+ fail "corrupted copy after get with glob metacharacters"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: get to directory"
+echo "get $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob get to directory"
+echo "get /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+for x in $GLOBFILES; do
+ cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get"
+done
+
+rm -f ${COPY}.dd/*
+verbose "$tid: get to local dir"
+(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after get"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob get to local dir"
+(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "get failed"
+for x in $GLOBFILES; do
+ cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get"
+done
+
+rm -f ${COPY}
+verbose "$tid: put"
+echo "put $DATA $COPY" | \
+ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
+cmp $DATA ${COPY} || fail "corrupted copy after put"
+
+if [ "$os" != "cygwin" ]; then
+rm -f ${QUOTECOPY}
+verbose "$tid: put filename with quotes"
+echo "put $DATA \"$QUOTECOPY_ARG\"" | \
+ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
+cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes"
+fi
+
+rm -f "$SPACECOPY"
+verbose "$tid: put filename with spaces"
+echo "put $DATA ${SPACECOPY_ARG}" | \
+ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
+cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: put to directory"
+echo "put $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put failed"
+cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob put to directory"
+echo "put /bin/l? ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put failed"
+for x in $GLOBFILES; do
+ cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put"
+done
+
+rm -f ${COPY}.dd/*
+verbose "$tid: put to local dir"
+(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put failed"
+cmp $DATA ${COPY}.dd/$DATANAME || fail "corrupted copy after put"
+
+rm -f ${COPY}.dd/*
+verbose "$tid: glob put to local dir"
+(echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "put failed"
+for x in $GLOBFILES; do
+ cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put"
+done
+
+verbose "$tid: rename"
+echo "rename $COPY ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "rename failed"
+test -f ${COPY}.1 || fail "missing file after rename"
+cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename"
+
+verbose "$tid: rename directory"
+echo "rename ${COPY}.dd ${COPY}.dd2" | \
+ ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || \
+ fail "rename directory failed"
+test -d ${COPY}.dd && fail "oldname exists after rename directory"
+test -d ${COPY}.dd2 || fail "missing newname after rename directory"
+
+verbose "$tid: ln"
+echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed"
+test -f ${COPY}.2 || fail "missing file after ln"
+cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after ln"
+
+verbose "$tid: ln -s"
+rm -f ${COPY}.2
+echo "ln -s ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln -s failed"
+test -h ${COPY}.2 || fail "missing file after ln -s"
+
+verbose "$tid: mkdir"
+echo "mkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "mkdir failed"
+test -d ${COPY}.dd || fail "missing directory after mkdir"
+
+# XXX do more here
+verbose "$tid: chdir"
+echo "chdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "chdir failed"
+
+verbose "$tid: rmdir"
+echo "rmdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "rmdir failed"
+test -d ${COPY}.1 && fail "present directory after rmdir"
+
+verbose "$tid: lmkdir"
+echo "lmkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "lmkdir failed"
+test -d ${COPY}.dd || fail "missing directory after lmkdir"
+
+# XXX do more here
+verbose "$tid: lchdir"
+echo "lchdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \
+ || fail "lchdir failed"
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2
+rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY"
+
+
diff --git a/crypto/openssh/regress/sftp-glob.sh b/crypto/openssh/regress/sftp-glob.sh
new file mode 100644
index 0000000..8d4df2c
--- /dev/null
+++ b/crypto/openssh/regress/sftp-glob.sh
@@ -0,0 +1,75 @@
+# $OpenBSD: sftp-glob.sh,v 1.4 2009/08/13 01:11:55 djm Exp $
+# Placed in the Public Domain.
+
+tid="sftp glob"
+
+config_defined FILESYSTEM_NO_BACKSLASH && nobs="not supported on this platform"
+
+sftp_ls() {
+ target=$1
+ errtag=$2
+ expected=$3
+ unexpected=$4
+ skip=$5
+ if test "x$skip" != "x" ; then
+ verbose "$tid: $errtag (skipped: $skip)"
+ return
+ fi
+ verbose "$tid: $errtag"
+ printf "ls -l %s" "${target}" | \
+ ${SFTP} -b - -D ${SFTPSERVER} 2>/dev/null | \
+ grep -v "^sftp>" > ${RESULTS}
+ if [ $? -ne 0 ]; then
+ fail "$errtag failed"
+ fi
+ if test "x$expected" != "x" ; then
+ if fgrep "$expected" ${RESULTS} >/dev/null 2>&1 ; then
+ :
+ else
+ fail "$expected missing from $errtag results"
+ fi
+ fi
+ if test "x$unexpected" != "x" && \
+ fgrep "$unexpected" ${RESULTS} >/dev/null 2>&1 ; then
+ fail "$unexpected present in $errtag results"
+ fi
+ rm -f ${RESULTS}
+}
+
+BASE=${OBJ}/glob
+RESULTS=${OBJ}/results
+DIR=${BASE}/dir
+DATA=${DIR}/file
+
+GLOB1="${DIR}/g-wild*"
+GLOB2="${DIR}/g-wildx"
+QUOTE="${DIR}/g-quote\""
+SLASH="${DIR}/g-sl\\ash"
+ESLASH="${DIR}/g-slash\\"
+QSLASH="${DIR}/g-qs\\\""
+SPACE="${DIR}/g-q space"
+
+rm -rf ${BASE}
+mkdir -p ${DIR}
+touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}" "${SPACE}"
+test "x$nobs" = "x" && touch "${QSLASH}" "${ESLASH}" "${SLASH}"
+
+# target message expected unexpected
+sftp_ls "${DIR}/fil*" "file glob" "${DATA}" ""
+sftp_ls "${BASE}/d*" "dir glob" "`basename ${DATA}`" ""
+sftp_ls "${DIR}/g-wild\"*\"" "quoted glob" "g-wild*" "g-wildx"
+sftp_ls "${DIR}/g-wild\*" "escaped glob" "g-wild*" "g-wildx"
+sftp_ls "${DIR}/g-quote\\\"" "escaped quote" "g-quote\"" ""
+sftp_ls "\"${DIR}/g-quote\\\"\"" "quoted quote" "g-quote\"" ""
+sftp_ls "'${DIR}/g-quote\"'" "single-quoted quote" "g-quote\"" ""
+sftp_ls "${DIR}/g-q\\ space" "escaped space" "g-q space" ""
+sftp_ls "'${DIR}/g-q space'" "quoted space" "g-q space" ""
+sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" "" "$nobs"
+sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" "" "$nobs"
+sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" "" "$nobs"
+sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" "" "$nobs"
+sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" "" "$nobs"
+sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" "" "$nobs"
+
+rm -rf ${BASE}
+
diff --git a/crypto/openssh/regress/sftp-perm.sh b/crypto/openssh/regress/sftp-perm.sh
new file mode 100644
index 0000000..304ca0a
--- /dev/null
+++ b/crypto/openssh/regress/sftp-perm.sh
@@ -0,0 +1,269 @@
+# $OpenBSD: sftp-perm.sh,v 1.2 2013/10/17 22:00:18 djm Exp $
+# Placed in the Public Domain.
+
+tid="sftp permissions"
+
+SERVER_LOG=${OBJ}/sftp-server.log
+CLIENT_LOG=${OBJ}/sftp.log
+TEST_SFTP_SERVER=${OBJ}/sftp-server.sh
+
+prepare_server() {
+ printf "#!/bin/sh\nexec $SFTPSERVER -el debug3 $* 2>$SERVER_LOG\n" \
+ > $TEST_SFTP_SERVER
+ chmod a+x $TEST_SFTP_SERVER
+}
+
+run_client() {
+ echo "$@" | ${SFTP} -D ${TEST_SFTP_SERVER} -vvvb - >$CLIENT_LOG 2>&1
+}
+
+prepare_files() {
+ _prep="$1"
+ rm -f ${COPY} ${COPY}.1
+ test -d ${COPY}.dd && { rmdir ${COPY}.dd || fatal "rmdir ${COPY}.dd"; }
+ test -z "$_prep" && return
+ sh -c "$_prep" || fail "preparation failed: \"$_prep\""
+}
+
+postcondition() {
+ _title="$1"
+ _check="$2"
+ test -z "$_check" && return
+ ${TEST_SHELL} -c "$_check" || fail "postcondition check failed: $_title"
+}
+
+ro_test() {
+ _desc=$1
+ _cmd="$2"
+ _prep="$3"
+ _expect_success_post="$4"
+ _expect_fail_post="$5"
+ verbose "$tid: read-only $_desc"
+ # Plain (no options, mostly to test that _cmd is good)
+ prepare_files "$_prep"
+ prepare_server
+ run_client "$_cmd" || fail "plain $_desc failed"
+ postcondition "$_desc no-readonly" "$_expect_success_post"
+ # Read-only enabled
+ prepare_files "$_prep"
+ prepare_server -R
+ run_client "$_cmd" && fail "read-only $_desc succeeded"
+ postcondition "$_desc readonly" "$_expect_fail_post"
+}
+
+perm_test() {
+ _op=$1
+ _whitelist_ops=$2
+ _cmd="$3"
+ _prep="$4"
+ _expect_success_post="$5"
+ _expect_fail_post="$6"
+ verbose "$tid: explicit $_op"
+ # Plain (no options, mostly to test that _cmd is good)
+ prepare_files "$_prep"
+ prepare_server
+ run_client "$_cmd" || fail "plain $_op failed"
+ postcondition "$_op no white/blacklists" "$_expect_success_post"
+ # Whitelist
+ prepare_files "$_prep"
+ prepare_server -p $_op,$_whitelist_ops
+ run_client "$_cmd" || fail "whitelisted $_op failed"
+ postcondition "$_op whitelisted" "$_expect_success_post"
+ # Blacklist
+ prepare_files "$_prep"
+ prepare_server -P $_op
+ run_client "$_cmd" && fail "blacklisted $_op succeeded"
+ postcondition "$_op blacklisted" "$_expect_fail_post"
+ # Whitelist with op missing.
+ prepare_files "$_prep"
+ prepare_server -p $_whitelist_ops
+ run_client "$_cmd" && fail "no whitelist $_op succeeded"
+ postcondition "$_op not in whitelist" "$_expect_fail_post"
+}
+
+ro_test \
+ "upload" \
+ "put $DATA $COPY" \
+ "" \
+ "cmp $DATA $COPY" \
+ "test ! -f $COPY"
+
+ro_test \
+ "setstat" \
+ "chmod 0700 $COPY" \
+ "touch $COPY; chmod 0400 $COPY" \
+ "test -x $COPY" \
+ "test ! -x $COPY"
+
+ro_test \
+ "rm" \
+ "rm $COPY" \
+ "touch $COPY" \
+ "test ! -f $COPY" \
+ "test -f $COPY"
+
+ro_test \
+ "mkdir" \
+ "mkdir ${COPY}.dd" \
+ "" \
+ "test -d ${COPY}.dd" \
+ "test ! -d ${COPY}.dd"
+
+ro_test \
+ "rmdir" \
+ "rmdir ${COPY}.dd" \
+ "mkdir ${COPY}.dd" \
+ "test ! -d ${COPY}.dd" \
+ "test -d ${COPY}.dd"
+
+ro_test \
+ "posix-rename" \
+ "rename $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1 -a ! -f $COPY" \
+ "test -f $COPY -a ! -f ${COPY}.1"
+
+ro_test \
+ "oldrename" \
+ "rename -l $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1 -a ! -f $COPY" \
+ "test -f $COPY -a ! -f ${COPY}.1"
+
+ro_test \
+ "symlink" \
+ "ln -s $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -h ${COPY}.1" \
+ "test ! -h ${COPY}.1"
+
+ro_test \
+ "hardlink" \
+ "ln $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1" \
+ "test ! -f ${COPY}.1"
+
+# Test explicit permissions
+
+perm_test \
+ "open" \
+ "realpath,stat,lstat,read,close" \
+ "get $DATA $COPY" \
+ "" \
+ "cmp $DATA $COPY" \
+ "! cmp $DATA $COPY 2>/dev/null"
+
+perm_test \
+ "read" \
+ "realpath,stat,lstat,open,close" \
+ "get $DATA $COPY" \
+ "" \
+ "cmp $DATA $COPY" \
+ "! cmp $DATA $COPY 2>/dev/null"
+
+perm_test \
+ "write" \
+ "realpath,stat,lstat,open,close" \
+ "put $DATA $COPY" \
+ "" \
+ "cmp $DATA $COPY" \
+ "! cmp $DATA $COPY 2>/dev/null"
+
+perm_test \
+ "lstat" \
+ "realpath,stat,open,read,close" \
+ "get $DATA $COPY" \
+ "" \
+ "cmp $DATA $COPY" \
+ "! cmp $DATA $COPY 2>/dev/null"
+
+perm_test \
+ "opendir" \
+ "realpath,readdir,stat,lstat" \
+ "ls -ln $OBJ"
+
+perm_test \
+ "readdir" \
+ "realpath,opendir,stat,lstat" \
+ "ls -ln $OBJ"
+
+perm_test \
+ "setstat" \
+ "realpath,stat,lstat" \
+ "chmod 0700 $COPY" \
+ "touch $COPY; chmod 0400 $COPY" \
+ "test -x $COPY" \
+ "test ! -x $COPY"
+
+perm_test \
+ "remove" \
+ "realpath,stat,lstat" \
+ "rm $COPY" \
+ "touch $COPY" \
+ "test ! -f $COPY" \
+ "test -f $COPY"
+
+perm_test \
+ "mkdir" \
+ "realpath,stat,lstat" \
+ "mkdir ${COPY}.dd" \
+ "" \
+ "test -d ${COPY}.dd" \
+ "test ! -d ${COPY}.dd"
+
+perm_test \
+ "rmdir" \
+ "realpath,stat,lstat" \
+ "rmdir ${COPY}.dd" \
+ "mkdir ${COPY}.dd" \
+ "test ! -d ${COPY}.dd" \
+ "test -d ${COPY}.dd"
+
+perm_test \
+ "posix-rename" \
+ "realpath,stat,lstat" \
+ "rename $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1 -a ! -f $COPY" \
+ "test -f $COPY -a ! -f ${COPY}.1"
+
+perm_test \
+ "rename" \
+ "realpath,stat,lstat" \
+ "rename -l $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1 -a ! -f $COPY" \
+ "test -f $COPY -a ! -f ${COPY}.1"
+
+perm_test \
+ "symlink" \
+ "realpath,stat,lstat" \
+ "ln -s $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -h ${COPY}.1" \
+ "test ! -h ${COPY}.1"
+
+perm_test \
+ "hardlink" \
+ "realpath,stat,lstat" \
+ "ln $COPY ${COPY}.1" \
+ "touch $COPY" \
+ "test -f ${COPY}.1" \
+ "test ! -f ${COPY}.1"
+
+perm_test \
+ "statvfs" \
+ "realpath,stat,lstat" \
+ "df /"
+
+# XXX need good tests for:
+# fstat
+# fsetstat
+# realpath
+# stat
+# readlink
+# fstatvfs
+
+rm -rf ${COPY} ${COPY}.1 ${COPY}.dd
+
diff --git a/crypto/openssh/regress/sftp.sh b/crypto/openssh/regress/sftp.sh
new file mode 100644
index 0000000..b8e9f75
--- /dev/null
+++ b/crypto/openssh/regress/sftp.sh
@@ -0,0 +1,32 @@
+# $OpenBSD: sftp.sh,v 1.5 2013/05/17 10:28:11 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="basic sftp put/get"
+
+SFTPCMDFILE=${OBJ}/batch
+cat >$SFTPCMDFILE <<EOF
+version
+get $DATA ${COPY}.1
+put $DATA ${COPY}.2
+EOF
+
+BUFFERSIZE="5 1000 32000 64000"
+REQUESTS="1 2 10"
+
+for B in ${BUFFERSIZE}; do
+ for R in ${REQUESTS}; do
+ verbose "test $tid: buffer_size $B num_requests $R"
+ rm -f ${COPY}.1 ${COPY}.2
+ ${SFTP} -D ${SFTPSERVER} -B $B -R $R -b $SFTPCMDFILE \
+ > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "sftp failed with $r"
+ else
+ cmp $DATA ${COPY}.1 || fail "corrupted copy after get"
+ cmp $DATA ${COPY}.2 || fail "corrupted copy after put"
+ fi
+ done
+done
+rm -f ${COPY}.1 ${COPY}.2
+rm -f $SFTPCMDFILE
diff --git a/crypto/openssh/regress/ssh-com-client.sh b/crypto/openssh/regress/ssh-com-client.sh
new file mode 100644
index 0000000..e4f80cf
--- /dev/null
+++ b/crypto/openssh/regress/ssh-com-client.sh
@@ -0,0 +1,130 @@
+# $OpenBSD: ssh-com-client.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="connect with ssh.com client"
+
+#TEST_COMBASE=/path/to/ssh/com/binaries
+if [ "X${TEST_COMBASE}" = "X" ]; then
+ fatal '$TEST_COMBASE is not set'
+fi
+
+VERSIONS="
+ 2.1.0
+ 2.2.0
+ 2.3.0
+ 2.3.1
+ 2.4.0
+ 3.0.0
+ 3.1.0
+ 3.2.0
+ 3.2.2
+ 3.2.3
+ 3.2.5
+ 3.2.9
+ 3.2.9.1
+ 3.3.0"
+
+# 2.0.10 2.0.12 2.0.13 don't like the test setup
+
+# setup authorized keys
+SRC=`dirname ${SCRIPT}`
+cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com
+chmod 600 ${OBJ}/id.com
+${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh
+chmod 600 ${OBJ}/id.openssh
+${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER
+${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub
+echo IdKey ${OBJ}/id.com > ${OBJ}/id.list
+
+# we need a DSA host key
+t=dsa
+rm -f ${OBJ}/$t ${OBJ}/$t.pub
+${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t
+$SUDO cp $OBJ/$t $OBJ/host.$t
+echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
+
+# add hostkeys to known hosts
+mkdir -p ${OBJ}/${USER}/hostkeys
+HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1
+${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub
+${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub
+
+cat > ${OBJ}/ssh2_config << EOF
+*:
+ QuietMode yes
+ StrictHostKeyChecking yes
+ Port ${PORT}
+ User ${USER}
+ Host 127.0.0.1
+ IdentityFile ${OBJ}/id.list
+ RandomSeedFile ${OBJ}/random_seed
+ UserConfigDirectory ${OBJ}/%U
+ AuthenticationSuccessMsg no
+ BatchMode yes
+ ForwardX11 no
+EOF
+
+# we need a real server (no ProxyConnect option)
+start_sshd
+
+# go for it
+for v in ${VERSIONS}; do
+ ssh2=${TEST_COMBASE}/${v}/ssh2
+ if [ ! -x ${ssh2} ]; then
+ continue
+ fi
+ verbose "ssh2 ${v}"
+ key=ssh-dss
+ skipcat=0
+ case $v in
+ 2.1.*|2.3.0)
+ skipcat=1
+ ;;
+ 3.0.*)
+ key=ssh-rsa
+ ;;
+ esac
+ cp ${HK}.$key.pub ${HK}.pub
+
+ # check exit status
+ ${ssh2} -q -F ${OBJ}/ssh2_config somehost exit 42
+ r=$?
+ if [ $r -ne 42 ]; then
+ fail "ssh2 ${v} exit code test failed (got $r, expected 42)"
+ fi
+
+ # data transfer
+ rm -f ${COPY}
+ ${ssh2} -F ${OBJ}/ssh2_config somehost cat ${DATA} > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh2 ${v} cat test (receive) failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "ssh2 ${v} cat test (receive) data mismatch"
+
+ # data transfer, again
+ if [ $skipcat -eq 0 ]; then
+ rm -f ${COPY}
+ cat ${DATA} | \
+ ${ssh2} -F ${OBJ}/ssh2_config host "cat > ${COPY}"
+ if [ $? -ne 0 ]; then
+ fail "ssh2 ${v} cat test (send) failed"
+ fi
+ cmp ${DATA} ${COPY} || \
+ fail "ssh2 ${v} cat test (send) data mismatch"
+ fi
+
+ # no stderr after eof
+ rm -f ${COPY}
+ ${ssh2} -F ${OBJ}/ssh2_config somehost \
+ exec sh -c \'"exec > /dev/null; sleep 1; echo bla 1>&2; exit 0"\' \
+ 2> /dev/null
+ if [ $? -ne 0 ]; then
+ fail "ssh2 ${v} stderr test failed"
+ fi
+done
+
+rm -rf ${OBJ}/${USER}
+for i in ssh2_config random_seed dsa.pub dsa host.dsa \
+ id.list id.com id.com.pub id.openssh; do
+ rm -f ${OBJ}/$i
+done
diff --git a/crypto/openssh/regress/ssh-com-keygen.sh b/crypto/openssh/regress/ssh-com-keygen.sh
new file mode 100644
index 0000000..29b02d9
--- /dev/null
+++ b/crypto/openssh/regress/ssh-com-keygen.sh
@@ -0,0 +1,74 @@
+# $OpenBSD: ssh-com-keygen.sh,v 1.4 2004/02/24 17:06:52 markus Exp $
+# Placed in the Public Domain.
+
+tid="ssh.com key import"
+
+#TEST_COMBASE=/path/to/ssh/com/binaries
+if [ "X${TEST_COMBASE}" = "X" ]; then
+ fatal '$TEST_COMBASE is not set'
+fi
+
+VERSIONS="
+ 2.0.10
+ 2.0.12
+ 2.0.13
+ 2.1.0
+ 2.2.0
+ 2.3.0
+ 2.3.1
+ 2.4.0
+ 3.0.0
+ 3.1.0
+ 3.2.0
+ 3.2.2
+ 3.2.3
+ 3.2.5
+ 3.2.9
+ 3.2.9.1
+ 3.3.0"
+
+COMPRV=${OBJ}/comkey
+COMPUB=${COMPRV}.pub
+OPENSSHPRV=${OBJ}/opensshkey
+OPENSSHPUB=${OPENSSHPRV}.pub
+
+# go for it
+for v in ${VERSIONS}; do
+ keygen=${TEST_COMBASE}/${v}/ssh-keygen2
+ if [ ! -x ${keygen} ]; then
+ continue
+ fi
+ types="dss"
+ case $v in
+ 2.3.1|3.*)
+ types="$types rsa"
+ ;;
+ esac
+ for t in $types; do
+ verbose "ssh-keygen $v/$t"
+ rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB
+ ${keygen} -q -P -t $t ${COMPRV} > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ fail "${keygen} -t $t failed"
+ continue
+ fi
+ ${SSHKEYGEN} -if ${COMPUB} > ${OPENSSHPUB}
+ if [ $? -ne 0 ]; then
+ fail "import public key ($v/$t) failed"
+ continue
+ fi
+ ${SSHKEYGEN} -if ${COMPRV} > ${OPENSSHPRV}
+ if [ $? -ne 0 ]; then
+ fail "import private key ($v/$t) failed"
+ continue
+ fi
+ chmod 600 ${OPENSSHPRV}
+ ${SSHKEYGEN} -yf ${OPENSSHPRV} |\
+ diff - ${OPENSSHPUB}
+ if [ $? -ne 0 ]; then
+ fail "public keys ($v/$t) differ"
+ fi
+ done
+done
+
+rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB
diff --git a/crypto/openssh/regress/ssh-com-sftp.sh b/crypto/openssh/regress/ssh-com-sftp.sh
new file mode 100644
index 0000000..fabfa49
--- /dev/null
+++ b/crypto/openssh/regress/ssh-com-sftp.sh
@@ -0,0 +1,65 @@
+# $OpenBSD: ssh-com-sftp.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="basic sftp put/get with ssh.com server"
+
+SFTPCMDFILE=${OBJ}/batch
+
+cat >$SFTPCMDFILE <<EOF
+version
+get $DATA ${COPY}.1
+put $DATA ${COPY}.2
+EOF
+
+BUFFERSIZE="5 1000 32000 64000"
+REQUESTS="1 2 10"
+
+#TEST_COMBASE=/path/to/ssh/com/binaries
+if [ "X${TEST_COMBASE}" = "X" ]; then
+ fatal '$TEST_COMBASE is not set'
+fi
+
+VERSIONS="
+ 2.0.10
+ 2.0.12
+ 2.0.13
+ 2.1.0
+ 2.2.0
+ 2.3.0
+ 2.3.1
+ 2.4.0
+ 3.0.0
+ 3.1.0
+ 3.2.0
+ 3.2.2
+ 3.2.3
+ 3.2.5
+ 3.2.9
+ 3.2.9.1
+ 3.3.0"
+
+# go for it
+for v in ${VERSIONS}; do
+ server=${TEST_COMBASE}/${v}/sftp-server2
+ if [ ! -x ${server} ]; then
+ continue
+ fi
+ verbose "sftp-server $v"
+ for B in ${BUFFERSIZE}; do
+ for R in ${REQUESTS}; do
+ verbose "test $tid: buffer_size $B num_requests $R"
+ rm -f ${COPY}.1 ${COPY}.2
+ ${SFTP} -D ${server} -B $B -R $R -b $SFTPCMDFILE \
+ > /dev/null 2>&1
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "sftp failed with $r"
+ else
+ cmp $DATA ${COPY}.1 || fail "corrupted copy after get"
+ cmp $DATA ${COPY}.2 || fail "corrupted copy after put"
+ fi
+ done
+ done
+done
+rm -f ${COPY}.1 ${COPY}.2
+rm -f $SFTPCMDFILE
diff --git a/crypto/openssh/regress/ssh-com.sh b/crypto/openssh/regress/ssh-com.sh
new file mode 100644
index 0000000..6c5cfe8
--- /dev/null
+++ b/crypto/openssh/regress/ssh-com.sh
@@ -0,0 +1,119 @@
+# $OpenBSD: ssh-com.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="connect to ssh.com server"
+
+#TEST_COMBASE=/path/to/ssh/com/binaries
+if [ "X${TEST_COMBASE}" = "X" ]; then
+ fatal '$TEST_COMBASE is not set'
+fi
+
+VERSIONS="
+ 2.0.12
+ 2.0.13
+ 2.1.0
+ 2.2.0
+ 2.3.0
+ 2.4.0
+ 3.0.0
+ 3.1.0
+ 3.2.0
+ 3.2.2
+ 3.2.3
+ 3.2.5
+ 3.2.9
+ 3.2.9.1
+ 3.3.0"
+# 2.0.10 does not support UserConfigDirectory
+# 2.3.1 requires a config in $HOME/.ssh2
+
+SRC=`dirname ${SCRIPT}`
+
+# ssh.com
+cat << EOF > $OBJ/sshd2_config
+#*:
+ # Port and ListenAddress are not used.
+ QuietMode yes
+ Port 4343
+ ListenAddress 127.0.0.1
+ UserConfigDirectory ${OBJ}/%U
+ Ciphers AnyCipher
+ PubKeyAuthentication yes
+ #AllowedAuthentications publickey
+ AuthorizationFile authorization
+ HostKeyFile ${SRC}/dsa_ssh2.prv
+ PublicHostKeyFile ${SRC}/dsa_ssh2.pub
+ RandomSeedFile ${OBJ}/random_seed
+ MaxConnections 0
+ PermitRootLogin yes
+ VerboseMode no
+ CheckMail no
+ Ssh1Compatibility no
+EOF
+
+# create client config
+sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \
+ < $OBJ/ssh_config > $OBJ/ssh_config_com
+
+# we need a DSA key for
+rm -f ${OBJ}/dsa ${OBJ}/dsa.pub
+${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa
+
+# setup userdir, try rsa first
+mkdir -p ${OBJ}/${USER}
+cp /dev/null ${OBJ}/${USER}/authorization
+for t in rsa dsa; do
+ ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com
+ echo Key $t.com >> ${OBJ}/${USER}/authorization
+ echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com
+done
+
+# convert and append DSA hostkey
+(
+ printf 'ssh2-localhost-with-alias,127.0.0.1,::1 '
+ ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub
+) >> $OBJ/known_hosts
+
+# go for it
+for v in ${VERSIONS}; do
+ sshd2=${TEST_COMBASE}/${v}/sshd2
+ if [ ! -x ${sshd2} ]; then
+ continue
+ fi
+ trace "sshd2 ${v}"
+ PROXY="proxycommand ${sshd2} -qif ${OBJ}/sshd2_config 2> /dev/null"
+ ${SSH} -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0
+ if [ $? -ne 0 ]; then
+ fail "ssh connect to sshd2 ${v} failed"
+ fi
+
+ ciphers="3des-cbc blowfish-cbc arcfour"
+ macs="hmac-md5"
+ case $v in
+ 2.4.*)
+ ciphers="$ciphers cast128-cbc"
+ macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96"
+ ;;
+ 3.*)
+ ciphers="$ciphers aes128-cbc cast128-cbc"
+ macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96"
+ ;;
+ esac
+ #ciphers="3des-cbc"
+ for m in $macs; do
+ for c in $ciphers; do
+ trace "sshd2 ${v} cipher $c mac $m"
+ verbose "test ${tid}: sshd2 ${v} cipher $c mac $m"
+ ${SSH} -c $c -m $m -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0
+ if [ $? -ne 0 ]; then
+ fail "ssh connect to sshd2 ${v} with $c/$m failed"
+ fi
+ done
+ done
+done
+
+rm -rf ${OBJ}/${USER}
+for i in sshd_config_proxy ssh_config_proxy random_seed \
+ sshd2_config dsa.pub dsa ssh_config_com; do
+ rm -f ${OBJ}/$i
+done
diff --git a/crypto/openssh/regress/ssh2putty.sh b/crypto/openssh/regress/ssh2putty.sh
new file mode 100755
index 0000000..691db16
--- /dev/null
+++ b/crypto/openssh/regress/ssh2putty.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# $OpenBSD: ssh2putty.sh,v 1.2 2009/10/06 23:51:49 dtucker Exp $
+
+if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then
+ echo "Usage: ssh2putty hostname port ssh-private-key"
+ exit 1
+fi
+
+HOST=$1
+PORT=$2
+KEYFILE=$3
+
+# XXX - support DSA keys too
+if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then
+ :
+else
+ echo "Unsupported private key format"
+ exit 1
+fi
+
+public_exponent=`
+ openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent |
+ sed 's/.*(//;s/).*//'
+`
+test $? -ne 0 && exit 1
+
+modulus=`
+ openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= |
+ sed 's/^Modulus=/0x/' | tr A-Z a-z
+`
+test $? -ne 0 && exit 1
+
+echo "rsa2@$PORT:$HOST $public_exponent,$modulus"
+
diff --git a/crypto/openssh/regress/sshd-log-wrapper.sh b/crypto/openssh/regress/sshd-log-wrapper.sh
new file mode 100644
index 0000000..a9386be
--- /dev/null
+++ b/crypto/openssh/regress/sshd-log-wrapper.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $OpenBSD: sshd-log-wrapper.sh,v 1.3 2013/04/07 02:16:03 dtucker Exp $
+# Placed in the Public Domain.
+#
+# simple wrapper for sshd proxy mode to catch stderr output
+# sh sshd-log-wrapper.sh /path/to/sshd /path/to/logfile
+
+sshd=$1
+log=$2
+shift
+shift
+
+exec $sshd -E$log $@
diff --git a/crypto/openssh/regress/stderr-after-eof.sh b/crypto/openssh/regress/stderr-after-eof.sh
new file mode 100644
index 0000000..218ac6b
--- /dev/null
+++ b/crypto/openssh/regress/stderr-after-eof.sh
@@ -0,0 +1,24 @@
+# $OpenBSD: stderr-after-eof.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="stderr data after eof"
+
+# setup data
+rm -f ${DATA} ${COPY}
+cp /dev/null ${DATA}
+for i in 1 2 3 4 5 6; do
+ (date;echo $i) | md5 >> ${DATA}
+done
+
+${SSH} -2 -F $OBJ/ssh_proxy otherhost \
+ exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \
+ 2> ${COPY}
+r=$?
+if [ $r -ne 0 ]; then
+ fail "ssh failed with exit code $r"
+fi
+egrep 'Disconnecting: Received extended_data after EOF' ${COPY} &&
+ fail "ext data received after eof"
+cmp ${DATA} ${COPY} || fail "stderr corrupt"
+
+rm -f ${DATA} ${COPY}
diff --git a/crypto/openssh/regress/stderr-data.sh b/crypto/openssh/regress/stderr-data.sh
new file mode 100644
index 0000000..b0bd235
--- /dev/null
+++ b/crypto/openssh/regress/stderr-data.sh
@@ -0,0 +1,29 @@
+# $OpenBSD: stderr-data.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="stderr data transfer"
+
+for n in '' -n; do
+for p in 1 2; do
+ verbose "test $tid: proto $p ($n)"
+ ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \
+ exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \
+ 2> ${COPY}
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh failed with exit code $r"
+ fi
+ cmp ${DATA} ${COPY} || fail "stderr corrupt"
+ rm -f ${COPY}
+
+ ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \
+ exec sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \
+ > /dev/null 2> ${COPY}
+ r=$?
+ if [ $r -ne 0 ]; then
+ fail "ssh failed with exit code $r"
+ fi
+ cmp ${DATA} ${COPY} || fail "stderr corrupt"
+ rm -f ${COPY}
+done
+done
diff --git a/crypto/openssh/regress/t4.ok b/crypto/openssh/regress/t4.ok
new file mode 100644
index 0000000..8c4942b
--- /dev/null
+++ b/crypto/openssh/regress/t4.ok
@@ -0,0 +1 @@
+3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36
diff --git a/crypto/openssh/regress/t5.ok b/crypto/openssh/regress/t5.ok
new file mode 100644
index 0000000..bd622f3
--- /dev/null
+++ b/crypto/openssh/regress/t5.ok
@@ -0,0 +1 @@
+xokes-lylis-byleh-zebib-kalus-bihas-tevah-haroz-suhar-foved-noxex
diff --git a/crypto/openssh/regress/test-exec.sh b/crypto/openssh/regress/test-exec.sh
new file mode 100644
index 0000000..a1bab83
--- /dev/null
+++ b/crypto/openssh/regress/test-exec.sh
@@ -0,0 +1,494 @@
+# $OpenBSD: test-exec.sh,v 1.48 2014/07/06 07:42:03 djm Exp $
+# Placed in the Public Domain.
+
+#SUDO=sudo
+
+# Unbreak GNU head(1)
+_POSIX2_VERSION=199209
+export _POSIX2_VERSION
+
+case `uname -s 2>/dev/null` in
+OSF1*)
+ BIN_SH=xpg4
+ export BIN_SH
+ ;;
+CYGWIN_NT-5.0)
+ os=cygwin
+ TEST_SSH_IPV6=no
+ ;;
+CYGWIN*)
+ os=cygwin
+ ;;
+esac
+
+if [ ! -z "$TEST_SSH_PORT" ]; then
+ PORT="$TEST_SSH_PORT"
+else
+ PORT=4242
+fi
+
+if [ -x /usr/ucb/whoami ]; then
+ USER=`/usr/ucb/whoami`
+elif whoami >/dev/null 2>&1; then
+ USER=`whoami`
+elif logname >/dev/null 2>&1; then
+ USER=`logname`
+else
+ USER=`id -un`
+fi
+
+OBJ=$1
+if [ "x$OBJ" = "x" ]; then
+ echo '$OBJ not defined'
+ exit 2
+fi
+if [ ! -d $OBJ ]; then
+ echo "not a directory: $OBJ"
+ exit 2
+fi
+SCRIPT=$2
+if [ "x$SCRIPT" = "x" ]; then
+ echo '$SCRIPT not defined'
+ exit 2
+fi
+if [ ! -f $SCRIPT ]; then
+ echo "not a file: $SCRIPT"
+ exit 2
+fi
+if $TEST_SHELL -n $SCRIPT; then
+ true
+else
+ echo "syntax error in $SCRIPT"
+ exit 2
+fi
+unset SSH_AUTH_SOCK
+
+SRC=`dirname ${SCRIPT}`
+
+# defaults
+SSH=ssh
+SSHD=sshd
+SSHAGENT=ssh-agent
+SSHADD=ssh-add
+SSHKEYGEN=ssh-keygen
+SSHKEYSCAN=ssh-keyscan
+SFTP=sftp
+SFTPSERVER=/usr/libexec/openssh/sftp-server
+SCP=scp
+
+# Interop testing
+PLINK=plink
+PUTTYGEN=puttygen
+CONCH=conch
+
+if [ "x$TEST_SSH_SSH" != "x" ]; then
+ SSH="${TEST_SSH_SSH}"
+fi
+if [ "x$TEST_SSH_SSHD" != "x" ]; then
+ SSHD="${TEST_SSH_SSHD}"
+fi
+if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then
+ SSHAGENT="${TEST_SSH_SSHAGENT}"
+fi
+if [ "x$TEST_SSH_SSHADD" != "x" ]; then
+ SSHADD="${TEST_SSH_SSHADD}"
+fi
+if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then
+ SSHKEYGEN="${TEST_SSH_SSHKEYGEN}"
+fi
+if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then
+ SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}"
+fi
+if [ "x$TEST_SSH_SFTP" != "x" ]; then
+ SFTP="${TEST_SSH_SFTP}"
+fi
+if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then
+ SFTPSERVER="${TEST_SSH_SFTPSERVER}"
+fi
+if [ "x$TEST_SSH_SCP" != "x" ]; then
+ SCP="${TEST_SSH_SCP}"
+fi
+if [ "x$TEST_SSH_PLINK" != "x" ]; then
+ # Find real binary, if it exists
+ case "${TEST_SSH_PLINK}" in
+ /*) PLINK="${TEST_SSH_PLINK}" ;;
+ *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;;
+ esac
+fi
+if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then
+ # Find real binary, if it exists
+ case "${TEST_SSH_PUTTYGEN}" in
+ /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;;
+ *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;;
+ esac
+fi
+if [ "x$TEST_SSH_CONCH" != "x" ]; then
+ # Find real binary, if it exists
+ case "${TEST_SSH_CONCH}" in
+ /*) CONCH="${TEST_SSH_CONCH}" ;;
+ *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;;
+ esac
+fi
+
+# Path to sshd must be absolute for rexec
+case "$SSHD" in
+/*) ;;
+*) SSHD=`which $SSHD` ;;
+esac
+
+case "$SSHAGENT" in
+/*) ;;
+*) SSHAGENT=`which $SSHAGENT` ;;
+esac
+
+# Logfiles.
+# SSH_LOGFILE should be the debug output of ssh(1) only
+# SSHD_LOGFILE should be the debug output of sshd(8) only
+# REGRESS_LOGFILE is the output of the test itself stdout and stderr
+if [ "x$TEST_SSH_LOGFILE" = "x" ]; then
+ TEST_SSH_LOGFILE=$OBJ/ssh.log
+fi
+if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then
+ TEST_SSHD_LOGFILE=$OBJ/sshd.log
+fi
+if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then
+ TEST_REGRESS_LOGFILE=$OBJ/regress.log
+fi
+
+# truncate logfiles
+>$TEST_SSH_LOGFILE
+>$TEST_SSHD_LOGFILE
+>$TEST_REGRESS_LOGFILE
+
+# Create wrapper ssh with logging. We can't just specify "SSH=ssh -E..."
+# because sftp and scp don't handle spaces in arguments.
+SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh
+echo "#!/bin/sh" > $SSHLOGWRAP
+echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP
+
+chmod a+rx $OBJ/ssh-log-wrapper.sh
+SSH="$SSHLOGWRAP"
+
+# Some test data. We make a copy because some tests will overwrite it.
+# The tests may assume that $DATA exists and is writable and $COPY does
+# not exist. Tests requiring larger data files can call increase_datafile_size
+# [kbytes] to ensure the file is at least that large.
+DATANAME=data
+DATA=$OBJ/${DATANAME}
+cat ${SSHAGENT} >${DATA}
+chmod u+w ${DATA}
+COPY=$OBJ/copy
+rm -f ${COPY}
+
+increase_datafile_size()
+{
+ while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do
+ cat ${SSHAGENT} >>${DATA}
+ done
+}
+
+# these should be used in tests
+export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
+#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
+
+# Portable specific functions
+have_prog()
+{
+ saved_IFS="$IFS"
+ IFS=":"
+ for i in $PATH
+ do
+ if [ -x $i/$1 ]; then
+ IFS="$saved_IFS"
+ return 0
+ fi
+ done
+ IFS="$saved_IFS"
+ return 1
+}
+
+jot() {
+ awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }"
+}
+
+# Check whether preprocessor symbols are defined in config.h.
+config_defined ()
+{
+ str=$1
+ while test "x$2" != "x" ; do
+ str="$str|$2"
+ shift
+ done
+ egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1
+}
+
+md5 () {
+ if have_prog md5sum; then
+ md5sum
+ elif have_prog openssl; then
+ openssl md5
+ elif have_prog cksum; then
+ cksum
+ elif have_prog sum; then
+ sum
+ else
+ wc -c
+ fi
+}
+# End of portable specific functions
+
+# helper
+cleanup ()
+{
+ if [ "x$SSH_PID" != "x" ]; then
+ if [ $SSH_PID -lt 2 ]; then
+ echo bad pid for ssh: $SSH_PID
+ else
+ kill $SSH_PID
+ fi
+ fi
+ if [ -f $PIDFILE ]; then
+ pid=`$SUDO cat $PIDFILE`
+ if [ "X$pid" = "X" ]; then
+ echo no sshd running
+ else
+ if [ $pid -lt 2 ]; then
+ echo bad pid for sshd: $pid
+ else
+ $SUDO kill $pid
+ trace "wait for sshd to exit"
+ i=0;
+ while [ -f $PIDFILE -a $i -lt 5 ]; do
+ i=`expr $i + 1`
+ sleep $i
+ done
+ test -f $PIDFILE && \
+ fatal "sshd didn't exit port $PORT pid $pid"
+ fi
+ fi
+ fi
+}
+
+start_debug_log ()
+{
+ echo "trace: $@" >$TEST_REGRESS_LOGFILE
+ echo "trace: $@" >$TEST_SSH_LOGFILE
+ echo "trace: $@" >$TEST_SSHD_LOGFILE
+}
+
+save_debug_log ()
+{
+ echo $@ >>$TEST_REGRESS_LOGFILE
+ echo $@ >>$TEST_SSH_LOGFILE
+ echo $@ >>$TEST_SSHD_LOGFILE
+ (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log
+ (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log
+ (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log
+}
+
+trace ()
+{
+ start_debug_log $@
+ if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then
+ echo "$@"
+ fi
+}
+
+verbose ()
+{
+ start_debug_log $@
+ if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then
+ echo "$@"
+ fi
+}
+
+warn ()
+{
+ echo "WARNING: $@" >>$TEST_SSH_LOGFILE
+ echo "WARNING: $@"
+}
+
+fail ()
+{
+ save_debug_log "FAIL: $@"
+ RESULT=1
+ echo "$@"
+
+}
+
+fatal ()
+{
+ save_debug_log "FATAL: $@"
+ printf "FATAL: "
+ fail "$@"
+ cleanup
+ exit $RESULT
+}
+
+RESULT=0
+PIDFILE=$OBJ/pidfile
+
+trap fatal 3 2
+
+# create server config
+cat << EOF > $OBJ/sshd_config
+ StrictModes no
+ Port $PORT
+ Protocol 2,1
+ AddressFamily inet
+ ListenAddress 127.0.0.1
+ #ListenAddress ::1
+ PidFile $PIDFILE
+ AuthorizedKeysFile $OBJ/authorized_keys_%u
+ LogLevel DEBUG3
+ AcceptEnv _XXX_TEST_*
+ AcceptEnv _XXX_TEST
+ Subsystem sftp $SFTPSERVER
+EOF
+
+if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
+ trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
+ echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
+fi
+
+# server config for proxy connects
+cp $OBJ/sshd_config $OBJ/sshd_proxy
+
+# allow group-writable directories in proxy-mode
+echo 'StrictModes no' >> $OBJ/sshd_proxy
+
+# create client config
+cat << EOF > $OBJ/ssh_config
+Host *
+ Protocol 2,1
+ Hostname 127.0.0.1
+ HostKeyAlias localhost-with-alias
+ Port $PORT
+ User $USER
+ GlobalKnownHostsFile $OBJ/known_hosts
+ UserKnownHostsFile $OBJ/known_hosts
+ RSAAuthentication yes
+ PubkeyAuthentication yes
+ ChallengeResponseAuthentication no
+ HostbasedAuthentication no
+ PasswordAuthentication no
+ RhostsRSAAuthentication no
+ BatchMode yes
+ StrictHostKeyChecking yes
+ LogLevel DEBUG3
+EOF
+
+if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
+ trace "adding ssh_config option $TEST_SSH_SSHD_CONFOPTS"
+ echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
+fi
+
+rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
+
+trace "generate keys"
+for t in rsa rsa1; do
+ # generate user key
+ if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN} -nt $OBJ/$t ]; then
+ rm -f $OBJ/$t
+ ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\
+ fail "ssh-keygen for $t failed"
+ fi
+
+ # known hosts file for client
+ (
+ printf 'localhost-with-alias,127.0.0.1,::1 '
+ cat $OBJ/$t.pub
+ ) >> $OBJ/known_hosts
+
+ # setup authorized keys
+ cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
+ echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
+
+ # use key as host key, too
+ $SUDO cp $OBJ/$t $OBJ/host.$t
+ echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
+
+ # don't use SUDO for proxy connect
+ echo HostKey $OBJ/$t >> $OBJ/sshd_proxy
+done
+chmod 644 $OBJ/authorized_keys_$USER
+
+# Activate Twisted Conch tests if the binary is present
+REGRESS_INTEROP_CONCH=no
+if test -x "$CONCH" ; then
+ REGRESS_INTEROP_CONCH=yes
+fi
+
+# If PuTTY is present and we are running a PuTTY test, prepare keys and
+# configuration
+REGRESS_INTEROP_PUTTY=no
+if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
+ REGRESS_INTEROP_PUTTY=yes
+fi
+case "$SCRIPT" in
+*putty*) ;;
+*) REGRESS_INTEROP_PUTTY=no ;;
+esac
+
+if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
+ mkdir -p ${OBJ}/.putty
+
+ # Add a PuTTY key to authorized_keys
+ rm -f ${OBJ}/putty.rsa2
+ puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
+ puttygen -O public-openssh ${OBJ}/putty.rsa2 \
+ >> $OBJ/authorized_keys_$USER
+
+ # Convert rsa2 host key to PuTTY format
+ ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \
+ ${OBJ}/.putty/sshhostkeys
+ ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \
+ ${OBJ}/.putty/sshhostkeys
+
+ # Setup proxied session
+ mkdir -p ${OBJ}/.putty/sessions
+ rm -f ${OBJ}/.putty/sessions/localhost_proxy
+ echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
+ echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
+ echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
+ echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
+
+ REGRESS_INTEROP_PUTTY=yes
+fi
+
+# create a proxy version of the client config
+(
+ cat $OBJ/ssh_config
+ echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy
+) > $OBJ/ssh_proxy
+
+# check proxy config
+${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken"
+
+start_sshd ()
+{
+ # start sshd
+ $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
+ $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
+
+ trace "wait for sshd"
+ i=0;
+ while [ ! -f $PIDFILE -a $i -lt 10 ]; do
+ i=`expr $i + 1`
+ sleep $i
+ done
+
+ test -f $PIDFILE || fatal "no sshd running on port $PORT"
+}
+
+# source test body
+. $SCRIPT
+
+# kill sshd
+cleanup
+if [ $RESULT -eq 0 ]; then
+ verbose ok $tid
+else
+ echo failed $tid
+fi
+exit $RESULT
diff --git a/crypto/openssh/regress/transfer.sh b/crypto/openssh/regress/transfer.sh
new file mode 100644
index 0000000..1ae3ef5
--- /dev/null
+++ b/crypto/openssh/regress/transfer.sh
@@ -0,0 +1,26 @@
+# $OpenBSD: transfer.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $
+# Placed in the Public Domain.
+
+tid="transfer data"
+
+for p in 1 2; do
+ verbose "$tid: proto $p"
+ rm -f ${COPY}
+ ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY}
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp ${DATA} ${COPY} || fail "corrupted copy"
+
+ for s in 10 100 1k 32k 64k 128k 256k; do
+ trace "proto $p dd-size ${s}"
+ rm -f ${COPY}
+ dd if=$DATA obs=${s} 2> /dev/null | \
+ ${SSH} -q -$p -F $OBJ/ssh_proxy somehost "cat > ${COPY}"
+ if [ $? -ne 0 ]; then
+ fail "ssh cat $DATA failed"
+ fi
+ cmp $DATA ${COPY} || fail "corrupted copy"
+ done
+done
+rm -f ${COPY}
diff --git a/crypto/openssh/regress/try-ciphers.sh b/crypto/openssh/regress/try-ciphers.sh
new file mode 100644
index 0000000..2881ce1
--- /dev/null
+++ b/crypto/openssh/regress/try-ciphers.sh
@@ -0,0 +1,38 @@
+# $OpenBSD: try-ciphers.sh,v 1.23 2014/04/21 22:15:37 djm Exp $
+# Placed in the Public Domain.
+
+tid="try ciphers"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+for c in `${SSH} -Q cipher`; do
+ n=0
+ for m in `${SSH} -Q mac`; do
+ trace "proto 2 cipher $c mac $m"
+ verbose "test $tid: proto 2 cipher $c mac $m"
+ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+ echo "Ciphers=$c" >> $OBJ/sshd_proxy
+ echo "MACs=$m" >> $OBJ/sshd_proxy
+ ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh -2 failed with mac $m cipher $c"
+ fi
+ # No point trying all MACs for AEAD ciphers since they
+ # are ignored.
+ if ssh -Q cipher-auth | grep "^${c}\$" >/dev/null 2>&1 ; then
+ break
+ fi
+ n=`expr $n + 1`
+ done
+done
+
+ciphers="3des blowfish"
+for c in $ciphers; do
+ trace "proto 1 cipher $c"
+ verbose "test $tid: proto 1 cipher $c"
+ ${SSH} -F $OBJ/ssh_proxy -1 -c $c somehost true
+ if [ $? -ne 0 ]; then
+ fail "ssh -1 failed with cipher $c"
+ fi
+done
+
diff --git a/crypto/openssh/regress/unittests/Makefile b/crypto/openssh/regress/unittests/Makefile
new file mode 100644
index 0000000..bdb4574
--- /dev/null
+++ b/crypto/openssh/regress/unittests/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
+
+SUBDIR= test_helper sshbuf sshkey
+
+.include <bsd.subdir.mk>
diff --git a/crypto/openssh/regress/unittests/Makefile.inc b/crypto/openssh/regress/unittests/Makefile.inc
new file mode 100644
index 0000000..4c33637
--- /dev/null
+++ b/crypto/openssh/regress/unittests/Makefile.inc
@@ -0,0 +1,59 @@
+# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $
+
+.include <bsd.own.mk>
+.include <bsd.obj.mk>
+
+# enable warnings
+WARNINGS=Yes
+
+DEBUG=-g
+CFLAGS+= -fstack-protector-all
+CDIAGFLAGS= -Wall
+CDIAGFLAGS+= -Wextra
+CDIAGFLAGS+= -Werror
+CDIAGFLAGS+= -Wchar-subscripts
+CDIAGFLAGS+= -Wcomment
+CDIAGFLAGS+= -Wformat
+CDIAGFLAGS+= -Wformat-security
+CDIAGFLAGS+= -Wimplicit
+CDIAGFLAGS+= -Winline
+CDIAGFLAGS+= -Wmissing-declarations
+CDIAGFLAGS+= -Wmissing-prototypes
+CDIAGFLAGS+= -Wparentheses
+CDIAGFLAGS+= -Wpointer-arith
+CDIAGFLAGS+= -Wpointer-sign
+CDIAGFLAGS+= -Wreturn-type
+CDIAGFLAGS+= -Wshadow
+CDIAGFLAGS+= -Wsign-compare
+CDIAGFLAGS+= -Wstrict-aliasing
+CDIAGFLAGS+= -Wstrict-prototypes
+CDIAGFLAGS+= -Wswitch
+CDIAGFLAGS+= -Wtrigraphs
+CDIAGFLAGS+= -Wuninitialized
+CDIAGFLAGS+= -Wunused
+.if ${COMPILER_VERSION} == "gcc4"
+CDIAGFLAGS+= -Wold-style-definition
+.endif
+
+SSHREL=../../../../../usr.bin/ssh
+
+CFLAGS+=-I${.CURDIR}/../test_helper -I${.CURDIR}/${SSHREL}
+
+.if exists(${.CURDIR}/../test_helper/${__objdir})
+LDADD+=-L${.CURDIR}/../test_helper/${__objdir} -ltest_helper
+DPADD+=${.CURDIR}/../test_helper/${__objdir}/libtest_helper.a
+.else
+LDADD+=-L${.CURDIR}/../test_helper -ltest_helper
+DPADD+=${.CURDIR}/../test_helper/libtest_helper.a
+.endif
+
+.if exists(${.CURDIR}/${SSHREL}/lib/${__objdir})
+LDADD+=-L${.CURDIR}/${SSHREL}/lib/${__objdir} -lssh
+DPADD+=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a
+.else
+LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh
+DPADD+=${.CURDIR}/${SSHREL}/lib/libssh.a
+.endif
+
+LDADD+= -lcrypto
+DPADD+= ${LIBCRYPTO}
diff --git a/crypto/openssh/regress/unittests/sshbuf/Makefile b/crypto/openssh/regress/unittests/sshbuf/Makefile
new file mode 100644
index 0000000..85f99ac
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/Makefile
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
+
+PROG=test_sshbuf
+SRCS=tests.c
+SRCS+=test_sshbuf.c
+SRCS+=test_sshbuf_getput_basic.c
+SRCS+=test_sshbuf_getput_crypto.c
+SRCS+=test_sshbuf_misc.c
+SRCS+=test_sshbuf_fuzz.c
+SRCS+=test_sshbuf_getput_fuzz.c
+SRCS+=test_sshbuf_fixed.c
+
+.include <bsd.regress.mk>
+
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c
new file mode 100644
index 0000000..ee77d69
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf.c
@@ -0,0 +1,240 @@
+/* $OpenBSD: test_sshbuf.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#define SSHBUF_INTERNAL 1 /* access internals for testing */
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "sshbuf.h"
+
+void sshbuf_tests(void);
+
+void
+sshbuf_tests(void)
+{
+ struct sshbuf *p1;
+ const u_char *cdp;
+ u_char *dp;
+ size_t sz;
+ int r;
+
+ TEST_START("allocate sshbuf");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ TEST_DONE();
+
+ TEST_START("max size on fresh buffer");
+ ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0);
+ TEST_DONE();
+
+ TEST_START("available on fresh buffer");
+ ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0);
+ TEST_DONE();
+
+ TEST_START("len = 0 on empty buffer");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ TEST_DONE();
+
+ TEST_START("set valid max size");
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536);
+ TEST_DONE();
+
+ TEST_START("available on limited buffer");
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536);
+ TEST_DONE();
+
+ TEST_START("free");
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("consume on empty buffer");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("consume_end on empty buffer");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0);
+ ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("reserve space");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ r = sshbuf_reserve(p1, 1, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ *dp = 0x11;
+ r = sshbuf_reserve(p1, 3, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ *dp++ = 0x22;
+ *dp++ = 0x33;
+ *dp++ = 0x44;
+ TEST_DONE();
+
+ TEST_START("sshbuf_len on filled buffer");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ TEST_DONE();
+
+ TEST_START("sshbuf_ptr on filled buffer");
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(cdp, NULL);
+ ASSERT_U8_EQ(cdp[0], 0x11);
+ ASSERT_U8_EQ(cdp[1], 0x22);
+ ASSERT_U8_EQ(cdp[2], 0x33);
+ ASSERT_U8_EQ(cdp[3], 0x44);
+ TEST_DONE();
+
+ TEST_START("consume on filled buffer");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ r = sshbuf_consume(p1, 64);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_U8_EQ(cdp[0], 0x22);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_U8_EQ(cdp[0], 0x44);
+ r = sshbuf_consume(p1, 2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ r = sshbuf_consume(p1, 1);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("consume_end on filled buffer");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ r = sshbuf_reserve(p1, 4, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ *dp++ = 0x11;
+ *dp++ = 0x22;
+ *dp++ = 0x33;
+ *dp++ = 0x44;
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ r = sshbuf_consume_end(p1, 5);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(cdp, NULL);
+ ASSERT_U8_EQ(*cdp, 0x11);
+ r = sshbuf_consume_end(p1, 2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("fill limited buffer");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
+ r = sshbuf_reserve(p1, 1223, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ memset(dp, 0xd7, 1223);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
+ r = sshbuf_reserve(p1, 1, &dp);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_PTR_EQ(dp, NULL);
+ TEST_DONE();
+
+ TEST_START("consume and force compaction");
+ ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
+ r = sshbuf_reserve(p1, 224, &dp);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_PTR_EQ(dp, NULL);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223);
+ r = sshbuf_reserve(p1, 223, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ memset(dp, 0x7d, 223);
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(cdp, NULL);
+ ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
+ ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
+ TEST_DONE();
+
+ TEST_START("resize full buffer");
+ r = sshbuf_set_max_size(p1, 1000);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223);
+ ASSERT_INT_EQ(sshbuf_len(p1), 1223);
+ TEST_DONE();
+
+ /* NB. uses sshbuf internals */
+ TEST_START("alloc chunking");
+ r = sshbuf_reserve(p1, 1, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ *dp = 0xff;
+ cdp = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(cdp, NULL);
+ ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000);
+ ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223);
+ ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1);
+ ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("reset buffer");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
+ r = sshbuf_reserve(p1, 1223, &dp);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_PTR_NE(dp, NULL);
+ memset(dp, 0xd7, 1223);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223);
+ sshbuf_reset(p1);
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223);
+ sshbuf_free(p1);
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c
new file mode 100644
index 0000000..df4925f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fixed.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: test_sshbuf_fixed.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#define SSHBUF_INTERNAL 1 /* access internals for testing */
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "sshbuf.h"
+#include "ssherr.h"
+
+void sshbuf_fixed(void);
+
+const u_char test_buf[] = "\x01\x12\x34\x56\x78\x00\x00\x00\x05hello";
+
+void
+sshbuf_fixed(void)
+{
+ struct sshbuf *p1, *p2, *p3;
+ u_char c;
+ char *s;
+ u_int i;
+ size_t l;
+
+ TEST_START("sshbuf_from");
+ p1 = sshbuf_from(test_buf, sizeof(test_buf));
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
+ ASSERT_INT_EQ(sshbuf_check_reserve(p1, 1), SSH_ERR_BUFFER_READ_ONLY);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 1, NULL), SSH_ERR_BUFFER_READ_ONLY);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 200), SSH_ERR_BUFFER_READ_ONLY);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), SSH_ERR_BUFFER_READ_ONLY);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0);
+ ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_from data");
+ p1 = sshbuf_from(test_buf, sizeof(test_buf) - 1);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf);
+ ASSERT_INT_EQ(sshbuf_get_u8(p1, &c), 0);
+ ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 1);
+ ASSERT_U8_EQ(c, 1);
+ ASSERT_INT_EQ(sshbuf_get_u32(p1, &i), 0);
+ ASSERT_PTR_EQ(sshbuf_ptr(p1), test_buf + 5);
+ ASSERT_U32_EQ(i, 0x12345678);
+ ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s, &l), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ ASSERT_STRING_EQ(s, "hello");
+ ASSERT_SIZE_T_EQ(l, 5);
+ sshbuf_free(p1);
+ free(s);
+ TEST_DONE();
+
+ TEST_START("sshbuf_fromb ");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
+ ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, test_buf, sizeof(test_buf) - 1), 0);
+ p2 = sshbuf_fromb(p1);
+ ASSERT_PTR_NE(p2, NULL);
+ ASSERT_U_INT_EQ(sshbuf_refcount(p1), 2);
+ ASSERT_PTR_EQ(sshbuf_parent(p1), NULL);
+ ASSERT_PTR_EQ(sshbuf_parent(p2), p1);
+ ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1));
+ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
+ ASSERT_PTR_NE(sshbuf_ptr(p2), NULL);
+ ASSERT_PTR_EQ(sshbuf_mutable_ptr(p1), NULL);
+ ASSERT_PTR_EQ(sshbuf_mutable_ptr(p2), NULL);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p2));
+ ASSERT_INT_EQ(sshbuf_get_u8(p2, &c), 0);
+ ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 1);
+ ASSERT_U8_EQ(c, 1);
+ ASSERT_INT_EQ(sshbuf_get_u32(p2, &i), 0);
+ ASSERT_PTR_EQ(sshbuf_ptr(p2), sshbuf_ptr(p1) + 5);
+ ASSERT_U32_EQ(i, 0x12345678);
+ ASSERT_INT_EQ(sshbuf_get_cstring(p2, &s, &l), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
+ ASSERT_STRING_EQ(s, "hello");
+ ASSERT_SIZE_T_EQ(l, 5);
+ sshbuf_free(p1);
+ ASSERT_U_INT_EQ(sshbuf_refcount(p1), 1);
+ sshbuf_free(p2);
+ free(s);
+ TEST_DONE();
+
+ TEST_START("sshbuf_froms");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x01), 0);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
+ ASSERT_INT_EQ(sshbuf_put_cstring(p1, "hello"), 0);
+ p2 = sshbuf_new();
+ ASSERT_PTR_NE(p2, NULL);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(test_buf) - 1);
+ ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p2), sizeof(test_buf) + 4 - 1);
+ ASSERT_INT_EQ(sshbuf_froms(p2, &p3), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p2), 0);
+ ASSERT_PTR_NE(p3, NULL);
+ ASSERT_PTR_NE(sshbuf_ptr(p3), NULL);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p3), sizeof(test_buf) - 1);
+ ASSERT_MEM_EQ(sshbuf_ptr(p3), test_buf, sizeof(test_buf) - 1);
+ sshbuf_free(p3);
+ ASSERT_INT_EQ(sshbuf_put_stringb(p2, p1), 0);
+ ASSERT_INT_EQ(sshbuf_consume_end(p2, 1), 0);
+ ASSERT_INT_EQ(sshbuf_froms(p2, &p3), SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_PTR_EQ(p3, NULL);
+ sshbuf_free(p2);
+ sshbuf_free(p1);
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c
new file mode 100644
index 0000000..c52376b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c
@@ -0,0 +1,127 @@
+/* $OpenBSD: test_sshbuf_fuzz.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "sshbuf.h"
+
+#define NUM_FUZZ_TESTS (1 << 18)
+
+void sshbuf_fuzz_tests(void);
+
+void
+sshbuf_fuzz_tests(void)
+{
+ struct sshbuf *p1;
+ u_char *dp;
+ size_t sz, sz2, i;
+ u_int32_t r;
+ int ret;
+
+ /* NB. uses sshbuf internals */
+ TEST_START("fuzz alloc/dealloc");
+ p1 = sshbuf_new();
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
+ ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
+ for (i = 0; i < NUM_FUZZ_TESTS; i++) {
+ r = arc4random_uniform(10);
+ if (r == 0) {
+ /* 10% chance: small reserve */
+ r = arc4random_uniform(10);
+ fuzz_reserve:
+ sz = sshbuf_avail(p1);
+ sz2 = sshbuf_len(p1);
+ ret = sshbuf_reserve(p1, r, &dp);
+ if (ret < 0) {
+ ASSERT_PTR_EQ(dp, NULL);
+ ASSERT_SIZE_T_LT(sz, r);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
+ } else {
+ ASSERT_PTR_NE(dp, NULL);
+ ASSERT_SIZE_T_GE(sz, r);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
+ memset(dp, arc4random_uniform(255) + 1, r);
+ }
+ } else if (r < 3) {
+ /* 20% chance: big reserve */
+ r = arc4random_uniform(8 * 1024);
+ goto fuzz_reserve;
+ } else if (r == 3) {
+ /* 10% chance: small consume */
+ r = arc4random_uniform(10);
+ fuzz_consume:
+ sz = sshbuf_avail(p1);
+ sz2 = sshbuf_len(p1);
+ /* 50% change consume from end, otherwise start */
+ ret = ((arc4random() & 1) ?
+ sshbuf_consume : sshbuf_consume_end)(p1, r);
+ if (ret < 0) {
+ ASSERT_SIZE_T_LT(sz2, r);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
+ } else {
+ ASSERT_SIZE_T_GE(sz2, r);
+ ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
+ }
+ } else if (r < 8) {
+ /* 40% chance: big consume */
+ r = arc4random_uniform(2 * 1024);
+ goto fuzz_consume;
+ } else if (r == 8) {
+ /* 10% chance: reset max size */
+ r = arc4random_uniform(16 * 1024);
+ sz = sshbuf_max_size(p1);
+ if (sshbuf_set_max_size(p1, r) < 0)
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
+ else
+ ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
+ } else {
+ if (arc4random_uniform(8192) == 0) {
+ /* tiny chance: new buffer */
+ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
+ ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
+ sshbuf_free(p1);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1,
+ 16 * 1024), 0);
+ } else {
+ /* Almost 10%: giant reserve */
+ /* use arc4random_buf for r > 2^32 on 64 bit */
+ arc4random_buf(&r, sizeof(r));
+ while (r < SSHBUF_SIZE_MAX / 2) {
+ r <<= 1;
+ r |= arc4random() & 1;
+ }
+ goto fuzz_reserve;
+ }
+ }
+ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
+ ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
+ }
+ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
+ ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
+ sshbuf_free(p1);
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
new file mode 100644
index 0000000..966e843
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_basic.c
@@ -0,0 +1,484 @@
+/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+
+void sshbuf_getput_basic_tests(void);
+
+void
+sshbuf_getput_basic_tests(void)
+{
+ struct sshbuf *p1, *p2;
+ const u_char *cd;
+ u_char *d, d2[32], x[] = {
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99
+ };
+ u_int64_t v64;
+ u_int32_t v32;
+ u_int16_t v16;
+ u_char v8;
+ size_t s;
+ char *s2;
+ int r;
+ u_char bn1[] = { 0x00, 0x00, 0x00 };
+ u_char bn2[] = { 0x00, 0x00, 0x01, 0x02 };
+ u_char bn3[] = { 0x00, 0x80, 0x09 };
+ u_char bn_exp1[] = { 0x00, 0x00, 0x00, 0x00 };
+ u_char bn_exp2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 0x02 };
+ u_char bn_exp3[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x09 };
+
+ TEST_START("PEEK_U64");
+ ASSERT_U64_EQ(PEEK_U64(x), 0x1122334455667788ULL);
+ TEST_DONE();
+
+ TEST_START("PEEK_U32");
+ ASSERT_U32_EQ(PEEK_U32(x), 0x11223344);
+ TEST_DONE();
+
+ TEST_START("PEEK_U16");
+ ASSERT_U16_EQ(PEEK_U16(x), 0x1122);
+ TEST_DONE();
+
+ TEST_START("POKE_U64");
+ bzero(d2, sizeof(d2));
+ POKE_U64(d2, 0x1122334455667788ULL);
+ ASSERT_MEM_EQ(d2, x, 8);
+ TEST_DONE();
+
+ TEST_START("POKE_U32");
+ bzero(d2, sizeof(d2));
+ POKE_U32(d2, 0x11223344);
+ ASSERT_MEM_EQ(d2, x, 4);
+ TEST_DONE();
+
+ TEST_START("POKE_U16");
+ bzero(d2, sizeof(d2));
+ POKE_U16(d2, 0x1122);
+ ASSERT_MEM_EQ(d2, x, 2);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, 5), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
+ cd = sshbuf_ptr(p1);
+ ASSERT_PTR_NE(cd, NULL);
+ ASSERT_U8_EQ(cd[0], 0x11);
+ ASSERT_U8_EQ(cd[1], 0x22);
+ ASSERT_U8_EQ(cd[2], 0x33);
+ ASSERT_U8_EQ(cd[3], 0x44);
+ ASSERT_U8_EQ(cd[4], 0x55);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get");
+ ASSERT_INT_EQ(sshbuf_get(p1, d2, 4), 0);
+ ASSERT_MEM_EQ(d2, x, 4);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get truncated");
+ r = sshbuf_get(p1, d2, 4);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ ASSERT_U8_EQ(*(sshbuf_ptr(p1)), 0x55);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put truncated");
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
+ r = sshbuf_put(p1, x, 5);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u64");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
+ ASSERT_INT_EQ(sshbuf_get_u64(p1, &v64), 0);
+ ASSERT_U64_EQ(v64, 0x1122334455667788ULL);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u64 truncated");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ r = sshbuf_get_u64(p1, &v64);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u32");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, 10), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 10);
+ ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
+ ASSERT_U32_EQ(v32, 0x11223344);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6);
+ ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0);
+ ASSERT_U32_EQ(v32, 0x55667788);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u32 truncated");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ r = sshbuf_get_u32(p1, &v32);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, 9), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 9);
+ ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x1122);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7);
+ ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x3344);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5);
+ ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x5566);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3);
+ ASSERT_INT_EQ(sshbuf_get_u16(p1, &v16), 0);
+ ASSERT_U16_EQ(v16, 0x7788);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u16 truncated");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ r = sshbuf_get_u16(p1, &v16);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u8");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, 2), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
+ ASSERT_U8_EQ(v8, 0x11);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ ASSERT_INT_EQ(sshbuf_get_u8(p1, &v8), 0);
+ ASSERT_U8_EQ(v8, 0x22);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_u8 truncated");
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ r = sshbuf_get_u8(p1, &v8);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u64");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u64 exact");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 8), 0);
+ ASSERT_INT_EQ(sshbuf_put_u64(p1, 0x1122334455667788ULL), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 8);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 8);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u64 limited");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 7), 0);
+ r = sshbuf_put_u64(p1, 0x1122334455667788ULL);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u32");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u32 exact");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 4), 0);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x11223344), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 4);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u32 limited");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 3), 0);
+ r = sshbuf_put_u32(p1, 0x11223344);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 2), 0);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0x1122), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), x, 2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_u16 limited");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1), 0);
+ r = sshbuf_put_u16(p1, 0x1122);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_string");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 + 4);
+ ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
+ ASSERT_SIZE_T_EQ(s, sizeof(x));
+ ASSERT_MEM_EQ(d, x, sizeof(x));
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ free(d);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_string exact");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4), 0);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ ASSERT_INT_EQ(sshbuf_get_string(p1, &d, &s), 0);
+ ASSERT_SIZE_T_EQ(s, sizeof(x));
+ ASSERT_MEM_EQ(d, x, sizeof(x));
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ free(d);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_string truncated");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
+ r = sshbuf_get_string(p1, &d, &s);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 3);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_string giant");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ r = sshbuf_get_string(p1, &d, &s);
+ ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_cstring giant");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xffffffff), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ r = sshbuf_get_cstring(p1, &s2, &s);
+ ASSERT_INT_EQ(r, SSH_ERR_STRING_TOO_LARGE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_cstring embedded \\0");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ r = sshbuf_get_cstring(p1, &s2, NULL);
+ ASSERT_INT_EQ(r, SSH_ERR_INVALID_FORMAT);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_cstring trailing \\0");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, sizeof(x) - 1), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, x, sizeof(x) - 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4 - 1);
+ ASSERT_INT_EQ(sshbuf_get_cstring(p1, &s2, &s), 0);
+ ASSERT_SIZE_T_EQ(s, sizeof(x) - 1);
+ ASSERT_MEM_EQ(s2, x, s);
+ free(s2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_string");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_string(p1, x, sizeof(x)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(x) + 4);
+ ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), sizeof(x));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, x, sizeof(x));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_string limited");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(x) + 4 - 1), 0);
+ r = sshbuf_put_string(p1, x, sizeof(x));
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_string giant");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ r = sshbuf_put_string(p1, (void *)0x01, 0xfffffffc);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_putf");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ r = sshbuf_putf(p1, "%s %d %x", "hello", 23, 0x5f);
+ ASSERT_INT_EQ(r, 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), "hello 23 5f", 11);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_putb");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ p2 = sshbuf_new();
+ ASSERT_PTR_NE(p2, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, "blahblahblah", 12), 0);
+ ASSERT_INT_EQ(sshbuf_putb(p2, p1), 0);
+ sshbuf_free(p1);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p2), 12);
+ ASSERT_MEM_EQ(sshbuf_ptr(p2), "blahblahblah", 12);
+ sshbuf_free(p2);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes empty buf");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, NULL, 0), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes all zeroes");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn1, sizeof(bn1)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp1));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp1, sizeof(bn_exp1));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes simple");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2+2, sizeof(bn2)-2), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes leading zero");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn2, sizeof(bn2)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp2));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp2, sizeof(bn_exp2));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes neg");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3+1, sizeof(bn3)-1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2_bytes neg and leading zero");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2_bytes(p1, bn3, sizeof(bn3)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(bn_exp3));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1), bn_exp3, sizeof(bn_exp3));
+ sshbuf_free(p1);
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
new file mode 100644
index 0000000..0c4c71e
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c
@@ -0,0 +1,409 @@
+/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+
+void sshbuf_getput_crypto_tests(void);
+
+void
+sshbuf_getput_crypto_tests(void)
+{
+ struct sshbuf *p1;
+ const u_char *d;
+ size_t s;
+ BIGNUM *bn, *bn2;
+ /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */
+ const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10";
+ /* This one has MSB set to test bignum2 encoding negative-avoidance */
+ const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11";
+ u_char expbn1[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ };
+ u_char expbn2[] = {
+ 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
+ 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
+ 0x7f, 0xff, 0x11
+ };
+#ifdef OPENSSL_HAS_NISTP256
+ BIGNUM *bn_x, *bn_y;
+ int ec256_nid = NID_X9_62_prime256v1;
+ char *ec256_x = "0C828004839D0106AA59575216191357"
+ "34B451459DADB586677EF9DF55784999";
+ char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2"
+ "C8F9A35E42BDD047550F69D80EC23CD4";
+ u_char expec256[] = {
+ 0x04,
+ 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
+ 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
+ 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
+ 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
+ 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
+ 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
+ 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
+ 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4
+ };
+ EC_KEY *eck;
+ EC_POINT *ecp;
+#endif
+ int r;
+
+#define MKBN(b, bnn) \
+ do { \
+ bnn = NULL; \
+ ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \
+ } while (0)
+
+ TEST_START("sshbuf_put_bignum1");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2);
+ ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1));
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum1 limited");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
+ r = sshbuf_put_bignum1(p1, bn);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum1 bn2");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2);
+ ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2));
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum1 bn2 limited");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0);
+ r = sshbuf_put_bignum1(p1, bn);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4);
+ ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn));
+ ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1));
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2 limited");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0);
+ r = sshbuf_put_bignum2(p1, bn);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2 bn2");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */
+ ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1);
+ ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00);
+ ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2));
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_put_bignum2 bn2 limited");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0);
+ r = sshbuf_put_bignum2(p1, bn);
+ ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0);
+ BN_free(bn);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum1");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1));
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
+ bn2 = BN_new();
+ ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
+ ASSERT_BIGNUM_EQ(bn, bn2);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum1 truncated");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum1(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum1 giant");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
+ bn2 = BN_new();
+ r = sshbuf_get_bignum1(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8));
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum1 bn2");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2));
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
+ bn2 = BN_new();
+ ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0);
+ ASSERT_BIGNUM_EQ(bn, bn2);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum1 bn2 truncated");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum1(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1));
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
+ bn2 = BN_new();
+ ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
+ ASSERT_BIGNUM_EQ(bn, bn2);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2 truncated");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum2(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2 giant");
+ MKBN(hexbn1, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum2(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2 bn2");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2));
+ ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0);
+ bn2 = BN_new();
+ ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0);
+ ASSERT_BIGNUM_EQ(bn, bn2);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2 bn2 truncated");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum2(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_bignum2 bn2 negative");
+ MKBN(hexbn2, bn);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0);
+ ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0);
+ bn2 = BN_new();
+ r = sshbuf_get_bignum2(p1, bn2);
+ ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4);
+ BN_free(bn);
+ BN_free(bn2);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_NISTP256
+ TEST_START("sshbuf_put_ec");
+ eck = EC_KEY_new_by_curve_name(ec256_nid);
+ ASSERT_PTR_NE(eck, NULL);
+ ecp = EC_POINT_new(EC_KEY_get0_group(eck));
+ ASSERT_PTR_NE(ecp, NULL);
+ MKBN(ec256_x, bn_x);
+ MKBN(ec256_y, bn_y);
+ ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp(
+ EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1);
+ ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1);
+ BN_free(bn_x);
+ BN_free(bn_y);
+ EC_POINT_free(ecp);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0);
+ ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0);
+ ASSERT_SIZE_T_EQ(s, sizeof(expec256));
+ ASSERT_MEM_EQ(d, expec256, sizeof(expec256));
+ sshbuf_free(p1);
+ EC_KEY_free(eck);
+ TEST_DONE();
+
+ TEST_START("sshbuf_get_ec");
+ eck = EC_KEY_new_by_curve_name(ec256_nid);
+ ASSERT_PTR_NE(eck, NULL);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0);
+ ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0);
+ bn_x = BN_new();
+ bn_y = BN_new();
+ ASSERT_PTR_NE(bn_x, NULL);
+ ASSERT_PTR_NE(bn_y, NULL);
+ ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp(
+ EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck),
+ bn_x, bn_y, NULL), 1);
+ MKBN(ec256_x, bn);
+ MKBN(ec256_y, bn2);
+ ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0);
+ ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ sshbuf_free(p1);
+ EC_KEY_free(eck);
+ BN_free(bn_x);
+ BN_free(bn_y);
+ BN_free(bn);
+ BN_free(bn2);
+ TEST_DONE();
+#endif
+}
+
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
new file mode 100644
index 0000000..8c3269b
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c
@@ -0,0 +1,130 @@
+/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+
+void sshbuf_getput_fuzz_tests(void);
+
+static void
+attempt_parse_blob(u_char *blob, size_t len)
+{
+ struct sshbuf *p1;
+ BIGNUM *bn;
+#ifdef OPENSSL_HAS_NISTP256
+ EC_KEY *eck;
+#endif
+ u_char *s;
+ size_t l;
+ u_int8_t u8;
+ u_int16_t u16;
+ u_int32_t u32;
+ u_int64_t u64;
+
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
+ sshbuf_get_u8(p1, &u8);
+ sshbuf_get_u16(p1, &u16);
+ sshbuf_get_u32(p1, &u32);
+ sshbuf_get_u64(p1, &u64);
+ if (sshbuf_get_string(p1, &s, &l) == 0) {
+ bzero(s, l);
+ free(s);
+ }
+ bn = BN_new();
+ sshbuf_get_bignum1(p1, bn);
+ BN_clear_free(bn);
+ bn = BN_new();
+ sshbuf_get_bignum2(p1, bn);
+ BN_clear_free(bn);
+#ifdef OPENSSL_HAS_NISTP256
+ eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ ASSERT_PTR_NE(eck, NULL);
+ sshbuf_get_eckey(p1, eck);
+ EC_KEY_free(eck);
+#endif
+ sshbuf_free(p1);
+}
+
+
+static void
+onerror(void *fuzz)
+{
+ fprintf(stderr, "Failed during fuzz:\n");
+ fuzz_dump((struct fuzz *)fuzz);
+}
+
+void
+sshbuf_getput_fuzz_tests(void)
+{
+ u_char blob[] = {
+ /* u8 */
+ 0xd0,
+ /* u16 */
+ 0xc0, 0xde,
+ /* u32 */
+ 0xfa, 0xce, 0xde, 0xad,
+ /* u64 */
+ 0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
+ /* string */
+ 0x00, 0x00, 0x00, 0x09,
+ 'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
+ /* bignum1 */
+ 0x79,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ /* bignum2 */
+ 0x00, 0x00, 0x00, 0x14,
+ 0x00,
+ 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
+ 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
+ 0x7f, 0xff, 0x11,
+ /* EC point (NIST-256 curve) */
+ 0x00, 0x00, 0x00, 0x41,
+ 0x04,
+ 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
+ 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
+ 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
+ 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
+ 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
+ 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
+ 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
+ 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
+ };
+ struct fuzz *fuzz;
+
+ TEST_START("fuzz blob parsing");
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
+ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz))
+ attempt_parse_blob(blob, sizeof(blob));
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+ TEST_ONERROR(NULL, NULL);
+}
+
diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c
new file mode 100644
index 0000000..f155491
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_misc.c
@@ -0,0 +1,138 @@
+/* $OpenBSD: test_sshbuf_misc.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "sshbuf.h"
+
+void sshbuf_misc_tests(void);
+
+void
+sshbuf_misc_tests(void)
+{
+ struct sshbuf *p1;
+ char tmp[512], *p;
+ FILE *out;
+ size_t sz;
+
+ TEST_START("sshbuf_dump");
+ out = tmpfile();
+ ASSERT_PTR_NE(out, NULL);
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
+ sshbuf_dump(p1, out);
+ fflush(out);
+ rewind(out);
+ sz = fread(tmp, 1, sizeof(tmp), out);
+ ASSERT_INT_EQ(ferror(out), 0);
+ ASSERT_INT_NE(feof(out), 0);
+ ASSERT_SIZE_T_GT(sz, 0);
+ tmp[sz] = '\0';
+ ASSERT_PTR_NE(strstr(tmp, "12 34 56 78"), NULL);
+ fclose(out);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_dtob16");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x12345678), 0);
+ p = sshbuf_dtob16(p1);
+ ASSERT_PTR_NE(p, NULL);
+ ASSERT_STRING_EQ(p, "12345678");
+ free(p);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_dtob64 len 1");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
+ p = sshbuf_dtob64(p1);
+ ASSERT_PTR_NE(p, NULL);
+ ASSERT_STRING_EQ(p, "EQ==");
+ free(p);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_dtob64 len 2");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
+ p = sshbuf_dtob64(p1);
+ ASSERT_PTR_NE(p, NULL);
+ ASSERT_STRING_EQ(p, "ESI=");
+ free(p);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_dtob64 len 3");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x11), 0);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x22), 0);
+ ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x33), 0);
+ p = sshbuf_dtob64(p1);
+ ASSERT_PTR_NE(p, NULL);
+ ASSERT_STRING_EQ(p, "ESIz");
+ free(p);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_dtob64 len 8191");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_reserve(p1, 8192, NULL), 0);
+ bzero(sshbuf_mutable_ptr(p1), 8192);
+ p = sshbuf_dtob64(p1);
+ ASSERT_PTR_NE(p, NULL);
+ ASSERT_SIZE_T_EQ(strlen(p), ((8191 + 2) / 3) * 4);
+ free(p);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_b64tod len 1");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A=="), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1);
+ ASSERT_U8_EQ(*sshbuf_ptr(p1), 0xd0);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_b64tod len 2");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A8="), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2);
+ ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), 0xd00f);
+ sshbuf_free(p1);
+ TEST_DONE();
+
+ TEST_START("sshbuf_b64tod len 4");
+ p1 = sshbuf_new();
+ ASSERT_PTR_NE(p1, NULL);
+ ASSERT_INT_EQ(sshbuf_b64tod(p1, "0A/QDw=="), 0);
+ ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4);
+ ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f);
+ sshbuf_free(p1);
+ TEST_DONE();
+}
+
diff --git a/crypto/openssh/regress/unittests/sshbuf/tests.c b/crypto/openssh/regress/unittests/sshbuf/tests.c
new file mode 100644
index 0000000..1557e43
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshbuf/tests.c
@@ -0,0 +1,28 @@
+/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "../test_helper/test_helper.h"
+
+void sshbuf_tests(void);
+void sshbuf_getput_basic_tests(void);
+void sshbuf_getput_crypto_tests(void);
+void sshbuf_misc_tests(void);
+void sshbuf_fuzz_tests(void);
+void sshbuf_getput_fuzz_tests(void);
+void sshbuf_fixed(void);
+
+void
+tests(void)
+{
+ sshbuf_tests();
+ sshbuf_getput_basic_tests();
+ sshbuf_getput_crypto_tests();
+ sshbuf_misc_tests();
+ sshbuf_fuzz_tests();
+ sshbuf_getput_fuzz_tests();
+ sshbuf_fixed();
+}
diff --git a/crypto/openssh/regress/unittests/sshkey/Makefile b/crypto/openssh/regress/unittests/sshkey/Makefile
new file mode 100644
index 0000000..1bcd266
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/Makefile
@@ -0,0 +1,13 @@
+# $OpenBSD: Makefile,v 1.1 2014/06/24 01:14:18 djm Exp $
+
+TEST_ENV= "MALLOC_OPTIONS=AFGJPRX"
+
+PROG=test_sshkey
+SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c
+REGRESS_TARGETS=run-regress-${PROG}
+
+run-regress-${PROG}: ${PROG}
+ env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
+
+.include <bsd.regress.mk>
+
diff --git a/crypto/openssh/regress/unittests/sshkey/common.c b/crypto/openssh/regress/unittests/sshkey/common.c
new file mode 100644
index 0000000..0a4b3a9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/common.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Helpers for key API tests
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+struct sshbuf *
+load_file(const char *name)
+{
+ int fd;
+ struct sshbuf *ret;
+
+ ASSERT_PTR_NE(ret = sshbuf_new(), NULL);
+ ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1);
+ ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0);
+ close(fd);
+ return ret;
+}
+
+struct sshbuf *
+load_text_file(const char *name)
+{
+ struct sshbuf *ret = load_file(name);
+ const u_char *p;
+
+ /* Trim whitespace at EOL */
+ for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) {
+ if (p[sshbuf_len(ret) - 1] == '\r' ||
+ p[sshbuf_len(ret) - 1] == '\t' ||
+ p[sshbuf_len(ret) - 1] == ' ' ||
+ p[sshbuf_len(ret) - 1] == '\n')
+ ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0);
+ else
+ break;
+ }
+ /* \0 terminate */
+ ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0);
+ return ret;
+}
+
+BIGNUM *
+load_bignum(const char *name)
+{
+ BIGNUM *ret = NULL;
+ struct sshbuf *buf;
+
+ buf = load_text_file(name);
+ ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0);
+ sshbuf_free(buf);
+ return ret;
+}
+
diff --git a/crypto/openssh/regress/unittests/sshkey/common.h b/crypto/openssh/regress/unittests/sshkey/common.h
new file mode 100644
index 0000000..bf7d19d
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/common.h
@@ -0,0 +1,16 @@
+/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Helpers for key API tests
+ *
+ * Placed in the public domain
+ */
+
+/* Load a binary file into a buffer */
+struct sshbuf *load_file(const char *name);
+
+/* Load a text file into a buffer */
+struct sshbuf *load_text_file(const char *name);
+
+/* Load a bignum from a file */
+BIGNUM *load_bignum(const char *name);
+
diff --git a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
new file mode 100755
index 0000000..ee1fe39
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh
@@ -0,0 +1,190 @@
+#!/bin/sh
+# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $
+
+PW=mekmitasdigoat
+
+rsa1_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ ssh-keygen -f $_in -e -m pkcs8 | \
+ openssl rsa -noout -text -pubin | \
+ awk '/^Modulus:$/,/^Exponent:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
+ # XXX need conversion support in ssh-keygen for the other params
+ for x in n ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+rsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl rsa -noout -text -in $_in | \
+ awk '/^modulus:$/,/^publicExponent:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
+ openssl rsa -noout -text -in $_in | \
+ awk '/^prime1:$/,/^prime2:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.p
+ openssl rsa -noout -text -in $_in | \
+ awk '/^prime2:$/,/^exponent1:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.q
+ for x in n p q ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+dsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl dsa -noout -text -in $_in | \
+ awk '/^priv:$/,/^pub:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
+ openssl dsa -noout -text -in $_in | \
+ awk '/^pub:/,/^P:/' | #\
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
+ openssl dsa -noout -text -in $_in | \
+ awk '/^G:/,0' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g
+ for x in priv pub g ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+ecdsa_params() {
+ _in="$1"
+ _outbase="$2"
+ set -e
+ openssl ec -noout -text -in $_in | \
+ awk '/^priv:$/,/^pub:/' | \
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv
+ openssl ec -noout -text -in $_in | \
+ awk '/^pub:/,/^ASN1 OID:/' | #\
+ grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub
+ openssl ec -noout -text -in $_in | \
+ grep "ASN1 OID:" | tr -d '\n' | \
+ sed 's/.*: //;s/ *$//' > ${_outbase}.curve
+ for x in priv pub curve ; do
+ echo "" >> ${_outbase}.$x
+ echo ============ ${_outbase}.$x
+ cat ${_outbase}.$x
+ echo ============
+ done
+}
+
+set -ex
+
+cd testdata
+
+rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1
+rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2
+rm -f rsa_n dsa_n ecdsa_n # new-format keys
+rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw
+rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw
+rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb
+
+ssh-keygen -t rsa1 -b 768 -C "RSA1 test key #1" -N "" -f rsa1_1
+ssh-keygen -t rsa -b 768 -C "RSA test key #1" -N "" -f rsa_1
+ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1
+ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1
+ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1
+
+ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2
+ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2
+ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2
+ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2
+ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_2
+
+cp rsa_1 rsa_n
+cp dsa_1 dsa_n
+cp ecdsa_1 ecdsa_n
+
+cp rsa1_1 rsa1_1_pw
+cp rsa_1 rsa_1_pw
+cp dsa_1 dsa_1_pw
+cp ecdsa_1 ecdsa_1_pw
+cp ed25519_1 ed25519_1_pw
+cp rsa_1 rsa_n_pw
+cp dsa_1 dsa_n_pw
+cp ecdsa_1 ecdsa_n_pw
+
+ssh-keygen -pf rsa1_1_pw -N "$PW"
+ssh-keygen -pf rsa_1_pw -N "$PW"
+ssh-keygen -pf dsa_1_pw -N "$PW"
+ssh-keygen -pf ecdsa_1_pw -N "$PW"
+ssh-keygen -pf ed25519_1_pw -N "$PW"
+ssh-keygen -opf rsa_n_pw -N "$PW"
+ssh-keygen -opf dsa_n_pw -N "$PW"
+ssh-keygen -opf ecdsa_n_pw -N "$PW"
+
+rsa1_params rsa1_1 rsa1_1.param
+rsa1_params rsa1_2 rsa1_2.param
+rsa_params rsa_1 rsa_1.param
+rsa_params rsa_2 rsa_2.param
+dsa_params dsa_1 dsa_1.param
+dsa_params dsa_1 dsa_1.param
+ecdsa_params ecdsa_1 ecdsa_1.param
+ecdsa_params ecdsa_2 ecdsa_2.param
+# XXX ed25519 params
+
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 1 rsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 2 dsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 3 ecdsa_1.pub
+ssh-keygen -s rsa_2 -I hugo -n user1,user2 \
+ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \
+ -V 19990101:20110101 -z 4 ed25519_1.pub
+
+ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 5 rsa_1.pub
+ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 6 dsa_1.pub
+ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 7 ecdsa_1.pub
+ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
+ -V 19990101:20110101 -z 8 ed25519_1.pub
+
+ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp
+ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp
+ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp
+ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp
+ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp
+ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp
+ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp
+ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp
+ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp
+ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp
+
+ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp
+ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp
+ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp
+ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp
+
+ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb
+ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb
+ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb
+ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb
+ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb
+ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb
+ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb
+ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
+ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
+ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
+
+echo "$PW" > pw
diff --git a/crypto/openssh/regress/unittests/sshkey/test_file.c b/crypto/openssh/regress/unittests/sshkey/test_file.c
new file mode 100644
index 0000000..764f7fb
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/test_file.c
@@ -0,0 +1,457 @@
+/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshkey.h key management API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+void sshkey_file_tests(void);
+
+void
+sshkey_file_tests(void)
+{
+ struct sshkey *k1, *k2;
+ struct sshbuf *buf, *pw;
+ BIGNUM *a, *b, *c;
+ char *cp;
+
+ TEST_START("load passphrase");
+ pw = load_text_file("pw");
+ TEST_DONE();
+
+ TEST_START("parse RSA1 from private");
+ buf = load_file("rsa1_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("rsa1_1.param.n");
+ ASSERT_BIGNUM_EQ(k1->rsa->n, a);
+ BN_free(a);
+ TEST_DONE();
+
+ TEST_START("parse RSA1 from private w/ passphrase");
+ buf = load_file("rsa1_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA1 from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("RSA1 key hex fingerprint");
+ buf = load_text_file("rsa1_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("RSA1 key bubblebabble fingerprint");
+ buf = load_text_file("rsa1_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse RSA from private");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("rsa_1.param.n");
+ b = load_bignum("rsa_1.param.p");
+ c = load_bignum("rsa_1.param.q");
+ ASSERT_BIGNUM_EQ(k1->rsa->n, a);
+ ASSERT_BIGNUM_EQ(k1->rsa->p, b);
+ ASSERT_BIGNUM_EQ(k1->rsa->q, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse RSA from private w/ passphrase");
+ buf = load_file("rsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse RSA from new-format");
+ buf = load_file("rsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "rsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse RSA from new-format w/ passphrase");
+ buf = load_file("rsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load RSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_RSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("RSA key hex fingerprint");
+ buf = load_text_file("rsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("RSA cert hex fingerprint");
+ buf = load_text_file("rsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("RSA key bubblebabble fingerprint");
+ buf = load_text_file("rsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ TEST_START("parse DSA from private");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ a = load_bignum("dsa_1.param.g");
+ b = load_bignum("dsa_1.param.priv");
+ c = load_bignum("dsa_1.param.pub");
+ ASSERT_BIGNUM_EQ(k1->dsa->g, a);
+ ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
+ ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse DSA from private w/ passphrase");
+ buf = load_file("dsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse DSA from new-format");
+ buf = load_file("dsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "dsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse DSA from new-format w/ passphrase");
+ buf = load_file("dsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load DSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load DSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_DSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("DSA key hex fingerprint");
+ buf = load_text_file("dsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("DSA cert hex fingerprint");
+ buf = load_text_file("dsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("DSA key bubblebabble fingerprint");
+ buf = load_text_file("dsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("parse ECDSA from private");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ buf = load_text_file("ecdsa_1.param.curve");
+ ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf),
+ OBJ_nid2sn(k1->ecdsa_nid));
+ sshbuf_free(buf);
+ a = load_bignum("ecdsa_1.param.priv");
+ b = load_bignum("ecdsa_1.param.pub");
+ c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa),
+ EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED,
+ NULL, NULL);
+ ASSERT_PTR_NE(c, NULL);
+ ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a);
+ ASSERT_BIGNUM_EQ(b, c);
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from private w/ passphrase");
+ buf = load_file("ecdsa_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from new-format");
+ buf = load_file("ecdsa_n");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ "", "ecdsa_n", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("parse ECDSA from new-format w/ passphrase");
+ buf = load_file("ecdsa_n_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load ECDSA from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load ECDSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("ECDSA key hex fingerprint");
+ buf = load_text_file("ecdsa_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("ECDSA cert hex fingerprint");
+ buf = load_text_file("ecdsa_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("ECDSA key bubblebabble fingerprint");
+ buf = load_text_file("ecdsa_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+#endif /* OPENSSL_HAS_ECC */
+
+ TEST_START("parse Ed25519 from private");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_INT_EQ(k1->type, KEY_ED25519);
+ /* XXX check key contents */
+ TEST_DONE();
+
+ TEST_START("parse Ed25519 from private w/ passphrase");
+ buf = load_file("ed25519_1_pw");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
+ (const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load Ed25519 from public");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2,
+ NULL), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("load Ed25519 cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0);
+ ASSERT_PTR_NE(k2, NULL);
+ ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT);
+ ASSERT_INT_EQ(sshkey_equal(k1, k2), 0);
+ ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
+ TEST_DONE();
+
+ TEST_START("Ed25519 key hex fingerprint");
+ buf = load_text_file("ed25519_1.fp");
+ cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ TEST_START("Ed25519 cert hex fingerprint");
+ buf = load_text_file("ed25519_1-cert.fp");
+ cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("Ed25519 key bubblebabble fingerprint");
+ buf = load_text_file("ed25519_1.fp.bb");
+ cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE);
+ ASSERT_PTR_NE(cp, NULL);
+ ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
+ sshbuf_free(buf);
+ free(cp);
+ TEST_DONE();
+
+ sshkey_free(k1);
+
+ sshbuf_free(pw);
+
+}
diff --git a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
new file mode 100644
index 0000000..a3f61a6
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c
@@ -0,0 +1,406 @@
+/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Fuzz tests for key parsing
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "authfile.h"
+#include "sshkey.h"
+#include "sshbuf.h"
+
+#include "common.h"
+
+void sshkey_fuzz_tests(void);
+
+static void
+onerror(void *fuzz)
+{
+ fprintf(stderr, "Failed during fuzz:\n");
+ fuzz_dump((struct fuzz *)fuzz);
+}
+
+static void
+public_fuzz(struct sshkey *k)
+{
+ struct sshkey *k1;
+ struct sshbuf *buf;
+ struct fuzz *fuzz;
+
+ ASSERT_PTR_NE(buf = sshbuf_new(), NULL);
+ ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0);
+ /* XXX need a way to run the tests in "slow, but complete" mode */
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */
+ FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf),
+ &k1), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0)
+ sshkey_free(k1);
+ }
+ fuzz_cleanup(fuzz);
+}
+
+static void
+sig_fuzz(struct sshkey *k)
+{
+ struct fuzz *fuzz;
+ u_char *sig, c[] = "some junk to be signed";
+ size_t l;
+
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0);
+ ASSERT_SIZE_T_GT(l, 0);
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */
+ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0);
+ free(sig);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz),
+ c, sizeof(c), 0);
+ }
+ fuzz_cleanup(fuzz);
+}
+
+void
+sshkey_fuzz_tests(void)
+{
+ struct sshkey *k1;
+ struct sshbuf *buf, *fuzzed;
+ struct fuzz *fuzz;
+ int r;
+
+ TEST_START("fuzz RSA1 private");
+ buf = load_file("rsa1_1");
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA1 public");
+ buf = load_file("rsa1_1_pw");
+ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
+ FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
+ sshbuf_mutable_ptr(buf), sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA private");
+ buf = load_file("rsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA new-format private");
+ buf = load_file("rsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA private");
+ buf = load_file("dsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA new-format private");
+ buf = load_file("dsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("fuzz ECDSA private");
+ buf = load_file("ecdsa_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA new-format private");
+ buf = load_file("ecdsa_n");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+#endif
+
+ TEST_START("fuzz Ed25519 private");
+ buf = load_file("ed25519_1");
+ fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf),
+ sshbuf_len(buf));
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshkey_free(k1);
+ sshbuf_free(buf);
+ ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
+ TEST_ONERROR(onerror, fuzz);
+ for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
+ r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
+ ASSERT_INT_EQ(r, 0);
+ if (sshkey_parse_private_fileblob(fuzzed, "", "key",
+ &k1, NULL) == 0)
+ sshkey_free(k1);
+ sshbuf_reset(fuzzed);
+ }
+ sshbuf_free(fuzzed);
+ fuzz_cleanup(fuzz);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA public");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA public");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("fuzz ECDSA public");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz ECDSA cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+#endif
+
+ TEST_START("fuzz Ed25519 public");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz Ed25519 cert");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0);
+ public_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz RSA sig");
+ buf = load_file("rsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("fuzz DSA sig");
+ buf = load_file("dsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("fuzz ECDSA sig");
+ buf = load_file("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+#endif
+
+ TEST_START("fuzz Ed25519 sig");
+ buf = load_file("ed25519_1");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key",
+ &k1, NULL), 0);
+ sshbuf_free(buf);
+ sig_fuzz(k1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+/* XXX fuzz decoded new-format blobs too */
+
+}
diff --git a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
new file mode 100644
index 0000000..ef0c679
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
@@ -0,0 +1,357 @@
+/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshkey.h key management API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#ifdef OPENSSL_HAS_NISTP256
+# include <openssl/ec.h>
+#endif
+
+#include "../test_helper/test_helper.h"
+
+#include "ssherr.h"
+#include "sshbuf.h"
+#define SSHBUF_INTERNAL 1 /* access internals for testing */
+#include "sshkey.h"
+
+#include "authfile.h"
+#include "common.h"
+#include "ssh2.h"
+
+void sshkey_tests(void);
+
+static void
+build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
+ const struct sshkey *sign_key, const struct sshkey *ca_key)
+{
+ struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
+ u_char *sigblob;
+ size_t siglen;
+
+ ca_buf = sshbuf_new();
+ ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
+
+ /*
+ * Get the public key serialisation by rendering the key and skipping
+ * the type string. This is a bit of a hack :/
+ */
+ pk = sshbuf_new();
+ ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
+ ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
+
+ principals = sshbuf_new();
+ ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
+ ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
+
+ critopts = sshbuf_new();
+ /* XXX fill this in */
+
+ exts = sshbuf_new();
+ /* XXX fill this in */
+
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
+ ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */
+ ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */
+ ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */
+ ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
+ ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
+ sshbuf_ptr(b), sshbuf_len(b), 0), 0);
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
+
+ free(sigblob);
+ sshbuf_free(ca_buf);
+ sshbuf_free(exts);
+ sshbuf_free(critopts);
+ sshbuf_free(principals);
+ sshbuf_free(pk);
+}
+
+void
+sshkey_tests(void)
+{
+ struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf;
+ struct sshbuf *b;
+
+ TEST_START("new invalid");
+ k1 = sshkey_new(-42);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_UNSPEC");
+ k1 = sshkey_new(KEY_UNSPEC);
+ ASSERT_PTR_NE(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_RSA1");
+ k1 = sshkey_new(KEY_RSA1);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_RSA");
+ k1 = sshkey_new(KEY_RSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_DSA");
+ k1 = sshkey_new(KEY_DSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_ECDSA");
+ k1 = sshkey_new(KEY_ECDSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new/free KEY_ED25519");
+ k1 = sshkey_new(KEY_ED25519);
+ ASSERT_PTR_NE(k1, NULL);
+ /* These should be blank until key loaded or generated */
+ ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
+ ASSERT_PTR_EQ(k1->ed25519_pk, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new_private KEY_RSA");
+ k1 = sshkey_new_private(KEY_RSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_NE(k1->rsa->p, NULL);
+ ASSERT_INT_EQ(sshkey_add_private(k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("new_private KEY_DSA");
+ k1 = sshkey_new_private(KEY_DSA);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
+ ASSERT_INT_EQ(sshkey_add_private(k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA too small modulus");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA too large modulus");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ TEST_DONE();
+
+ TEST_START("generate KEY_DSA wrong bits");
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_ECDSA wrong bits");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
+ SSH_ERR_INVALID_ARGUMENT);
+ ASSERT_PTR_EQ(k1, NULL);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("generate KEY_RSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0);
+ ASSERT_PTR_NE(kr, NULL);
+ ASSERT_PTR_NE(kr->rsa, NULL);
+ ASSERT_PTR_NE(kr->rsa->n, NULL);
+ ASSERT_PTR_NE(kr->rsa->e, NULL);
+ ASSERT_PTR_NE(kr->rsa->p, NULL);
+ ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768);
+ TEST_DONE();
+
+ TEST_START("generate KEY_DSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
+ ASSERT_PTR_NE(kd, NULL);
+ ASSERT_PTR_NE(kd->dsa, NULL);
+ ASSERT_PTR_NE(kd->dsa->g, NULL);
+ ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("generate KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
+ ASSERT_PTR_NE(ke, NULL);
+ ASSERT_PTR_NE(ke->ecdsa, NULL);
+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
+ ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL);
+ TEST_DONE();
+#endif
+
+ TEST_START("generate KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
+ ASSERT_PTR_NE(kf, NULL);
+ ASSERT_INT_EQ(kf->type, KEY_ED25519);
+ ASSERT_PTR_NE(kf->ed25519_pk, NULL);
+ ASSERT_PTR_NE(kf->ed25519_sk, NULL);
+ TEST_DONE();
+
+ TEST_START("demote KEY_RSA");
+ ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kr, k1);
+ ASSERT_INT_EQ(k1->type, KEY_RSA);
+ ASSERT_PTR_NE(k1->rsa, NULL);
+ ASSERT_PTR_NE(k1->rsa->n, NULL);
+ ASSERT_PTR_NE(k1->rsa->e, NULL);
+ ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_RSA/demoted KEY_RSA");
+ ASSERT_INT_EQ(sshkey_equal(kr, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("demote KEY_DSA");
+ ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kd, k1);
+ ASSERT_INT_EQ(k1->type, KEY_DSA);
+ ASSERT_PTR_NE(k1->dsa, NULL);
+ ASSERT_PTR_NE(k1->dsa->g, NULL);
+ ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_DSA/demoted KEY_DSA");
+ ASSERT_INT_EQ(sshkey_equal(kd, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+#ifdef OPENSSL_HAS_ECC
+ TEST_START("demote KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(ke, k1);
+ ASSERT_INT_EQ(k1->type, KEY_ECDSA);
+ ASSERT_PTR_NE(k1->ecdsa, NULL);
+ ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
+ ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");
+ ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+#endif
+
+ TEST_START("demote KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0);
+ ASSERT_PTR_NE(k1, NULL);
+ ASSERT_PTR_NE(kf, k1);
+ ASSERT_INT_EQ(k1->type, KEY_ED25519);
+ ASSERT_PTR_NE(k1->ed25519_pk, NULL);
+ ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
+ TEST_DONE();
+
+ TEST_START("equal KEY_ED25519/demoted KEY_ED25519");
+ ASSERT_INT_EQ(sshkey_equal(kf, k1), 1);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ TEST_START("equal mismatched key types");
+ ASSERT_INT_EQ(sshkey_equal(kd, kr), 0);
+#ifdef OPENSSL_HAS_ECC
+ ASSERT_INT_EQ(sshkey_equal(kd, ke), 0);
+ ASSERT_INT_EQ(sshkey_equal(kr, ke), 0);
+ ASSERT_INT_EQ(sshkey_equal(ke, kf), 0);
+#endif
+ ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
+ TEST_DONE();
+
+ TEST_START("equal different keys");
+ ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
+ sshkey_free(k1);
+ ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kd, k1), 0);
+ sshkey_free(k1);
+#ifdef OPENSSL_HAS_ECC
+ ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
+ sshkey_free(k1);
+#endif
+ ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
+ ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
+ sshkey_free(k1);
+ TEST_DONE();
+
+ sshkey_free(kr);
+ sshkey_free(kd);
+#ifdef OPENSSL_HAS_ECC
+ sshkey_free(ke);
+#endif
+ sshkey_free(kf);
+
+/* XXX certify test */
+/* XXX sign test */
+/* XXX verify test */
+
+ TEST_START("nested certificate");
+ ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
+ NULL), 0);
+ b = load_file("rsa_2");
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
+ &k3, NULL), 0);
+ sshbuf_reset(b);
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
+ SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
+ ASSERT_PTR_EQ(k4, NULL);
+ sshbuf_free(b);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ sshkey_free(k3);
+ TEST_DONE();
+
+}
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1 b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1
new file mode 100644
index 0000000..3434686
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCxBNwH8TmLXqiZa0b9pxC6W+zS4Voqp8S+QwecYpNPTmhjaUYI
+E/aJWAzFVtdbysLM89ukvw/z8qBkbMSefdypKmjUtgv51ZD4nfV4Wxb+G+1QExHr
+M+kowOOL3XbcsdbPLUt8vxDJbBlQRch4zyai7CWjQR3JFXpR8sevUFJxSQIVAIdE
+oncp2DEY2U/ZZnIyGCwApCzfAoGARW+eewZTv1Eosxv3ANKx372pf5+fQKwnWizI
+j5z/GY3w3xobRCP9FiL4K3Nip2FvHLTGpRrlfm19RWYAg77VsNgztC4V9C8QrKWc
+WJdkUkoQpZ3VoO25rO13hmIelkal3omKCF4ZE/edeF3d2B8DlzYs0aBcjTCMDrub
+/CJILcYCgYEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
+4hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1
+/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gCFBl7Lc6V
+hmTiTuhLXjoRdCZS/p/m
+-----END DSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp
new file mode 100644
index 0000000..56ee1f8
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.pub
new file mode 100644
index 0000000..023edf1
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp
new file mode 100644
index 0000000..56ee1f8
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp.bb
new file mode 100644
index 0000000..07dd9b4
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.g b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.g
new file mode 100644
index 0000000..4b09f6d
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.g
@@ -0,0 +1 @@
+456f9e7b0653bf5128b31bf700d2b1dfbda97f9f9f40ac275a2cc88f9cff198df0df1a1b4423fd1622f82b7362a7616f1cb4c6a51ae57e6d7d45660083bed5b0d833b42e15f42f10aca59c589764524a10a59dd5a0edb9aced7786621e9646a5de898a085e1913f79d785dddd81f0397362cd1a05c8d308c0ebb9bfc22482dc6
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.priv b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.priv
new file mode 100644
index 0000000..2dd737c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.priv
@@ -0,0 +1 @@
+197b2dce958664e24ee84b5e3a11742652fe9fe6
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.pub b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.pub
new file mode 100644
index 0000000..b23d720
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.param.pub
@@ -0,0 +1 @@
+00809b7d8de7c6422e1297917c8778d8a39d8bca013cb0d632bab12530a566ca1152289d487e2f63e21369da3673bbb8e96568589dd5283da1ba81b441edf2f7a79927951a373f60f39ddeaee8d01d86b003596f895fd9f5fc430a52fd21f2b44523fddbf516351d55730501fb577b0d27a89e907f09a8ecb596208c68cca5c388
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.pub
new file mode 100644
index 0000000..8968197
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1_pw
new file mode 100644
index 0000000..1402153
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1_pw
@@ -0,0 +1,15 @@
+-----BEGIN DSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,9E668E24E7B9D658E3E7D0446B32B376
+
+hDjDLbfCAQutblxLuyNzSLxISSgXTgyzq8St9GE0lUtEc7i0xGNWwoWpFSbtD9y1
+yTG5UkhATQt56SY1ABfXZ21wieYuEEQeSJi0gwUQNNt2SwwITx4EdzDedWiHjikt
+jbzH3v33agp/odw2X9wY6zu75y9CeW9o7SszRl286DliWIHJmhMlbb8r7jRqu62H
+s5YYxD0xS1ipWauxklmIXMWNZHcARo8ZiJOuNdLshrSrl8DUW9P6F89FvxclQzKr
+44u3OBm7KbgPvPURDFLgNP6uCGBjzHvhHTpzVBxmQzCl3aGgsTKXiwJ1eupNjntB
+ji0EnbznvoxR6qhXxw/WQ+MnWlWqTXka/2qaB6m3oJv+Zn7cPCJ5kvHnhr2JmNMl
+igTh4Ov4LZLyNgO0Lbec4KyxW9QInRV5CY4Pu5lhqHteiPmOIGMWFtuh8Bb8Kg2q
+VvXnPo5I3FjqV7UhDduO1Wn558sBZWQPqRbHVPN6wXJuM3HGkBl+aNjn0qddv9tr
+VFJd/xdly2Ne81g3CB8jysE+3WEOrV9kdybocp/EhSOzP4i6pjWlyWdR5+CgbvRm
+TUIeIaQbmPIB5251o5YK+Q==
+-----END DSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2 b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2
new file mode 100644
index 0000000..b189dc8
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDoMxCTyBnLPSO7CRU3RyfJLANLKBZ3/LdcsyNaARctaRA5gzRb
+XdTFFU+rWKfxv+otm0KyCOepLtWy8tjKRYb7Ni46USlGwtM0Adx/3vR4iWNfipDP
+K2V4O97JyMe3wsbF7siC01U4b8Ki+J44iFG9nuRnOTHqUWI615mraQRwlQIVAMsX
+nsPGH8QrU11F1ScAIfZC165dAoGACCXyOHFkxABpJDtJs6AE7Hl3XjI4dnlim/XH
+Y60W6gcO7gHSE2r2ljCubJqoUXmxd5mLKgnu91jIG/4URwDM4V7pb2k99sXpAi8I
+L52eQl88C0bRD9+lEJfR4PMT39EccDRPB4+E055RoYQZ/McIyad8sF3Qwt084Eq+
+IkUt2coCgYEAxZRpCY82sM9Mu4B0EcH6O8seRqIRScmelljhUtKxuvf2PChwIWkR
+HK9lORHBE3iKyurC5Muf3abuHKwMFjrOjHKOTqXBRrDZ7RgLQA0aUAQD3lWc9OTP
+NShjphpq5xr0HZB31eJg3/Mo6KxYlRpzMXbTyenZP0XLICSSAywvTDoCFG5whl2k
+Y2FLGfi9V6ylUVH6jKgE
+-----END DSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp
new file mode 100644
index 0000000..ba9de82
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp.bb
new file mode 100644
index 0000000..37a5221
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.pub
new file mode 100644
index 0000000..6ed2736
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n
new file mode 100644
index 0000000..3434686
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCxBNwH8TmLXqiZa0b9pxC6W+zS4Voqp8S+QwecYpNPTmhjaUYI
+E/aJWAzFVtdbysLM89ukvw/z8qBkbMSefdypKmjUtgv51ZD4nfV4Wxb+G+1QExHr
+M+kowOOL3XbcsdbPLUt8vxDJbBlQRch4zyai7CWjQR3JFXpR8sevUFJxSQIVAIdE
+oncp2DEY2U/ZZnIyGCwApCzfAoGARW+eewZTv1Eosxv3ANKx372pf5+fQKwnWizI
+j5z/GY3w3xobRCP9FiL4K3Nip2FvHLTGpRrlfm19RWYAg77VsNgztC4V9C8QrKWc
+WJdkUkoQpZ3VoO25rO13hmIelkal3omKCF4ZE/edeF3d2B8DlzYs0aBcjTCMDrub
+/CJILcYCgYEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
+4hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1
+/EMKUv0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gCFBl7Lc6V
+hmTiTuhLXjoRdCZS/p/m
+-----END DSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n_pw b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n_pw
new file mode 100644
index 0000000..42f70dd
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_n_pw
@@ -0,0 +1,22 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABD5nB+Nkw
+LNoPtAG7C3IdXmAAAAEAAAAAEAAAGyAAAAB3NzaC1kc3MAAACBALEE3AfxOYteqJlrRv2n
+ELpb7NLhWiqnxL5DB5xik09OaGNpRggT9olYDMVW11vKwszz26S/D/PyoGRsxJ593KkqaN
+S2C/nVkPid9XhbFv4b7VATEesz6SjA44vddtyx1s8tS3y/EMlsGVBFyHjPJqLsJaNBHckV
+elHyx69QUnFJAAAAFQCHRKJ3KdgxGNlP2WZyMhgsAKQs3wAAAIBFb557BlO/USizG/cA0r
+Hfval/n59ArCdaLMiPnP8ZjfDfGhtEI/0WIvgrc2KnYW8ctMalGuV+bX1FZgCDvtWw2DO0
+LhX0LxCspZxYl2RSShClndWg7bms7XeGYh6WRqXeiYoIXhkT9514Xd3YHwOXNizRoFyNMI
+wOu5v8IkgtxgAAAIEAgJt9jefGQi4Sl5F8h3jYo52LygE8sNYyurElMKVmyhFSKJ1Ifi9j
+4hNp2jZzu7jpZWhYndUoPaG6gbRB7fL3p5knlRo3P2Dznd6u6NAdhrADWW+JX9n1/EMKUv
+0h8rRFI/3b9RY1HVVzBQH7V3sNJ6iekH8JqOy1liCMaMylw4gAAAHw8P1DtkBulOGv85qf
+P+md2+LL+NKufVzHl9k2UKQFjeqY6uqs4HSDqvhXe7oiXd5mz6I7orxjtKU9hGjNF4ABUD
+OawVGe/GCRUQ4WgpAgDnqQLeFcdIwtMSIrRZU6xjs314EI7TM7IIiG26JEuXDfZI1e7C3y
+Cc38ZsP3zmg/UjgcCQar5c4n++vhOmeO36+fcUyZ1QlR05SaEtFYJA+otP3RmKTiDwob8Q
+zRMr8Y57i2NTTtFjkmnnnQCibP62yz7N22Dve7RTOH8jiaW7p02Vn/6WmCarevN1rxtLLR
+lkuWtPoKY8z/Ktcev8YE9f2+9H2TfXDRKYqIEfxgZLCJ4yP2gxDe6zurabS0hAO1CP+ej5
+htdJM3/rTqHAIevXX5uhIDmMvRHnLGldaIX1xux8TIJvSfMkYNIwscIP4kx7BGMk04vXtW
+5DLm6IZhzw9T3hjr8R0kBugmT6/h9vD5iN1D+wiHIhHYzQKMU9nOeFNsMBFWgJjU0l8VlF
+gEjEMgAEfwynnmIoKB1iA/0em1tdU3naS59DBK+buE0trxUpTAAB5z8yPhAm6DdqrPE8cA
+N3HlMoWrbCuak2A0uyOlEJjPg4UJUnv12ve2c9pAMsAu/4CAszCEM0prR+qd/RA4nn4M5u
+Xrny2wNtt/DybCkA==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1 b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1
new file mode 100644
index 0000000..aec73dd
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFghsFR1K95tz8qOl3+tX6fv8a/O6AfNbxOSFZX3ihxooAoGCCqGSM49
+AwEHoUQDQgAEalpgP0BOePHtTw0Pus4tdhTb8P9yWUZluvLf1D8vrHImT+G4vr/W
+xo5iXGKQVEifuUVyLkAW2kDrq8J/szeRiQ==
+-----END EC PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp
new file mode 100644
index 0000000..a56dbc8
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub
new file mode 100644
index 0000000..29b06a4
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp
new file mode 100644
index 0000000..a56dbc8
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb
new file mode 100644
index 0000000..f01a5dd
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.curve b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.curve
new file mode 100644
index 0000000..fa04004
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.curve
@@ -0,0 +1 @@
+prime256v1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.priv b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.priv
new file mode 100644
index 0000000..3475f1f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.priv
@@ -0,0 +1 @@
+5821b054752bde6dcfca8e977fad5fa7eff1afcee807cd6f13921595f78a1c68
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.pub
new file mode 100644
index 0000000..11847a3
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.param.pub
@@ -0,0 +1 @@
+046a5a603f404e78f1ed4f0d0fbace2d7614dbf0ff72594665baf2dfd43f2fac72264fe1b8bebfd6c68e625c629054489fb945722e4016da40ebabc27fb3379189
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.pub
new file mode 100644
index 0000000..eca1620
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1_pw
new file mode 100644
index 0000000..071154a
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1_pw
@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,74C8AEA5BFAFCC2B1C8B13DE671F5610
+
+vUsgOvCqezxPmcZcFqrSy9Y1MMlVguY0h9cfSPFC7gUrRr+45uCOYX5bOwEXecKn
+/9uCXZtlBwwqDS9iK5IPoUrjEHvzI5rVbHWUxDrEOVbsfiDuCxrQM19It6QIqC1v
+OSQEdXuBWR5WmhKNc3dqLbWsU8u2s60YwKQmZrj9nM4=
+-----END EC PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2 b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2
new file mode 100644
index 0000000..76ae07a
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIBg4kVxUfoo/RE/78/QBRqG6PZuHZ82eLnhmZVzBa7XREUiYI/Jw7r
+Qwp4FTBVfXL76Pt5AyBMf+52aVeOUlLRERSgBwYFK4EEACOhgYkDgYYABACNTJ5O
+uNo5dNgIQRLHzKU91m7immKFiutJ6BlDbkRkKr+Envj13J6HOgYvOTm0n7SPlKHS
+STZ4/T36d/rzQOAbIwEnbbwD9HMj6IzE4WH9lJzH7Zy7Tcyu6dOM8L7nOxCp3DUk
+F3aAnPSFJhD7NN0jBWOFsD6uy1OmaTklPfRAnCt1MQ==
+-----END EC PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp
new file mode 100644
index 0000000..eb4bbdf
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb
new file mode 100644
index 0000000..267bc63
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.curve b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.curve
new file mode 100644
index 0000000..617ea2f
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.curve
@@ -0,0 +1 @@
+secp521r1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.priv b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.priv
new file mode 100644
index 0000000..537cdaa
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.priv
@@ -0,0 +1 @@
+01838915c547e8a3f444ffbf3f40146a1ba3d9b8767cd9e2e7866655cc16bb5d111489823f270eeb430a781530557d72fbe8fb7903204c7fee7669578e5252d11114
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.pub
new file mode 100644
index 0000000..3352ac7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.param.pub
@@ -0,0 +1 @@
+04008d4c9e4eb8da3974d8084112c7cca53dd66ee29a62858aeb49e819436e44642abf849ef8f5dc9e873a062f3939b49fb48f94a1d2493678fd3dfa77faf340e01b2301276dbc03f47323e88cc4e161fd949cc7ed9cbb4dccaee9d38cf0bee73b10a9dc35241776809cf4852610fb34dd23056385b03eaecb53a66939253df4409c2b7531
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.pub
new file mode 100644
index 0000000..34e1881
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACNTJ5OuNo5dNgIQRLHzKU91m7immKFiutJ6BlDbkRkKr+Envj13J6HOgYvOTm0n7SPlKHSSTZ4/T36d/rzQOAbIwEnbbwD9HMj6IzE4WH9lJzH7Zy7Tcyu6dOM8L7nOxCp3DUkF3aAnPSFJhD7NN0jBWOFsD6uy1OmaTklPfRAnCt1MQ== ECDSA test key #2
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n
new file mode 100644
index 0000000..aec73dd
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFghsFR1K95tz8qOl3+tX6fv8a/O6AfNbxOSFZX3ihxooAoGCCqGSM49
+AwEHoUQDQgAEalpgP0BOePHtTw0Pus4tdhTb8P9yWUZluvLf1D8vrHImT+G4vr/W
+xo5iXGKQVEifuUVyLkAW2kDrq8J/szeRiQ==
+-----END EC PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n_pw
new file mode 100644
index 0000000..75d5859
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_n_pw
@@ -0,0 +1,9 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBXqI6Z6o
+uRM+jAwdhnDoIMAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz
+dHAyNTYAAABBBGpaYD9ATnjx7U8ND7rOLXYU2/D/cllGZbry39Q/L6xyJk/huL6/1saOYl
+xikFRIn7lFci5AFtpA66vCf7M3kYkAAACwYMnoCTqvUTG0ktSSMNsOZLCdal5J4avEpM1L
+sV9SL/RVcwo3ChprhwsnQsaAtMiJCRcHerKgD9qy1MNNaE5VNfVJ0Ih/7ut04cbFKed8p6
+0V+w8WP7WvFffBPoHn+GGbQd1FDGzHhXUB61pH8Qzd1bI/sld/XEtMk7iYjNGQe9Rt0RaK
+Wi8trwaA0Fb2w/EFnrdsFFxrIhQEqYBdEQJo782IqAsMG9OwUaM0vy+8bcI=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1 b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1
new file mode 100644
index 0000000..a537ae1
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACC5PeVeSdyylcfG3C0geNO90e3dGgL0fICaz751dA9zEAAAAJglsAcYJbAH
+GAAAAAtzc2gtZWQyNTUxOQAAACC5PeVeSdyylcfG3C0geNO90e3dGgL0fICaz751dA9zEA
+AAAED6HJ8Bh8tdQvhMd5o8IxtIwBv8/FV48FpBFWAbYdsIsLk95V5J3LKVx8bcLSB4073R
+7d0aAvR8gJrPvnV0D3MQAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp
new file mode 100644
index 0000000..e6d23d0
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.pub
new file mode 100644
index 0000000..ad0b9a8
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp
new file mode 100644
index 0000000..e6d23d0
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp.bb
new file mode 100644
index 0000000..591a711
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.pub
new file mode 100644
index 0000000..633e050
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bcLSB4073R7d0aAvR8gJrPvnV0D3MQ ED25519 test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw
new file mode 100644
index 0000000..9fc6352
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1_pw
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAlT1eewp
+9gl0gue+sSrBWKAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAILk95V5J3LKVx8bc
+LSB4073R7d0aAvR8gJrPvnV0D3MQAAAAoMrL9ixIQHoJ86DcKMGt26+bCeaoyGjW5hha2Y
+IxAZ+rRvNjUuv3MGvbUxtUpPZkTP/vk2fVSCuCD9St5Lbt/LKdIk2MfWIFbjZ6iEfdzxz0
+DHmsSDMps8dbePqqIPULR8av447jEzQEkUc8GSR6WqFSJOjJ8OvrJat1KcEK7V2tjZnLS1
+GoLMqVAtCVhuXwUkeJiRQE/JRl172hxB+LAVw=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2 b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2
new file mode 100644
index 0000000..a6e5f00
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBXUfO5Kid+jhRnyVt+1r9wj2FN/mZ6RfgGdySeYoq4WAAAAJjGeKsZxnir
+GQAAAAtzc2gtZWQyNTUxOQAAACBXUfO5Kid+jhRnyVt+1r9wj2FN/mZ6RfgGdySeYoq4WA
+AAAEB+gn4gGClQl2WMeOkikY+w0A0kSw1KH4Oyami7hlypsFdR87kqJ36OFGfJW37Wv3CP
+YU3+ZnpF+AZ3JJ5iirhYAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp
new file mode 100644
index 0000000..02c684f
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp.bb
new file mode 100644
index 0000000..ebe782e
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.pub
new file mode 100644
index 0000000..37b9335
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdR87kqJ36OFGfJW37Wv3CPYU3+ZnpF+AZ3JJ5iirhY ED25519 test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/pw b/crypto/openssh/regress/unittests/sshkey/testdata/pw
new file mode 100644
index 0000000..8a1dff9
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/pw
@@ -0,0 +1 @@
+mekmitasdigoat
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1
new file mode 100644
index 0000000..d22014e
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp
new file mode 100644
index 0000000..782ece0
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp.bb
new file mode 100644
index 0000000..caaf951
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n
new file mode 100644
index 0000000..4ceb373
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.param.n
@@ -0,0 +1 @@
+00cf68059e5c7743318d740d3ebb55eb577891c9c3098817703f4c3157285055c2daa50102509ebdcade324e541c965e2931fd3459052fe65d013722da805d7ec8ef5b97cc006789d0566c5578b23e7aaa5be2b055d85798030cdead2eb2cc4eb3
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub
new file mode 100644
index 0000000..56cf30d
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.pub
@@ -0,0 +1 @@
+768 65537 1257820658919101781627826212425999371251377782154008557690434337796299274692579921603319269571889066123773172648045269780061837011867522525764583065919572648969392756890567918758763032103894830246827894023662422727333291801518558899 RSA1 test key #1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw
new file mode 100644
index 0000000..3113dbc
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1_pw
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2
new file mode 100644
index 0000000..e75e665
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2
Binary files differ
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp
new file mode 100644
index 0000000..c332537
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp.bb
new file mode 100644
index 0000000..cd80371
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n
new file mode 100644
index 0000000..f8143a4
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.param.n
@@ -0,0 +1 @@
+00b08a9fa386aceaab2ec3e9cdc7e6cb4eac9e98620279eed6762e1f513739a417ac8a86231fad3b8727a9de994973a7aae674a132547341984ade91aa1c22f01d2f0204ea7fa121969c367a5d04bda384066cf94e0b56d1efc47f50ca28e90603547df41c0676550d82d369f699b457d4f0f077999d9e76ab679fbf4206d418dbabed1823f14e4ddf3aac987686e6b006f8a23ea6af13b4c0e5b1fb5b1eb4db2f47b229422c450574cae9c64db5dcfce050836b6bdfa8fb541b4d426444a5ea20ad51a25d3048414ced2e199da2997968273e8beb10f3a351e98a57b00dadfa8f00a39bb55be94dae898fda6021d728f32b2ec93edd16e51073be3ac7511e5085
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub
new file mode 100644
index 0000000..de1afbb
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.pub
@@ -0,0 +1 @@
+2048 65537 22286299513474010485021611215236051675183880694440075228245854420062562171290421803318459093678819161498086077099067169041536315773126601869537036602014639497662916952995546870691495931205282427606841521014293638607226118353743812583642616889028731910222603216563207637006843580936568089467160095319593442255227365472917576488012409542775346105980501967996562422764758836868135158147777193940857952623773420292946843206784104932927528915610322518810753953608862466374219925252817405397507396462117715293725218947744085154122395590957537510003558169729949140038634486299736757269280065662263306737701939154762092925061 RSA1 test key #2
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1
new file mode 100644
index 0000000..09e79a7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBywIBAAJhAM/6MDmVVm/uNQmZpOcthoAAgMDUg7G4H6ZLLyPEhboKaBBHvIdw
+ZdDmB+0LDf3D1aWXyUd2/pCkCysiBzqd/523zAzjY7HayqL6A940AxKBBbWLn+X6
+i2yJR7dTOYkk6QIDAQABAmAgKanBjfWzE5yCIo+c7K5rJyjCKVtAZaAHYIMmveKM
+VcWoFt/x9hDY0GoTX21HfDxLX8oDxnsmhsOrnvSmgUChFwkm45eSETqeVDWwIVFA
+FGL1s38xQsciWZWBFNppAIECMQD7nslReAxwz/Ad++ACXswfJg1l2wUQ1gJA3zh3
+jln6a4s3aV1zxbKlIn8iqBv0BZkCMQDTmO4WqyNnin73XCZs0DWu7GsfcuaH8QnD
+wqPjJgrclTZXedxHkeqO2oyZW4mLC9ECMBb/blsZ49kzyDiVWuYcj/+Q1MyodhAR
+32bagCi9RBAVYEYSRU5dlXRucLxULSnikQIxAJ5teY5Vcru6kZfJUifUuO0QrKAu
+WnbcPVBqMmUHfchsm/RhFFIt6W4uKmlEhTYrkQIxAMAStb7QCU3yU6ZkN7uL22Zs
+498i4jY6y+VEXv+L9O09VdlEnXhbUisOhy1bhyS3yg==
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp
new file mode 100644
index 0000000..bf9c2e3
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.pub
new file mode 100644
index 0000000..51b1ce0
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp
new file mode 100644
index 0000000..bf9c2e3
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp.bb
new file mode 100644
index 0000000..448133b
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.n
new file mode 100644
index 0000000..2ffc2ba
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.n
@@ -0,0 +1 @@
+00cffa303995566fee350999a4e72d86800080c0d483b1b81fa64b2f23c485ba0a681047bc877065d0e607ed0b0dfdc3d5a597c94776fe90a40b2b22073a9dff9db7cc0ce363b1dacaa2fa03de3403128105b58b9fe5fa8b6c8947b753398924e9
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.p b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.p
new file mode 100644
index 0000000..4fcf148
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.p
@@ -0,0 +1 @@
+00fb9ec951780c70cff01dfbe0025ecc1f260d65db0510d60240df38778e59fa6b8b37695d73c5b2a5227f22a81bf40599
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.q b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.q
new file mode 100644
index 0000000..3473f51
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.param.q
@@ -0,0 +1 @@
+00d398ee16ab23678a7ef75c266cd035aeec6b1f72e687f109c3c2a3e3260adc95365779dc4791ea8eda8c995b898b0bd1
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.pub
new file mode 100644
index 0000000..889fdae
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1_pw b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1_pw
new file mode 100644
index 0000000..71637a5
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1_pw
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,1E851A01F12A49FDC256E7A665C61D4B
+
++sfWU7kg3idmHL6vShby5LXnfF4bZDPhJjv89uldae7qPEgEW8qS8o0Ssokxf7Au
+/vTQnbSB+gy/qZaUOykOzqiV1YL7UfkbOkM2QYnzzrVeGzI5RZ0G9iH8HBn2owQ+
+Ejf1UKDUVZEea5X0IwQRfE0zaZqFS4tyEex0iKz8dI4FvyabKLZsCs1DBGO7A3ml
+LgP947mh10yKWTP2fbq8LOhDUEWCXrh2NzuH6Rl5nNyC4MNQEkLzK1wL7J/WCNaL
+sciYmuqEQRDikDDQQFZw2wjBD638fhK+IhuN3VGegiXFnu5C+p9kzUvqVk4X9g2r
+BMmlP0pceFv/fEwtNNaeI2Tt7mIsWsZTmCqdzOUAYqGIiNjzykWw64nMO3TpVpbA
+i4854RhblbeiyjENbMVPU6BAk4fx7OJvDElLxwN43CS3U0MldbI7A4uG3B3RTSCj
+1rGxRNAHWC3q3zzrn6gLwrUVje4iTedaKItLIHQeo1A091Tr8AqQdZi/Ck2Ju0Hl
+4Qdwzjw1Y5n1Akm+EWh31ydxtUQ0YBOz/W6DKwTNA1D8oH9bZBG4f0pnvVhtttAO
+WKj+DUqMa+f3OOmQ9UXlitk2pEgjeMngTgfQnhZiCts=
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2 b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2
new file mode 100644
index 0000000..058cf77
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAlDS/ygeFfsR/mhZK/XMHU/gzRogPuMQIYUd17WDjMprA6dQb
+ckTDrNm/mrf09I6YAhjgooEL16oWM1z6cesDE0KwaJsy6uTmXFMLO+Ha4mtFHhmu
+tiyJcQ9MKKr0vC64384WQZygZk0OlVz7x9WSPiGXzal5MzsX4TYq5B05o2Cb+epA
+FxK0c8cdYZD0Sy57gWRpRA3yJq4zh/hks98jzn0XA3HAJA39MKhUG5tf5e6z5BeP
+Yi5FvdnDQ9WcasRiEvkmHbg59pbgg/Lbsl6OgZQruS8hKiJ3YBARt2euCCeg7qAF
+KbXRR9TMwfphH3Ai4Oi/w6HPRAhdrwooA/gKkQIDAQABAoIBAH22OLB/rMaYmrvz
+COzvM1oQgD3lj6Bj98+8M9WEh3MXPWeaGSXWGjx1/0aXn1oJ0fqFa5Wr7IWkqmwr
+A+y5McSWntg8PPZt7tCFSFQlAetonhooIsA4CuUx2qHsUOeGoh6EyvAgkRX1atdb
+Jd6d1AyLph43EK1aBKltrvgLqiZfs7mcuwyvKtN9ktdKY2FDhn6DHpm9pE9MEHJV
+Xv1isNc6a0qNoRlKqxrSZHNEN4fbjLw31wBySzmmnIog5wVEwaHeASwLJT6TmuIZ
+eZxnd7/jMwRZWH8ZIGKvkTMp4fYzK9QkehO7A2HFD3FPDBVrkSJjqRdkujF8vu1C
+0RwrD1kCgYEAxFXUoE1ero6vp9akvR/mw94kYjXE/YOz1yi0KTkZUs6gURc8Kzsm
+MzlEZ31rnngE4jQHYAvuPEfiqcnUgylW3QuevMgo2hCLYO7aG5C0fk8TeOiuvnrF
+YPO8rSJWk/BgdrPtzu45P7jmWsjkHn+y+t8cKvq1sZY40sn2YgIhYK8CgYEAwT6j
+5tReI6sxpHltPUbvOdpD04eL6ggBAKwzb5aBoa/Dj+sU1zg5uyY8diggQEEznlBW
+iWTQmmmfy1ef9i6YAwNuZveKOrVwNMcdubQJ2X26XoFrmA59PjsbLtr1bdUb02gz
+6P5x6pcw5qzEq0mddgvHiU3RhL24xdc1LW8nmL8CgYEAmgaT1macPuklmNBlURGz
+4jll5b41GoW2EreWDzkCStpbHwLRa0DuCQWGSoI0aY/SlPsoRgtWDOiAQ59ZHsTR
+pnw1PfjxQ5HzJkp7xWBSmTzEE/jHDhwWuKa+gD0OGuVbaARkLhDpzLnrzZEIlXyt
+Fu7tlDI3VGh7j7Jtnhn5wXUCgYBKmPbGfcaVeFmih2lfFUn2CEbUmmetgUd5zf/R
+HMWP9/zDStlxt3e5winm5tiEVWcqvxKY2T0Zzppr8biDXTs7NpDg2MAYp7/X7+GO
+tWxz8/AE2WsCeN1qL4Dv1oCV1IV4V6pqUAcDqzeqZJlLEhDh5+wwGcU+u8pfPRN/
+JYCgmwKBgDa+kXPqzcc6vzD9cwEEk4ftn9/Vk2yBx0XOu8RdEkRhXj1QXGJckCqh
+FkXzVbuurFhsBt+H0B4arw+51T9fVCZqfcaU34u+Qa/FQvTod4OJUSRxYUaDqygs
+VTyuP+zGZlIw7JWktxjVazENsM/ef5wBH0Nf839OZbPVDLfn7K0j
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp
new file mode 100644
index 0000000..53939f4
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp.bb b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp.bb
new file mode 100644
index 0000000..e90a357
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.n
new file mode 100644
index 0000000..389de42
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.n
@@ -0,0 +1 @@
+009434bfca07857ec47f9a164afd730753f83346880fb8c408614775ed60e3329ac0e9d41b7244c3acd9bf9ab7f4f48e980218e0a2810bd7aa16335cfa71eb031342b0689b32eae4e65c530b3be1dae26b451e19aeb62c89710f4c28aaf4bc2eb8dfce16419ca0664d0e955cfbc7d5923e2197cda979333b17e1362ae41d39a3609bf9ea401712b473c71d6190f44b2e7b816469440df226ae3387f864b3df23ce7d170371c0240dfd30a8541b9b5fe5eeb3e4178f622e45bdd9c343d59c6ac46212f9261db839f696e083f2dbb25e8e81942bb92f212a2277601011b767ae0827a0eea00529b5d147d4ccc1fa611f7022e0e8bfc3a1cf44085daf0a2803f80a91
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.p b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.p
new file mode 100644
index 0000000..c3c9a13
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.p
@@ -0,0 +1 @@
+00c455d4a04d5eae8eafa7d6a4bd1fe6c3de246235c4fd83b3d728b429391952cea051173c2b3b26333944677d6b9e7804e23407600bee3c47e2a9c9d4832956dd0b9ebcc828da108b60eeda1b90b47e4f1378e8aebe7ac560f3bcad225693f06076b3edceee393fb8e65ac8e41e7fb2fadf1c2afab5b19638d2c9f662022160af
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.q b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.q
new file mode 100644
index 0000000..728c474
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.param.q
@@ -0,0 +1 @@
+00c13ea3e6d45e23ab31a4796d3d46ef39da43d3878bea080100ac336f9681a1afc38feb14d73839bb263c7628204041339e50568964d09a699fcb579ff62e9803036e66f78a3ab57034c71db9b409d97dba5e816b980e7d3e3b1b2edaf56dd51bd36833e8fe71ea9730e6acc4ab499d760bc7894dd184bdb8c5d7352d6f2798bf
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.pub b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.pub
new file mode 100644
index 0000000..ed9f78c
--- /dev/null
+++ b/crypto/openssh/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/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n
new file mode 100644
index 0000000..09e79a7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBywIBAAJhAM/6MDmVVm/uNQmZpOcthoAAgMDUg7G4H6ZLLyPEhboKaBBHvIdw
+ZdDmB+0LDf3D1aWXyUd2/pCkCysiBzqd/523zAzjY7HayqL6A940AxKBBbWLn+X6
+i2yJR7dTOYkk6QIDAQABAmAgKanBjfWzE5yCIo+c7K5rJyjCKVtAZaAHYIMmveKM
+VcWoFt/x9hDY0GoTX21HfDxLX8oDxnsmhsOrnvSmgUChFwkm45eSETqeVDWwIVFA
+FGL1s38xQsciWZWBFNppAIECMQD7nslReAxwz/Ad++ACXswfJg1l2wUQ1gJA3zh3
+jln6a4s3aV1zxbKlIn8iqBv0BZkCMQDTmO4WqyNnin73XCZs0DWu7GsfcuaH8QnD
+wqPjJgrclTZXedxHkeqO2oyZW4mLC9ECMBb/blsZ49kzyDiVWuYcj/+Q1MyodhAR
+32bagCi9RBAVYEYSRU5dlXRucLxULSnikQIxAJ5teY5Vcru6kZfJUifUuO0QrKAu
+WnbcPVBqMmUHfchsm/RhFFIt6W4uKmlEhTYrkQIxAMAStb7QCU3yU6ZkN7uL22Zs
+498i4jY6y+VEXv+L9O09VdlEnXhbUisOhy1bhyS3yg==
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n_pw b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n_pw
new file mode 100644
index 0000000..0166fd5
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_n_pw
@@ -0,0 +1,14 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABClELgtaZ
+qAmMwESpqXDN0uAAAAEAAAAAEAAAB3AAAAB3NzaC1yc2EAAAADAQABAAAAYQDP+jA5lVZv
+7jUJmaTnLYaAAIDA1IOxuB+mSy8jxIW6CmgQR7yHcGXQ5gftCw39w9Wll8lHdv6QpAsrIg
+c6nf+dt8wM42Ox2sqi+gPeNAMSgQW1i5/l+otsiUe3UzmJJOkAAAGgwJpHy/nshQa9+Jbw
+yomvgNMYvuuoD7Ll7iCY/RFFGXivTkki27C9q0qx3afauSLQQWFanGhjeJn7JPy98lMcVl
+qnn5XOE5+xxZqA8ONOBD8eH0KBcTH17DH1A1z94p5zZ1VJKIWsBZ0krxgHIXcdv9ucAckj
+N0vAEBm+0wsfy2TTOtuqXvcj65wFwknpyy/SSvU0QTr99FiYe9PIhIslBHO6wlqxfKj+Tm
+E/nCb75dAVu6gTtS2P0pdOqV/V7VHX5C0z3BROqpKDJJcVeoc7vRkEl+MWfvvQrG66IPEW
+luohFXPDPDrxu1zDduyRsmNwpBHChi2rFhxtsjxNK0svMwESeCCKAWmPxnzLJfvMbTCv00
+SpaCr7WhtzsGt73axqSkeOdynp5NNrN7MEdwruMZFirF4BcI2z2H9ugpS+qbLPuE2H5vln
+h7NSwBUNwmZ+4TC8MXFH9KIpRg8dNhf66OU610LYiN4+ZfOYCmfQfgQuBGhMTYFMY6O4SB
+NCdIavvWY6rDSBq7QC1f4rHpwiXxpkiE43Rd8fM32TaPlBPtA=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/crypto/openssh/regress/unittests/sshkey/tests.c b/crypto/openssh/regress/unittests/sshkey/tests.c
new file mode 100644
index 0000000..13f265c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/sshkey/tests.c
@@ -0,0 +1,27 @@
+/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/*
+ * Regress test for sshbuf.h buffer API
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <openssl/evp.h>
+
+#include "../test_helper/test_helper.h"
+
+void sshkey_tests(void);
+void sshkey_file_tests(void);
+void sshkey_fuzz_tests(void);
+
+void
+tests(void)
+{
+ OpenSSL_add_all_algorithms();
+ ERR_load_CRYPTO_strings();
+
+ sshkey_tests();
+ sshkey_file_tests();
+ sshkey_fuzz_tests();
+}
diff --git a/crypto/openssh/regress/unittests/test_helper/Makefile b/crypto/openssh/regress/unittests/test_helper/Makefile
new file mode 100644
index 0000000..3e90903
--- /dev/null
+++ b/crypto/openssh/regress/unittests/test_helper/Makefile
@@ -0,0 +1,13 @@
+# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $
+
+LIB= test_helper
+SRCS= test_helper.c fuzz.c
+
+DEBUGLIBS= no
+NOPROFILE= yes
+NOPIC= yes
+
+install:
+ @echo -n
+
+.include <bsd.lib.mk>
diff --git a/crypto/openssh/regress/unittests/test_helper/fuzz.c b/crypto/openssh/regress/unittests/test_helper/fuzz.c
new file mode 100644
index 0000000..77c6e7c
--- /dev/null
+++ b/crypto/openssh/regress/unittests/test_helper/fuzz.c
@@ -0,0 +1,378 @@
+/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */
+/*
+ * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Utility functions/framework for fuzz tests */
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "test_helper.h"
+
+/* #define FUZZ_DEBUG */
+
+#ifdef FUZZ_DEBUG
+# define FUZZ_DBG(x) do { \
+ printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
+ printf x; \
+ printf("\n"); \
+ fflush(stdout); \
+ } while (0)
+#else
+# define FUZZ_DBG(x)
+#endif
+
+/* For brevity later */
+typedef unsigned long long fuzz_ullong;
+
+/* For base-64 fuzzing */
+static const char fuzz_b64chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+struct fuzz {
+ /* Fuzz method currently in use */
+ int strategy;
+
+ /* Fuzz methods remaining */
+ int strategies;
+
+ /* Original seed data blob */
+ void *seed;
+ size_t slen;
+
+ /* Current working copy of seed with fuzz mutations applied */
+ u_char *fuzzed;
+
+ /* Used by fuzz methods */
+ size_t o1, o2;
+};
+
+static const char *
+fuzz_ntop(u_int n)
+{
+ switch (n) {
+ case 0:
+ return "NONE";
+ case FUZZ_1_BIT_FLIP:
+ return "FUZZ_1_BIT_FLIP";
+ case FUZZ_2_BIT_FLIP:
+ return "FUZZ_2_BIT_FLIP";
+ case FUZZ_1_BYTE_FLIP:
+ return "FUZZ_1_BYTE_FLIP";
+ case FUZZ_2_BYTE_FLIP:
+ return "FUZZ_2_BYTE_FLIP";
+ case FUZZ_TRUNCATE_START:
+ return "FUZZ_TRUNCATE_START";
+ case FUZZ_TRUNCATE_END:
+ return "FUZZ_TRUNCATE_END";
+ case FUZZ_BASE64:
+ return "FUZZ_BASE64";
+ default:
+ abort();
+ }
+}
+
+void
+fuzz_dump(struct fuzz *fuzz)
+{
+ u_char *p = fuzz_ptr(fuzz);
+ size_t i, j, len = fuzz_len(fuzz);
+
+ switch (fuzz->strategy) {
+ case FUZZ_1_BIT_FLIP:
+ fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ fuzz->o1, fuzz->slen * 8, fuzz->o1);
+ break;
+ case FUZZ_2_BIT_FLIP:
+ fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
+ ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
+ fuzz->o1, fuzz->o2);
+ break;
+ case FUZZ_1_BYTE_FLIP:
+ fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ fuzz->o1, fuzz->slen, fuzz->o1);
+ break;
+ case FUZZ_2_BYTE_FLIP:
+ fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
+ ((fuzz_ullong)fuzz->slen) * fuzz->slen,
+ fuzz->o1, fuzz->o2);
+ break;
+ case FUZZ_TRUNCATE_START:
+ fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ fuzz->o1, fuzz->slen, fuzz->o1);
+ break;
+ case FUZZ_TRUNCATE_END:
+ fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n",
+ fuzz_ntop(fuzz->strategy),
+ fuzz->o1, fuzz->slen, fuzz->o1);
+ break;
+ case FUZZ_BASE64:
+ assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
+ fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n",
+ fuzz_ntop(fuzz->strategy),
+ (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
+ fuzz->slen * (fuzz_ullong)64, fuzz->o1,
+ fuzz_b64chars[fuzz->o2]);
+ break;
+ default:
+ abort();
+ }
+
+ fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len);
+ for (i = 0; i < len; i += 16) {
+ fprintf(stderr, "%.4zd: ", i);
+ for (j = i; j < i + 16; j++) {
+ if (j < len)
+ fprintf(stderr, "%02x ", p[j]);
+ else
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, " ");
+ for (j = i; j < i + 16; j++) {
+ if (j < len) {
+ if (isascii(p[j]) && isprint(p[j]))
+ fprintf(stderr, "%c", p[j]);
+ else
+ fprintf(stderr, ".");
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+struct fuzz *
+fuzz_begin(u_int strategies, const void *p, size_t l)
+{
+ struct fuzz *ret = calloc(sizeof(*ret), 1);
+
+ assert(p != NULL);
+ assert(ret != NULL);
+ ret->seed = malloc(l);
+ assert(ret->seed != NULL);
+ memcpy(ret->seed, p, l);
+ ret->slen = l;
+ ret->strategies = strategies;
+
+ assert(ret->slen < SIZE_MAX / 8);
+ assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1)));
+
+ FUZZ_DBG(("begin, ret = %p", ret));
+
+ fuzz_next(ret);
+ return ret;
+}
+
+void
+fuzz_cleanup(struct fuzz *fuzz)
+{
+ FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
+ assert(fuzz != NULL);
+ assert(fuzz->seed != NULL);
+ assert(fuzz->fuzzed != NULL);
+ free(fuzz->seed);
+ free(fuzz->fuzzed);
+ free(fuzz);
+}
+
+static int
+fuzz_strategy_done(struct fuzz *fuzz)
+{
+ FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu",
+ fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen));
+
+ switch (fuzz->strategy) {
+ case FUZZ_1_BIT_FLIP:
+ return fuzz->o1 >= fuzz->slen * 8;
+ case FUZZ_2_BIT_FLIP:
+ return fuzz->o2 >= fuzz->slen * 8;
+ case FUZZ_2_BYTE_FLIP:
+ return fuzz->o2 >= fuzz->slen;
+ case FUZZ_1_BYTE_FLIP:
+ case FUZZ_TRUNCATE_START:
+ case FUZZ_TRUNCATE_END:
+ case FUZZ_BASE64:
+ return fuzz->o1 >= fuzz->slen;
+ default:
+ abort();
+ }
+}
+
+void
+fuzz_next(struct fuzz *fuzz)
+{
+ u_int i;
+
+ FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, "
+ "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
+ (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
+
+ if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) {
+ /* If we are just starting out, we need to allocate too */
+ if (fuzz->fuzzed == NULL) {
+ FUZZ_DBG(("alloc"));
+ fuzz->fuzzed = calloc(fuzz->slen, 1);
+ }
+ /* Pick next strategy */
+ FUZZ_DBG(("advance"));
+ for (i = 1; i <= FUZZ_MAX; i <<= 1) {
+ if ((fuzz->strategies & i) != 0) {
+ fuzz->strategy = i;
+ break;
+ }
+ }
+ FUZZ_DBG(("selected = %u", fuzz->strategy));
+ if (fuzz->strategy == 0) {
+ FUZZ_DBG(("done, no more strategies"));
+ return;
+ }
+ fuzz->strategies &= ~(fuzz->strategy);
+ fuzz->o1 = fuzz->o2 = 0;
+ }
+
+ assert(fuzz->fuzzed != NULL);
+
+ switch (fuzz->strategy) {
+ case FUZZ_1_BIT_FLIP:
+ assert(fuzz->o1 / 8 < fuzz->slen);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
+ fuzz->o1++;
+ break;
+ case FUZZ_2_BIT_FLIP:
+ assert(fuzz->o1 / 8 < fuzz->slen);
+ assert(fuzz->o2 / 8 < fuzz->slen);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
+ fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8);
+ fuzz->o1++;
+ if (fuzz->o1 >= fuzz->slen * 8) {
+ fuzz->o1 = 0;
+ fuzz->o2++;
+ }
+ break;
+ case FUZZ_1_BYTE_FLIP:
+ assert(fuzz->o1 < fuzz->slen);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->fuzzed[fuzz->o1] ^= 0xff;
+ fuzz->o1++;
+ break;
+ case FUZZ_2_BYTE_FLIP:
+ assert(fuzz->o1 < fuzz->slen);
+ assert(fuzz->o2 < fuzz->slen);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->fuzzed[fuzz->o1] ^= 0xff;
+ fuzz->fuzzed[fuzz->o2] ^= 0xff;
+ fuzz->o1++;
+ if (fuzz->o1 >= fuzz->slen) {
+ fuzz->o1 = 0;
+ fuzz->o2++;
+ }
+ break;
+ case FUZZ_TRUNCATE_START:
+ case FUZZ_TRUNCATE_END:
+ assert(fuzz->o1 < fuzz->slen);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->o1++;
+ break;
+ case FUZZ_BASE64:
+ assert(fuzz->o1 < fuzz->slen);
+ assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
+ memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
+ fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2];
+ fuzz->o2++;
+ if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) {
+ fuzz->o2 = 0;
+ fuzz->o1++;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, "
+ "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
+ (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
+}
+
+int
+fuzz_done(struct fuzz *fuzz)
+{
+ FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
+ (u_long)fuzz->strategies));
+
+ return fuzz_strategy_done(fuzz) && fuzz->strategies == 0;
+}
+
+size_t
+fuzz_len(struct fuzz *fuzz)
+{
+ assert(fuzz->fuzzed != NULL);
+ switch (fuzz->strategy) {
+ case FUZZ_1_BIT_FLIP:
+ case FUZZ_2_BIT_FLIP:
+ case FUZZ_1_BYTE_FLIP:
+ case FUZZ_2_BYTE_FLIP:
+ case FUZZ_BASE64:
+ return fuzz->slen;
+ case FUZZ_TRUNCATE_START:
+ case FUZZ_TRUNCATE_END:
+ assert(fuzz->o1 <= fuzz->slen);
+ return fuzz->slen - fuzz->o1;
+ default:
+ abort();
+ }
+}
+
+u_char *
+fuzz_ptr(struct fuzz *fuzz)
+{
+ assert(fuzz->fuzzed != NULL);
+ switch (fuzz->strategy) {
+ case FUZZ_1_BIT_FLIP:
+ case FUZZ_2_BIT_FLIP:
+ case FUZZ_1_BYTE_FLIP:
+ case FUZZ_2_BYTE_FLIP:
+ case FUZZ_BASE64:
+ return fuzz->fuzzed;
+ case FUZZ_TRUNCATE_START:
+ assert(fuzz->o1 <= fuzz->slen);
+ return fuzz->fuzzed + fuzz->o1;
+ case FUZZ_TRUNCATE_END:
+ assert(fuzz->o1 <= fuzz->slen);
+ return fuzz->fuzzed;
+ default:
+ abort();
+ }
+}
+
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.c b/crypto/openssh/regress/unittests/test_helper/test_helper.c
new file mode 100644
index 0000000..d0bc678
--- /dev/null
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.c
@@ -0,0 +1,471 @@
+/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */
+/*
+ * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Utility functions/framework for regress tests */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+
+#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
+# include <vis.h>
+#endif
+
+#include "test_helper.h"
+
+#define TEST_CHECK_INT(r, pred) do { \
+ switch (pred) { \
+ case TEST_EQ: \
+ if (r == 0) \
+ return; \
+ break; \
+ case TEST_NE: \
+ if (r != 0) \
+ return; \
+ break; \
+ case TEST_LT: \
+ if (r < 0) \
+ return; \
+ break; \
+ case TEST_LE: \
+ if (r <= 0) \
+ return; \
+ break; \
+ case TEST_GT: \
+ if (r > 0) \
+ return; \
+ break; \
+ case TEST_GE: \
+ if (r >= 0) \
+ return; \
+ break; \
+ default: \
+ abort(); \
+ } \
+ } while (0)
+
+#define TEST_CHECK(x1, x2, pred) do { \
+ switch (pred) { \
+ case TEST_EQ: \
+ if (x1 == x2) \
+ return; \
+ break; \
+ case TEST_NE: \
+ if (x1 != x2) \
+ return; \
+ break; \
+ case TEST_LT: \
+ if (x1 < x2) \
+ return; \
+ break; \
+ case TEST_LE: \
+ if (x1 <= x2) \
+ return; \
+ break; \
+ case TEST_GT: \
+ if (x1 > x2) \
+ return; \
+ break; \
+ case TEST_GE: \
+ if (x1 >= x2) \
+ return; \
+ break; \
+ default: \
+ abort(); \
+ } \
+ } while (0)
+
+extern char *__progname;
+
+static int verbose_mode = 0;
+static int quiet_mode = 0;
+static char *active_test_name = NULL;
+static u_int test_number = 0;
+static test_onerror_func_t *test_onerror = NULL;
+static void *onerror_ctx = NULL;
+static const char *data_dir = NULL;
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+ /* Handle systems without __progname */
+ if (__progname == NULL) {
+ __progname = strrchr(argv[0], '/');
+ if (__progname == NULL || __progname[1] == '\0')
+ __progname = argv[0];
+ else
+ __progname++;
+ if ((__progname = strdup(__progname)) == NULL) {
+ fprintf(stderr, "strdup failed\n");
+ exit(1);
+ }
+ }
+
+ while ((ch = getopt(argc, argv, "vqd:")) != -1) {
+ switch (ch) {
+ case 'd':
+ data_dir = optarg;
+ break;
+ case 'q':
+ verbose_mode = 0;
+ quiet_mode = 1;
+ break;
+ case 'v':
+ verbose_mode = 1;
+ quiet_mode = 0;
+ break;
+ default:
+ fprintf(stderr, "Unrecognised command line option\n");
+ fprintf(stderr, "Usage: %s [-v]\n", __progname);
+ exit(1);
+ }
+ }
+ setvbuf(stdout, NULL, _IONBF, 0);
+ if (!quiet_mode)
+ printf("%s: ", __progname);
+ if (verbose_mode)
+ printf("\n");
+
+ tests();
+
+ if (!quiet_mode)
+ printf(" %u tests ok\n", test_number);
+ return 0;
+}
+
+const char *
+test_data_file(const char *name)
+{
+ static char ret[PATH_MAX];
+
+ if (data_dir != NULL)
+ snprintf(ret, sizeof(ret), "%s/%s", data_dir, name);
+ else
+ strlcpy(ret, name, sizeof(ret));
+ if (access(ret, F_OK) != 0) {
+ fprintf(stderr, "Cannot access data file %s: %s\n",
+ ret, strerror(errno));
+ exit(1);
+ }
+ return ret;
+}
+
+void
+test_start(const char *n)
+{
+ assert(active_test_name == NULL);
+ assert((active_test_name = strdup(n)) != NULL);
+ if (verbose_mode)
+ printf("test %u - \"%s\": ", test_number, active_test_name);
+ test_number++;
+}
+
+void
+set_onerror_func(test_onerror_func_t *f, void *ctx)
+{
+ test_onerror = f;
+ onerror_ctx = ctx;
+}
+
+void
+test_done(void)
+{
+ assert(active_test_name != NULL);
+ free(active_test_name);
+ active_test_name = NULL;
+ if (verbose_mode)
+ printf("OK\n");
+ else if (!quiet_mode) {
+ printf(".");
+ fflush(stdout);
+ }
+}
+
+void
+ssl_err_check(const char *file, int line)
+{
+ long openssl_error = ERR_get_error();
+
+ if (openssl_error == 0)
+ return;
+
+ fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s",
+ file, line, ERR_error_string(openssl_error, NULL));
+ abort();
+}
+
+static const char *
+pred_name(enum test_predicate p)
+{
+ switch (p) {
+ case TEST_EQ:
+ return "EQ";
+ case TEST_NE:
+ return "NE";
+ case TEST_LT:
+ return "LT";
+ case TEST_LE:
+ return "LE";
+ case TEST_GT:
+ return "GT";
+ case TEST_GE:
+ return "GE";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static void
+test_die(void)
+{
+ if (test_onerror != NULL)
+ test_onerror(onerror_ctx);
+ abort();
+}
+
+static void
+test_header(const char *file, int line, const char *a1, const char *a2,
+ const char *name, enum test_predicate pred)
+{
+ fprintf(stderr, "\n%s:%d test #%u \"%s\"\n",
+ file, line, test_number, active_test_name);
+ fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
+ name, pred_name(pred), a1,
+ a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
+}
+
+void
+assert_bignum(const char *file, int line, const char *a1, const char *a2,
+ const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred)
+{
+ int r = BN_cmp(aa1, aa2);
+
+ TEST_CHECK_INT(r, pred);
+ test_header(file, line, a1, a2, "BIGNUM", pred);
+ fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1));
+ fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2));
+ test_die();
+}
+
+void
+assert_string(const char *file, int line, const char *a1, const char *a2,
+ const char *aa1, const char *aa2, enum test_predicate pred)
+{
+ int r = strcmp(aa1, aa2);
+
+ TEST_CHECK_INT(r, pred);
+ test_header(file, line, a1, a2, "STRING", pred);
+ fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
+ fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2));
+ test_die();
+}
+
+static char *
+tohex(const void *_s, size_t l)
+{
+ u_int8_t *s = (u_int8_t *)_s;
+ size_t i, j;
+ const char *hex = "0123456789abcdef";
+ char *r = malloc((l * 2) + 1);
+
+ assert(r != NULL);
+ for (i = j = 0; i < l; i++) {
+ r[j++] = hex[(s[i] >> 4) & 0xf];
+ r[j++] = hex[s[i] & 0xf];
+ }
+ r[j] = '\0';
+ return r;
+}
+
+void
+assert_mem(const char *file, int line, const char *a1, const char *a2,
+ const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
+{
+ int r = memcmp(aa1, aa2, l);
+
+ TEST_CHECK_INT(r, pred);
+ test_header(file, line, a1, a2, "STRING", pred);
+ fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
+ fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l);
+ test_die();
+}
+
+static int
+memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where)
+{
+ size_t i;
+
+ for (i = 0; i < l; i++) {
+ if (s[i] != v) {
+ *where = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+assert_mem_filled(const char *file, int line, const char *a1,
+ const void *aa1, u_char v, size_t l, enum test_predicate pred)
+{
+ size_t where = -1;
+ int r = memvalcmp(aa1, v, l, &where);
+ char tmp[64];
+
+ if (l == 0)
+ return;
+ TEST_CHECK_INT(r, pred);
+ test_header(file, line, a1, NULL, "MEM_ZERO", pred);
+ fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
+ tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l);
+ snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where);
+ fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp,
+ ((u_char *)aa1)[where], v);
+ test_die();
+}
+
+void
+assert_int(const char *file, int line, const char *a1, const char *a2,
+ int aa1, int aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "INT", pred);
+ fprintf(stderr, "%12s = %d\n", a1, aa1);
+ fprintf(stderr, "%12s = %d\n", a2, aa2);
+ test_die();
+}
+
+void
+assert_size_t(const char *file, int line, const char *a1, const char *a2,
+ size_t aa1, size_t aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "SIZE_T", pred);
+ fprintf(stderr, "%12s = %zu\n", a1, aa1);
+ fprintf(stderr, "%12s = %zu\n", a2, aa2);
+ test_die();
+}
+
+void
+assert_u_int(const char *file, int line, const char *a1, const char *a2,
+ u_int aa1, u_int aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "U_INT", pred);
+ fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1);
+ fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2);
+ test_die();
+}
+
+void
+assert_long_long(const char *file, int line, const char *a1, const char *a2,
+ long long aa1, long long aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "LONG LONG", pred);
+ fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1);
+ fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2);
+ test_die();
+}
+
+void
+assert_char(const char *file, int line, const char *a1, const char *a2,
+ char aa1, char aa2, enum test_predicate pred)
+{
+ char buf[8];
+
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "CHAR", pred);
+ fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
+ vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1);
+ fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1,
+ vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2);
+ test_die();
+}
+
+void
+assert_u8(const char *file, int line, const char *a1, const char *a2,
+ u_int8_t aa1, u_int8_t aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "U8", pred);
+ fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1);
+ fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2);
+ test_die();
+}
+
+void
+assert_u16(const char *file, int line, const char *a1, const char *a2,
+ u_int16_t aa1, u_int16_t aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "U16", pred);
+ fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1);
+ fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2);
+ test_die();
+}
+
+void
+assert_u32(const char *file, int line, const char *a1, const char *a2,
+ u_int32_t aa1, u_int32_t aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "U32", pred);
+ fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1);
+ fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2);
+ test_die();
+}
+
+void
+assert_u64(const char *file, int line, const char *a1, const char *a2,
+ u_int64_t aa1, u_int64_t aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "U64", pred);
+ fprintf(stderr, "%12s = 0x%016llx %llu\n", a1,
+ (unsigned long long)aa1, (unsigned long long)aa1);
+ fprintf(stderr, "%12s = 0x%016llx %llu\n", a2,
+ (unsigned long long)aa2, (unsigned long long)aa2);
+ test_die();
+}
+
+void
+assert_ptr(const char *file, int line, const char *a1, const char *a2,
+ const void *aa1, const void *aa2, enum test_predicate pred)
+{
+ TEST_CHECK(aa1, aa2, pred);
+ test_header(file, line, a1, a2, "PTR", pred);
+ fprintf(stderr, "%12s = %p\n", a1, aa1);
+ fprintf(stderr, "%12s = %p\n", a2, aa2);
+ test_die();
+}
+
diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.h b/crypto/openssh/regress/unittests/test_helper/test_helper.h
new file mode 100644
index 0000000..a398c61
--- /dev/null
+++ b/crypto/openssh/regress/unittests/test_helper/test_helper.h
@@ -0,0 +1,292 @@
+/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */
+/*
+ * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Utility functions/framework for regress tests */
+
+#ifndef _TEST_HELPER_H
+#define _TEST_HELPER_H
+
+#include "includes.h"
+
+#include <sys/types.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+enum test_predicate {
+ TEST_EQ, TEST_NE, TEST_LT, TEST_LE, TEST_GT, TEST_GE
+};
+typedef void (test_onerror_func_t)(void *);
+
+/* Supplied by test suite */
+void tests(void);
+
+const char *test_data_file(const char *name);
+void test_start(const char *n);
+void set_onerror_func(test_onerror_func_t *f, void *ctx);
+void test_done(void);
+void ssl_err_check(const char *file, int line);
+void assert_bignum(const char *file, int line,
+ const char *a1, const char *a2,
+ const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred);
+void assert_string(const char *file, int line,
+ const char *a1, const char *a2,
+ const char *aa1, const char *aa2, enum test_predicate pred);
+void assert_mem(const char *file, int line,
+ const char *a1, const char *a2,
+ const void *aa1, const void *aa2, size_t l, enum test_predicate pred);
+void assert_mem_filled(const char *file, int line,
+ const char *a1,
+ const void *aa1, u_char v, size_t l, enum test_predicate pred);
+void assert_int(const char *file, int line,
+ const char *a1, const char *a2,
+ int aa1, int aa2, enum test_predicate pred);
+void assert_size_t(const char *file, int line,
+ const char *a1, const char *a2,
+ size_t aa1, size_t aa2, enum test_predicate pred);
+void assert_u_int(const char *file, int line,
+ const char *a1, const char *a2,
+ u_int aa1, u_int aa2, enum test_predicate pred);
+void assert_long_long(const char *file, int line,
+ const char *a1, const char *a2,
+ long long aa1, long long aa2, enum test_predicate pred);
+void assert_char(const char *file, int line,
+ const char *a1, const char *a2,
+ char aa1, char aa2, enum test_predicate pred);
+void assert_ptr(const char *file, int line,
+ const char *a1, const char *a2,
+ const void *aa1, const void *aa2, enum test_predicate pred);
+void assert_u8(const char *file, int line,
+ const char *a1, const char *a2,
+ u_int8_t aa1, u_int8_t aa2, enum test_predicate pred);
+void assert_u16(const char *file, int line,
+ const char *a1, const char *a2,
+ u_int16_t aa1, u_int16_t aa2, enum test_predicate pred);
+void assert_u32(const char *file, int line,
+ const char *a1, const char *a2,
+ u_int32_t aa1, u_int32_t aa2, enum test_predicate pred);
+void assert_u64(const char *file, int line,
+ const char *a1, const char *a2,
+ u_int64_t aa1, u_int64_t aa2, enum test_predicate pred);
+
+#define TEST_START(n) test_start(n)
+#define TEST_DONE() test_done()
+#define TEST_ONERROR(f, c) set_onerror_func(f, c)
+#define SSL_ERR_CHECK() ssl_err_check(__FILE__, __LINE__)
+
+#define ASSERT_BIGNUM_EQ(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_STRING_EQ(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_MEM_EQ(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_EQ)
+#define ASSERT_MEM_FILLED_EQ(a1, c, l) \
+ assert_mem_filled(__FILE__, __LINE__, #a1, a1, c, l, TEST_EQ)
+#define ASSERT_MEM_ZERO_EQ(a1, l) \
+ assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_EQ)
+#define ASSERT_INT_EQ(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_SIZE_T_EQ(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_U_INT_EQ(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_LONG_LONG_EQ(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_CHAR_EQ(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_PTR_EQ(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_U8_EQ(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_U16_EQ(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_U32_EQ(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+#define ASSERT_U64_EQ(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
+
+#define ASSERT_BIGNUM_NE(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_STRING_NE(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_MEM_NE(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_NE)
+#define ASSERT_MEM_ZERO_NE(a1, l) \
+ assert_mem_filled(__FILE__, __LINE__, #a1, a1, '\0', l, TEST_NE)
+#define ASSERT_INT_NE(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_SIZE_T_NE(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_U_INT_NE(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_LONG_LONG_NE(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_CHAR_NE(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_PTR_NE(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_U8_NE(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_U16_NE(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_U32_NE(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+#define ASSERT_U64_NE(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
+
+#define ASSERT_BIGNUM_LT(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_STRING_LT(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_MEM_LT(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LT)
+#define ASSERT_INT_LT(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_SIZE_T_LT(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_U_INT_LT(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_LONG_LONG_LT(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_CHAR_LT(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_PTR_LT(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_U8_LT(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_U16_LT(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_U32_LT(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+#define ASSERT_U64_LT(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
+
+#define ASSERT_BIGNUM_LE(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_STRING_LE(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_MEM_LE(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_LE)
+#define ASSERT_INT_LE(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_SIZE_T_LE(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_U_INT_LE(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_LONG_LONG_LE(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_CHAR_LE(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_PTR_LE(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_U8_LE(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_U16_LE(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_U32_LE(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+#define ASSERT_U64_LE(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
+
+#define ASSERT_BIGNUM_GT(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_STRING_GT(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_MEM_GT(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GT)
+#define ASSERT_INT_GT(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_SIZE_T_GT(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_U_INT_GT(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_LONG_LONG_GT(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_CHAR_GT(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_PTR_GT(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_U8_GT(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_U16_GT(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_U32_GT(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+#define ASSERT_U64_GT(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
+
+#define ASSERT_BIGNUM_GE(a1, a2) \
+ assert_bignum(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_STRING_GE(a1, a2) \
+ assert_string(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_MEM_GE(a1, a2, l) \
+ assert_mem(__FILE__, __LINE__, #a1, #a2, a1, a2, l, TEST_GE)
+#define ASSERT_INT_GE(a1, a2) \
+ assert_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_SIZE_T_GE(a1, a2) \
+ assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_U_INT_GE(a1, a2) \
+ assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_LONG_LONG_GE(a1, a2) \
+ assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_CHAR_GE(a1, a2) \
+ assert_char(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_PTR_GE(a1, a2) \
+ assert_ptr(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_U8_GE(a1, a2) \
+ assert_u8(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_U16_GE(a1, a2) \
+ assert_u16(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_U32_GE(a1, a2) \
+ assert_u32(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+#define ASSERT_U64_GE(a1, a2) \
+ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
+
+/* Fuzzing support */
+
+struct fuzz;
+#define FUZZ_1_BIT_FLIP 0x00000001 /* Flip one bit at a time */
+#define FUZZ_2_BIT_FLIP 0x00000002 /* Flip two bits at a time */
+#define FUZZ_1_BYTE_FLIP 0x00000004 /* Flip one byte at a time */
+#define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */
+#define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */
+#define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */
+#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */
+#define FUZZ_MAX FUZZ_BASE64
+
+/* Start fuzzing a blob of data with selected strategies (bitmask) */
+struct fuzz *fuzz_begin(u_int strategies, const void *p, size_t l);
+
+/* Free a fuzz context */
+void fuzz_cleanup(struct fuzz *fuzz);
+
+/* Prepare the next fuzz case in the series */
+void fuzz_next(struct fuzz *fuzz);
+
+/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
+int fuzz_done(struct fuzz *fuzz);
+
+/* Return the length and a pointer to the current fuzzed case */
+size_t fuzz_len(struct fuzz *fuzz);
+u_char *fuzz_ptr(struct fuzz *fuzz);
+
+/* Dump the current fuzz case to stderr */
+void fuzz_dump(struct fuzz *fuzz);
+#endif /* _TEST_HELPER_H */
diff --git a/crypto/openssh/regress/yes-head.sh b/crypto/openssh/regress/yes-head.sh
new file mode 100644
index 0000000..a8e6bc8
--- /dev/null
+++ b/crypto/openssh/regress/yes-head.sh
@@ -0,0 +1,15 @@
+# $OpenBSD: yes-head.sh,v 1.4 2002/03/15 13:08:56 markus Exp $
+# Placed in the Public Domain.
+
+tid="yes pipe head"
+
+for p in 1 2; do
+ lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)`
+ if [ $? -ne 0 ]; then
+ fail "yes|head test failed"
+ lines = 0;
+ fi
+ if [ $lines -ne 2000 ]; then
+ fail "yes|head returns $lines lines instead of 2000"
+ fi
+done
OpenPOWER on IntegriCloud