1*123df87bSdjm /* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */ 2a7772ff7Sdjm /* 3a7772ff7Sdjm * Regress test for sshkey.h key management API 4a7772ff7Sdjm * 5a7772ff7Sdjm * Placed in the public domain 6a7772ff7Sdjm */ 7a7772ff7Sdjm 8a7772ff7Sdjm #include <sys/types.h> 9a7772ff7Sdjm #include <stdio.h> 10a7772ff7Sdjm #include <stdint.h> 11a7772ff7Sdjm #include <stdlib.h> 12a7772ff7Sdjm #include <string.h> 13a7772ff7Sdjm 14a7772ff7Sdjm #include <openssl/bn.h> 15a7772ff7Sdjm #include <openssl/ec.h> 16a7772ff7Sdjm #include <openssl/rsa.h> 17a7772ff7Sdjm #include <openssl/dsa.h> 18a7772ff7Sdjm 19a7772ff7Sdjm #include "test_helper.h" 20a7772ff7Sdjm 21a7772ff7Sdjm #include "ssherr.h" 22a7772ff7Sdjm #include "sshbuf.h" 23a7772ff7Sdjm #define SSHBUF_INTERNAL 1 /* access internals for testing */ 24a7772ff7Sdjm #include "sshkey.h" 25a7772ff7Sdjm 26a7772ff7Sdjm #include "authfile.h" 27a7772ff7Sdjm #include "common.h" 28a7772ff7Sdjm #include "ssh2.h" 29a7772ff7Sdjm 30a7772ff7Sdjm void sshkey_tests(void); 31a7772ff7Sdjm 32a7772ff7Sdjm static void 33f03f699fSdjm put_opt(struct sshbuf *b, const char *name, const char *value) 34f03f699fSdjm { 35f03f699fSdjm struct sshbuf *sect; 36f03f699fSdjm 37f03f699fSdjm sect = sshbuf_new(); 38f03f699fSdjm ASSERT_PTR_NE(sect, NULL); 39f03f699fSdjm ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0); 40f03f699fSdjm if (value != NULL) 41f03f699fSdjm ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0); 42f03f699fSdjm ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0); 43f03f699fSdjm sshbuf_free(sect); 44f03f699fSdjm } 45f03f699fSdjm 46f03f699fSdjm static void 47e05e5c20Sdjm build_cert(struct sshbuf *b, struct sshkey *k, const char *type, 48e05e5c20Sdjm struct sshkey *sign_key, struct sshkey *ca_key, 493382e080Sdjm const char *sig_alg) 50a7772ff7Sdjm { 51a7772ff7Sdjm struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; 52a7772ff7Sdjm u_char *sigblob; 53a7772ff7Sdjm size_t siglen; 54a7772ff7Sdjm 55a7772ff7Sdjm ca_buf = sshbuf_new(); 56f03f699fSdjm ASSERT_PTR_NE(ca_buf, NULL); 57f427794eSdjm ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); 58a7772ff7Sdjm 59a7772ff7Sdjm /* 60a7772ff7Sdjm * Get the public key serialisation by rendering the key and skipping 61a7772ff7Sdjm * the type string. This is a bit of a hack :/ 62a7772ff7Sdjm */ 63a7772ff7Sdjm pk = sshbuf_new(); 64f03f699fSdjm ASSERT_PTR_NE(pk, NULL); 65f427794eSdjm ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0); 66a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); 67a7772ff7Sdjm 68a7772ff7Sdjm principals = sshbuf_new(); 69f03f699fSdjm ASSERT_PTR_NE(principals, NULL); 70a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); 71a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); 72a7772ff7Sdjm 73a7772ff7Sdjm critopts = sshbuf_new(); 74f03f699fSdjm ASSERT_PTR_NE(critopts, NULL); 75f03f699fSdjm put_opt(critopts, "force-command", "/usr/local/bin/nethack"); 76f03f699fSdjm put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1"); 77a7772ff7Sdjm 78a7772ff7Sdjm exts = sshbuf_new(); 79f03f699fSdjm ASSERT_PTR_NE(exts, NULL); 80f03f699fSdjm put_opt(critopts, "permit-X11-forwarding", NULL); 81a7772ff7Sdjm 82a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); 83a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ 84a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */ 85a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */ 86a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */ 87a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */ 88a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */ 89a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */ 90a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */ 91a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */ 92a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */ 93a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ 94a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ 95a7772ff7Sdjm ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, 96d83aa1b4Sdjm sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0); 97a7772ff7Sdjm ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ 98a7772ff7Sdjm 99a7772ff7Sdjm free(sigblob); 100a7772ff7Sdjm sshbuf_free(ca_buf); 101a7772ff7Sdjm sshbuf_free(exts); 102a7772ff7Sdjm sshbuf_free(critopts); 103a7772ff7Sdjm sshbuf_free(principals); 104a7772ff7Sdjm sshbuf_free(pk); 105a7772ff7Sdjm } 106a7772ff7Sdjm 107f03f699fSdjm static void 1083382e080Sdjm signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, 1093382e080Sdjm const u_char *d, size_t l) 110f03f699fSdjm { 111f03f699fSdjm size_t len; 112f03f699fSdjm u_char *sig; 113f03f699fSdjm 114d83aa1b4Sdjm ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 115d83aa1b4Sdjm NULL, NULL, 0), 0); 116f03f699fSdjm ASSERT_SIZE_T_GT(len, 8); 117f03f699fSdjm ASSERT_PTR_NE(sig, NULL); 118760ae021Sdjm ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); 119760ae021Sdjm ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0); 120f03f699fSdjm /* Fuzz test is more comprehensive, this is just a smoke test */ 121f03f699fSdjm sig[len - 5] ^= 0x10; 122760ae021Sdjm ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); 123f03f699fSdjm free(sig); 124f03f699fSdjm } 125f03f699fSdjm 126f03f699fSdjm static void 127f03f699fSdjm banana(u_char *s, size_t l) 128f03f699fSdjm { 129f03f699fSdjm size_t o; 130f03f699fSdjm const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' }; 131f03f699fSdjm 132f03f699fSdjm for (o = 0; o < l; o += sizeof(the_banana)) { 133f03f699fSdjm if (l - o < sizeof(the_banana)) { 134f03f699fSdjm memcpy(s + o, "nanananana", l - o); 135f03f699fSdjm break; 136f03f699fSdjm } 137674e0662Stb memcpy(s + o, the_banana, sizeof(the_banana)); 138f03f699fSdjm } 139f03f699fSdjm } 140f03f699fSdjm 141f03f699fSdjm static void 1423382e080Sdjm signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg) 143f03f699fSdjm { 144f03f699fSdjm u_char i, buf[2049]; 145f03f699fSdjm size_t lens[] = { 146f03f699fSdjm 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129, 147f03f699fSdjm 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049 148f03f699fSdjm }; 149f03f699fSdjm 150f03f699fSdjm for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) { 151f03f699fSdjm test_subtest_info("%s key, banana length %zu", 152f03f699fSdjm sshkey_type(k), lens[i]); 153f03f699fSdjm banana(buf, lens[i]); 1543382e080Sdjm signature_test(k, bad, sig_alg, buf, lens[i]); 155f03f699fSdjm } 156f03f699fSdjm } 157f03f699fSdjm 158f03f699fSdjm static struct sshkey * 159f03f699fSdjm get_private(const char *n) 160f03f699fSdjm { 161f03f699fSdjm struct sshbuf *b; 162f03f699fSdjm struct sshkey *ret; 163f03f699fSdjm 164f03f699fSdjm b = load_file(n); 16534c8ff87Sdjm ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0); 166f03f699fSdjm sshbuf_free(b); 167f03f699fSdjm return ret; 168f03f699fSdjm } 169f03f699fSdjm 170a7772ff7Sdjm void 171a7772ff7Sdjm sshkey_tests(void) 172a7772ff7Sdjm { 17333ada582Sdjm struct sshkey *k1 = NULL, *k2 = NULL, *k3 = NULL, *k4 = NULL; 17433ada582Sdjm struct sshkey *kr = NULL, *kd = NULL, *ke = NULL, *kf = NULL; 17533ada582Sdjm struct sshbuf *b = NULL; 176a7772ff7Sdjm 177a7772ff7Sdjm TEST_START("new invalid"); 178a7772ff7Sdjm k1 = sshkey_new(-42); 179a7772ff7Sdjm ASSERT_PTR_EQ(k1, NULL); 180a7772ff7Sdjm TEST_DONE(); 181a7772ff7Sdjm 182a7772ff7Sdjm TEST_START("new/free KEY_UNSPEC"); 183a7772ff7Sdjm k1 = sshkey_new(KEY_UNSPEC); 184a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 185a7772ff7Sdjm sshkey_free(k1); 186a7772ff7Sdjm TEST_DONE(); 187a7772ff7Sdjm 188a7772ff7Sdjm TEST_START("new/free KEY_RSA"); 189a7772ff7Sdjm k1 = sshkey_new(KEY_RSA); 190a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 191*123df87bSdjm ASSERT_PTR_NE(k1->pkey, NULL); 192a7772ff7Sdjm sshkey_free(k1); 193a7772ff7Sdjm TEST_DONE(); 194a7772ff7Sdjm 19533ada582Sdjm #ifdef WiTH_DSA 196a7772ff7Sdjm TEST_START("new/free KEY_DSA"); 197a7772ff7Sdjm k1 = sshkey_new(KEY_DSA); 198a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 199a7772ff7Sdjm ASSERT_PTR_NE(k1->dsa, NULL); 200a7772ff7Sdjm sshkey_free(k1); 201a7772ff7Sdjm TEST_DONE(); 20233ada582Sdjm #endif 203a7772ff7Sdjm 204a7772ff7Sdjm TEST_START("new/free KEY_ECDSA"); 205a7772ff7Sdjm k1 = sshkey_new(KEY_ECDSA); 206a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 207*123df87bSdjm ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */ 208a7772ff7Sdjm sshkey_free(k1); 209a7772ff7Sdjm TEST_DONE(); 210a7772ff7Sdjm 211a7772ff7Sdjm TEST_START("new/free KEY_ED25519"); 212a7772ff7Sdjm k1 = sshkey_new(KEY_ED25519); 213a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 214a7772ff7Sdjm /* These should be blank until key loaded or generated */ 215a7772ff7Sdjm ASSERT_PTR_EQ(k1->ed25519_sk, NULL); 216a7772ff7Sdjm ASSERT_PTR_EQ(k1->ed25519_pk, NULL); 217a7772ff7Sdjm sshkey_free(k1); 218a7772ff7Sdjm TEST_DONE(); 219a7772ff7Sdjm 220a7772ff7Sdjm TEST_START("generate KEY_RSA too small modulus"); 221a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), 222ebde02b0Sdjm SSH_ERR_KEY_LENGTH); 223a7772ff7Sdjm ASSERT_PTR_EQ(k1, NULL); 224a7772ff7Sdjm TEST_DONE(); 225a7772ff7Sdjm 226a7772ff7Sdjm TEST_START("generate KEY_RSA too large modulus"); 227a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), 228ebde02b0Sdjm SSH_ERR_KEY_LENGTH); 229a7772ff7Sdjm ASSERT_PTR_EQ(k1, NULL); 230a7772ff7Sdjm TEST_DONE(); 231a7772ff7Sdjm 23233ada582Sdjm #ifdef WITH_DSA 233a7772ff7Sdjm TEST_START("generate KEY_DSA wrong bits"); 234a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), 235ebde02b0Sdjm SSH_ERR_KEY_LENGTH); 236a7772ff7Sdjm ASSERT_PTR_EQ(k1, NULL); 237a7772ff7Sdjm sshkey_free(k1); 238a7772ff7Sdjm TEST_DONE(); 23933ada582Sdjm #endif 240a7772ff7Sdjm 241a7772ff7Sdjm TEST_START("generate KEY_ECDSA wrong bits"); 242a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), 243ebde02b0Sdjm SSH_ERR_KEY_LENGTH); 244a7772ff7Sdjm ASSERT_PTR_EQ(k1, NULL); 245a7772ff7Sdjm sshkey_free(k1); 246a7772ff7Sdjm TEST_DONE(); 247a7772ff7Sdjm 248a7772ff7Sdjm TEST_START("generate KEY_RSA"); 249671b1ef5Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr), 250ebde02b0Sdjm SSH_ERR_KEY_LENGTH); 251a63db763Smarkus ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); 252a7772ff7Sdjm ASSERT_PTR_NE(kr, NULL); 253*123df87bSdjm ASSERT_PTR_NE(EVP_PKEY_get0_RSA(kr->pkey), NULL); 2547ae22a9aSdjm ASSERT_PTR_NE(rsa_n(kr), NULL); 2557ae22a9aSdjm ASSERT_PTR_NE(rsa_e(kr), NULL); 2567ae22a9aSdjm ASSERT_PTR_NE(rsa_p(kr), NULL); 2577ae22a9aSdjm ASSERT_INT_EQ(BN_num_bits(rsa_n(kr)), 1024); 258a7772ff7Sdjm TEST_DONE(); 259a7772ff7Sdjm 26033ada582Sdjm #ifdef WITH_DSA 261a7772ff7Sdjm TEST_START("generate KEY_DSA"); 262a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); 263a7772ff7Sdjm ASSERT_PTR_NE(kd, NULL); 264a7772ff7Sdjm ASSERT_PTR_NE(kd->dsa, NULL); 2657ae22a9aSdjm ASSERT_PTR_NE(dsa_g(kd), NULL); 2667ae22a9aSdjm ASSERT_PTR_NE(dsa_priv_key(kd), NULL); 267a7772ff7Sdjm TEST_DONE(); 26833ada582Sdjm #endif 269a7772ff7Sdjm 270a7772ff7Sdjm TEST_START("generate KEY_ECDSA"); 271a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); 272a7772ff7Sdjm ASSERT_PTR_NE(ke, NULL); 273*123df87bSdjm ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(ke->pkey), NULL); 274*123df87bSdjm ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), 275*123df87bSdjm NULL); 276*123df87bSdjm ASSERT_PTR_NE(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), 277*123df87bSdjm NULL); 278a7772ff7Sdjm TEST_DONE(); 279a7772ff7Sdjm 280a7772ff7Sdjm TEST_START("generate KEY_ED25519"); 281a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); 282a7772ff7Sdjm ASSERT_PTR_NE(kf, NULL); 283a7772ff7Sdjm ASSERT_INT_EQ(kf->type, KEY_ED25519); 284a7772ff7Sdjm ASSERT_PTR_NE(kf->ed25519_pk, NULL); 285a7772ff7Sdjm ASSERT_PTR_NE(kf->ed25519_sk, NULL); 286a7772ff7Sdjm TEST_DONE(); 287a7772ff7Sdjm 288a7772ff7Sdjm TEST_START("demote KEY_RSA"); 289925162a5Sdjm ASSERT_INT_EQ(sshkey_from_private(kr, &k1), 0); 290a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 291a7772ff7Sdjm ASSERT_PTR_NE(kr, k1); 292a7772ff7Sdjm ASSERT_INT_EQ(k1->type, KEY_RSA); 293*123df87bSdjm ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k1->pkey), NULL); 2947ae22a9aSdjm ASSERT_PTR_NE(rsa_n(k1), NULL); 2957ae22a9aSdjm ASSERT_PTR_NE(rsa_e(k1), NULL); 2967ae22a9aSdjm ASSERT_PTR_EQ(rsa_p(k1), NULL); 297a7772ff7Sdjm TEST_DONE(); 298a7772ff7Sdjm 299a7772ff7Sdjm TEST_START("equal KEY_RSA/demoted KEY_RSA"); 300a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); 301a7772ff7Sdjm sshkey_free(k1); 302a7772ff7Sdjm TEST_DONE(); 303a7772ff7Sdjm 30433ada582Sdjm #ifdef WITH_DSA 305a7772ff7Sdjm TEST_START("demote KEY_DSA"); 306925162a5Sdjm ASSERT_INT_EQ(sshkey_from_private(kd, &k1), 0); 307a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 308a7772ff7Sdjm ASSERT_PTR_NE(kd, k1); 309a7772ff7Sdjm ASSERT_INT_EQ(k1->type, KEY_DSA); 310a7772ff7Sdjm ASSERT_PTR_NE(k1->dsa, NULL); 3117ae22a9aSdjm ASSERT_PTR_NE(dsa_g(k1), NULL); 3127ae22a9aSdjm ASSERT_PTR_EQ(dsa_priv_key(k1), NULL); 313a7772ff7Sdjm TEST_DONE(); 314a7772ff7Sdjm 315a7772ff7Sdjm TEST_START("equal KEY_DSA/demoted KEY_DSA"); 316a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); 317a7772ff7Sdjm sshkey_free(k1); 318a7772ff7Sdjm TEST_DONE(); 31933ada582Sdjm #endif 320a7772ff7Sdjm 321a7772ff7Sdjm TEST_START("demote KEY_ECDSA"); 322925162a5Sdjm ASSERT_INT_EQ(sshkey_from_private(ke, &k1), 0); 323a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 324a7772ff7Sdjm ASSERT_PTR_NE(ke, k1); 325a7772ff7Sdjm ASSERT_INT_EQ(k1->type, KEY_ECDSA); 326*123df87bSdjm ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(k1->pkey), NULL); 327a7772ff7Sdjm ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); 328*123df87bSdjm ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), 329*123df87bSdjm NULL); 330*123df87bSdjm ASSERT_PTR_EQ(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), 331*123df87bSdjm NULL); 332a7772ff7Sdjm TEST_DONE(); 333a7772ff7Sdjm 334a7772ff7Sdjm TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); 335a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); 336a7772ff7Sdjm sshkey_free(k1); 337a7772ff7Sdjm TEST_DONE(); 338a7772ff7Sdjm 339a7772ff7Sdjm TEST_START("demote KEY_ED25519"); 340925162a5Sdjm ASSERT_INT_EQ(sshkey_from_private(kf, &k1), 0); 341a7772ff7Sdjm ASSERT_PTR_NE(k1, NULL); 342a7772ff7Sdjm ASSERT_PTR_NE(kf, k1); 343a7772ff7Sdjm ASSERT_INT_EQ(k1->type, KEY_ED25519); 344a7772ff7Sdjm ASSERT_PTR_NE(k1->ed25519_pk, NULL); 345a7772ff7Sdjm ASSERT_PTR_EQ(k1->ed25519_sk, NULL); 346a7772ff7Sdjm TEST_DONE(); 347a7772ff7Sdjm 348a7772ff7Sdjm TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); 349a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); 350a7772ff7Sdjm sshkey_free(k1); 351a7772ff7Sdjm TEST_DONE(); 352a7772ff7Sdjm 353a7772ff7Sdjm TEST_START("equal mismatched key types"); 354a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); 355a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); 356a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); 357a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); 358a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); 359a7772ff7Sdjm TEST_DONE(); 360a7772ff7Sdjm 361a7772ff7Sdjm TEST_START("equal different keys"); 362a63db763Smarkus ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); 363a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); 364a7772ff7Sdjm sshkey_free(k1); 365a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); 366a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); 367a7772ff7Sdjm sshkey_free(k1); 368a7772ff7Sdjm ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); 369a7772ff7Sdjm ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); 370a7772ff7Sdjm sshkey_free(k1); 371a7772ff7Sdjm TEST_DONE(); 372a7772ff7Sdjm 373a7772ff7Sdjm sshkey_free(kr); 374a7772ff7Sdjm sshkey_free(kd); 375a7772ff7Sdjm sshkey_free(ke); 376a7772ff7Sdjm sshkey_free(kf); 377a7772ff7Sdjm 378f03f699fSdjm TEST_START("certify key"); 379f03f699fSdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), 380f03f699fSdjm &k1, NULL), 0); 381f03f699fSdjm k2 = get_private("ed25519_2"); 38225852f75Sdjm ASSERT_INT_EQ(sshkey_to_certified(k1), 0); 383f03f699fSdjm ASSERT_PTR_NE(k1->cert, NULL); 384f03f699fSdjm k1->cert->type = SSH2_CERT_TYPE_USER; 385f03f699fSdjm k1->cert->serial = 1234; 386f03f699fSdjm k1->cert->key_id = strdup("estragon"); 387f03f699fSdjm ASSERT_PTR_NE(k1->cert->key_id, NULL); 388f03f699fSdjm k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); 389f03f699fSdjm ASSERT_PTR_NE(k1->cert->principals, NULL); 390f03f699fSdjm k1->cert->principals[0] = strdup("estragon"); 391f03f699fSdjm k1->cert->principals[1] = strdup("vladimir"); 392f03f699fSdjm k1->cert->principals[2] = strdup("pozzo"); 393f03f699fSdjm k1->cert->principals[3] = strdup("lucky"); 394f03f699fSdjm ASSERT_PTR_NE(k1->cert->principals[0], NULL); 395f03f699fSdjm ASSERT_PTR_NE(k1->cert->principals[1], NULL); 396f03f699fSdjm ASSERT_PTR_NE(k1->cert->principals[2], NULL); 397f03f699fSdjm ASSERT_PTR_NE(k1->cert->principals[3], NULL); 3989a2c6a51Sdjm k1->cert->nprincipals = 4; 399f03f699fSdjm k1->cert->valid_after = 0; 400f03f699fSdjm k1->cert->valid_before = (u_int64_t)-1; 4019a2c6a51Sdjm sshbuf_free(k1->cert->critical); 402f03f699fSdjm k1->cert->critical = sshbuf_new(); 403f03f699fSdjm ASSERT_PTR_NE(k1->cert->critical, NULL); 4049a2c6a51Sdjm sshbuf_free(k1->cert->extensions); 405f03f699fSdjm k1->cert->extensions = sshbuf_new(); 406f03f699fSdjm ASSERT_PTR_NE(k1->cert->extensions, NULL); 407f03f699fSdjm put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); 408f03f699fSdjm put_opt(k1->cert->critical, "source-address", "127.0.0.1"); 409f03f699fSdjm put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); 410f03f699fSdjm put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); 411f03f699fSdjm ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); 412d83aa1b4Sdjm ASSERT_INT_EQ(sshkey_certify(k1, k2, NULL, NULL, NULL), 0); 413f03f699fSdjm b = sshbuf_new(); 414f03f699fSdjm ASSERT_PTR_NE(b, NULL); 415f427794eSdjm ASSERT_INT_EQ(sshkey_putb(k1, b), 0); 416f03f699fSdjm ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); 417f03f699fSdjm 418f03f699fSdjm sshkey_free(k1); 419f03f699fSdjm sshkey_free(k2); 420f03f699fSdjm sshkey_free(k3); 421f03f699fSdjm sshbuf_reset(b); 422f03f699fSdjm TEST_DONE(); 423f03f699fSdjm 424f03f699fSdjm TEST_START("sign and verify RSA"); 425f03f699fSdjm k1 = get_private("rsa_1"); 426f03f699fSdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, 427f03f699fSdjm NULL), 0); 4283382e080Sdjm signature_tests(k1, k2, "ssh-rsa"); 4293382e080Sdjm sshkey_free(k1); 4303382e080Sdjm sshkey_free(k2); 4313382e080Sdjm TEST_DONE(); 4323382e080Sdjm 4333382e080Sdjm TEST_START("sign and verify RSA-SHA256"); 4343382e080Sdjm k1 = get_private("rsa_1"); 4353382e080Sdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, 4363382e080Sdjm NULL), 0); 4373382e080Sdjm signature_tests(k1, k2, "rsa-sha2-256"); 4383382e080Sdjm sshkey_free(k1); 4393382e080Sdjm sshkey_free(k2); 4403382e080Sdjm TEST_DONE(); 4413382e080Sdjm 4423382e080Sdjm TEST_START("sign and verify RSA-SHA512"); 4433382e080Sdjm k1 = get_private("rsa_1"); 4443382e080Sdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, 4453382e080Sdjm NULL), 0); 4463382e080Sdjm signature_tests(k1, k2, "rsa-sha2-512"); 447f03f699fSdjm sshkey_free(k1); 448f03f699fSdjm sshkey_free(k2); 449f03f699fSdjm TEST_DONE(); 450f03f699fSdjm 45133ada582Sdjm #ifdef WITH_DSA 452f03f699fSdjm TEST_START("sign and verify DSA"); 453f03f699fSdjm k1 = get_private("dsa_1"); 454f03f699fSdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, 455f03f699fSdjm NULL), 0); 4563382e080Sdjm signature_tests(k1, k2, NULL); 457f03f699fSdjm sshkey_free(k1); 458f03f699fSdjm sshkey_free(k2); 459f03f699fSdjm TEST_DONE(); 46033ada582Sdjm #endif 461f03f699fSdjm 462f03f699fSdjm TEST_START("sign and verify ECDSA"); 463f03f699fSdjm k1 = get_private("ecdsa_1"); 464f03f699fSdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, 465f03f699fSdjm NULL), 0); 4663382e080Sdjm signature_tests(k1, k2, NULL); 467f03f699fSdjm sshkey_free(k1); 468f03f699fSdjm sshkey_free(k2); 469f03f699fSdjm TEST_DONE(); 470f03f699fSdjm 471f03f699fSdjm TEST_START("sign and verify ED25519"); 472f03f699fSdjm k1 = get_private("ed25519_1"); 473f03f699fSdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, 474f03f699fSdjm NULL), 0); 4753382e080Sdjm signature_tests(k1, k2, NULL); 476f03f699fSdjm sshkey_free(k1); 477f03f699fSdjm sshkey_free(k2); 478f03f699fSdjm TEST_DONE(); 479a7772ff7Sdjm 480a7772ff7Sdjm TEST_START("nested certificate"); 481a7772ff7Sdjm ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); 482a7772ff7Sdjm ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, 483a7772ff7Sdjm NULL), 0); 48481a46d91Sdjm k3 = get_private("rsa_1"); 4853382e080Sdjm build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL); 486a7772ff7Sdjm ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), 487a7772ff7Sdjm SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); 488a7772ff7Sdjm ASSERT_PTR_EQ(k4, NULL); 489a7772ff7Sdjm sshkey_free(k1); 490a7772ff7Sdjm sshkey_free(k2); 491a7772ff7Sdjm sshkey_free(k3); 492f03f699fSdjm sshbuf_free(b); 493a7772ff7Sdjm TEST_DONE(); 494a7772ff7Sdjm 495a7772ff7Sdjm } 496