diff --git a/unittests/sshkey/test_file.c b/unittests/sshkey/test_file.c new file mode 100644 index 0000000..d90d4ff --- /dev/null +++ b/unittests/sshkey/test_file.c @@ -0,0 +1,246 @@ +/* $OpenBSD$ */ +/* + * Regress test for sshkey.h key management API + * + * Placed in the public domain + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "test_helper.h" + +#include "err.h" +#include "authfile.h" +#include "key.h" +#include "sshbuf.h" + +void sshkey_file_tests(void); + +static struct sshbuf * +load_file(const char *name) +{ + int fd; + struct sshbuf *ret; + u_char *p; + + ASSERT_PTR_NE(ret = sshbuf_new(), NULL); + ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); + ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0); + close(fd); + /* Trim whitespace at EOL */ + for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) { + if (p[sshbuf_len(ret) - 1] == '\r' || + p[sshbuf_len(ret) - 1] == '\t' || + p[sshbuf_len(ret) - 1] == ' ' || + p[sshbuf_len(ret) - 1] == '\n') + ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0); + else + break; + } + /* \0 terminate */ + ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0); + return ret; +} + +static BIGNUM * +load_bignum(const char *name) +{ + BIGNUM *ret = NULL; + struct sshbuf *buf; + + buf = load_file(name); + ASSERT_INT_NE(BN_hex2bn(&ret, sshbuf_ptr(buf)), 0); + sshbuf_free(buf); + return ret; +} + +void +sshkey_file_tests(void) +{ + struct sshkey *k1, *k2; + struct sshbuf *buf, *pw; + BIGNUM *a, *b, *c; + char *cp; + + TEST_START("load passphrase"); + pw = load_file("pw"); + TEST_DONE(); + + TEST_START("parse RSA from private"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private(buf, "", "rsa_1", &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("rsa_1.param.n"); + b = load_bignum("rsa_1.param.p"); + c = load_bignum("rsa_1.param.q"); + ASSERT_BIGNUM_EQ(k1->rsa->n, a); + ASSERT_BIGNUM_EQ(k1->rsa->p, b); + ASSERT_BIGNUM_EQ(k1->rsa->q, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse RSA from private w/ passphrase"); + buf = load_file("rsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private(buf, sshbuf_ptr(pw), "rsa_1_pw", + &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load RSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("RSA key hex fingerprint"); + buf = load_file("rsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + TEST_START("RSA key bubblebabble fingerprint"); + buf = load_file("rsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + sshkey_free(k1); + + TEST_START("parse DSA from private"); + buf = load_file("dsa_1"); + ASSERT_INT_EQ(sshkey_parse_private(buf, "", "dsa_1", &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + a = load_bignum("dsa_1.param.g"); + b = load_bignum("dsa_1.param.priv"); + c = load_bignum("dsa_1.param.pub"); + ASSERT_BIGNUM_EQ(k1->dsa->g, a); + ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); + ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse DSA from private w/ passphrase"); + buf = load_file("dsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private(buf, sshbuf_ptr(pw), "dsa_1_pw", + &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load DSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("DSA key hex fingerprint"); + buf = load_file("dsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + TEST_START("DSA key bubblebabble fingerprint"); + buf = load_file("dsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + sshkey_free(k1); + + TEST_START("parse ECDSA from private"); + buf = load_file("ecdsa_1"); + ASSERT_INT_EQ(sshkey_parse_private(buf, "", "ecdsa_1", &k1, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k1, NULL); + buf = load_file("ecdsa_1.param.curve"); + ASSERT_STRING_EQ(sshbuf_ptr(buf), OBJ_nid2sn(k1->ecdsa_nid)); + sshbuf_free(buf); + a = load_bignum("ecdsa_1.param.priv"); + b = load_bignum("ecdsa_1.param.pub"); + c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), + EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, + NULL, NULL); + ASSERT_PTR_NE(c, NULL); + ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); + ASSERT_BIGNUM_EQ(b, c); + BN_free(a); + BN_free(b); + BN_free(c); + TEST_DONE(); + + TEST_START("parse ECDSA from private w/ passphrase"); + buf = load_file("ecdsa_1_pw"); + ASSERT_INT_EQ(sshkey_parse_private(buf, sshbuf_ptr(pw), "ecdsa_1_pw", + &k2, NULL), 0); + sshbuf_free(buf); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("load ECDSA from public"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2, + NULL), 0); + ASSERT_PTR_NE(k2, NULL); + ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("ECDSA key hex fingerprint"); + buf = load_file("ecdsa_1.fp"); + cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + TEST_START("ECDSA key bubblebabble fingerprint"); + buf = load_file("ecdsa_1.fp.bb"); + cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + ASSERT_PTR_NE(cp, NULL); + ASSERT_STRING_EQ(cp, sshbuf_ptr(buf)); + sshbuf_free(buf); + TEST_DONE(); + + sshkey_free(k1); + + sshbuf_free(pw); + +} diff --git a/unittests/sshkey/testdata/ecdsa_1.param.curve b/unittests/sshkey/testdata/ecdsa_1.param.curve new file mode 100644 index 0000000..fa04004 --- /dev/null +++ b/unittests/sshkey/testdata/ecdsa_1.param.curve @@ -0,0 +1 @@ +prime256v1 diff --git a/unittests/sshkey/testdata/ecdsa_1.param.priv b/unittests/sshkey/testdata/ecdsa_1.param.priv new file mode 100644 index 0000000..5be1266 --- /dev/null +++ b/unittests/sshkey/testdata/ecdsa_1.param.priv @@ -0,0 +1 @@ +28cb04241fc1722c2cac86ba00d9b08a768056c1142a435480842e400b42fbb2 diff --git a/unittests/sshkey/testdata/ecdsa_1.param.pub b/unittests/sshkey/testdata/ecdsa_1.param.pub new file mode 100644 index 0000000..afeac52 --- /dev/null +++ b/unittests/sshkey/testdata/ecdsa_1.param.pub @@ -0,0 +1 @@ +047f1540ca82ddd161b7f6db5e3e09ec7340f06f536ecf8c7ade48adf87ae248708668afc99545581554644ec6d01220b096bf56487c5a4de8669c6aad0104d000