1 /* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 2 /* 3 * Regress test for sshkey.h key management API 4 * 5 * Placed in the public domain 6 */ 7 8 #include <sys/types.h> 9 #include <sys/param.h> 10 #include <stdio.h> 11 #include <stdint.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <openssl/bn.h> 16 #include <openssl/ec.h> 17 #include <openssl/rsa.h> 18 #include <openssl/dsa.h> 19 20 #include "test_helper.h" 21 22 #include "ssherr.h" 23 #include "sshbuf.h" 24 #define SSHBUF_INTERNAL 1 /* access internals for testing */ 25 #include "sshkey.h" 26 27 #include "authfile.h" 28 #include "common.h" 29 #include "ssh2.h" 30 31 void sshkey_tests(void); 32 33 static void 34 build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, 35 const struct sshkey *sign_key, const struct sshkey *ca_key) 36 { 37 struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; 38 u_char *sigblob; 39 size_t siglen; 40 41 ca_buf = sshbuf_new(); 42 ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); 43 44 /* 45 * Get the public key serialisation by rendering the key and skipping 46 * the type string. This is a bit of a hack :/ 47 */ 48 pk = sshbuf_new(); 49 ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); 50 ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); 51 52 principals = sshbuf_new(); 53 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); 54 ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); 55 56 critopts = sshbuf_new(); 57 /* XXX fill this in */ 58 59 exts = sshbuf_new(); 60 /* XXX fill this in */ 61 62 ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); 63 ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ 64 ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */ 65 ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */ 66 ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */ 67 ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */ 68 ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */ 69 ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */ 70 ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */ 71 ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */ 72 ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */ 73 ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ 74 ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ 75 ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, 76 sshbuf_ptr(b), sshbuf_len(b), 0), 0); 77 ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ 78 79 free(sigblob); 80 sshbuf_free(ca_buf); 81 sshbuf_free(exts); 82 sshbuf_free(critopts); 83 sshbuf_free(principals); 84 sshbuf_free(pk); 85 } 86 87 void 88 sshkey_tests(void) 89 { 90 struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; 91 struct sshbuf *b; 92 93 TEST_START("new invalid"); 94 k1 = sshkey_new(-42); 95 ASSERT_PTR_EQ(k1, NULL); 96 TEST_DONE(); 97 98 TEST_START("new/free KEY_UNSPEC"); 99 k1 = sshkey_new(KEY_UNSPEC); 100 ASSERT_PTR_NE(k1, NULL); 101 sshkey_free(k1); 102 TEST_DONE(); 103 104 TEST_START("new/free KEY_RSA1"); 105 k1 = sshkey_new(KEY_RSA1); 106 ASSERT_PTR_NE(k1, NULL); 107 ASSERT_PTR_NE(k1->rsa, NULL); 108 ASSERT_PTR_NE(k1->rsa->n, NULL); 109 ASSERT_PTR_NE(k1->rsa->e, NULL); 110 ASSERT_PTR_EQ(k1->rsa->p, NULL); 111 sshkey_free(k1); 112 TEST_DONE(); 113 114 TEST_START("new/free KEY_RSA"); 115 k1 = sshkey_new(KEY_RSA); 116 ASSERT_PTR_NE(k1, NULL); 117 ASSERT_PTR_NE(k1->rsa, NULL); 118 ASSERT_PTR_NE(k1->rsa->n, NULL); 119 ASSERT_PTR_NE(k1->rsa->e, NULL); 120 ASSERT_PTR_EQ(k1->rsa->p, NULL); 121 sshkey_free(k1); 122 TEST_DONE(); 123 124 TEST_START("new/free KEY_DSA"); 125 k1 = sshkey_new(KEY_DSA); 126 ASSERT_PTR_NE(k1, NULL); 127 ASSERT_PTR_NE(k1->dsa, NULL); 128 ASSERT_PTR_NE(k1->dsa->g, NULL); 129 ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); 130 sshkey_free(k1); 131 TEST_DONE(); 132 133 TEST_START("new/free KEY_ECDSA"); 134 k1 = sshkey_new(KEY_ECDSA); 135 ASSERT_PTR_NE(k1, NULL); 136 ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ 137 sshkey_free(k1); 138 TEST_DONE(); 139 140 TEST_START("new/free KEY_ED25519"); 141 k1 = sshkey_new(KEY_ED25519); 142 ASSERT_PTR_NE(k1, NULL); 143 /* These should be blank until key loaded or generated */ 144 ASSERT_PTR_EQ(k1->ed25519_sk, NULL); 145 ASSERT_PTR_EQ(k1->ed25519_pk, NULL); 146 sshkey_free(k1); 147 TEST_DONE(); 148 149 TEST_START("new_private KEY_RSA"); 150 k1 = sshkey_new_private(KEY_RSA); 151 ASSERT_PTR_NE(k1, NULL); 152 ASSERT_PTR_NE(k1->rsa, NULL); 153 ASSERT_PTR_NE(k1->rsa->n, NULL); 154 ASSERT_PTR_NE(k1->rsa->e, NULL); 155 ASSERT_PTR_NE(k1->rsa->p, NULL); 156 ASSERT_INT_EQ(sshkey_add_private(k1), 0); 157 sshkey_free(k1); 158 TEST_DONE(); 159 160 TEST_START("new_private KEY_DSA"); 161 k1 = sshkey_new_private(KEY_DSA); 162 ASSERT_PTR_NE(k1, NULL); 163 ASSERT_PTR_NE(k1->dsa, NULL); 164 ASSERT_PTR_NE(k1->dsa->g, NULL); 165 ASSERT_PTR_NE(k1->dsa->priv_key, NULL); 166 ASSERT_INT_EQ(sshkey_add_private(k1), 0); 167 sshkey_free(k1); 168 TEST_DONE(); 169 170 TEST_START("generate KEY_RSA too small modulus"); 171 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), 172 SSH_ERR_INVALID_ARGUMENT); 173 ASSERT_PTR_EQ(k1, NULL); 174 TEST_DONE(); 175 176 TEST_START("generate KEY_RSA too large modulus"); 177 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), 178 SSH_ERR_INVALID_ARGUMENT); 179 ASSERT_PTR_EQ(k1, NULL); 180 TEST_DONE(); 181 182 TEST_START("generate KEY_DSA wrong bits"); 183 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), 184 SSH_ERR_INVALID_ARGUMENT); 185 ASSERT_PTR_EQ(k1, NULL); 186 sshkey_free(k1); 187 TEST_DONE(); 188 189 TEST_START("generate KEY_ECDSA wrong bits"); 190 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), 191 SSH_ERR_INVALID_ARGUMENT); 192 ASSERT_PTR_EQ(k1, NULL); 193 sshkey_free(k1); 194 TEST_DONE(); 195 196 TEST_START("generate KEY_RSA"); 197 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); 198 ASSERT_PTR_NE(kr, NULL); 199 ASSERT_PTR_NE(kr->rsa, NULL); 200 ASSERT_PTR_NE(kr->rsa->n, NULL); 201 ASSERT_PTR_NE(kr->rsa->e, NULL); 202 ASSERT_PTR_NE(kr->rsa->p, NULL); 203 ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768); 204 TEST_DONE(); 205 206 TEST_START("generate KEY_DSA"); 207 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); 208 ASSERT_PTR_NE(kd, NULL); 209 ASSERT_PTR_NE(kd->dsa, NULL); 210 ASSERT_PTR_NE(kd->dsa->g, NULL); 211 ASSERT_PTR_NE(kd->dsa->priv_key, NULL); 212 TEST_DONE(); 213 214 TEST_START("generate KEY_ECDSA"); 215 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); 216 ASSERT_PTR_NE(ke, NULL); 217 ASSERT_PTR_NE(ke->ecdsa, NULL); 218 ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); 219 ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); 220 TEST_DONE(); 221 222 TEST_START("generate KEY_ED25519"); 223 ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); 224 ASSERT_PTR_NE(kf, NULL); 225 ASSERT_INT_EQ(kf->type, KEY_ED25519); 226 ASSERT_PTR_NE(kf->ed25519_pk, NULL); 227 ASSERT_PTR_NE(kf->ed25519_sk, NULL); 228 TEST_DONE(); 229 230 TEST_START("demote KEY_RSA"); 231 ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); 232 ASSERT_PTR_NE(k1, NULL); 233 ASSERT_PTR_NE(kr, k1); 234 ASSERT_INT_EQ(k1->type, KEY_RSA); 235 ASSERT_PTR_NE(k1->rsa, NULL); 236 ASSERT_PTR_NE(k1->rsa->n, NULL); 237 ASSERT_PTR_NE(k1->rsa->e, NULL); 238 ASSERT_PTR_EQ(k1->rsa->p, NULL); 239 TEST_DONE(); 240 241 TEST_START("equal KEY_RSA/demoted KEY_RSA"); 242 ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); 243 sshkey_free(k1); 244 TEST_DONE(); 245 246 TEST_START("demote KEY_DSA"); 247 ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); 248 ASSERT_PTR_NE(k1, NULL); 249 ASSERT_PTR_NE(kd, k1); 250 ASSERT_INT_EQ(k1->type, KEY_DSA); 251 ASSERT_PTR_NE(k1->dsa, NULL); 252 ASSERT_PTR_NE(k1->dsa->g, NULL); 253 ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); 254 TEST_DONE(); 255 256 TEST_START("equal KEY_DSA/demoted KEY_DSA"); 257 ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); 258 sshkey_free(k1); 259 TEST_DONE(); 260 261 TEST_START("demote KEY_ECDSA"); 262 ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); 263 ASSERT_PTR_NE(k1, NULL); 264 ASSERT_PTR_NE(ke, k1); 265 ASSERT_INT_EQ(k1->type, KEY_ECDSA); 266 ASSERT_PTR_NE(k1->ecdsa, NULL); 267 ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); 268 ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); 269 ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); 270 TEST_DONE(); 271 272 TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); 273 ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); 274 sshkey_free(k1); 275 TEST_DONE(); 276 277 TEST_START("demote KEY_ED25519"); 278 ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); 279 ASSERT_PTR_NE(k1, NULL); 280 ASSERT_PTR_NE(kf, k1); 281 ASSERT_INT_EQ(k1->type, KEY_ED25519); 282 ASSERT_PTR_NE(k1->ed25519_pk, NULL); 283 ASSERT_PTR_EQ(k1->ed25519_sk, NULL); 284 TEST_DONE(); 285 286 TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); 287 ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); 288 sshkey_free(k1); 289 TEST_DONE(); 290 291 TEST_START("equal mismatched key types"); 292 ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); 293 ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); 294 ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); 295 ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); 296 ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); 297 TEST_DONE(); 298 299 TEST_START("equal different keys"); 300 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0); 301 ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); 302 sshkey_free(k1); 303 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); 304 ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); 305 sshkey_free(k1); 306 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); 307 ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); 308 sshkey_free(k1); 309 ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); 310 ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); 311 sshkey_free(k1); 312 TEST_DONE(); 313 314 sshkey_free(kr); 315 sshkey_free(kd); 316 sshkey_free(ke); 317 sshkey_free(kf); 318 319 /* XXX certify test */ 320 /* XXX sign test */ 321 /* XXX verify test */ 322 323 TEST_START("nested certificate"); 324 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); 325 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, 326 NULL), 0); 327 b = load_file("rsa_2"); 328 ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1", 329 &k3, NULL), 0); 330 sshbuf_reset(b); 331 build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); 332 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), 333 SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); 334 ASSERT_PTR_EQ(k4, NULL); 335 sshbuf_free(b); 336 sshkey_free(k1); 337 sshkey_free(k2); 338 sshkey_free(k3); 339 TEST_DONE(); 340 341 } 342