Changeset 3310
- Timestamp:
- 01/03/08 08:59:14 (12 months ago)
- Location:
- trunk/src
- Files:
-
- 8 modified
-
libopensc/Makefile.am (modified) (1 diff)
-
libopensc/card-rutoken.c (modified) (34 diffs)
-
libopensc/cardctl.h (modified) (3 diffs)
-
libopensc/pkcs15-rutoken.c (modified) (5 diffs)
-
pkcs11/framework-pkcs15.c (modified) (2 diffs)
-
pkcs15init/Makefile.am (modified) (1 diff)
-
pkcs15init/rutoken.profile (modified) (1 diff)
-
tools/rutoken-tool.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libopensc/Makefile.am
r3304 r3310 37 37 pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ 38 38 pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ 39 compression.c p15card-helper.c pkcs15-rutoken.c 39 pkcs15-rutoken.c pkcs15-prkey-rutoken.c \ 40 compression.c p15card-helper.c 40 41 libopensc_la_LDFLAGS = -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@ 41 42 libopensc_la_LIBADD = @LIBSCCONF@ $(OPENSSL_LIBS) $(OPENCT_LIBS) $(PCSC_LIBS) $(LTLIB_LIBS) -
trunk/src/libopensc/card-rutoken.c
r3304 r3310 21 21 #include "internal.h" 22 22 #include "cardctl.h" 23 #include <sys/types.h> 23 24 #include <ctype.h> 24 25 #include <string.h> … … 37 38 #endif 38 39 39 40 41 40 #define FDESCR_DF 0x38 /*00111000b*/ 42 41 #define FDESCR_EF 0x01 … … 44 43 #define ID_RESERVED_CURDF 0x3FFF /*Reserved ID for current DF*/ 45 44 46 int get_prkey_from_bin(u8* data, int len, struct sc_pkcs15_prkey **key); 45 #ifdef HAVE_OPENSSL 46 int get_prkey_from_bin(const u8 *data, size_t len, struct sc_pkcs15_prkey **key); 47 #endif 47 48 48 49 #ifdef BIG_ENDIAN_RUTOKEN … … 51 52 #define MF_PATH "\x00\x3F" 52 53 #endif 54 53 55 struct auth_senv { 54 56 unsigned int algorithm; 55 int key_file_id;56 size_t key_size;57 unsigned int algorithm_flags;58 sc_path_t path;59 57 }; 60 58 typedef struct auth_senv auth_senv_t; 61 59 62 60 static const sc_SecAttrV2_t default_sec_attr = { 63 0x4 0,64 0, 0, 0, 0, 0, 0, 1,65 0, 0, 0, 0, 0, 0, 261 0x42, 62 0, 1, 0, 0, 0, 0, 1, 63 0, 2, 0, 0, 0, 0, 2 66 64 }; 67 65 68 66 static const struct sc_card_operations *iso_ops = NULL; 69 67 70 struct sc_card_operations rutoken_ops; 68 static struct sc_card_operations rutoken_ops; 69 71 70 static struct sc_card_driver rutoken_drv = { 72 71 "ruToken driver", … … 81 80 }; 82 81 83 static int make_le_path(u8 *hPath, size_t len);84 static int rutoken_get_do_info(sc_card_t *card, sc_DO_INFO_t * pInfo);85 86 82 const char *hexdump(const void *data, size_t len) 87 83 { … … 124 120 { 125 121 int ret = SC_ERROR_MEMORY_FAILURE; 126 #ifdef DEBUG 127 /* if(!card->ctx->debug) card->ctx->debug = 1; */ 128 #endif 129 SC_FUNC_CALLED(card->ctx, 1); 122 123 SC_FUNC_CALLED(card->ctx, 1); 124 130 125 card->name = "rutoken card"; 131 126 card->drv_data = malloc(sizeof(auth_senv_t)); … … 138 133 /* add algorithm 139 134 TODO: may nid som other flag */ 140 unsigned int flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; /* SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_HASH_MD5_SHA1 | SC_ALGORITHM_RSA_PAD_NONE*/ 135 unsigned int flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; 136 /* SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 137 | SC_ALGORITHM_RSA_HASH_MD5_SHA1 138 | SC_ALGORITHM_RSA_PAD_NONE */ 141 139 142 140 _sc_card_add_rsa_alg(card, 256, flags, 0); … … 146 144 _sc_card_add_rsa_alg(card, 2048, flags, 0); 147 145 sc_algorithm_info_t info; 148 flags = SC_ALGORITHM_GOST_CRYPT_PZ | SC_ALGORITHM_GOST_CRYPT_GAMM | SC_ALGORITHM_GOST_CRYPT_GAMMOS; 146 flags = SC_ALGORITHM_GOST_CRYPT_PZ | SC_ALGORITHM_GOST_CRYPT_GAMM 147 | SC_ALGORITHM_GOST_CRYPT_GAMMOS; 149 148 memset(&info, 0, sizeof(info)); 150 149 info.algorithm = SC_ALGORITHM_GOST; … … 221 220 for (i = 0; i < err_count; i++) { 222 221 if (rutoken_errors[i].SWs == ((sw1 << 8) | sw2)) { 223 if ( rutoken_errors[i].errorstr ) sc_debug(card->ctx, rutoken_errors[i].errorstr); 222 if ( rutoken_errors[i].errorstr ) 223 sc_debug(card->ctx, rutoken_errors[i].errorstr); 224 224 /*SC_FUNC_RETURN(card->ctx, 1, rutoken_errors[i].errorno);*/ 225 225 return rutoken_errors[i].errorno; … … 231 231 } 232 232 233 int rutoken_dir_up(sc_card_t *card)233 static int rutoken_dir_up(sc_card_t *card) 234 234 { 235 235 u8 rbuf[256]; … … 252 252 } 253 253 254 /* make little endian path from normal path. 255 return 1 if right len, otherwise 0 */ 256 static int make_le_path(u8 *hPath, size_t len) 257 { 258 #ifdef BIG_ENDIAN_RUTOKEN 259 /* we don't need it any more */ 260 return 1; 261 #else 262 int i, ret = (len > 1) && !(len & 1); /* && (len <= SC_MAX_PATH_SIZE); */ 263 if (ret) 264 { 265 for(i = 0; i < len; i += 2) 266 { 267 u8 b = hPath[i]; 268 hPath[i] = hPath[i+1]; 269 hPath[i+1] = b; 270 } 271 } 272 return ret; 273 #endif 274 } 254 275 255 276 static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) … … 288 309 289 310 /* 00 a4 00 02 02 prev id - next */ 290 while(1){ 311 while(1) 312 { 291 313 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x06); 292 314 apdu.cla = 0x00; … … 318 340 } 319 341 320 /* make little endian path from normal path. 321 return 1 if right len, otherwise 0 */ 322 static int make_le_path(u8 *hPath, size_t len) 323 { 324 #ifdef BIG_ENDIAN_RUTOKEN 325 /* we don't need it any more */ 326 return 1; 327 #else 328 int i, ret = (len > 1) && !(len & 1); /* && (len <= SC_MAX_PATH_SIZE); */ 329 if (ret) 330 { 331 for(i = 0; i < len; i += 2) 332 { 333 u8 b = hPath[i]; 334 hPath[i] = hPath[i+1]; 335 hPath[i+1] = b; 336 } 337 } 338 return ret; 339 #endif 340 } 341 342 void rutoken_process_fcp(sc_card_t *card, u8 *pIn, sc_file_t *file) 342 static void rutoken_process_fcp(sc_card_t *card, u8 *pIn, sc_file_t *file) 343 343 { 344 344 #ifdef BIG_ENDIAN_RUTOKEN … … 466 466 { 467 467 int ret = SC_ERROR_NOT_SUPPORTED; 468 469 468 return ret; 470 469 } 471 470 */ 472 471 473 static int rutoken_construct_fcp(sc_card_t *card, const sc_file_t *file, 474 u8 *out) 472 static int rutoken_construct_fcp(sc_card_t *card, const sc_file_t *file, u8 *out) 475 473 { 476 474 SC_FUNC_CALLED(card->ctx, 1); … … 494 492 out[4] = 0x01; 495 493 /* set the length (write to wBodyLen) */ 496 /* *((unsigned short int*)(out) + 1) = (unsigned short int)file->size; */497 494 #ifdef BIG_ENDIAN_RUTOKEN 498 495 out[2] = file->size / 256; … … 508 505 } 509 506 /* set file ID */ 510 /* *((unsigned short int*)(out) + 3) = (unsigned short int)file->id; */511 507 #ifdef BIG_ENDIAN_RUTOKEN 512 508 out[6] = file->id / 256; … … 522 518 memcpy(out + 17, &default_sec_attr, SEC_ATTR_SIZE); 523 519 524 525 520 SC_FUNC_RETURN(card->ctx, 1, SC_NO_ERROR); 526 521 } … … 579 574 } 580 575 576 static int rutoken_verify(sc_card_t *card, unsigned int type, int ref_qualifier, 577 const u8 *data, size_t data_len, int *tries_left) 578 { 579 int ret = SC_ERROR_CARD_CMD_FAILED; 580 sc_apdu_t apdu; 581 582 SC_FUNC_CALLED(card->ctx, 1); 583 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, ref_qualifier); 584 apdu.lc = data_len; 585 apdu.datalen = data_len; 586 apdu.data = data; 587 if(sc_transmit_apdu(card, &apdu) >= 0) 588 { 589 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 590 if(ret == SC_ERROR_PIN_CODE_INCORRECT && tries_left) 591 { 592 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 593 ref_qualifier); 594 ret = sc_transmit_apdu(card, &apdu); 595 if(ret >= 0) 596 { 597 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 598 if(ret == SC_ERROR_PIN_CODE_INCORRECT) 599 *tries_left = (int)(apdu.sw2 & 0x0f); 600 } 601 } 602 } 603 SC_FUNC_RETURN(card->ctx, 1, ret); 604 } 605 581 606 static int rutoken_logout(sc_card_t *card) 582 607 { … … 585 610 sc_path_t path; 586 611 612 SC_FUNC_CALLED(card->ctx, 1); 587 613 sc_format_path("3F00", &path); 588 614 if (rutoken_select_file(card, &path, NULL) == SC_SUCCESS) … … 596 622 } 597 623 624 static int rutoken_change_reference_data(sc_card_t *card, unsigned int type, 625 int ref_qualifier, const u8 *old, size_t oldlen, 626 const u8 *newref, size_t newlen, int *tries_left) 627 { 628 int left; 629 int ret = SC_ERROR_CARD_CMD_FAILED; 630 sc_apdu_t apdu; 631 632 SC_FUNC_CALLED(card->ctx, 1); 633 634 if(old && oldlen) 635 { 636 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, ref_qualifier); 637 if(sc_transmit_apdu(card, &apdu) >= 0 638 && apdu.sw1 != 0x90 && apdu.sw2 != 0x00) 639 { 640 rutoken_logout(card); 641 rutoken_verify(card, type, ref_qualifier, old, oldlen, &left); 642 } 643 } 644 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); 645 apdu.lc = newlen; 646 apdu.datalen = newlen; 647 apdu.data = newref; 648 if(sc_transmit_apdu(card, &apdu) >= 0) 649 { 650 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 651 if(ret == SC_ERROR_PIN_CODE_INCORRECT && tries_left) 652 *tries_left = (int)(apdu.sw2 & 0x0f); 653 } 654 SC_FUNC_RETURN(card->ctx, 1, ret); 655 } 656 657 static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, 658 int ref_qualifier, const u8 *puk, size_t puklen, 659 const u8 *newref, size_t newlen) 660 { 661 #ifdef FORCE_VERIFY_RUTOKEN 662 int left; 663 #endif 664 int ret = SC_ERROR_CARD_CMD_FAILED; 665 sc_apdu_t apdu; 666 667 SC_FUNC_CALLED(card->ctx, 1); 668 #ifdef FORCE_VERIFY_RUTOKEN 669 if(puk && puklen) 670 { 671 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, ref_qualifier); 672 if(sc_transmit_apdu(card, &apdu) >= 0 673 && apdu.sw1 != 0x90 && apdu.sw2 != 0x00) 674 { 675 rutoken_logout(card); 676 rutoken_verify(card, type, ref_qualifier, puk, puklen, &left); 677 } 678 } 679 #endif 680 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2c, 0x03, ref_qualifier); 681 if(sc_transmit_apdu(card, &apdu) >= 0) 682 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 683 SC_FUNC_RETURN(card->ctx, 1, ret); 684 } 685 598 686 static int rutoken_restore_security_env(sc_card_t *card, int se_num) 599 687 { 600 688 int ret = SC_ERROR_CARD_CMD_FAILED; 601 689 sc_apdu_t apdu; 602 SC_FUNC_CALLED(card->ctx, 1); 603 690 691 SC_FUNC_CALLED(card->ctx, 1); 604 692 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 3, se_num); 605 693 if(sc_transmit_apdu(card, &apdu) >= 0) 606 694 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 607 608 SC_FUNC_RETURN(card->ctx, 1, ret); 609 } 610 611 int rutoken_set_security_env(sc_card_t *card, 695 SC_FUNC_RETURN(card->ctx, 1, ret); 696 } 697 698 static int rutoken_set_security_env(sc_card_t *card, 612 699 const sc_security_env_t *env, 613 700 int se_num) … … 621 708 if(env->algorithm == SC_ALGORITHM_RSA) 622 709 { 623 const char PRK_DF[] = "3F0000000000FF001001";624 sc_debug(card->ctx, "RSA\n");625 710 senv->algorithm = SC_ALGORITHM_RSA_RAW; 626 if(env->operation == SC_SEC_OPERATION_DECIPHER || env->operation == SC_SEC_OPERATION_SIGN)627 {628 sc_format_path(PRK_DF, &senv->path);629 sc_append_path(&senv->path, &env->file_ref);630 }631 else ret = SC_ERROR_INVALID_ARGUMENTS;632 711 return ret; 633 712 } 634 713 else 635 714 senv->algorithm = SC_ALGORITHM_GOST; 715 636 716 if (env->key_ref_len != 1) 637 717 { … … 672 752 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 673 753 } 674 /* set driver data */ 675 if (ret == SC_NO_ERROR) 676 { 677 /* TODO: add check */ 678 senv->algorithm = SC_ALGORITHM_GOST; 679 senv->algorithm_flags = env->algorithm_flags; 680 senv->key_file_id = env->key_ref[0]; 681 senv->key_size = 256; 682 } 683 SC_FUNC_RETURN(card->ctx, 1, ret); 684 } 685 686 void rutoken_set_do_hdr(u8 *data, sc_DOHdrV2_t *pHdr) 754 SC_FUNC_RETURN(card->ctx, 1, ret); 755 } 756 757 static void rutoken_set_do_hdr(u8 *data, sc_DOHdrV2_t *pHdr) 687 758 { 688 759 if(data) 689 760 { 761 #ifdef BIG_ENDIAN_RUTOKEN 762 data[0] = (u8)(pHdr->wDOBodyLen / 0x100); 763 data[1] = (u8)(pHdr->wDOBodyLen % 0x100); 764 #else 690 765 data[0] = (u8)(pHdr->wDOBodyLen % 0x100); 691 766 data[1] = (u8)(pHdr->wDOBodyLen / 0x100); 767 #endif 692 768 data[2] = (u8)(pHdr->OTID.byObjectType); 693 769 data[3] = (u8)(pHdr->OTID.byObjectID); … … 699 775 memcpy(data + 17, pHdr->SA_V2, SEC_ATTR_SIZE); 700 776 } 701 }702 703 void rutoken_set_do(u8 *data, sc_DO_V2_t * pDO)704 {705 rutoken_set_do_hdr(data, &pDO->HDR);706 memcpy(data + SC_RUTOKEN_DO_HDR_LEN, pDO->abyDOBody, pDO->HDR.wDOBodyLen);707 777 } 708 778 … … 762 832 else 763 833 { 764 rutoken_set_do(data, pDO); 834 rutoken_set_do_hdr(data, &pDO->HDR); 835 memcpy(data + SC_RUTOKEN_DO_HDR_LEN, pDO->abyDOBody, pDO->HDR.wDOBodyLen); 765 836 766 837 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xda, 0x01, 0x62); … … 865 936 u8 * out, size_t outlen, int p1, int p2, int isIV) 866 937 { 867 sc_apdu_t apdu; 868 int rv = SC_NO_ERROR; 869 870 sc_debug(card->ctx,": crgram_len %i; outlen %i\n", crgram_len, outlen); 871 if (!out || !outlen) 938 const size_t cipher_chunk = 248; /* cipher_chunk <= SC_MAX_APDU_BUFFER_SIZE */ 939 size_t len, outlen_tail = outlen; 940 u8 *buf; 941 int ret; 942 sc_apdu_t apdu; 943 944 SC_FUNC_CALLED(card->ctx, 1); 945 sc_debug(card->ctx, ": crgram_len %i; outlen %i\n", crgram_len, outlen); 946 947 if (!out) 872 948 return SC_ERROR_INVALID_ARGUMENTS; 949 if (crgram_len < 16 || ((crgram_len) % 8)) 950 return SC_ERROR_WRONG_LENGTH; 951 952 buf = malloc(cipher_chunk); 953 if (!buf) 954 return SC_ERROR_OUT_OF_MEMORY; 873 955 874 956 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, p1, p2); 875 876 apdu.resp = (u8*)malloc(SC_MAX_APDU_BUFFER_SIZE); 877 if (!apdu.resp) 878 return SC_ERROR_OUT_OF_MEMORY; 879 apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; 880 if (crgram_len < 16 || ((crgram_len) % 8)) 881 rv = SC_ERROR_WRONG_LENGTH; 882 size_t cur_len = 0; 883 unsigned char is_first = 1; 884 unsigned int cur_data_len; 885 886 while( (rv == SC_NO_ERROR) && (cur_len != crgram_len) && (outlen > cur_len)) 887 { 888 cur_data_len = (crgram_len - cur_len) % 248; 889 if(!cur_data_len) cur_data_len = 248; 890 891 apdu.data = crgram + cur_len; 892 apdu.lc = apdu.datalen = cur_data_len; 893 apdu.cla = crgram_len - cur_len - cur_data_len > 0 ? 0x10 : 0x00; 894 apdu.le = apdu.resplen = 248; 895 896 if((rv = sc_transmit_apdu(card, &apdu)) >= 0 && 897 (rv = rutoken_check_sw(card, apdu.sw1, apdu.sw2)) == SC_NO_ERROR) 957 do 958 { 959 len = (crgram_len > cipher_chunk) ? cipher_chunk : crgram_len; 960 apdu.lc = len; 961 apdu.datalen = len; 962 apdu.data = crgram; 963 crgram += len; 964 crgram_len -= len; 965 966 apdu.cla = (crgram_len == 0) ? 0x00 : 0x10; 967 apdu.le = len; 968 apdu.resplen = len; 969 apdu.resp = buf; 970 971 if (sc_transmit_apdu(card, &apdu) >= 0) 972 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 973 else 974 ret = SC_ERROR_CARD_CMD_FAILED; 975 if (ret == SC_NO_ERROR) 898 976 { 899 if (isIV && is_first)977 if (isIV) 900 978 { 901 /* break initialization vector */ 902 memcpy(out, apdu.resp + 8, apdu.resplen - 8); 903 out += apdu.resplen - 8; 904 cur_len += apdu.resplen; 905 is_first = 0; 979 apdu.resp += 8; 980 apdu.resplen -= 8; 981 isIV = 0; 906 982 } 983 if (apdu.resplen > outlen_tail) 984 ret = SC_ERROR_BUFFER_TOO_SMALL; 907 985 else 908 986 { 909 /* memcpy(out + cur_len, apdu.resp, apdu.resplen); */910 987 memcpy(out, apdu.resp, apdu.resplen); 911 cur_len += apdu.resplen;912 988 out += apdu.resplen; 989 outlen_tail -= apdu.resplen; 913 990 } 914 991 } 915 } 916 if (rv == SC_NO_ERROR) rv = (cur_len == crgram_len) ? isIV ? cur_len - 8 : cur_len : SC_ERROR_BUFFER_TOO_SMALL; 917 918 if (apdu.resp) 919 free(apdu.resp); 920 921 sc_debug(card->ctx, "return decipher len %d\n", rv); 922 return rv; 992 } while (ret == SC_NO_ERROR && crgram_len != 0); 993 994 free(buf); 995 996 sc_debug(card->ctx, "len out cipher %d\n", outlen - outlen_tail); 997 if (ret == SC_NO_ERROR) 998 ret = (outlen_tail == 0) ? (int)outlen : SC_ERROR_WRONG_LENGTH; 999 1000 SC_FUNC_RETURN(card->ctx, 1, ret); 923 1001 } 924 1002 925 1003 /* Launcher for chipher */ 926 static int rutoken_decipher(sc_card_t *card, struct sc_rutoken_decipherinfo *ptr) 927 { 928 return rutoken_cipher_p(card, ptr->inbuf, ptr->inlen, ptr->outbuf, ptr->outlen, 0x80, 0x86, 1); 929 } 930 931 /* Launcher for chipher */ 932 933 static int rutoken_encipher(sc_card_t *card, struct sc_rutoken_decipherinfo *ptr) 934 { 935 return rutoken_cipher_p(card, ptr->inbuf, ptr->inlen, ptr->outbuf, ptr->outlen, 0x86, 0x80, 0); 936 } 937 938 int rutoken_read_file(sc_card_t *card, sc_path_t *path, u8 **out, int *len) 1004 1005 static int rutoken_cipher_gost(sc_card_t *card, 1006 struct sc_rutoken_decipherinfo *ptr, char is_enchiper) 1007 { 1008 int ret; 1009 1010 if (is_enchiper) 1011 ret = rutoken_cipher_p(card, ptr->inbuf, ptr->inlen, 1012 ptr->outbuf, ptr->outlen, 0x86, 0x80, 0); 1013 else 1014 ret = rutoken_cipher_p(card, ptr->inbuf, ptr->inlen, 1015 ptr->outbuf, ptr->outlen, 0x80, 0x86, 1); 1016 if (ret > 0) 1017 { 1018 if ((size_t)ret == ptr->outlen) 1019 ret = SC_SUCCESS; 1020 else 1021 ret = SC_ERROR_INTERNAL; /* SC_ERROR_DECRYPT_FAILED; */ 1022 } 1023 return ret; 1024 1025 } 1026 1027 static int rutoken_compute_mac_gost(sc_card_t *card, 1028 const u8 *in, size_t ilen, 1029 u8 *out, size_t olen) 1030 { 1031 const size_t signing_chunk = 248; 1032 size_t len; 1033 int ret; 1034 sc_apdu_t apdu; 1035 1036 SC_FUNC_CALLED(card->ctx, 1); 1037 1038 if (!in || !out || olen != 4 || ilen == 0) 1039 return SC_ERROR_INVALID_ARGUMENTS; 1040 do 1041 { 1042 sc_format_apdu(card, &apdu, 1043 ilen > signing_chunk ? 1044 SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 1045 0x2A, 0x90, 0x80); 1046 len = (ilen > signing_chunk) ? signing_chunk : ilen; 1047 apdu.lc = len; 1048 apdu.datalen = len; 1049 apdu.data = in; 1050 in += len; 1051 ilen -= len; 1052 if (ilen == 0) 1053 { 1054 apdu.cla = 0x00; 1055 apdu.le = olen; 1056 apdu.resplen = olen; 1057 apdu.resp = out; 1058 } 1059 else 1060 apdu.cla = 0x10; 1061 if (sc_transmit_apdu(card, &apdu) >= 0) 1062 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 1063 else 1064 ret = SC_ERROR_CARD_CMD_FAILED; 1065 } while (ret == SC_NO_ERROR && ilen != 0); 1066 1067 SC_FUNC_RETURN(card->ctx, 1, ret); 1068 } 1069 1070 /* RSA emulation */ 1071 1072 #ifdef HAVE_OPENSSL 1073 1074 static int rutoken_get_current_fileid(sc_card_t *card, u8 id[2]) 1075 { 1076 sc_apdu_t apdu; 1077 int ret = SC_ERROR_CARD_CMD_FAILED; 1078 1079 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x11); 1080 apdu.resp = id; 1081 apdu.resplen = sizeof(id); 1082 apdu.le = 2; 1083 if(sc_transmit_apdu(card, &apdu) >= 0) 1084 ret = rutoken_check_sw(card, apdu.sw1, apdu.sw2); 1085 SC_FUNC_RETURN(card->ctx, 1, ret); 1086 }
