@@ -395,20 +395,103 @@ static int cmd_get_metadata() {
395
395
return SW_INCORRECT_P1P2 ();
396
396
}
397
397
uint8_t * meta = NULL ;
398
- int meta_len = 0 ;
399
- if ((meta_len = meta_find (P2 (apdu ), & meta )) <= 0 ) {
400
- return SW_REFERENCE_NOT_FOUND ();
398
+ uint16_t key_ref = P2 (apdu );
399
+ if (key_ref == 0x80 ) {
400
+ key_ref = EF_PIV_PIN ;
401
+ }
402
+ else if (key_ref == 0x81 ) {
403
+ key_ref = EF_PIV_PUK ;
404
+ }
405
+ file_t * ef_key = search_by_fid (key_ref , NULL , SPECIFY_EF );
406
+ if (!file_has_data (ef_key )) {
407
+ return SW_MEMORY_FAILURE ();
408
+ }
409
+ if (key_ref != EF_PIV_PIN && key_ref != EF_PIV_PUK ) {
410
+ int meta_len = 0 ;
411
+ if ((meta_len = meta_find (key_ref , & meta )) <= 0 ) {
412
+ return SW_REFERENCE_NOT_FOUND ();
413
+ }
414
+ res_APDU [res_APDU_size ++ ] = 0x1 ;
415
+ res_APDU [res_APDU_size ++ ] = 1 ;
416
+ res_APDU [res_APDU_size ++ ] = meta [0 ];
417
+ res_APDU [res_APDU_size ++ ] = 0x2 ;
418
+ res_APDU [res_APDU_size ++ ] = 2 ;
419
+ res_APDU [res_APDU_size ++ ] = meta [1 ];
420
+ res_APDU [res_APDU_size ++ ] = meta [2 ];
421
+ res_APDU [res_APDU_size ++ ] = 0x3 ;
422
+ res_APDU [res_APDU_size ++ ] = 1 ;
423
+ res_APDU [res_APDU_size ++ ] = meta [3 ];
424
+ if (meta [0 ] == PIV_ALGO_RSA1024 || meta [0 ] == PIV_ALGO_RSA2048 || meta [0 ] == PIV_ALGO_ECCP256 || meta [0 ] == PIV_ALGO_ECCP384 ) {
425
+ res_APDU [res_APDU_size ++ ] = 0x4 ;
426
+ if (meta [0 ] == PIV_ALGO_RSA1024 || meta [0 ] == PIV_ALGO_RSA2048 ) {
427
+ mbedtls_rsa_context ctx ;
428
+ mbedtls_rsa_init (& ctx );
429
+ int r = load_private_key_rsa (& ctx , ef_key , false);
430
+ if (r != CCID_OK ) {
431
+ mbedtls_rsa_free (& ctx );
432
+ return SW_EXEC_ERROR ();
433
+ }
434
+ res_APDU [res_APDU_size ++ ] = 0x81 ;
435
+ res_APDU [res_APDU_size ++ ] = 0x82 ;
436
+ put_uint16_t (mbedtls_mpi_size (& ctx .N ), res_APDU + res_APDU_size ); res_APDU_size += 2 ;
437
+ mbedtls_mpi_write_binary (& ctx .N , res_APDU + res_APDU_size , mbedtls_mpi_size (& ctx .N ));
438
+ res_APDU_size += mbedtls_mpi_size (& ctx .N );
439
+ res_APDU [res_APDU_size ++ ] = 0x82 ;
440
+ res_APDU [res_APDU_size ++ ] = mbedtls_mpi_size (& ctx .E ) & 0xff ;
441
+ mbedtls_mpi_write_binary (& ctx .E , res_APDU + res_APDU_size , mbedtls_mpi_size (& ctx .E ));
442
+ res_APDU_size += mbedtls_mpi_size (& ctx .E );
443
+ mbedtls_rsa_free (& ctx );
444
+ }
445
+ else {
446
+ mbedtls_ecdsa_context ctx ;
447
+ mbedtls_ecdsa_init (& ctx );
448
+ int r = load_private_key_ecdsa (& ctx , ef_key , false);
449
+ if (r != CCID_OK ) {
450
+ mbedtls_ecdsa_free (& ctx );
451
+ return SW_EXEC_ERROR ();
452
+ }
453
+ uint8_t pt [MBEDTLS_ECP_MAX_PT_LEN ];
454
+ size_t plen = 0 ;
455
+ mbedtls_ecp_point_write_binary (& ctx .grp , & ctx .Q , MBEDTLS_ECP_PF_UNCOMPRESSED , & plen , pt , sizeof (pt ));
456
+ mbedtls_ecdsa_free (& ctx );
457
+ res_APDU [res_APDU_size ++ ] = 0x86 ;
458
+ if (plen >= 128 ) {
459
+ res_APDU [res_APDU_size ++ ] = 0x81 ;
460
+ }
461
+ res_APDU [res_APDU_size ++ ] = plen ;
462
+ memcpy (res_APDU + res_APDU_size , pt , plen );
463
+ res_APDU_size += plen ;
464
+ }
465
+ }
466
+ }
467
+ if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK || key_ref == EF_PIV_KEY_MANAGEMENT ) {
468
+ uint8_t dhash [32 ];
469
+ int32_t eq = false;
470
+ if (key_ref == EF_PIV_PIN ) {
471
+ double_hash_pin ((const uint8_t * )"\x31\x32\x33\x34\x35\x36\xFF\xFF" , 8 , dhash );
472
+ eq = memcmp (dhash , file_get_data (ef_key ) + 1 , file_get_size (ef_key ) - 1 );
473
+ }
474
+ else if (key_ref == EF_PIV_PUK ) {
475
+ double_hash_pin ((const uint8_t * )"\x31\x32\x33\x34\x35\x36\x37\x38" , 8 , dhash );
476
+ eq = memcmp (dhash , file_get_data (ef_key ) + 1 , file_get_size (ef_key ) - 1 );
477
+ }
478
+ else if (key_ref == EF_PIV_KEY_MANAGEMENT ) {
479
+ eq = memcmp ("\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08" , file_get_data (ef_key ), file_get_size (ef_key ));
480
+ }
481
+ res_APDU [res_APDU_size ++ ] = 0x5 ;
482
+ res_APDU [res_APDU_size ++ ] = 1 ;
483
+ res_APDU [res_APDU_size ++ ] = eq ;
484
+ if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK ) {
485
+ file_t * pw_status ;
486
+ if (!(pw_status = search_by_fid (EF_PW_PRIV , NULL , SPECIFY_EF ))) {
487
+ return SW_REFERENCE_NOT_FOUND ();
488
+ }
489
+ uint8_t retries = * (file_get_data (pw_status ) + 3 + (key_ref & 0xf ));
490
+ res_APDU [res_APDU_size ++ ] = 0x6 ;
491
+ res_APDU [res_APDU_size ++ ] = 1 ;
492
+ res_APDU [res_APDU_size ++ ] = retries ;
493
+ }
401
494
}
402
- res_APDU [res_APDU_size ++ ] = 0x1 ;
403
- res_APDU [res_APDU_size ++ ] = 1 ;
404
- res_APDU [res_APDU_size ++ ] = meta [0 ];
405
- res_APDU [res_APDU_size ++ ] = 0x2 ;
406
- res_APDU [res_APDU_size ++ ] = 2 ;
407
- res_APDU [res_APDU_size ++ ] = meta [1 ];
408
- res_APDU [res_APDU_size ++ ] = meta [2 ];
409
- res_APDU [res_APDU_size ++ ] = 0x3 ;
410
- res_APDU [res_APDU_size ++ ] = 1 ;
411
- res_APDU [res_APDU_size ++ ] = meta [3 ];
412
495
return SW_OK ();
413
496
}
414
497
uint8_t challenge [16 ];
@@ -649,14 +732,17 @@ static int cmd_asym_keygen() {
649
732
if (!asn1_find_tag (& ctxi , 0xAC , & aac ) || asn1_len (& aac ) == 0 ) {
650
733
return SW_WRONG_DATA ();
651
734
}
652
- asn1_ctx_t a80 = {0 }, a81 = {0 };
735
+ asn1_ctx_t a80 = {0 }, aaa = { 0 }, aab = {0 };
653
736
asn1_find_tag (& aac , 0x80 , & a80 );
654
- asn1_find_tag (& aac , 0x81 , & a81 );
737
+ asn1_find_tag (& aac , 0xAA , & aaa );
738
+ asn1_find_tag (& aac , 0xAB , & aab );
655
739
if (asn1_len (& a80 ) == 0 ) {
656
740
return SW_WRONG_DATA ();
657
741
}
658
742
if (a80 .data [0 ] == PIV_ALGO_RSA1024 || a80 .data [0 ] == PIV_ALGO_RSA2048 ) {
659
743
printf ("KEYPAIR RSA\r\n" );
744
+ asn1_ctx_t a81 = {0 };
745
+ asn1_find_tag (& aac , 0x81 , & a81 );
660
746
mbedtls_rsa_context rsa ;
661
747
mbedtls_rsa_init (& rsa );
662
748
uint8_t index = 0 ;
@@ -696,6 +782,9 @@ static int cmd_asym_keygen() {
696
782
}
697
783
else if (a80 .data [0 ] == PIV_ALGO_X25519 ) {
698
784
}
785
+ uint8_t meta [] = {a80 .data [0 ], asn1_len (& aaa ) ? aaa .data [0 ] : PINPOLICY_ALWAYS , asn1_len (& aab ) ? aab .data [0 ] : TOUCHPOLICY_ALWAYS , ORIGIN_GENERATED };
786
+ meta_add (key_ref , meta , sizeof (meta ));
787
+ low_flash_available ();
699
788
return SW_OK ();
700
789
}
701
790
0 commit comments