summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2015-01-18 19:54:47 +0000
committerDamien Miller <djm@cvs.openbsd.org>2015-01-18 19:54:47 +0000
commit8abc848728add5d90bdad5da8cf27b79b6644340 (patch)
treea03514e69039be20f5f0cb63ef37a3a72b3a0cb0 /regress
parentccf5b985236313c4b5baf11b42b10d37c32e3d6a (diff)
more and better key tests
test signatures and verification test certificate generation flesh out nested cert test removes most of the XXX todo markers
Diffstat (limited to 'regress')
-rwxr-xr-xregress/usr.bin/ssh/unittests/sshkey/mktestdata.sh4
-rw-r--r--regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c175
2 files changed, 167 insertions, 12 deletions
diff --git a/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh b/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh
index ee1fe396208..09165af02fd 100755
--- a/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh
+++ b/regress/usr.bin/ssh/unittests/sshkey/mktestdata.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $
+# $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $
PW=mekmitasdigoat
@@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
+# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against)
+
echo "$PW" > pw
diff --git a/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c
index 0864ffd78a0..d455c4408d1 100644
--- a/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c
+++ b/regress/usr.bin/ssh/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: test_sshkey.c,v 1.2 2015/01/18 19:54:46 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -31,6 +31,20 @@
void sshkey_tests(void);
static void
+put_opt(struct sshbuf *b, const char *name, const char *value)
+{
+ struct sshbuf *sect;
+
+ sect = sshbuf_new();
+ ASSERT_PTR_NE(sect, NULL);
+ ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
+ if (value != NULL)
+ ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
+ ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
+ sshbuf_free(sect);
+}
+
+static void
build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
const struct sshkey *sign_key, const struct sshkey *ca_key)
{
@@ -39,6 +53,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
size_t siglen;
ca_buf = sshbuf_new();
+ ASSERT_PTR_NE(ca_buf, NULL);
ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
/*
@@ -46,18 +61,23 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
* the type string. This is a bit of a hack :/
*/
pk = sshbuf_new();
+ ASSERT_PTR_NE(pk, NULL);
ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
principals = sshbuf_new();
+ ASSERT_PTR_NE(principals, NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
critopts = sshbuf_new();
- /* XXX fill this in */
+ ASSERT_PTR_NE(critopts, NULL);
+ put_opt(critopts, "force-command", "/usr/local/bin/nethack");
+ put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
exts = sshbuf_new();
- /* XXX fill this in */
+ ASSERT_PTR_NE(exts, NULL);
+ put_opt(critopts, "permit-X11-forwarding", NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
@@ -84,6 +104,67 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
sshbuf_free(pk);
}
+static void
+signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l)
+{
+ size_t len;
+ u_char *sig;
+
+ ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0);
+ ASSERT_SIZE_T_GT(len, 8);
+ ASSERT_PTR_NE(sig, NULL);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0);
+ /* Fuzz test is more comprehensive, this is just a smoke test */
+ sig[len - 5] ^= 0x10;
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0);
+ free(sig);
+}
+
+static void
+banana(u_char *s, size_t l)
+{
+ size_t o;
+ const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
+
+ for (o = 0; o < l; o += sizeof(the_banana)) {
+ if (l - o < sizeof(the_banana)) {
+ memcpy(s + o, "nanananana", l - o);
+ break;
+ }
+ memcpy(s + o, banana, sizeof(the_banana));
+ }
+}
+
+static void
+signature_tests(struct sshkey *k, struct sshkey *bad)
+{
+ u_char i, buf[2049];
+ size_t lens[] = {
+ 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
+ 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
+ };
+
+ for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
+ test_subtest_info("%s key, banana length %zu",
+ sshkey_type(k), lens[i]);
+ banana(buf, lens[i]);
+ signature_test(k, bad, buf, lens[i]);
+ }
+}
+
+static struct sshkey *
+get_private(const char *n)
+{
+ struct sshbuf *b;
+ struct sshkey *ret;
+
+ b = load_file(n);
+ ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0);
+ sshbuf_free(b);
+ return ret;
+}
+
void
sshkey_tests(void)
{
@@ -316,26 +397,98 @@ sshkey_tests(void)
sshkey_free(ke);
sshkey_free(kf);
-/* XXX certify test */
-/* XXX sign test */
-/* XXX verify test */
+ TEST_START("certify key");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
+ &k1, NULL), 0);
+ k2 = get_private("ed25519_2");
+ ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0);
+ ASSERT_PTR_NE(k1->cert, NULL);
+ k1->cert->type = SSH2_CERT_TYPE_USER;
+ k1->cert->serial = 1234;
+ k1->cert->key_id = strdup("estragon");
+ ASSERT_PTR_NE(k1->cert->key_id, NULL);
+ k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
+ ASSERT_PTR_NE(k1->cert->principals, NULL);
+ k1->cert->principals[0] = strdup("estragon");
+ k1->cert->principals[1] = strdup("vladimir");
+ k1->cert->principals[2] = strdup("pozzo");
+ k1->cert->principals[3] = strdup("lucky");
+ ASSERT_PTR_NE(k1->cert->principals[0], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[1], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[2], NULL);
+ ASSERT_PTR_NE(k1->cert->principals[3], NULL);
+ k1->cert->valid_after = 0;
+ k1->cert->valid_before = (u_int64_t)-1;
+ k1->cert->critical = sshbuf_new();
+ ASSERT_PTR_NE(k1->cert->critical, NULL);
+ k1->cert->extensions = sshbuf_new();
+ ASSERT_PTR_NE(k1->cert->extensions, NULL);
+ put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
+ put_opt(k1->cert->critical, "source-address", "127.0.0.1");
+ put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
+ put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
+ ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
+ ASSERT_INT_EQ(sshkey_certify(k1, k2), 0);
+ b = sshbuf_new();
+ ASSERT_PTR_NE(b, NULL);
+ ASSERT_INT_EQ(sshkey_to_blob_buf(k1, b), 0);
+ ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
+
+ sshkey_free(k1);
+ sshkey_free(k2);
+ sshkey_free(k3);
+ sshbuf_reset(b);
+ TEST_DONE();
+
+ TEST_START("sign and verify RSA");
+ k1 = get_private("rsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("sign and verify DSA");
+ k1 = get_private("dsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("sign and verify ECDSA");
+ k1 = get_private("ecdsa_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
+
+ TEST_START("sign and verify ED25519");
+ k1 = get_private("ed25519_1");
+ ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
+ NULL), 0);
+ signature_tests(k1, k2);
+ sshkey_free(k1);
+ sshkey_free(k2);
+ TEST_DONE();
TEST_START("nested certificate");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
- b = load_file("rsa_2");
- ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
- &k3, NULL), 0);
- sshbuf_reset(b);
+ k3 = get_private("ed25519_2");
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
- sshbuf_free(b);
sshkey_free(k1);
sshkey_free(k2);
sshkey_free(k3);
+ sshbuf_free(b);
TEST_DONE();
}