void sshbuf_tests(void) { struct sshbuf *p1; const u_char *cdp; u_char *dp; size_t sz; int r; TEST_START("allocate sshbuf"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); TEST_DONE(); TEST_START("max size on fresh buffer"); ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0); TEST_DONE(); TEST_START("available on fresh buffer"); ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0); TEST_DONE(); TEST_START("len = 0 on empty buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); TEST_DONE(); TEST_START("set valid max size"); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536); TEST_DONE(); TEST_START("available on limited buffer"); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536); TEST_DONE(); TEST_START("free"); sshbuf_free(p1); TEST_DONE(); TEST_START("consume on empty buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("consume_end on empty buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0); ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("reserve space"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp = 0x11; r = sshbuf_reserve(p1, 3, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp++ = 0x22; *dp++ = 0x33; *dp++ = 0x44; TEST_DONE(); TEST_START("sshbuf_len on filled buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); TEST_DONE(); TEST_START("sshbuf_ptr on filled buffer"); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_U8_EQ(cdp[0], 0x11); ASSERT_U8_EQ(cdp[1], 0x22); ASSERT_U8_EQ(cdp[2], 0x33); ASSERT_U8_EQ(cdp[3], 0x44); TEST_DONE(); TEST_START("consume on filled buffer"); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); r = sshbuf_consume(p1, 64); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(p1, NULL); ASSERT_U8_EQ(cdp[0], 0x22); ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(p1, NULL); ASSERT_U8_EQ(cdp[0], 0x44); r = sshbuf_consume(p1, 2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); r = sshbuf_consume(p1, 1); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); sshbuf_free(p1); TEST_DONE(); TEST_START("consume_end on filled buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); r = sshbuf_reserve(p1, 4, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp++ = 0x11; *dp++ = 0x22; *dp++ = 0x33; *dp++ = 0x44; ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); r = sshbuf_consume_end(p1, 5); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_U8_EQ(*cdp, 0x11); r = sshbuf_consume_end(p1, 2); ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); sshbuf_free(p1); TEST_DONE(); TEST_START("fill limited buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); r = sshbuf_reserve(p1, 1223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0xd7, 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_PTR_EQ(dp, NULL); TEST_DONE(); TEST_START("consume and force compaction"); ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); r = sshbuf_reserve(p1, 224, &dp); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); ASSERT_PTR_EQ(dp, NULL); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); r = sshbuf_reserve(p1, 223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0x7d, 223); cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); TEST_DONE(); TEST_START("resize full buffer"); r = sshbuf_set_max_size(p1, 1000); ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC); ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223); ASSERT_INT_EQ(sshbuf_len(p1), 1223); TEST_DONE(); /* NB. uses sshbuf internals */ TEST_START("alloc chunking"); r = sshbuf_reserve(p1, 1, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); *dp = 0xff; cdp = sshbuf_ptr(p1); ASSERT_PTR_NE(cdp, NULL); ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1); ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0); sshbuf_free(p1); TEST_DONE(); TEST_START("reset buffer"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); r = sshbuf_reserve(p1, 1223, &dp); ASSERT_INT_EQ(r, 0); ASSERT_PTR_NE(dp, NULL); memset(dp, 0xd7, 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); sshbuf_reset(p1); ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); sshbuf_free(p1); TEST_DONE(); }
void sshkey_tests(void) { struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; #ifdef OPENSSL_HAS_ECC struct sshkey *ke; #endif struct sshbuf *b; TEST_START("new invalid"); k1 = sshkey_new(-42); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("new/free KEY_UNSPEC"); k1 = sshkey_new(KEY_UNSPEC); ASSERT_PTR_NE(k1, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA1"); k1 = sshkey_new(KEY_RSA1); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA"); k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_DSA"); k1 = sshkey_new(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); #endif TEST_START("new/free KEY_ED25519"); k1 = sshkey_new(KEY_ED25519); ASSERT_PTR_NE(k1, NULL); /* These should be blank until key loaded or generated */ ASSERT_PTR_EQ(k1->ed25519_sk, NULL); ASSERT_PTR_EQ(k1->ed25519_pk, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_RSA"); k1 = sshkey_new_private(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_NE(k1->rsa->p, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_DSA"); k1 = sshkey_new_private(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_NE(k1->dsa->priv_key, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("generate KEY_RSA too small modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_RSA too large modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_DSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); #endif TEST_START("generate KEY_RSA"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr), SSH_ERR_INVALID_ARGUMENT); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr->rsa, NULL); ASSERT_PTR_NE(kr->rsa->n, NULL); ASSERT_PTR_NE(kr->rsa->e, NULL); ASSERT_PTR_NE(kr->rsa->p, NULL); ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); TEST_DONE(); TEST_START("generate KEY_DSA"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); ASSERT_PTR_NE(kd, NULL); ASSERT_PTR_NE(kd->dsa, NULL); ASSERT_PTR_NE(kd->dsa->g, NULL); ASSERT_PTR_NE(kd->dsa->priv_key, NULL); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_PTR_NE(ke, NULL); ASSERT_PTR_NE(ke->ecdsa, NULL); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); TEST_DONE(); #endif TEST_START("generate KEY_ED25519"); ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); ASSERT_PTR_NE(kf, NULL); ASSERT_INT_EQ(kf->type, KEY_ED25519); ASSERT_PTR_NE(kf->ed25519_pk, NULL); ASSERT_PTR_NE(kf->ed25519_sk, NULL); TEST_DONE(); TEST_START("demote KEY_RSA"); ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); TEST_DONE(); TEST_START("equal KEY_RSA/demoted KEY_RSA"); ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("demote KEY_DSA"); ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kd, k1); ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("demote KEY_ECDSA"); ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(ke, k1); ASSERT_INT_EQ(k1->type, KEY_ECDSA); ASSERT_PTR_NE(k1->ecdsa, NULL); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); TEST_DONE(); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); sshkey_free(k1); TEST_DONE(); #endif TEST_START("demote KEY_ED25519"); ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kf, k1); ASSERT_INT_EQ(k1->type, KEY_ED25519); ASSERT_PTR_NE(k1->ed25519_pk, NULL); ASSERT_PTR_EQ(k1->ed25519_sk, NULL); TEST_DONE(); TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("equal mismatched key types"); ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); #ifdef OPENSSL_HAS_ECC ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); #endif ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); TEST_DONE(); TEST_START("equal different keys"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); sshkey_free(k1); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); sshkey_free(k1); #ifdef OPENSSL_HAS_ECC ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); sshkey_free(k1); #endif ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); sshkey_free(k1); TEST_DONE(); sshkey_free(kr); sshkey_free(kd); #ifdef OPENSSL_HAS_ECC sshkey_free(ke); #endif sshkey_free(kf); 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); 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_putb(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(); #ifdef OPENSSL_HAS_ECC #ifndef WIN32_FIXME 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(); #endif #endif 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); k3 = get_private("rsa_1"); build_cert(b, k2, "*****@*****.**", 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); sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); sshbuf_free(b); TEST_DONE(); }
void sshkey_tests(void) { struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; struct sshbuf *b; TEST_START("new invalid"); k1 = sshkey_new(-42); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("new/free KEY_UNSPEC"); k1 = sshkey_new(KEY_UNSPEC); ASSERT_PTR_NE(k1, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA1"); k1 = sshkey_new(KEY_RSA1); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_RSA"); k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_DSA"); k1 = sshkey_new(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); TEST_START("new/free KEY_ED25519"); k1 = sshkey_new(KEY_ED25519); ASSERT_PTR_NE(k1, NULL); /* These should be blank until key loaded or generated */ ASSERT_PTR_EQ(k1->ed25519_sk, NULL); ASSERT_PTR_EQ(k1->ed25519_pk, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_RSA"); k1 = sshkey_new_private(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_NE(k1->rsa->p, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("new_private KEY_DSA"); k1 = sshkey_new_private(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_NE(k1->dsa->priv_key, NULL); ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); TEST_START("generate KEY_RSA too small modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_RSA too large modulus"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); TEST_START("generate KEY_DSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("generate KEY_ECDSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); TEST_START("generate KEY_RSA"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr->rsa, NULL); ASSERT_PTR_NE(kr->rsa->n, NULL); ASSERT_PTR_NE(kr->rsa->e, NULL); ASSERT_PTR_NE(kr->rsa->p, NULL); ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768); TEST_DONE(); TEST_START("generate KEY_DSA"); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); ASSERT_PTR_NE(kd, NULL); ASSERT_PTR_NE(kd->dsa, NULL); ASSERT_PTR_NE(kd->dsa->g, NULL); ASSERT_PTR_NE(kd->dsa->priv_key, NULL); TEST_DONE(); TEST_START("generate KEY_ECDSA"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_PTR_NE(ke, NULL); ASSERT_PTR_NE(ke->ecdsa, NULL); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); TEST_DONE(); TEST_START("generate KEY_ED25519"); ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); ASSERT_PTR_NE(kf, NULL); ASSERT_INT_EQ(kf->type, KEY_ED25519); ASSERT_PTR_NE(kf->ed25519_pk, NULL); ASSERT_PTR_NE(kf->ed25519_sk, NULL); TEST_DONE(); TEST_START("demote KEY_RSA"); ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->rsa->n, NULL); ASSERT_PTR_NE(k1->rsa->e, NULL); ASSERT_PTR_EQ(k1->rsa->p, NULL); TEST_DONE(); TEST_START("equal KEY_RSA/demoted KEY_RSA"); ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("demote KEY_DSA"); ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kd, k1); ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa->g, NULL); ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("demote KEY_ECDSA"); ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(ke, k1); ASSERT_INT_EQ(k1->type, KEY_ECDSA); ASSERT_PTR_NE(k1->ecdsa, NULL); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); TEST_DONE(); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("demote KEY_ED25519"); ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kf, k1); ASSERT_INT_EQ(k1->type, KEY_ED25519); ASSERT_PTR_NE(k1->ed25519_pk, NULL); ASSERT_PTR_EQ(k1->ed25519_sk, NULL); TEST_DONE(); TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); sshkey_free(k1); TEST_DONE(); TEST_START("equal mismatched key types"); ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); TEST_DONE(); TEST_START("equal different keys"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); sshkey_free(k1); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); sshkey_free(k1); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); sshkey_free(k1); ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); sshkey_free(k1); TEST_DONE(); sshkey_free(kr); sshkey_free(kd); sshkey_free(ke); sshkey_free(kf); /* XXX certify test */ /* XXX sign test */ /* XXX verify test */ 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); build_cert(b, k2, "*****@*****.**", 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); TEST_DONE(); }
void sshbuf_fuzz_tests(void) { struct sshbuf *p1; u_char *dp; size_t sz, sz2, i; u_int32_t r; int ret; /* NB. uses sshbuf internals */ TEST_START("fuzz alloc/dealloc"); p1 = sshbuf_new(); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0); ASSERT_PTR_NE(p1, NULL); ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); for (i = 0; i < NUM_FUZZ_TESTS; i++) { r = arc4random_uniform(10); if (r == 0) { /* 10% chance: small reserve */ r = arc4random_uniform(10); fuzz_reserve: sz = sshbuf_avail(p1); sz2 = sshbuf_len(p1); ret = sshbuf_reserve(p1, r, &dp); if (ret < 0) { ASSERT_PTR_EQ(dp, NULL); ASSERT_SIZE_T_LT(sz, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); } else { ASSERT_PTR_NE(dp, NULL); ASSERT_SIZE_T_GE(sz, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r); memset(dp, arc4random_uniform(255) + 1, r); } } else if (r < 3) { /* 20% chance: big reserve */ r = arc4random_uniform(8 * 1024); goto fuzz_reserve; } else if (r == 3) { /* 10% chance: small consume */ r = arc4random_uniform(10); fuzz_consume: sz = sshbuf_avail(p1); sz2 = sshbuf_len(p1); /* 50% change consume from end, otherwise start */ ret = ((arc4random() & 1) ? sshbuf_consume : sshbuf_consume_end)(p1, r); if (ret < 0) { ASSERT_SIZE_T_LT(sz2, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2); } else { ASSERT_SIZE_T_GE(sz2, r); ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r); } } else if (r < 8) { /* 40% chance: big consume */ r = arc4random_uniform(2 * 1024); goto fuzz_consume; } else if (r == 8) { /* 10% chance: reset max size */ r = arc4random_uniform(16 * 1024); sz = sshbuf_max_size(p1); if (sshbuf_set_max_size(p1, r) < 0) ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); else ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r); } else { if (arc4random_uniform(8192) == 0) { /* tiny chance: new buffer */ ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); sshbuf_free(p1); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0); } else { /* Almost 10%: giant reserve */ /* use arc4random_buf for r > 2^32 on 64 bit */ arc4random_buf(&r, sizeof(r)); while (r < SSHBUF_SIZE_MAX / 2) { r <<= 1; r |= arc4random() & 1; } goto fuzz_reserve; } } ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024); } ASSERT_PTR_NE(sshbuf_ptr(p1), NULL); ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1)); sshbuf_free(p1); TEST_DONE(); }