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
|
#!/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
|
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 ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
|
||||||
ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_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
|
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
|
* Regress test for sshkey.h key management API
|
||||||
*
|
*
|
||||||
|
@ -36,6 +36,20 @@
|
||||||
|
|
||||||
void sshkey_tests(void);
|
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
|
static void
|
||||||
build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
|
build_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
|
||||||
const struct sshkey *sign_key, const struct sshkey *ca_key)
|
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;
|
size_t siglen;
|
||||||
|
|
||||||
ca_buf = sshbuf_new();
|
ca_buf = sshbuf_new();
|
||||||
|
ASSERT_PTR_NE(ca_buf, NULL);
|
||||||
ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0);
|
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 :/
|
* the type string. This is a bit of a hack :/
|
||||||
*/
|
*/
|
||||||
pk = sshbuf_new();
|
pk = sshbuf_new();
|
||||||
|
ASSERT_PTR_NE(pk, NULL);
|
||||||
ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
|
ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0);
|
||||||
ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
|
ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
|
||||||
|
|
||||||
principals = sshbuf_new();
|
principals = sshbuf_new();
|
||||||
|
ASSERT_PTR_NE(principals, NULL);
|
||||||
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
|
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
|
||||||
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
|
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
|
||||||
|
|
||||||
critopts = sshbuf_new();
|
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();
|
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, type), 0);
|
||||||
ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
|
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);
|
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
|
void
|
||||||
sshkey_tests(void)
|
sshkey_tests(void)
|
||||||
{
|
{
|
||||||
|
@ -332,26 +413,98 @@ sshkey_tests(void)
|
||||||
#endif
|
#endif
|
||||||
sshkey_free(kf);
|
sshkey_free(kf);
|
||||||
|
|
||||||
/* XXX certify test */
|
TEST_START("certify key");
|
||||||
/* XXX sign test */
|
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
|
||||||
/* XXX verify test */
|
&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");
|
TEST_START("nested certificate");
|
||||||
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
|
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,
|
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
|
||||||
NULL), 0);
|
NULL), 0);
|
||||||
b = load_file("rsa_2");
|
k3 = get_private("ed25519_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);
|
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),
|
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
|
||||||
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
|
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
|
||||||
ASSERT_PTR_EQ(k4, NULL);
|
ASSERT_PTR_EQ(k4, NULL);
|
||||||
sshbuf_free(b);
|
|
||||||
sshkey_free(k1);
|
sshkey_free(k1);
|
||||||
sshkey_free(k2);
|
sshkey_free(k2);
|
||||||
sshkey_free(k3);
|
sshkey_free(k3);
|
||||||
|
sshbuf_free(b);
|
||||||
TEST_DONE();
|
TEST_DONE();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue