1 /* 2 * Copyright (c) 2018 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include <assert.h> 8 #include <fido.h> 9 #include <fido/es256.h> 10 #include <fido/rs256.h> 11 #include <fido/eddsa.h> 12 #include <string.h> 13 14 #define FAKE_DEV_HANDLE ((void *)0xdeadbeef) 15 16 static const unsigned char es256_pk[64] = { 17 0x34, 0xeb, 0x99, 0x77, 0x02, 0x9c, 0x36, 0x38, 18 0xbb, 0xc2, 0xae, 0xa0, 0xa0, 0x18, 0xc6, 0x64, 19 0xfc, 0xe8, 0x49, 0x92, 0xd7, 0x74, 0x9e, 0x0c, 20 0x46, 0x8c, 0x9d, 0xa6, 0xdf, 0x46, 0xf7, 0x84, 21 0x60, 0x1e, 0x0f, 0x8b, 0x23, 0x85, 0x4a, 0x9a, 22 0xec, 0xc1, 0x08, 0x9f, 0x30, 0xd0, 0x0d, 0xd7, 23 0x76, 0x7b, 0x55, 0x48, 0x91, 0x7c, 0x4f, 0x0f, 24 0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a, 25 }; 26 27 static const unsigned char cdh[32] = { 28 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, 29 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, 30 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, 31 0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76, 32 }; 33 34 static const unsigned char authdata[39] = { 35 0x58, 0x25, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 36 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 37 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 38 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 39 0x97, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03, 40 }; 41 42 static const unsigned char sig[72] = { 43 0x30, 0x46, 0x02, 0x21, 0x00, 0xf6, 0xd1, 0xa3, 44 0xd5, 0x24, 0x2b, 0xde, 0xee, 0xa0, 0x90, 0x89, 45 0xcd, 0xf8, 0x9e, 0xbd, 0x6b, 0x4d, 0x55, 0x79, 46 0xe4, 0xc1, 0x42, 0x27, 0xb7, 0x9b, 0x9b, 0xa4, 47 0x0a, 0xe2, 0x47, 0x64, 0x0e, 0x02, 0x21, 0x00, 48 0xe5, 0xc9, 0xc2, 0x83, 0x47, 0x31, 0xc7, 0x26, 49 0xe5, 0x25, 0xb2, 0xb4, 0x39, 0xa7, 0xfc, 0x3d, 50 0x70, 0xbe, 0xe9, 0x81, 0x0d, 0x4a, 0x62, 0xa9, 51 0xab, 0x4a, 0x91, 0xc0, 0x7d, 0x2d, 0x23, 0x1e, 52 }; 53 54 static void * 55 dummy_open(const char *path) 56 { 57 (void)path; 58 59 return (FAKE_DEV_HANDLE); 60 } 61 62 static void 63 dummy_close(void *handle) 64 { 65 assert(handle == FAKE_DEV_HANDLE); 66 } 67 68 static int 69 dummy_read(void *handle, unsigned char *buf, size_t len, int ms) 70 { 71 (void)handle; 72 (void)buf; 73 (void)len; 74 (void)ms; 75 76 abort(); 77 /* NOTREACHED */ 78 } 79 80 static int 81 dummy_write(void *handle, const unsigned char *buf, size_t len) 82 { 83 (void)handle; 84 (void)buf; 85 (void)len; 86 87 abort(); 88 /* NOTREACHED */ 89 } 90 91 static fido_assert_t * 92 alloc_assert(void) 93 { 94 fido_assert_t *a; 95 96 a = fido_assert_new(); 97 assert(a != NULL); 98 99 return (a); 100 } 101 102 static void 103 free_assert(fido_assert_t *a) 104 { 105 fido_assert_free(&a); 106 assert(a == NULL); 107 } 108 109 static fido_dev_t * 110 alloc_dev(void) 111 { 112 fido_dev_t *d; 113 114 d = fido_dev_new(); 115 assert(d != NULL); 116 117 return (d); 118 } 119 120 static void 121 free_dev(fido_dev_t *d) 122 { 123 fido_dev_free(&d); 124 assert(d == NULL); 125 } 126 127 static es256_pk_t * 128 alloc_es256_pk(void) 129 { 130 es256_pk_t *pk; 131 132 pk = es256_pk_new(); 133 assert(pk != NULL); 134 135 return (pk); 136 } 137 138 static void 139 free_es256_pk(es256_pk_t *pk) 140 { 141 es256_pk_free(&pk); 142 assert(pk == NULL); 143 } 144 145 static rs256_pk_t * 146 alloc_rs256_pk(void) 147 { 148 rs256_pk_t *pk; 149 150 pk = rs256_pk_new(); 151 assert(pk != NULL); 152 153 return (pk); 154 } 155 156 static void 157 free_rs256_pk(rs256_pk_t *pk) 158 { 159 rs256_pk_free(&pk); 160 assert(pk == NULL); 161 } 162 163 static eddsa_pk_t * 164 alloc_eddsa_pk(void) 165 { 166 eddsa_pk_t *pk; 167 168 pk = eddsa_pk_new(); 169 assert(pk != NULL); 170 171 return (pk); 172 } 173 174 static void 175 free_eddsa_pk(eddsa_pk_t *pk) 176 { 177 eddsa_pk_free(&pk); 178 assert(pk == NULL); 179 } 180 181 static void 182 empty_assert(fido_dev_t *d, fido_assert_t *a, size_t idx) 183 { 184 es256_pk_t *es256; 185 rs256_pk_t *rs256; 186 eddsa_pk_t *eddsa; 187 188 assert(fido_assert_flags(a, idx) == 0); 189 assert(fido_assert_authdata_len(a, idx) == 0); 190 assert(fido_assert_authdata_ptr(a, idx) == NULL); 191 assert(fido_assert_clientdata_hash_len(a) == 0); 192 assert(fido_assert_clientdata_hash_ptr(a) == NULL); 193 assert(fido_assert_id_len(a, idx) == 0); 194 assert(fido_assert_id_ptr(a, idx) == NULL); 195 assert(fido_assert_rp_id(a) == NULL); 196 assert(fido_assert_sig_len(a, idx) == 0); 197 assert(fido_assert_sig_ptr(a, idx) == NULL); 198 assert(fido_assert_user_display_name(a, idx) == NULL); 199 assert(fido_assert_user_icon(a, idx) == NULL); 200 assert(fido_assert_user_id_len(a, idx) == 0); 201 assert(fido_assert_user_id_ptr(a, idx) == NULL); 202 assert(fido_assert_user_name(a, idx) == NULL); 203 204 es256 = alloc_es256_pk(); 205 rs256 = alloc_rs256_pk(); 206 eddsa = alloc_eddsa_pk(); 207 208 fido_dev_force_u2f(d); 209 assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); 210 assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); 211 assert(fido_assert_verify(a, idx, COSE_ES256, 212 NULL) == FIDO_ERR_INVALID_ARGUMENT); 213 assert(fido_assert_verify(a, idx, COSE_ES256, 214 es256) == FIDO_ERR_INVALID_ARGUMENT); 215 assert(fido_assert_verify(a, idx, -1, 216 es256) == FIDO_ERR_INVALID_ARGUMENT); 217 assert(fido_assert_verify(a, idx, COSE_RS256, 218 rs256) == FIDO_ERR_INVALID_ARGUMENT); 219 assert(fido_assert_verify(a, idx, COSE_EDDSA, 220 eddsa) == FIDO_ERR_INVALID_ARGUMENT); 221 222 fido_dev_force_fido2(d); 223 assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); 224 assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); 225 assert(fido_assert_verify(a, idx, COSE_ES256, 226 NULL) == FIDO_ERR_INVALID_ARGUMENT); 227 assert(fido_assert_verify(a, idx, COSE_ES256, 228 es256) == FIDO_ERR_INVALID_ARGUMENT); 229 assert(fido_assert_verify(a, idx, -1, 230 es256) == FIDO_ERR_INVALID_ARGUMENT); 231 assert(fido_assert_verify(a, idx, COSE_RS256, 232 rs256) == FIDO_ERR_INVALID_ARGUMENT); 233 assert(fido_assert_verify(a, idx, COSE_EDDSA, 234 eddsa) == FIDO_ERR_INVALID_ARGUMENT); 235 236 free_es256_pk(es256); 237 free_rs256_pk(rs256); 238 free_eddsa_pk(eddsa); 239 } 240 241 static void 242 empty_assert_tests(void) 243 { 244 fido_assert_t *a; 245 fido_dev_t *d; 246 fido_dev_io_t io_f; 247 size_t i; 248 249 memset(&io_f, 0, sizeof(io_f)); 250 251 a = alloc_assert(); 252 d = alloc_dev(); 253 254 io_f.open = dummy_open; 255 io_f.close = dummy_close; 256 io_f.read = dummy_read; 257 io_f.write = dummy_write; 258 259 assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); 260 261 empty_assert(d, a, 0); 262 assert(fido_assert_count(a) == 0); 263 assert(fido_assert_set_count(a, 4) == FIDO_OK); 264 assert(fido_assert_count(a) == 4); 265 for (i = 0; i < 4; i++) { 266 empty_assert(d, a, i); 267 } 268 empty_assert(d, a, 10); 269 free_assert(a); 270 free_dev(d); 271 } 272 273 static void 274 valid_assert(void) 275 { 276 fido_assert_t *a; 277 es256_pk_t *es256; 278 rs256_pk_t *rs256; 279 eddsa_pk_t *eddsa; 280 281 a = alloc_assert(); 282 es256 = alloc_es256_pk(); 283 rs256 = alloc_rs256_pk(); 284 eddsa = alloc_eddsa_pk(); 285 assert(es256_pk_from_ptr(es256, es256_pk, sizeof(es256_pk)) == FIDO_OK); 286 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 287 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 288 assert(fido_assert_set_count(a, 1) == FIDO_OK); 289 assert(fido_assert_set_authdata(a, 0, authdata, 290 sizeof(authdata)) == FIDO_OK); 291 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 292 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 293 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 294 assert(fido_assert_verify(a, 0, COSE_ES256, es256) == FIDO_OK); 295 assert(fido_assert_verify(a, 0, COSE_RS256, rs256) == FIDO_ERR_INVALID_SIG); 296 assert(fido_assert_verify(a, 0, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_SIG); 297 free_assert(a); 298 free_es256_pk(es256); 299 free_rs256_pk(rs256); 300 free_eddsa_pk(eddsa); 301 } 302 303 static void 304 no_cdh(void) 305 { 306 fido_assert_t *a; 307 es256_pk_t *pk; 308 309 a = alloc_assert(); 310 pk = alloc_es256_pk(); 311 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 312 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 313 assert(fido_assert_set_count(a, 1) == FIDO_OK); 314 assert(fido_assert_set_authdata(a, 0, authdata, 315 sizeof(authdata)) == FIDO_OK); 316 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 317 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 318 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 319 assert(fido_assert_verify(a, 0, COSE_ES256, 320 pk) == FIDO_ERR_INVALID_ARGUMENT); 321 free_assert(a); 322 free_es256_pk(pk); 323 } 324 325 static void 326 no_rp(void) 327 { 328 fido_assert_t *a; 329 es256_pk_t *pk; 330 331 a = alloc_assert(); 332 pk = alloc_es256_pk(); 333 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 334 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 335 assert(fido_assert_set_count(a, 1) == FIDO_OK); 336 assert(fido_assert_set_authdata(a, 0, authdata, 337 sizeof(authdata)) == FIDO_OK); 338 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 339 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 340 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 341 assert(fido_assert_verify(a, 0, COSE_ES256, 342 pk) == FIDO_ERR_INVALID_ARGUMENT); 343 free_assert(a); 344 free_es256_pk(pk); 345 } 346 347 static void 348 no_authdata(void) 349 { 350 fido_assert_t *a; 351 es256_pk_t *pk; 352 353 a = alloc_assert(); 354 pk = alloc_es256_pk(); 355 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 356 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 357 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 358 assert(fido_assert_set_count(a, 1) == FIDO_OK); 359 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 360 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 361 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 362 assert(fido_assert_verify(a, 0, COSE_ES256, 363 pk) == FIDO_ERR_INVALID_ARGUMENT); 364 free_assert(a); 365 free_es256_pk(pk); 366 } 367 368 static void 369 no_sig(void) 370 { 371 fido_assert_t *a; 372 es256_pk_t *pk; 373 374 a = alloc_assert(); 375 pk = alloc_es256_pk(); 376 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 377 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 378 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 379 assert(fido_assert_set_count(a, 1) == FIDO_OK); 380 assert(fido_assert_set_authdata(a, 0, authdata, 381 sizeof(authdata)) == FIDO_OK); 382 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 383 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 384 assert(fido_assert_verify(a, 0, COSE_ES256, 385 pk) == FIDO_ERR_INVALID_ARGUMENT); 386 free_assert(a); 387 free_es256_pk(pk); 388 } 389 390 static void 391 junk_cdh(void) 392 { 393 fido_assert_t *a; 394 es256_pk_t *pk; 395 unsigned char *junk; 396 397 junk = malloc(sizeof(cdh)); 398 assert(junk != NULL); 399 memcpy(junk, cdh, sizeof(cdh)); 400 junk[0] = ~junk[0]; 401 402 a = alloc_assert(); 403 pk = alloc_es256_pk(); 404 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 405 assert(fido_assert_set_clientdata_hash(a, junk, sizeof(cdh)) == FIDO_OK); 406 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 407 assert(fido_assert_set_count(a, 1) == FIDO_OK); 408 assert(fido_assert_set_authdata(a, 0, authdata, 409 sizeof(authdata)) == FIDO_OK); 410 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 411 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 412 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 413 assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); 414 free_assert(a); 415 free_es256_pk(pk); 416 free(junk); 417 } 418 419 static void 420 junk_rp(void) 421 { 422 fido_assert_t *a; 423 es256_pk_t *pk; 424 425 a = alloc_assert(); 426 pk = alloc_es256_pk(); 427 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 428 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 429 assert(fido_assert_set_rp(a, "potato") == FIDO_OK); 430 assert(fido_assert_set_count(a, 1) == FIDO_OK); 431 assert(fido_assert_set_authdata(a, 0, authdata, 432 sizeof(authdata)) == FIDO_OK); 433 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 434 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 435 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 436 assert(fido_assert_verify(a, 0, COSE_ES256, 437 pk) == FIDO_ERR_INVALID_PARAM); 438 free_assert(a); 439 free_es256_pk(pk); 440 } 441 442 static void 443 junk_authdata(void) 444 { 445 fido_assert_t *a; 446 unsigned char *junk; 447 448 junk = malloc(sizeof(authdata)); 449 assert(junk != NULL); 450 memcpy(junk, authdata, sizeof(authdata)); 451 junk[0] = ~junk[0]; 452 453 a = alloc_assert(); 454 assert(fido_assert_set_count(a, 1) == FIDO_OK); 455 assert(fido_assert_set_authdata(a, 0, junk, 456 sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); 457 free_assert(a); 458 free(junk); 459 } 460 461 static void 462 junk_sig(void) 463 { 464 fido_assert_t *a; 465 es256_pk_t *pk; 466 unsigned char *junk; 467 468 junk = malloc(sizeof(sig)); 469 assert(junk != NULL); 470 memcpy(junk, sig, sizeof(sig)); 471 junk[0] = ~junk[0]; 472 473 a = alloc_assert(); 474 pk = alloc_es256_pk(); 475 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 476 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 477 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 478 assert(fido_assert_set_count(a, 1) == FIDO_OK); 479 assert(fido_assert_set_authdata(a, 0, authdata, 480 sizeof(authdata)) == FIDO_OK); 481 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 482 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 483 assert(fido_assert_set_sig(a, 0, junk, sizeof(sig)) == FIDO_OK); 484 assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); 485 free_assert(a); 486 free_es256_pk(pk); 487 free(junk); 488 } 489 490 static void 491 wrong_options(void) 492 { 493 fido_assert_t *a; 494 es256_pk_t *pk; 495 496 a = alloc_assert(); 497 pk = alloc_es256_pk(); 498 assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); 499 assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); 500 assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); 501 assert(fido_assert_set_count(a, 1) == FIDO_OK); 502 assert(fido_assert_set_authdata(a, 0, authdata, 503 sizeof(authdata)) == FIDO_OK); 504 assert(fido_assert_set_up(a, FIDO_OPT_TRUE) == FIDO_OK); 505 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 506 assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); 507 assert(fido_assert_verify(a, 0, COSE_ES256, 508 pk) == FIDO_ERR_INVALID_PARAM); 509 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 510 assert(fido_assert_set_uv(a, FIDO_OPT_TRUE) == FIDO_OK); 511 assert(fido_assert_verify(a, 0, COSE_ES256, 512 pk) == FIDO_ERR_INVALID_PARAM); 513 assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); 514 assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); 515 assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_OK); 516 free_assert(a); 517 free_es256_pk(pk); 518 } 519 520 /* cbor_serialize_alloc misuse */ 521 static void 522 bad_cbor_serialize(void) 523 { 524 fido_assert_t *a; 525 526 a = alloc_assert(); 527 assert(fido_assert_set_count(a, 1) == FIDO_OK); 528 assert(fido_assert_set_authdata(a, 0, authdata, 529 sizeof(authdata)) == FIDO_OK); 530 assert(fido_assert_authdata_len(a, 0) == sizeof(authdata)); 531 free_assert(a); 532 } 533 534 int 535 main(void) 536 { 537 fido_init(0); 538 539 empty_assert_tests(); 540 valid_assert(); 541 no_cdh(); 542 no_rp(); 543 no_authdata(); 544 no_sig(); 545 junk_cdh(); 546 junk_rp(); 547 junk_authdata(); 548 junk_sig(); 549 wrong_options(); 550 bad_cbor_serialize(); 551 552 exit(0); 553 } 554