| 166 | Â | { 0x6300, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 167 | Â | { 0x63C1, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 168 | Â | { 0x63C2, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 169 | Â | { 0x63C3, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 170 | Â | { 0x63C4, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 171 | Â | { 0x63C5, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 172 | Â | { 0x63C6, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 173 | Â | { 0x63C7, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 174 | Â | { 0x63C8, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 175 | Â | { 0x63C9, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 176 | Â | { 0x63Ca, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 177 | Â | { 0x63Cb, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 178 | Â | { 0x63Cc, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 179 | Â | { 0x63Cd, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 180 | Â | { 0x63Ce, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 181 | Â | { 0x63Cf, SC_ERROR_PIN_CODE_INCORRECT,"authentication failed"}, Â |
| 182 | Â | Â |
| 183 | Â | { 0x6400, SC_ERROR_CARD_CMD_FAILED,"Aborting"}, Â |
| 184 | Â | Â |
| 185 | Â | { 0x6500, SC_ERROR_MEMORY_FAILURE, "Memory failure"}, Â |
| 186 | Â | { 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure"}, Â |
| 187 | Â | Â |
| 188 | Â | { 0x6700, SC_ERROR_WRONG_LENGTH, "Lc or Le invalid"}, Â |
| 189 | Â | Â |
| 190 | Â | { 0x6883, SC_ERROR_CARD_CMD_FAILED, "The finishing command of a chain is expected"}, Â |
| 191 | Â | Â |
| 192 | Â | { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED,"required access right not granted"}, Â |
| 193 | Â | { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "bs object blocked"}, Â |
| 194 | Â | { 0x6985, SC_ERROR_CARD_CMD_FAILED, "command not allowed (unsuitable conditions)"}, Â |
| 195 | Â | { 0x6986, SC_ERROR_INCORRECT_PARAMETERS,"no current ef selected"}, Â |
| 196 | Â | Â |
| 197 | Â | { 0x6a80, SC_ERROR_INCORRECT_PARAMETERS,"invalid parameters in data field"}, Â |
| 198 | Â | { 0x6a81, SC_ERROR_NOT_SUPPORTED, "function/mode not supported"}, Â |
| 199 | Â | { 0x6a82, SC_ERROR_FILE_NOT_FOUND, "file (DO) not found"}, Â |
| 200 | Â | { 0x6a84, SC_ERROR_CARD_CMD_FAILED, "not enough memory"}, Â |
| 201 | Â | { 0x6a86, SC_ERROR_INCORRECT_PARAMETERS,"p1/p2 invalid"}, Â |
| 202 | Â | { 0x6a89, SC_ERROR_FILE_ALREADY_EXISTS,"file (DO) already exists"}, Â |
| 203 | Â | Â |
| 204 | Â | { 0x6b00, SC_ERROR_INCORRECT_PARAMETERS,"Out of file length"}, Â |
| 205 | Â | Â |
| 206 | Â | { 0x6c00, SC_ERROR_WRONG_LENGTH, "le does not fit the data to be sent"}, Â |
| 207 | Â | Â |
| 208 | Â | { 0x6d00, SC_ERROR_INS_NOT_SUPPORTED, "ins invalid (not supported)"}, Â |
| Â | 157 | { 0x6300, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 158 | { 0x63C1, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed. One tries left"}, Â |
| Â | 159 | { 0x63C2, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed. Two tries left"}, Â |
| Â | 160 | { 0x63C3, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 161 | { 0x63C4, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 162 | { 0x63C5, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 163 | { 0x63C6, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 164 | { 0x63C7, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 165 | { 0x63C8, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 166 | { 0x63C9, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 167 | { 0x63CA, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 168 | { 0x63CB, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 169 | { 0x63CC, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 170 | { 0x63CD, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 171 | { 0x63CE, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 172 | { 0x63CF, SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed"}, Â |
| Â | 173 | Â |
| Â | 174 | { 0x6400, SC_ERROR_CARD_CMD_FAILED, "Aborting"}, Â |
| Â | 175 | Â |
| Â | 176 | { 0x6500, SC_ERROR_MEMORY_FAILURE, "Memory failure"}, Â |
| Â | 177 | { 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure"}, Â |
| Â | 178 | Â |
| Â | 179 | { 0x6700, SC_ERROR_WRONG_LENGTH, "Lc or Le invalid"}, Â |
| Â | 180 | Â |
| Â | 181 | { 0x6883, SC_ERROR_CARD_CMD_FAILED, "The finishing command of a chain is expected"}, Â |
| Â | 182 | Â |
| Â | 183 | { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Required access right not granted"}, Â |
| Â | 184 | { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "DO blocked"}, Â |
| Â | 185 | { 0x6985, SC_ERROR_CARD_CMD_FAILED, "Command not allowed (unsuitable conditions)"}, Â |
| Â | 186 | { 0x6986, SC_ERROR_INCORRECT_PARAMETERS,"No current EF selected"}, Â |
| Â | 187 | Â |
| Â | 188 | { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Invalid parameters in data field"}, Â |
| Â | 189 | { 0x6A81, SC_ERROR_NOT_SUPPORTED, "Function/mode not supported"}, Â |
| Â | 190 | { 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File (DO) not found"}, Â |
| Â | 191 | { 0x6A84, SC_ERROR_CARD_CMD_FAILED, "Not enough memory space in the token"}, Â |
| Â | 192 | { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"P1 or P2 invalid"}, Â |
| Â | 193 | { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS, "File (DO) already exists"}, Â |
| Â | 194 | Â |
| Â | 195 | { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Out of maximum file length"}, Â |
| Â | 196 | Â |
| Â | 197 | { 0x6C00, SC_ERROR_WRONG_LENGTH, "Le does not fit the data to be sent"}, Â |
| Â | 198 | Â |
| Â | 199 | { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Ins invalid (not supported)"}, Â |
| 242 | Â | u8 rbuf[256];Â |
| 243 | Â | int r = 0;Â |
| 244 | Â | sc_apdu_t apdu;Â |
| 245 | Â | SC_FUNC_CALLED(card->ctx, 1);Â |
| 246 | Â | /*sc_debug(card->ctx, "\n\tpath = %s\n\ttype = %d", hexdump(path, pathlen), in_path->type);Â |
| 247 | Â | prepare & transmit APDUÂ |
| 248 | Â | 00 a4 00 04 20 - first*/Â |
| 249 | Â | sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x03, 0x00);Â |
| 250 | Â | apdu.cla = 0x00;Â |
| 251 | Â | apdu.resplen = 256;Â |
| 252 | Â | apdu.resp = rbuf;Â |
| 253 | Â | apdu.le = 256;Â |
| 254 | Â | r = sc_transmit_apdu(card, &apdu);Â |
| 255 | Â | SC_TEST_RET(card->ctx, r, "APDU transmit failed");Â |
| 256 | Â | sc_debug(card->ctx, "rbuf = %s len %d", hexdump(apdu.resp, apdu.resplen), apdu.resplen);Â |
| 257 | Â | sc_debug(card->ctx, "sw1 = %x, sw2 = %x", apdu.sw1, apdu.sw2);Â |
| 258 | Â | return 0;Â |
| 259 | Â | }Â |
| 260 | Â | Â |
| 261 |  | /* make little endian path from normal path. |
| 262 | Â | return 1 if right len, otherwise 0 */Â |
| 263 | Â | static int make_le_path(u8 *hPath, size_t len)Â |
| 264 | Â | {Â |
| 265 | Â | #ifdef BIG_ENDIAN_RUTOKENÂ |
| 266 | Â | /* we don't need it any more */Â |
| 267 | Â | return 1;Â |
| 268 |  | #else |
| 269 | Â | int i, ret = (len > 1) && !(len & 1); /* && (len <= SC_MAX_PATH_SIZE); */Â |
| 270 | Â | if (ret)Â |
| 271 | Â | {Â |
| 272 | Â | for(i = 0; i < len; i += 2)Â |
| 273 | Â | {Â |
| 274 | Â | u8 b = hPath[i];Â |
| 275 | Â | hPath[i] = hPath[i+1];Â |
| 276 | Â | hPath[i+1] = b;Â |
| 277 | Â | }Â |
| 278 | Â | }Â |
| 279 | Â | return ret;Â |
| 280 |  | #endif |
| Â | 229 | u8 rbuf[256];Â |
| Â | 230 | sc_apdu_t apdu;Â |
| Â | 231 | int ret;Â |
| Â | 232 | Â |
| Â | 233 | SC_FUNC_CALLED(card->ctx, 3);Â |
| Â | 234 | Â |
| Â | 235 | sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x03, 0x00);Â |
| Â | 236 | apdu.cla = 0x00;Â |
| Â | 237 | apdu.resplen = sizeof(rbuf);Â |
| Â | 238 | apdu.resp = rbuf;Â |
| Â | 239 | apdu.le = sizeof(rbuf);Â |
| Â | 240 | Â |
| Â | 241 | ret = sc_transmit_apdu(card, &apdu);Â |
| Â | 242 | SC_TEST_RET(card->ctx, ret, "APDU transmit failed");Â |
| Â | 243 | ret = sc_check_sw(card, apdu.sw1, apdu.sw2);Â |
| Â | 244 | SC_FUNC_RETURN(card->ctx, 3, ret);Â |
| 287 | Â | int r = 0, len=0;Â |
| 288 | Â | sc_apdu_t apdu;Â |
| 289 | Â | Â |
| 290 | Â | SC_FUNC_CALLED(card->ctx, 1);Â |
| 291 | Â | /* sc_debug(card->ctx, "\n\tpath = %s\n\ttype = %d", hexdump(path, pathlen), in_path->type); */Â |
| 292 | Â | /* prepare & transmit APDU */Â |
| 293 | Â | /* 00 a4 00 04 20 - first */Â |
| 294 | Â | Â |
| 295 | Â | sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x00, 0x00);Â |
| 296 | Â | apdu.cla = 0x00;Â |
| 297 | Â | apdu.resplen = 256;Â |
| 298 | Â | apdu.resp = rbuf;Â |
| 299 | Â | apdu.le = 256;Â |
| 300 | Â | r = sc_transmit_apdu(card, &apdu);Â |
| 301 | Â | SC_TEST_RET(card->ctx, r, "APDU transmit failed");Â |
| 302 | Â | sc_debug(card->ctx, "rbuf = %s len %d", hexdump(apdu.resp, apdu.resplen), apdu.resplen);Â |
| 303 | Â | sc_debug(card->ctx, "sw1 = %x, sw2 = %x", apdu.sw1, apdu.sw2);Â |
| 304 | Â | if((apdu.sw1 == 0x6a) )Â |
| 305 | Â | {Â |
| 306 | Â | /* empty dir */Â |
| 307 | Â | return 0;Â |
| 308 | Â | }Â |
| 309 | Â | /* todo: add check buflen */Â |
| 310 | Â | /* save first file(dir) ID */Â |
| 311 | Â | memcpy(buf+len, rbuf+6, 2);Â |
| 312 | Â | memcpy(previd, rbuf+6, 2);Â |
| 313 | Â | len += 2;Â |
| 314 | Â | if(rbuf[4] == FDESCR_DF)Â |
| 315 | Â | rutoken_dir_up(card);Â |
| 316 | Â | Â |
| 317 | Â | /* 00 a4 00 02 02 prev id - next */Â |
| 318 | Â | while(1)Â |
| 319 | Â | {Â |
| 320 | Â | sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x06);Â |
| 321 | Â | apdu.cla = 0x00;Â |
| 322 | Â | apdu.lc = 2;Â |
| 323 | Â | apdu.data = previd;Â |
| 324 | Â | apdu.datalen = 2;Â |
| 325 | Â | apdu.resplen = 256;Â |
| 326 | Â | apdu.resp = rbuf;Â |
| 327 | Â | apdu.le = 256;Â |
| 328 | Â | r = sc_transmit_apdu(card, &apdu);Â |
| 329 | Â | SC_TEST_RET(card->ctx, r, "APDU transmit failed");Â |
| 330 | Â | sc_debug(card->ctx, "rbuf = %s len %d", hexdump(apdu.resp, apdu.resplen), apdu.resplen);Â |
| 331 | Â | sc_debug(card->ctx, "sw1 = %x, sw2 = %x", apdu.sw1, apdu.sw2);Â |
| 332 | Â | if((apdu.sw1 == 0x6a) )Â |
| 333 | Â | {Â |
| 334 | Â | /* end list */Â |
| 335 | Â | break;Â |
| 336 | Â | }Â |
| 337 | Â | /* todo: add check buflen */Â |
| 338 | Â | /* save first file(dir) ID */Â |
| 339 | Â | memcpy(buf+len, rbuf+6, 2);Â |
| 340 | Â | memcpy(previd, rbuf+6, 2);Â |
| 341 | Â | len += 2;Â |
| 342 | Â | if(rbuf[4] == FDESCR_DF)Â |
| Â | 251 | sc_apdu_t apdu;Â |
| Â | 252 | size_t len = 0;Â |
| Â | 253 | int ret, first = 1;Â |
| Â | 254 | Â |
| Â | 255 | SC_FUNC_CALLED(card->ctx, 1);Â |
| Â | 256 | while (1)Â |
| Â | 257 | {Â |
| Â | 258 | if (first)Â |
| Â | 259 | sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x00, 0x00);Â |
|  | 260 | else |
| Â | 261 | {Â |
| Â | 262 | /* 00 a4 00 02 02 prev id - next */Â |
| Â | 263 | sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x02);Â |
| Â | 264 | apdu.lc = sizeof(previd);Â |
| Â | 265 | apdu.data = previd;Â |
| Â | 266 | apdu.datalen = sizeof(previd);Â |
| Â | 267 | }Â |
| Â | 268 | apdu.cla = 0x00;Â |
| Â | 269 | apdu.resplen = sizeof(rbuf);Â |
| Â | 270 | apdu.resp = rbuf;Â |
| Â | 271 | apdu.le = sizeof(rbuf);Â |
| Â | 272 | ret = sc_transmit_apdu(card, &apdu);Â |
| Â | 273 | SC_TEST_RET(card->ctx, ret, "APDU transmit failed");Â |
| Â | 274 | Â |
| Â | 275 | if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82)Â |
| Â | 276 | break; /* if (first) "end list" else "empty dir" */Â |
| Â | 277 | Â |
| Â | 278 | ret = sc_check_sw(card, apdu.sw1, apdu.sw2);Â |
| Â | 279 | SC_TEST_RET(card->ctx, ret, "Get list files failed");Â |
| Â | 280 | Â |
| Â | 281 | /* save first file(dir) ID */Â |
| Â | 282 | if (len + 2 <= buflen)Â |
| Â | 283 | {Â |
| Â | 284 | buf[len++] = rbuf[6];Â |
| Â | 285 | buf[len++] = rbuf[7];Â |
| Â | 286 | }Â |
| Â | 287 | memcpy(previd, rbuf+6, sizeof(previd));Â |
| Â | 288 | if (rbuf[4] == FDESCR_DF)Â |
| Â | 310 | Â |
| Â | 311 | if (file->sec_attr && file->sec_attr_len == SEC_ATTR_SIZEÂ |
| Â | 312 | #ifndef SET_ACL_FOR_EF_LENLESS8_RUTOKENÂ |
| Â | 313 | /*Â |
| Â | 314 | * No set ACL for EF:Â |
| Â | 315 | * PrKDF_path: "3F00FF000001" - SC_PKCS15_PRKDFÂ |
| Â | 316 | * PuKDF_path: "3F00FF000002" - SC_PKCS15_PUKDFÂ |
| Â | 317 | * CDF_path: "3F00FF000003" - SC_PKCS15_CDFÂ |
| Â | 318 | * DODF_path: "3F00FF000004" - SC_PKCS15_DODFÂ |
| Â | 319 | * (see files: src/libopensc/pkcs15-rutoken.c, src/pkcs15init/rutoken.profile)Â |
| Â | 320 | */Â |
| Â | 321 | && (file->type != SC_FILE_TYPE_WORKING_EF || file->path.len >= 8)Â |
|  | 322 | #endif |
| Â | 323 | )Â |
| Â | 324 | {Â |
|  | 325 | sc_file_add_acl_entry(file, SC_AC_OP_SELECT, |
| Â | 326 | SC_AC_NONE, SC_AC_KEY_REF_NONE);Â |
| Â | 327 | if (file->sec_attr[0] & 0x40) /* if AccessMode.6 */Â |
| Â | 328 | {Â |
|  | 329 | sc_debug(card->ctx, "SC_AC_OP_DELETE %i %i", |
|  | 330 | (int)(*(int8_t*)&file->sec_attr[1 +6]), |
| Â | 331 | file->sec_attr[1+7 +6]);Â |
|  | 332 | sc_file_add_acl_entry(file, SC_AC_OP_DELETE, |
|  | 333 | (int)(*(int8_t*)&file->sec_attr[1 +6]), |
| Â | 334 | file->sec_attr[1+7 +6]);Â |
| Â | 335 | }Â |
| Â | 336 | if (file->sec_attr[0] & 0x01) /* if AccessMode.0 */Â |
| Â | 337 | {Â |
|  | 338 | sc_debug(card->ctx, (file->type == SC_FILE_TYPE_DF) ? |
|  | 339 | "SC_AC_OP_CREATE %i %i" : "SC_AC_OP_READ %i %i", |
|  | 340 | (int)(*(int8_t*)&file->sec_attr[1 +0]), |
| Â | 341 | file->sec_attr[1+7 +0]);Â |
|  | 342 | sc_file_add_acl_entry(file, |
|  | 343 | (file->type == SC_FILE_TYPE_DF) ? |
|  | 344 | SC_AC_OP_CREATE : SC_AC_OP_READ, |
|  | 345 | (int)(*(int8_t*)&file->sec_attr[1 +0]), |
| Â | 346 | file->sec_attr[1+7 +0]);Â |
| Â | 347 | }Â |
| Â | 348 | if (file->type == SC_FILE_TYPE_DF)Â |
| Â | 349 | {Â |
|  | 350 | sc_file_add_acl_entry(file, SC_AC_OP_LIST_FILES, |
| Â | 351 | SC_AC_NONE, SC_AC_KEY_REF_NONE);Â |
| Â | 352 | }Â |
|  | 353 | else |
| Â | 354 | if (file->sec_attr[0] & 0x02) /* if AccessMode.1 */Â |
| Â | 355 | {Â |
|  | 356 | sc_debug(card->ctx, "SC_AC_OP_UPDATE %i %i", |
|  | 357 | (int)(*(int8_t*)&file->sec_attr[1 +1]), |
| Â | 358 | file->sec_attr[1+7 +1]);Â |
|  | 359 | sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, |
|  | 360 | (int)(*(int8_t*)&file->sec_attr[1 +1]), |
| Â | 361 | file->sec_attr[1+7 +1]);Â |
|  | 362 | sc_debug(card->ctx, "SC_AC_OP_WRITE %i %i", |
|  | 363 | (int)(*(int8_t*)&file->sec_attr[1 +1]), |
| Â | 364 | file->sec_attr[1+7 +1]);Â |
|  | 365 | sc_file_add_acl_entry(file, SC_AC_OP_WRITE, |
|  | 366 | (int)(*(int8_t*)&file->sec_attr[1 +1]), |
| Â | 367 | file->sec_attr[1+7 +1]);Â |
| Â | 368 | }Â |
| Â | 369 | }Â |