summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-18 19:54:46 +0000
committerDamien Miller <djm@mindrot.org>2015-01-20 00:25:12 +1100
commit3a2b09d147a565d8a47edf37491e149a02c0d3a3 (patch)
tree4f892d936a838dff508007e1c063f1482d46e2a7
parent589e69fd82724cfc9738f128e4771da2e6405d0d (diff)
upstream commit
more and better key tests test signatures and verification test certificate generation flesh out nested cert test removes most of the XXX todo markers
-rwxr-xr-xregress/unittests/sshkey/mktestdata.sh4
-rw-r--r--regress/unittests/sshkey/test_sshkey.c175
2 files changed, 167 insertions, 12 deletions
diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh
index ee1fe3962..09165af02 100755
--- a/regress/unittests/sshkey/mktestdata.sh
+++ b/regress/unittests/sshkey/mktestdata.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $ 2# $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $
3 3
4PW=mekmitasdigoat 4PW=mekmitasdigoat
5 5
@@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb 187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
188ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb 188ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb
189 189
190# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against)
191
190echo "$PW" > pw 192echo "$PW" > pw
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
index ef0c67956..247d42019 100644
--- a/regress/unittests/sshkey/test_sshkey.c
+++ b/regress/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 1/* $OpenBSD: test_sshkey.c,v 1.2 2015/01/18 19:54:46 djm Exp $ */
2/* 2/*
3 * Regress test for sshkey.h key management API 3 * Regress test for sshkey.h key management API
4 * 4 *
@@ -37,6 +37,20 @@
37void sshkey_tests(void); 37void sshkey_tests(void);
38 38
39static void 39static void
40put_opt(struct sshbuf *b, const char *name, const char *value)
41{
42 struct sshbuf *sect;
43
44 sect = sshbuf_new();
45 ASSERT_PTR_NE(sect, NULL);
46 ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
47 if (value != NULL)
48 ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
49 ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
50 sshbuf_free(sect);
51}
52
53static void
40build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, 54build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
41 const struct sshkey *sign_key, const struct sshkey *ca_key) 55 const struct sshkey *sign_key, const struct sshkey *ca_key)
42{ 56{
@@ -45,6 +59,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
45 size_t siglen; 59 size_t siglen;
46 60
47 ca_buf = sshbuf_new(); 61 ca_buf = sshbuf_new();
62 ASSERT_PTR_NE(ca_buf, NULL);
48 ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); 63 ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
49 64
50 /* 65 /*
@@ -52,18 +67,23 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
52 * the type string. This is a bit of a hack :/ 67 * the type string. This is a bit of a hack :/
53 */ 68 */
54 pk = sshbuf_new(); 69 pk = sshbuf_new();
70 ASSERT_PTR_NE(pk, NULL);
55 ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); 71 ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
56 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); 72 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
57 73
58 principals = sshbuf_new(); 74 principals = sshbuf_new();
75 ASSERT_PTR_NE(principals, NULL);
59 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); 76 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
60 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); 77 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
61 78
62 critopts = sshbuf_new(); 79 critopts = sshbuf_new();
63 /* XXX fill this in */ 80 ASSERT_PTR_NE(critopts, NULL);
81 put_opt(critopts, "force-command", "/usr/local/bin/nethack");
82 put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
64 83
65 exts = sshbuf_new(); 84 exts = sshbuf_new();
66 /* XXX fill this in */ 85 ASSERT_PTR_NE(exts, NULL);
86 put_opt(critopts, "permit-X11-forwarding", NULL);
67 87
68 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); 88 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
69 ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ 89 ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
@@ -90,6 +110,67 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
90 sshbuf_free(pk); 110 sshbuf_free(pk);
91} 111}
92 112
113static void
114signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l)
115{
116 size_t len;
117 u_char *sig;
118
119 ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0);
120 ASSERT_SIZE_T_GT(len, 8);
121 ASSERT_PTR_NE(sig, NULL);
122 ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
123 ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0);
124 /* Fuzz test is more comprehensive, this is just a smoke test */
125 sig[len - 5] ^= 0x10;
126 ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0);
127 free(sig);
128}
129
130static void
131banana(u_char *s, size_t l)
132{
133 size_t o;
134 const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
135
136 for (o = 0; o < l; o += sizeof(the_banana)) {
137 if (l - o < sizeof(the_banana)) {
138 memcpy(s + o, "nanananana", l - o);
139 break;
140 }
141 memcpy(s + o, banana, sizeof(the_banana));
142 }
143}
144
145static void
146signature_tests(struct sshkey *k, struct sshkey *bad)
147{
148 u_char i, buf[2049];
149 size_t lens[] = {
150 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
151 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
152 };
153
154 for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
155 test_subtest_info("%s key, banana length %zu",
156 sshkey_type(k), lens[i]);
157 banana(buf, lens[i]);
158 signature_test(k, bad, buf, lens[i]);
159 }
160}
161
162static struct sshkey *
163get_private(const char *n)
164{
165 struct sshbuf *b;
166 struct sshkey *ret;
167
168 b = load_file(n);
169 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0);
170 sshbuf_free(b);
171 return ret;
172}
173
93void 174void
94sshkey_tests(void) 175sshkey_tests(void)
95{ 176{
@@ -332,26 +413,98 @@ sshkey_tests(void)
332#endif 413#endif
333 sshkey_free(kf); 414 sshkey_free(kf);
334 415
335/* XXX certify test */ 416 TEST_START("certify key");
336/* XXX sign test */ 417 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
337/* XXX verify test */ 418 &k1, NULL), 0);
419 k2 = get_private("ed25519_2");
420 ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0);
421 ASSERT_PTR_NE(k1->cert, NULL);
422 k1->cert->type = SSH2_CERT_TYPE_USER;
423 k1->cert->serial = 1234;
424 k1->cert->key_id = strdup("estragon");
425 ASSERT_PTR_NE(k1->cert->key_id, NULL);
426 k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
427 ASSERT_PTR_NE(k1->cert->principals, NULL);
428 k1->cert->principals[0] = strdup("estragon");
429 k1->cert->principals[1] = strdup("vladimir");
430 k1->cert->principals[2] = strdup("pozzo");
431 k1->cert->principals[3] = strdup("lucky");
432 ASSERT_PTR_NE(k1->cert->principals[0], NULL);
433 ASSERT_PTR_NE(k1->cert->principals[1], NULL);
434 ASSERT_PTR_NE(k1->cert->principals[2], NULL);
435 ASSERT_PTR_NE(k1->cert->principals[3], NULL);
436 k1->cert->valid_after = 0;
437 k1->cert->valid_before = (u_int64_t)-1;
438 k1->cert->critical = sshbuf_new();
439 ASSERT_PTR_NE(k1->cert->critical, NULL);
440 k1->cert->extensions = sshbuf_new();
441 ASSERT_PTR_NE(k1->cert->extensions, NULL);
442 put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
443 put_opt(k1->cert->critical, "source-address", "127.0.0.1");
444 put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
445 put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
446 ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
447 ASSERT_INT_EQ(sshkey_certify(k1, k2), 0);
448 b = sshbuf_new();
449 ASSERT_PTR_NE(b, NULL);
450 ASSERT_INT_EQ(sshkey_to_blob_buf(k1, b), 0);
451 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
452
453 sshkey_free(k1);
454 sshkey_free(k2);
455 sshkey_free(k3);
456 sshbuf_reset(b);
457 TEST_DONE();
458
459 TEST_START("sign and verify RSA");
460 k1 = get_private("rsa_1");
461 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
462 NULL), 0);
463 signature_tests(k1, k2);
464 sshkey_free(k1);
465 sshkey_free(k2);
466 TEST_DONE();
467
468 TEST_START("sign and verify DSA");
469 k1 = get_private("dsa_1");
470 ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
471 NULL), 0);
472 signature_tests(k1, k2);
473 sshkey_free(k1);
474 sshkey_free(k2);
475 TEST_DONE();
476
477 TEST_START("sign and verify ECDSA");
478 k1 = get_private("ecdsa_1");
479 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
480 NULL), 0);
481 signature_tests(k1, k2);
482 sshkey_free(k1);
483 sshkey_free(k2);
484 TEST_DONE();
485
486 TEST_START("sign and verify ED25519");
487 k1 = get_private("ed25519_1");
488 ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
489 NULL), 0);
490 signature_tests(k1, k2);
491 sshkey_free(k1);
492 sshkey_free(k2);
493 TEST_DONE();
338 494
339 TEST_START("nested certificate"); 495 TEST_START("nested certificate");
340 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); 496 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
341 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, 497 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
342 NULL), 0); 498 NULL), 0);
343 b = load_file("rsa_2"); 499 k3 = get_private("ed25519_2");
344 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1",
345 &k3, NULL), 0);
346 sshbuf_reset(b);
347 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); 500 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1);
348 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), 501 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
349 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); 502 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
350 ASSERT_PTR_EQ(k4, NULL); 503 ASSERT_PTR_EQ(k4, NULL);
351 sshbuf_free(b);
352 sshkey_free(k1); 504 sshkey_free(k1);
353 sshkey_free(k2); 505 sshkey_free(k2);
354 sshkey_free(k3); 506 sshkey_free(k3);
507 sshbuf_free(b);
355 TEST_DONE(); 508 TEST_DONE();
356 509
357} 510}