1 /* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ 2 /* 3 * Fuzz tests for key parsing 4 * 5 * Placed in the public domain 6 */ 7 8 #include <sys/types.h> 9 #include <sys/param.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <stdio.h> 13 #include <stdint.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <unistd.h> 17 18 #include <openssl/bn.h> 19 #include <openssl/ec.h> 20 #include <openssl/rsa.h> 21 #include <openssl/dsa.h> 22 #include <openssl/objects.h> 23 24 #include "test_helper.h" 25 26 #include "ssherr.h" 27 #include "authfile.h" 28 #include "sshkey.h" 29 #include "sshbuf.h" 30 31 #include "common.h" 32 33 void sshkey_fuzz_tests(void); 34 35 static void 36 onerror(void *fuzz) 37 { 38 fprintf(stderr, "Failed during fuzz:\n"); 39 fuzz_dump((struct fuzz *)fuzz); 40 } 41 42 static void 43 public_fuzz(struct sshkey *k) 44 { 45 struct sshkey *k1; 46 struct sshbuf *buf; 47 struct fuzz *fuzz; 48 49 ASSERT_PTR_NE(buf = sshbuf_new(), NULL); 50 ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0); 51 /* XXX need a way to run the tests in "slow, but complete" mode */ 52 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ 53 FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ 54 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, 55 sshbuf_mutable_ptr(buf), sshbuf_len(buf)); 56 ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(buf), sshbuf_len(buf), 57 &k1), 0); 58 sshkey_free(k1); 59 sshbuf_free(buf); 60 TEST_ONERROR(onerror, fuzz); 61 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 62 if (sshkey_from_blob(fuzz_ptr(fuzz), fuzz_len(fuzz), &k1) == 0) 63 sshkey_free(k1); 64 } 65 fuzz_cleanup(fuzz); 66 } 67 68 static void 69 sig_fuzz(struct sshkey *k) 70 { 71 struct fuzz *fuzz; 72 u_char *sig, c[] = "some junk to be signed"; 73 size_t l; 74 75 ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0); 76 ASSERT_SIZE_T_GT(l, 0); 77 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */ 78 FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | 79 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sig, l); 80 ASSERT_INT_EQ(sshkey_verify(k, sig, l, c, sizeof(c), 0), 0); 81 free(sig); 82 TEST_ONERROR(onerror, fuzz); 83 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 84 sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), 85 c, sizeof(c), 0); 86 } 87 fuzz_cleanup(fuzz); 88 } 89 90 void 91 sshkey_fuzz_tests(void) 92 { 93 struct sshkey *k1; 94 struct sshbuf *buf, *fuzzed; 95 struct fuzz *fuzz; 96 int r; 97 98 TEST_START("fuzz RSA1 private"); 99 buf = load_file("rsa1_1"); 100 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | 101 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, 102 sshbuf_mutable_ptr(buf), sshbuf_len(buf)); 103 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 104 &k1, NULL), 0); 105 sshkey_free(k1); 106 sshbuf_free(buf); 107 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 108 TEST_ONERROR(onerror, fuzz); 109 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 110 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 111 ASSERT_INT_EQ(r, 0); 112 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 113 &k1, NULL) == 0) 114 sshkey_free(k1); 115 sshbuf_reset(fuzzed); 116 } 117 sshbuf_free(fuzzed); 118 fuzz_cleanup(fuzz); 119 TEST_DONE(); 120 121 TEST_START("fuzz RSA1 public"); 122 buf = load_file("rsa1_1_pw"); 123 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | 124 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, 125 sshbuf_mutable_ptr(buf), sshbuf_len(buf)); 126 ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0); 127 sshkey_free(k1); 128 sshbuf_free(buf); 129 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 130 TEST_ONERROR(onerror, fuzz); 131 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 132 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 133 ASSERT_INT_EQ(r, 0); 134 if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0) 135 sshkey_free(k1); 136 sshbuf_reset(fuzzed); 137 } 138 sshbuf_free(fuzzed); 139 fuzz_cleanup(fuzz); 140 TEST_DONE(); 141 142 TEST_START("fuzz RSA private"); 143 buf = load_file("rsa_1"); 144 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 145 sshbuf_len(buf)); 146 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 147 &k1, NULL), 0); 148 sshkey_free(k1); 149 sshbuf_free(buf); 150 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 151 TEST_ONERROR(onerror, fuzz); 152 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 153 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 154 ASSERT_INT_EQ(r, 0); 155 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 156 &k1, NULL) == 0) 157 sshkey_free(k1); 158 sshbuf_reset(fuzzed); 159 } 160 sshbuf_free(fuzzed); 161 fuzz_cleanup(fuzz); 162 TEST_DONE(); 163 164 TEST_START("fuzz RSA new-format private"); 165 buf = load_file("rsa_n"); 166 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 167 sshbuf_len(buf)); 168 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 169 &k1, NULL), 0); 170 sshkey_free(k1); 171 sshbuf_free(buf); 172 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 173 TEST_ONERROR(onerror, fuzz); 174 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 175 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 176 ASSERT_INT_EQ(r, 0); 177 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 178 &k1, NULL) == 0) 179 sshkey_free(k1); 180 sshbuf_reset(fuzzed); 181 } 182 sshbuf_free(fuzzed); 183 fuzz_cleanup(fuzz); 184 TEST_DONE(); 185 186 TEST_START("fuzz DSA private"); 187 buf = load_file("dsa_1"); 188 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 189 sshbuf_len(buf)); 190 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 191 &k1, NULL), 0); 192 sshkey_free(k1); 193 sshbuf_free(buf); 194 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 195 TEST_ONERROR(onerror, fuzz); 196 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 197 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 198 ASSERT_INT_EQ(r, 0); 199 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 200 &k1, NULL) == 0) 201 sshkey_free(k1); 202 sshbuf_reset(fuzzed); 203 } 204 sshbuf_free(fuzzed); 205 fuzz_cleanup(fuzz); 206 TEST_DONE(); 207 208 TEST_START("fuzz DSA new-format private"); 209 buf = load_file("dsa_n"); 210 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 211 sshbuf_len(buf)); 212 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 213 &k1, NULL), 0); 214 sshkey_free(k1); 215 sshbuf_free(buf); 216 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 217 TEST_ONERROR(onerror, fuzz); 218 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 219 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 220 ASSERT_INT_EQ(r, 0); 221 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 222 &k1, NULL) == 0) 223 sshkey_free(k1); 224 sshbuf_reset(fuzzed); 225 } 226 sshbuf_free(fuzzed); 227 fuzz_cleanup(fuzz); 228 TEST_DONE(); 229 230 TEST_START("fuzz ECDSA private"); 231 buf = load_file("ecdsa_1"); 232 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 233 sshbuf_len(buf)); 234 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 235 &k1, NULL), 0); 236 sshkey_free(k1); 237 sshbuf_free(buf); 238 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 239 TEST_ONERROR(onerror, fuzz); 240 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 241 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 242 ASSERT_INT_EQ(r, 0); 243 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 244 &k1, NULL) == 0) 245 sshkey_free(k1); 246 sshbuf_reset(fuzzed); 247 } 248 sshbuf_free(fuzzed); 249 fuzz_cleanup(fuzz); 250 TEST_DONE(); 251 252 TEST_START("fuzz ECDSA new-format private"); 253 buf = load_file("ecdsa_n"); 254 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 255 sshbuf_len(buf)); 256 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 257 &k1, NULL), 0); 258 sshkey_free(k1); 259 sshbuf_free(buf); 260 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 261 TEST_ONERROR(onerror, fuzz); 262 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 263 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 264 ASSERT_INT_EQ(r, 0); 265 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 266 &k1, NULL) == 0) 267 sshkey_free(k1); 268 sshbuf_reset(fuzzed); 269 } 270 sshbuf_free(fuzzed); 271 fuzz_cleanup(fuzz); 272 TEST_DONE(); 273 274 TEST_START("fuzz Ed25519 private"); 275 buf = load_file("ed25519_1"); 276 fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), 277 sshbuf_len(buf)); 278 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 279 &k1, NULL), 0); 280 sshkey_free(k1); 281 sshbuf_free(buf); 282 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); 283 TEST_ONERROR(onerror, fuzz); 284 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { 285 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); 286 ASSERT_INT_EQ(r, 0); 287 if (sshkey_parse_private_fileblob(fuzzed, "", "key", 288 &k1, NULL) == 0) 289 sshkey_free(k1); 290 sshbuf_reset(fuzzed); 291 } 292 sshbuf_free(fuzzed); 293 fuzz_cleanup(fuzz); 294 TEST_DONE(); 295 296 TEST_START("fuzz RSA public"); 297 buf = load_file("rsa_1"); 298 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 299 &k1, NULL), 0); 300 sshbuf_free(buf); 301 public_fuzz(k1); 302 sshkey_free(k1); 303 TEST_DONE(); 304 305 TEST_START("fuzz RSA cert"); 306 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); 307 public_fuzz(k1); 308 sshkey_free(k1); 309 TEST_DONE(); 310 311 TEST_START("fuzz DSA public"); 312 buf = load_file("dsa_1"); 313 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 314 &k1, NULL), 0); 315 sshbuf_free(buf); 316 public_fuzz(k1); 317 sshkey_free(k1); 318 TEST_DONE(); 319 320 TEST_START("fuzz DSA cert"); 321 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0); 322 public_fuzz(k1); 323 sshkey_free(k1); 324 TEST_DONE(); 325 326 TEST_START("fuzz ECDSA public"); 327 buf = load_file("ecdsa_1"); 328 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 329 &k1, NULL), 0); 330 sshbuf_free(buf); 331 public_fuzz(k1); 332 sshkey_free(k1); 333 TEST_DONE(); 334 335 TEST_START("fuzz ECDSA cert"); 336 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k1), 0); 337 public_fuzz(k1); 338 sshkey_free(k1); 339 TEST_DONE(); 340 341 TEST_START("fuzz Ed25519 public"); 342 buf = load_file("ed25519_1"); 343 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 344 &k1, NULL), 0); 345 sshbuf_free(buf); 346 public_fuzz(k1); 347 sshkey_free(k1); 348 TEST_DONE(); 349 350 TEST_START("fuzz Ed25519 cert"); 351 ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k1), 0); 352 public_fuzz(k1); 353 sshkey_free(k1); 354 TEST_DONE(); 355 356 TEST_START("fuzz RSA sig"); 357 buf = load_file("rsa_1"); 358 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 359 &k1, NULL), 0); 360 sshbuf_free(buf); 361 sig_fuzz(k1); 362 sshkey_free(k1); 363 TEST_DONE(); 364 365 TEST_START("fuzz DSA sig"); 366 buf = load_file("dsa_1"); 367 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 368 &k1, NULL), 0); 369 sshbuf_free(buf); 370 sig_fuzz(k1); 371 sshkey_free(k1); 372 TEST_DONE(); 373 374 TEST_START("fuzz ECDSA sig"); 375 buf = load_file("ecdsa_1"); 376 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 377 &k1, NULL), 0); 378 sshbuf_free(buf); 379 sig_fuzz(k1); 380 sshkey_free(k1); 381 TEST_DONE(); 382 383 TEST_START("fuzz Ed25519 sig"); 384 buf = load_file("ed25519_1"); 385 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", 386 &k1, NULL), 0); 387 sshbuf_free(buf); 388 sig_fuzz(k1); 389 sshkey_free(k1); 390 TEST_DONE(); 391 392 /* XXX fuzz decoded new-format blobs too */ 393 394 } 395