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
This commit is contained in:
parent
589e69fd82
commit
3a2b09d147
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -36,6 +36,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)
|
||||
|
@ -45,6 +59,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);
|
||||
|
||||
/*
|
||||
|
@ -52,18 +67,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 */
|
||||
|
@ -90,6 +110,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)
|
||||
{
|
||||
|
@ -332,26 +413,98 @@ sshkey_tests(void)
|
|||
#endif
|
||||
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();
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue