diff options
author | Colin Watson <cjwatson@debian.org> | 2015-08-19 14:23:51 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2015-08-19 16:48:11 +0100 |
commit | 0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch) | |
tree | ba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /regress/unittests/sshkey/test_sshkey.c | |
parent | f2a5f5dae656759efb0b76c3d94890b65c197a02 (diff) | |
parent | 8698446b972003b63dfe5dcbdb86acfe986afb85 (diff) |
New upstream release (6.8p1).
Diffstat (limited to 'regress/unittests/sshkey/test_sshkey.c')
-rw-r--r-- | regress/unittests/sshkey/test_sshkey.c | 192 |
1 files changed, 177 insertions, 15 deletions
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index ef0c67956..ad10c9be2 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.3 2015/01/26 06:11:28 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Regress test for sshkey.h key management API | 3 | * Regress test for sshkey.h key management API |
4 | * | 4 | * |
@@ -19,7 +19,7 @@ | |||
19 | #include <openssl/bn.h> | 19 | #include <openssl/bn.h> |
20 | #include <openssl/rsa.h> | 20 | #include <openssl/rsa.h> |
21 | #include <openssl/dsa.h> | 21 | #include <openssl/dsa.h> |
22 | #ifdef OPENSSL_HAS_NISTP256 | 22 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
23 | # include <openssl/ec.h> | 23 | # include <openssl/ec.h> |
24 | #endif | 24 | #endif |
25 | 25 | ||
@@ -37,6 +37,20 @@ | |||
37 | void sshkey_tests(void); | 37 | void sshkey_tests(void); |
38 | 38 | ||
39 | static void | 39 | static void |
40 | put_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 | |||
53 | static void | ||
40 | build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | 54 | build_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,25 +59,31 @@ 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(); |
48 | ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); | 62 | ASSERT_PTR_NE(ca_buf, NULL); |
63 | ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); | ||
49 | 64 | ||
50 | /* | 65 | /* |
51 | * Get the public key serialisation by rendering the key and skipping | 66 | * Get the public key serialisation by rendering the key and skipping |
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(); |
55 | ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); | 70 | ASSERT_PTR_NE(pk, NULL); |
71 | ASSERT_INT_EQ(sshkey_putb_plain(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,10 +110,74 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | |||
90 | sshbuf_free(pk); | 110 | sshbuf_free(pk); |
91 | } | 111 | } |
92 | 112 | ||
113 | static void | ||
114 | signature_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 | |||
130 | static void | ||
131 | banana(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 | |||
145 | static void | ||
146 | signature_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 | |||
162 | static struct sshkey * | ||
163 | get_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 | |||
93 | void | 174 | void |
94 | sshkey_tests(void) | 175 | sshkey_tests(void) |
95 | { | 176 | { |
96 | struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; | 177 | struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; |
178 | #ifdef OPENSSL_HAS_ECC | ||
179 | struct sshkey *ke; | ||
180 | #endif | ||
97 | struct sshbuf *b; | 181 | struct sshbuf *b; |
98 | 182 | ||
99 | TEST_START("new invalid"); | 183 | TEST_START("new invalid"); |
@@ -136,12 +220,14 @@ sshkey_tests(void) | |||
136 | sshkey_free(k1); | 220 | sshkey_free(k1); |
137 | TEST_DONE(); | 221 | TEST_DONE(); |
138 | 222 | ||
223 | #ifdef OPENSSL_HAS_ECC | ||
139 | TEST_START("new/free KEY_ECDSA"); | 224 | TEST_START("new/free KEY_ECDSA"); |
140 | k1 = sshkey_new(KEY_ECDSA); | 225 | k1 = sshkey_new(KEY_ECDSA); |
141 | ASSERT_PTR_NE(k1, NULL); | 226 | ASSERT_PTR_NE(k1, NULL); |
142 | ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ | 227 | ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ |
143 | sshkey_free(k1); | 228 | sshkey_free(k1); |
144 | TEST_DONE(); | 229 | TEST_DONE(); |
230 | #endif | ||
145 | 231 | ||
146 | TEST_START("new/free KEY_ED25519"); | 232 | TEST_START("new/free KEY_ED25519"); |
147 | k1 = sshkey_new(KEY_ED25519); | 233 | k1 = sshkey_new(KEY_ED25519); |
@@ -192,12 +278,14 @@ sshkey_tests(void) | |||
192 | sshkey_free(k1); | 278 | sshkey_free(k1); |
193 | TEST_DONE(); | 279 | TEST_DONE(); |
194 | 280 | ||
281 | #ifdef OPENSSL_HAS_ECC | ||
195 | TEST_START("generate KEY_ECDSA wrong bits"); | 282 | TEST_START("generate KEY_ECDSA wrong bits"); |
196 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), | 283 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), |
197 | SSH_ERR_INVALID_ARGUMENT); | 284 | SSH_ERR_INVALID_ARGUMENT); |
198 | ASSERT_PTR_EQ(k1, NULL); | 285 | ASSERT_PTR_EQ(k1, NULL); |
199 | sshkey_free(k1); | 286 | sshkey_free(k1); |
200 | TEST_DONE(); | 287 | TEST_DONE(); |
288 | #endif | ||
201 | 289 | ||
202 | TEST_START("generate KEY_RSA"); | 290 | TEST_START("generate KEY_RSA"); |
203 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); | 291 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); |
@@ -332,26 +420,100 @@ sshkey_tests(void) | |||
332 | #endif | 420 | #endif |
333 | sshkey_free(kf); | 421 | sshkey_free(kf); |
334 | 422 | ||
335 | /* XXX certify test */ | 423 | TEST_START("certify key"); |
336 | /* XXX sign test */ | 424 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), |
337 | /* XXX verify test */ | 425 | &k1, NULL), 0); |
426 | k2 = get_private("ed25519_2"); | ||
427 | ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0); | ||
428 | ASSERT_PTR_NE(k1->cert, NULL); | ||
429 | k1->cert->type = SSH2_CERT_TYPE_USER; | ||
430 | k1->cert->serial = 1234; | ||
431 | k1->cert->key_id = strdup("estragon"); | ||
432 | ASSERT_PTR_NE(k1->cert->key_id, NULL); | ||
433 | k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); | ||
434 | ASSERT_PTR_NE(k1->cert->principals, NULL); | ||
435 | k1->cert->principals[0] = strdup("estragon"); | ||
436 | k1->cert->principals[1] = strdup("vladimir"); | ||
437 | k1->cert->principals[2] = strdup("pozzo"); | ||
438 | k1->cert->principals[3] = strdup("lucky"); | ||
439 | ASSERT_PTR_NE(k1->cert->principals[0], NULL); | ||
440 | ASSERT_PTR_NE(k1->cert->principals[1], NULL); | ||
441 | ASSERT_PTR_NE(k1->cert->principals[2], NULL); | ||
442 | ASSERT_PTR_NE(k1->cert->principals[3], NULL); | ||
443 | k1->cert->valid_after = 0; | ||
444 | k1->cert->valid_before = (u_int64_t)-1; | ||
445 | k1->cert->critical = sshbuf_new(); | ||
446 | ASSERT_PTR_NE(k1->cert->critical, NULL); | ||
447 | k1->cert->extensions = sshbuf_new(); | ||
448 | ASSERT_PTR_NE(k1->cert->extensions, NULL); | ||
449 | put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); | ||
450 | put_opt(k1->cert->critical, "source-address", "127.0.0.1"); | ||
451 | put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); | ||
452 | put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); | ||
453 | ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); | ||
454 | ASSERT_INT_EQ(sshkey_certify(k1, k2), 0); | ||
455 | b = sshbuf_new(); | ||
456 | ASSERT_PTR_NE(b, NULL); | ||
457 | ASSERT_INT_EQ(sshkey_putb(k1, b), 0); | ||
458 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); | ||
459 | |||
460 | sshkey_free(k1); | ||
461 | sshkey_free(k2); | ||
462 | sshkey_free(k3); | ||
463 | sshbuf_reset(b); | ||
464 | TEST_DONE(); | ||
465 | |||
466 | TEST_START("sign and verify RSA"); | ||
467 | k1 = get_private("rsa_1"); | ||
468 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, | ||
469 | NULL), 0); | ||
470 | signature_tests(k1, k2); | ||
471 | sshkey_free(k1); | ||
472 | sshkey_free(k2); | ||
473 | TEST_DONE(); | ||
474 | |||
475 | TEST_START("sign and verify DSA"); | ||
476 | k1 = get_private("dsa_1"); | ||
477 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, | ||
478 | NULL), 0); | ||
479 | signature_tests(k1, k2); | ||
480 | sshkey_free(k1); | ||
481 | sshkey_free(k2); | ||
482 | TEST_DONE(); | ||
483 | |||
484 | #ifdef OPENSSL_HAS_ECC | ||
485 | TEST_START("sign and verify ECDSA"); | ||
486 | k1 = get_private("ecdsa_1"); | ||
487 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, | ||
488 | NULL), 0); | ||
489 | signature_tests(k1, k2); | ||
490 | sshkey_free(k1); | ||
491 | sshkey_free(k2); | ||
492 | TEST_DONE(); | ||
493 | #endif | ||
494 | |||
495 | TEST_START("sign and verify ED25519"); | ||
496 | k1 = get_private("ed25519_1"); | ||
497 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, | ||
498 | NULL), 0); | ||
499 | signature_tests(k1, k2); | ||
500 | sshkey_free(k1); | ||
501 | sshkey_free(k2); | ||
502 | TEST_DONE(); | ||
338 | 503 | ||
339 | TEST_START("nested certificate"); | 504 | TEST_START("nested certificate"); |
340 | ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); | 505 | 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, | 506 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, |
342 | NULL), 0); | 507 | NULL), 0); |
343 | b = load_file("rsa_2"); | 508 | 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); | 509 | 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), | 510 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), |
349 | SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); | 511 | SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); |
350 | ASSERT_PTR_EQ(k4, NULL); | 512 | ASSERT_PTR_EQ(k4, NULL); |
351 | sshbuf_free(b); | ||
352 | sshkey_free(k1); | 513 | sshkey_free(k1); |
353 | sshkey_free(k2); | 514 | sshkey_free(k2); |
354 | sshkey_free(k3); | 515 | sshkey_free(k3); |
516 | sshbuf_free(b); | ||
355 | TEST_DONE(); | 517 | TEST_DONE(); |
356 | 518 | ||
357 | } | 519 | } |