Overview
Comment: | Added support for treating the DoD certs as a seperate slot |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dodcerts-on-seperate-slot |
Files: | files | file ages | folders |
SHA1: | b6b219036007e32349f4c3e7fffb268e969c5345 |
User & Date: | rkeene on 2012-07-21 06:09:55 |
Other Links: | manifest | tags |
Context
2012-07-21
| ||
06:19 | Protected access to cackey_slots with mutex check-in: 90faf75892 user: rkeene tags: dodcerts-on-seperate-slot | |
06:09 | Added support for treating the DoD certs as a seperate slot check-in: b6b2190360 user: rkeene tags: dodcerts-on-seperate-slot | |
04:55 | Create new branch named "dodcerts-on-seperate-slot" check-in: caac1986d6 user: rkeene tags: dodcerts-on-seperate-slot | |
Changes
Modified cackey.c from [1be2f8a22e] to [42750d148e].
709 709 CK_VOID_PTR decrypt_mech_parm; 710 710 CK_ULONG decrypt_mech_parmlen; 711 711 struct cackey_identity *decrypt_identity; 712 712 }; 713 713 714 714 struct cackey_slot { 715 715 int active; 716 + int internal; 716 717 717 718 char *pcsc_reader; 718 719 719 720 int pcsc_card_connected; 720 721 SCARDHANDLE pcsc_card; 721 722 722 723 int transaction_depth; ................................................................................ 853 854 */ 854 855 static void cackey_slots_disconnect_all(void) { 855 856 uint32_t idx; 856 857 857 858 CACKEY_DEBUG_PRINTF("Called."); 858 859 859 860 for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { 861 + if (cackey_slots[idx].internal) { 862 + /* Skip internal slots */ 863 + continue; 864 + } 865 + 860 866 if (cackey_slots[idx].pcsc_card_connected) { 861 867 CACKEY_DEBUG_PRINTF("SCardDisconnect(%lu) called", (unsigned long) idx); 862 868 863 869 SCardDisconnect(cackey_slots[idx].pcsc_card, SCARD_LEAVE_CARD); 864 870 } 865 871 866 872 if (cackey_slots[idx].label) { ................................................................................ 2602 2608 static cackey_ret cackey_token_present(struct cackey_slot *slot) { 2603 2609 cackey_ret pcsc_connect_ret; 2604 2610 DWORD reader_len, state, protocol, atr_len; 2605 2611 BYTE atr[MAX_ATR_SIZE]; 2606 2612 LONG status_ret, scard_reconn_ret; 2607 2613 2608 2614 CACKEY_DEBUG_PRINTF("Called."); 2615 + 2616 + if (slot->internal) { 2617 + CACKEY_DEBUG_PRINTF("Returning token present (internal token)"); 2618 + 2619 + return(CACKEY_PCSC_S_TOKENPRESENT); 2620 + } 2609 2621 2610 2622 pcsc_connect_ret = cackey_connect_card(slot); 2611 2623 if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { 2612 2624 CACKEY_DEBUG_PRINTF("Unable to connect to card, returning token absent"); 2613 2625 2614 2626 return(CACKEY_PCSC_E_TOKENABSENT); 2615 2627 } ................................................................................ 3401 3413 free(identities); 3402 3414 } 3403 3415 3404 3416 static struct cackey_identity *cackey_read_identities(struct cackey_slot *slot, unsigned long *ids_found) { 3405 3417 struct cackey_pcsc_identity *pcsc_identities; 3406 3418 struct cackey_identity *identities; 3407 3419 unsigned long num_ids, id_idx, curr_id_type; 3408 - unsigned long num_certs, num_extra_certs, cert_idx; 3409 - int include_extra_certs = 1; 3420 + unsigned long num_certs, num_dod_certs, cert_idx; 3410 3421 3411 3422 CACKEY_DEBUG_PRINTF("Called."); 3412 3423 3413 - if (getenv("CACKEY_NO_EXTRA_CERTS") != NULL) { 3414 - CACKEY_DEBUG_PRINTF("Asked not to include extra (DoD) certificates"); 3415 - 3416 - include_extra_certs = 0; 3417 - } 3418 - 3419 - if (include_extra_certs) { 3420 - num_extra_certs = sizeof(extra_certs) / sizeof(extra_certs[0]); 3421 - 3422 - CACKEY_DEBUG_PRINTF("Including %li DoD Certificates as objects on this token", num_extra_certs); 3423 - } else { 3424 - num_extra_certs = 0; 3425 - } 3426 - 3427 3424 if (ids_found == NULL) { 3428 3425 CACKEY_DEBUG_PRINTF("Error. ids_found is NULL"); 3429 3426 3430 3427 return(NULL); 3431 3428 } 3429 + 3430 + if (slot->internal) { 3431 + /* Add DoD Certificates and Netscape Trust Objects */ 3432 + num_dod_certs = sizeof(extra_certs) / sizeof(extra_certs[0]); 3433 + 3434 + num_ids = num_dod_certs * 3; 3435 + 3436 + identities = malloc(num_ids * sizeof(*identities)); 3437 + 3438 + id_idx = 0; 3439 + for (cert_idx = 0; cert_idx < num_dod_certs; cert_idx++) { 3440 + identities[id_idx].pcsc_identity = NULL; 3441 + identities[id_idx].attributes = cackey_get_attributes(CKO_CERTIFICATE, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3442 + id_idx++; 3443 + 3444 + identities[id_idx].pcsc_identity = NULL; 3445 + identities[id_idx].attributes = cackey_get_attributes(CKO_PUBLIC_KEY, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3446 + id_idx++; 3447 + 3448 + identities[id_idx].pcsc_identity = NULL; 3449 + identities[id_idx].attributes = cackey_get_attributes(CKO_NETSCAPE_TRUST, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3450 + id_idx++; 3451 + } 3452 + 3453 + *ids_found = num_ids; 3454 + 3455 + return(identities); 3456 + } 3432 3457 3433 3458 pcsc_identities = cackey_read_certs(slot, NULL, &num_certs); 3434 3459 if (pcsc_identities != NULL) { 3435 3460 /* Convert number of Certs to number of objects */ 3436 3461 num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs; 3437 - num_ids += num_extra_certs * 3; 3438 3462 3439 3463 identities = malloc(num_ids * sizeof(*identities)); 3440 3464 3441 3465 /* Add certificates, public keys, and private keys from the smartcard */ 3442 3466 id_idx = 0; 3443 3467 for (cert_idx = 0; cert_idx < num_certs; cert_idx++) { 3444 3468 for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) { ................................................................................ 3452 3476 3453 3477 id_idx++; 3454 3478 } 3455 3479 } 3456 3480 3457 3481 cackey_free_certs(pcsc_identities, num_certs, 1); 3458 3482 3459 - /* Add DoD Certificates and Netscape Trust Objects */ 3460 - for (cert_idx = 0; cert_idx < num_extra_certs; cert_idx++) { 3461 - identities[id_idx].pcsc_identity = NULL; 3462 - identities[id_idx].attributes = cackey_get_attributes(CKO_CERTIFICATE, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3463 - id_idx++; 3464 - 3465 - identities[id_idx].pcsc_identity = NULL; 3466 - identities[id_idx].attributes = cackey_get_attributes(CKO_PUBLIC_KEY, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3467 - id_idx++; 3468 - 3469 - identities[id_idx].pcsc_identity = NULL; 3470 - identities[id_idx].attributes = cackey_get_attributes(CKO_NETSCAPE_TRUST, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count); 3471 - id_idx++; 3472 - } 3473 - 3474 3483 *ids_found = num_ids; 3484 + 3475 3485 return(identities); 3476 3486 } 3477 3487 3478 3488 *ids_found = 0; 3479 3489 return(NULL); 3480 3490 } 3481 3491 3482 3492 CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) { 3483 3493 CK_C_INITIALIZE_ARGS CK_PTR args; 3484 - uint32_t idx; 3494 + uint32_t idx, highest_slot; 3485 3495 int mutex_init_ret; 3486 3496 3487 3497 CACKEY_DEBUG_PRINTF("Called."); 3488 3498 3489 3499 if (cackey_initialized) { 3490 3500 CACKEY_DEBUG_PRINTF("Error. Already initialized."); 3491 3501 ................................................................................ 3519 3529 cackey_slots[idx].active = 0; 3520 3530 cackey_slots[idx].pcsc_reader = NULL; 3521 3531 cackey_slots[idx].transaction_depth = 0; 3522 3532 cackey_slots[idx].transaction_need_hw_lock = 0; 3523 3533 cackey_slots[idx].slot_reset = 0; 3524 3534 cackey_slots[idx].token_flags = 0; 3525 3535 cackey_slots[idx].label = NULL; 3536 + cackey_slots[idx].internal = 0; 3537 + } 3538 + 3539 + if (getenv("CACKEY_NO_EXTRA_CERTS") != NULL) { 3540 + CACKEY_DEBUG_PRINTF("Asked not to include DoD certificates"); 3541 + } else { 3542 + highest_slot = (sizeof(cackey_slots) / sizeof(cackey_slots[0])) - 1; 3543 + 3544 + CACKEY_DEBUG_PRINTF("Including DoD certs in slot %lu", (unsigned long) highest_slot); 3545 + 3546 + cackey_slots[highest_slot].active = 1; 3547 + cackey_slots[highest_slot].internal = 1; 3548 + cackey_slots[highest_slot].label = (unsigned char *) "DoD Certificates"; 3549 + cackey_slots[highest_slot].pcsc_reader = "CACKey"; 3550 + cackey_slots[highest_slot].token_flags = 0; 3526 3551 } 3527 3552 3528 3553 cackey_initialized = 1; 3529 3554 3530 3555 if (!cackey_biglock_init) { 3531 3556 mutex_init_ret = cackey_mutex_create(&cackey_biglock); 3532 3557 ................................................................................ 3566 3591 C_CloseSession(idx); 3567 3592 } 3568 3593 } 3569 3594 3570 3595 cackey_slots_disconnect_all(); 3571 3596 3572 3597 for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { 3598 + if (cackey_slots[idx].internal) { 3599 + continue; 3600 + } 3601 + 3573 3602 if (cackey_slots[idx].pcsc_reader) { 3574 3603 free(cackey_slots[idx].pcsc_reader); 3575 3604 } 3576 3605 } 3577 3606 3578 3607 cackey_pcsc_disconnect(); 3579 3608 ................................................................................ 3623 3652 3624 3653 /* 3625 3654 * Process list of readers, and create mapping between reader name and slot ID 3626 3655 */ 3627 3656 CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { 3628 3657 int mutex_retval; 3629 3658 int pcsc_connect_ret; 3630 - CK_ULONG count, slot_count = 0, currslot; 3659 + CK_ULONG count, slot_count = 0, currslot, slot_idx; 3631 3660 char *pcsc_readers, *pcsc_readers_s, *pcsc_readers_e; 3632 3661 DWORD pcsc_readers_len; 3633 3662 LONG scard_listreaders_ret; 3634 3663 size_t curr_reader_len; 3635 3664 3636 3665 CACKEY_DEBUG_PRINTF("Called."); 3637 3666 ................................................................................ 3658 3687 if (pSlotList) { 3659 3688 CACKEY_DEBUG_PRINTF("Purging all slot information."); 3660 3689 3661 3690 /* Only update the list of slots if we are actually being supply the slot information */ 3662 3691 cackey_slots_disconnect_all(); 3663 3692 3664 3693 for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { 3694 + if (cackey_slots[currslot].internal) { 3695 + continue; 3696 + } 3697 + 3665 3698 if (cackey_slots[currslot].pcsc_reader) { 3666 3699 free(cackey_slots[currslot].pcsc_reader); 3667 3700 3668 3701 cackey_slots[currslot].pcsc_reader = NULL; 3669 3702 } 3670 3703 3671 3704 if (cackey_slots[currslot].label) { ................................................................................ 3706 3739 scard_listreaders_ret = SCardListReaders(*cackey_pcsc_handle, NULL, pcsc_readers, &pcsc_readers_len); 3707 3740 if (scard_listreaders_ret == SCARD_S_SUCCESS) { 3708 3741 pcsc_readers_e = pcsc_readers + pcsc_readers_len; 3709 3742 3710 3743 /* Start with Slot ID 1, to avoid a bug in GDM on RHEL */ 3711 3744 /* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */ 3712 3745 currslot = 1; 3746 + slot_count = 0; 3713 3747 while (pcsc_readers < pcsc_readers_e) { 3748 + /* Find next available slot */ 3749 + for (; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { 3750 + if (!cackey_slots[currslot].active) { 3751 + break; 3752 + } 3753 + } 3754 + 3714 3755 curr_reader_len = strlen(pcsc_readers); 3715 3756 3716 3757 if ((pcsc_readers + curr_reader_len) > pcsc_readers_e) { 3717 3758 break; 3718 3759 } 3719 3760 3720 3761 if (curr_reader_len == 0) { ................................................................................ 3728 3769 } 3729 3770 3730 3771 CACKEY_DEBUG_PRINTF("Found reader: %s", pcsc_readers); 3731 3772 3732 3773 /* Only update the list of slots if we are actually being asked supply the slot information */ 3733 3774 if (pSlotList) { 3734 3775 cackey_slots[currslot].active = 1; 3776 + cackey_slots[currslot].internal = 0; 3735 3777 cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers); 3736 3778 cackey_slots[currslot].pcsc_card_connected = 0; 3737 3779 cackey_slots[currslot].transaction_depth = 0; 3738 3780 cackey_slots[currslot].transaction_need_hw_lock = 0; 3739 3781 cackey_slots[currslot].slot_reset = 1; 3740 3782 cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED; 3741 3783 cackey_slots[currslot].label = NULL; 3742 3784 3743 3785 cackey_mark_slot_reset(&cackey_slots[currslot]); 3786 + } else { 3787 + /* Artificially increase the number of active slots by what will become active */ 3788 + slot_count++; 3744 3789 } 3745 3790 currslot++; 3746 3791 3747 3792 pcsc_readers += curr_reader_len + 1; 3748 3793 } 3749 3794 3750 - /* Start with Slot ID 1, to avoid a bug in GDM on RHEL */ 3751 - /* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */ 3752 - if (currslot > 1) { 3753 - /* Start with Slot ID 1, to avoid a bug in GDM on RHEL */ 3754 - /* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */ 3755 - slot_count = currslot - 1; 3795 + for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { 3796 + if (cackey_slots[currslot].active) { 3797 + CACKEY_DEBUG_PRINTF("Found active slot %lu", (unsigned long) currslot); 3798 + 3799 + slot_count++; 3800 + } 3756 3801 } 3757 3802 } else { 3758 3803 CACKEY_DEBUG_PRINTF("Second call to SCardListReaders failed, return %s/%li", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_listreaders_ret), (long) scard_listreaders_ret); 3759 3804 } 3760 3805 3761 3806 free(pcsc_readers_s); 3762 3807 } else { ................................................................................ 3779 3824 return(CKR_OK); 3780 3825 } 3781 3826 3782 3827 count = *pulCount; 3783 3828 if (count < slot_count) { 3784 3829 CACKEY_DEBUG_PRINTF("Error. User allocated %lu entries, but we have %lu entries.", count, slot_count); 3785 3830 3831 + CACKEY_DEBUG_PRINTF("Returning CKR_BUFFER_TOO_SMALL"); 3832 + 3786 3833 return(CKR_BUFFER_TOO_SMALL); 3787 3834 } 3788 3835 3789 - for (currslot = 0; currslot < slot_count; currslot++) { 3790 - /* Start with Slot ID 1, to avoid a bug in GDM on RHEL */ 3791 - /* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */ 3792 - pSlotList[currslot] = currslot + 1; 3836 + slot_idx = 0; 3837 + for (currslot = 0; (currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0]))); currslot++) { 3838 + if (!cackey_slots[currslot].active) { 3839 + continue; 3840 + } 3841 + 3842 + if (slot_idx >= count) { 3843 + CACKEY_DEBUG_PRINTF("Error. User allocated %lu entries, but we just tried to write to the %lu index.", count, slot_idx); 3844 + 3845 + CACKEY_DEBUG_PRINTF("Returning CKR_BUFFER_TOO_SMALL"); 3846 + 3847 + return(CKR_BUFFER_TOO_SMALL); 3848 + } 3849 + 3850 + pSlotList[slot_idx] = currslot; 3851 + slot_idx++; 3793 3852 } 3794 3853 3795 3854 *pulCount = slot_count; 3796 3855 3797 3856 CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i). Found %lu readers.", CKR_OK, (unsigned long) slot_count); 3798 3857 3799 3858 return(CKR_OK); ................................................................................ 3837 3896 CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID); 3838 3897 3839 3898 cackey_mutex_unlock(cackey_biglock); 3840 3899 3841 3900 return(CKR_SLOT_ID_INVALID); 3842 3901 } 3843 3902 3844 - pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT; 3903 + pInfo->flags = CKF_HW_SLOT; 3904 + 3905 + if (!cackey_slots[slotID].internal) { 3906 + pInfo->flags |= CKF_REMOVABLE_DEVICE; 3907 + } 3845 3908 3846 3909 if (cackey_token_present(&cackey_slots[slotID]) == CACKEY_PCSC_S_TOKENPRESENT) { 3847 3910 pInfo->flags |= CKF_TOKEN_PRESENT; 3848 3911 } 3849 3912 3850 3913 bytes_to_copy = strlen(cackey_slots[slotID].pcsc_reader); 3851 3914 if (sizeof(pInfo->manufacturerID) < bytes_to_copy) {
Modified test.c from [7438606333] to [86bd0fe2e2].
234 234 printf(" Slot %lu:\n", currSlot); 235 235 236 236 chk_rv = C_GetSlotInfo(slots[currSlot], &slotInfo); 237 237 if (chk_rv != CKR_OK) { 238 238 return(1); 239 239 } 240 240 241 + printf(" Id : %lu\n", (unsigned long) slots[currSlot]); 241 242 printf(" Desc : %.*s\n", 32, slotInfo.slotDescription); 242 243 printf(" ManufID: %.*s\n", 32, slotInfo.manufacturerID); 243 244 printf(" HWVers : %i.%i\n", slotInfo.hardwareVersion.major, slotInfo.hardwareVersion.minor); 244 245 printf(" FWVers : %i.%i\n", slotInfo.firmwareVersion.major, slotInfo.firmwareVersion.minor); 245 246 printf(" Flags : "); 246 247 if ((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) { 247 248 printf("CKF_TOKEN_PRESENT "); ................................................................................ 325 326 } 326 327 printf("\n"); 327 328 } 328 329 } 329 330 330 331 chk_rv = C_OpenSession(slots[0], CKF_SERIAL_SESSION, NULL, NULL, &hSession); 331 332 if (chk_rv == CKR_OK) { 333 + chk_rv = C_GetTokenInfo(slots[0], &tokenInfo); 334 + if (chk_rv != CKR_OK) { 335 + return(1); 336 + } 337 + 332 338 if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED) { 333 339 fgets_ret = NULL; 334 340 335 341 while (fgets_ret == NULL) { 336 342 printf("** ENTER PIN: "); 337 343 fflush(stdout); 338 344