diff --git a/ykcs11/utils.c b/ykcs11/utils.c index 45acf8c..81dac8d 100644 --- a/ykcs11/utils.c +++ b/ykcs11/utils.c @@ -34,7 +34,10 @@ CK_BBOOL parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len, // Unknown slot, just save what info we have memset(&slots[*n_slots].info, 0, sizeof(CK_SLOT_INFO)); memset(slots[*n_slots].info.slotDescription, ' ', sizeof(slots[*n_slots].info.slotDescription)); - strncpy(slots[*n_slots].info.slotDescription, p, strlen(p)); + if (strlen(p) <= sizeof(slots[*n_slots].info.slotDescription)) + strncpy(slots[*n_slots].info.slotDescription, p, strlen(p)); + else + strncpy(slots[*n_slots].info.slotDescription, p, sizeof(slots[*n_slots].info.slotDescription)); } else { vendor = get_vendor(slots[*n_slots].vid); diff --git a/ykcs11/vendors.c b/ykcs11/vendors.c index 36bc6dc..609453d 100644 --- a/ykcs11/vendors.c +++ b/ykcs11/vendors.c @@ -27,6 +27,8 @@ vendor_t get_vendor(vendor_id_t vid) { v.get_token_version = YUBICO_get_token_version; v.get_token_serial = YUBICO_get_token_serial; v.get_token_mechanisms_num = YUBICO_get_token_mechanisms_num; + v.get_token_mechanism_list = YUBICO_get_token_mechanism_list; + v.get_token_mechanism_info = YUBICO_get_token_mechanism_info; break; case UNKNOWN: @@ -42,6 +44,8 @@ vendor_t get_vendor(vendor_id_t vid) { v.get_token_version = NULL; v.get_token_serial = NULL; v.get_token_mechanisms_num = NULL; + v.get_token_mechanism_list = NULL; + v.get_token_mechanism_info = NULL; } return v; diff --git a/ykcs11/vendors.h b/ykcs11/vendors.h index ab2a75a..ace8dee 100644 --- a/ykcs11/vendors.h +++ b/ykcs11/vendors.h @@ -19,7 +19,8 @@ typedef CK_RV (*get_t_flags_f)(CK_FLAGS_PTR); typedef CK_RV (*get_t_version_f)(CK_UTF8CHAR_PTR, CK_ULONG, CK_VERSION_PTR); typedef CK_RV (*get_t_serial_f)(CK_CHAR_PTR, CK_ULONG); typedef CK_RV (*get_t_mechanisms_num_f)(CK_ULONG_PTR); -//typedef CK_RV (*get_t_mechanisms)(CK_); +typedef CK_RV (*get_t_mechanism_list_f)(CK_MECHANISM_TYPE_PTR, CK_ULONG); +typedef CK_RV (*get_t_mechanism_info_f)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR); typedef struct { @@ -34,6 +35,8 @@ typedef struct { get_t_version_f get_token_version; get_t_serial_f get_token_serial; get_t_mechanisms_num_f get_token_mechanisms_num; + get_t_mechanism_list_f get_token_mechanism_list; + get_t_mechanism_info_f get_token_mechanism_info; } vendor_t; vendor_id_t get_vendor_id(char *vendor_name); diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 163bc6a..271b4dd 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -74,9 +74,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( return CKR_FUNCTION_FAILED; } - parse_readers(readers, len, slots, &n_slots, &n_slots_with_token); + if (parse_readers(readers, len, slots, &n_slots, &n_slots_with_token) != CK_TRUE) + CKR_FUNCTION_FAILED; + DBG(("Found %lu slot(s) of which %lu tokenless/unsupported", n_slots, n_slots - n_slots_with_token)); + // TODO: FILL OUT INIT ARGS; + DOUT; return CKR_OK; } @@ -315,7 +319,6 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)( { DIN; vendor_t vendor; - int i; CK_ULONG count; if (piv_state == NULL) { @@ -351,9 +354,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)( return CKR_BUFFER_TOO_SMALL; } - for (i = 0; i < 3; i++) { - pMechanismList[i] = CKM_SHA_1; - } + if (vendor.get_token_mechanism_list(pMechanismList, *pulCount) != CKR_OK) + return CKR_FUNCTION_FAILED; DOUT; return CKR_OK; @@ -366,7 +368,30 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)( ) { DIN; - DBG(("TODO!!!")); + vendor_t vendor; + + if (piv_state == NULL) { + DBG(("libykpiv is not initialized or already finalized")); + return CKR_CRYPTOKI_NOT_INITIALIZED; + } + + if (slotID > n_slots || pInfo == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + if (slots[slotID].vid == UNKNOWN) { + DBG(("Slot %lu is tokenless/unsupported", slotID)); + return CKR_SLOT_ID_INVALID; + } + + // TODO: check more return values + // TODO: user NULL_PTR more for coherence + + vendor = get_vendor(slots[slotID].vid); // TODO: make a token field in slot_t ?; + + if (vendor.get_token_mechanism_info(type, pInfo) != CKR_OK) + return CKR_MECHANISM_INVALID; + + DOUT; return CKR_OK; } diff --git a/ykcs11/yubico.c b/ykcs11/yubico.c index 8b7d3c6..1004ace 100644 --- a/ykcs11/yubico.c +++ b/ykcs11/yubico.c @@ -4,6 +4,11 @@ #define YUBICO_MECHANISMS_NUM 5 +#define MIN_RSA_KEY_SIZE 1024 +#define MAX_RSA_KEY_SIZE 2048 +#define MIN_ECC_KEY_SIZE 256 +#define MAX_ECC_KEY_SIZE 384 + // TODO add a type in vendor_t for SLOT | READER static const CK_UTF8CHAR_PTR slot_description = "YubiKey Virtual Reader"; static const CK_UTF8CHAR_PTR slot_manufacturer = "Yubico"; @@ -14,7 +19,7 @@ static const CK_UTF8CHAR_PTR token_manufacturer = "Yubico"; static const CK_UTF8CHAR_PTR token_model = "YubiKey MODEL"; static const CK_FLAGS token_flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED; static const CK_BYTE_PTR token_serial = "1234"; -static const CK_MECHANISM_TYPE token_mechanisms[] = { +static const CK_MECHANISM_TYPE token_mechanisms[] = { // KEEP ALIGNED WITH token_mechanism_infos CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, // CKM_RSA_PKCS_PSS, @@ -26,13 +31,11 @@ static const CK_MECHANISM_TYPE token_mechanisms[] = { CKM_SHA1_RSA_PKCS_PSS, CKM_SHA256_RSA_PKCS_PSS, // CKM_SHA384_RSA_PKCS_PSS, - CKM_SHA256_RSA_PKCS_PSS, + CKM_SHA512_RSA_PKCS_PSS, CKM_EC_KEY_PAIR_GEN, //CKM_ECDSA_KEY_PAIR_GEN, Same as CKM_EC_KEY_PAIR_GEN, deprecated in 2.11 CKM_ECDSA, CKM_ECDSA_SHA1, - CKM_ECDH1_DERIVE, - // CKM_ECDH1_COFACTOR_DERIVE, CKM_SHA_1, CKM_SHA256, CKM_SHA384, @@ -41,6 +44,29 @@ static const CK_MECHANISM_TYPE token_mechanisms[] = { }; static const CK_ULONG token_mechanisms_num = sizeof(token_mechanisms) / sizeof(CK_MECHANISM_TYPE); +static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH token_mechanisms + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_RSA_PKCS_KEY_PAIR_GEN + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_PKCS + //{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_RSA_PKCS_PSS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_X_509 + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS + //{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA384_RSA_PKCS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS_PSS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS_PSS + //{, , }, // CKM_SHA384_RSA_PKCS_PSS + {MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS_PSS + {MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_EC_KEY_PAIR_GEN + //{, , }, // CKM_ECDSA_KEY_PAIR_GEN Same as CKM_EC_KEY_PAIR_GEN deprecated in 2.11 + {MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_ECDSA + {MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_ECDSA_SHA1 + {0, 0, CKF_DIGEST}, // CKM_SHA_1 + {0, 0, CKF_DIGEST}, // CKM_SHA256 + {0, 0, CKF_DIGEST}, // CKM_SHA384 + {0, 0, CKF_DIGEST} // CKM_SHA512 +}; + CK_RV YUBICO_get_slot_description(CK_UTF8CHAR_PTR str, CK_ULONG len) { @@ -163,6 +189,26 @@ CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num) { } -/*CK_RV YUBICO_get_token_mechanisms(void) { +CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num) { -}*/ + if (token_mechanisms_num > num) + return CKR_BUFFER_TOO_SMALL; + + memcpy(mec, token_mechanisms, token_mechanisms_num * sizeof(CK_MECHANISM_TYPE)); + return CKR_OK; + +} + +CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info) { + + CK_ULONG i; + + for (i = 0; i < token_mechanisms_num; i++) + if (token_mechanisms[i] == mec) { + memcpy((CK_BYTE_PTR) info, (CK_BYTE_PTR) (token_mechanism_infos + i), sizeof(CK_MECHANISM_INFO)); + return CKR_OK; + } + + return CKR_MECHANISM_INVALID; + +} diff --git a/ykcs11/yubico.h b/ykcs11/yubico.h index aefeb4e..c10500d 100644 --- a/ykcs11/yubico.h +++ b/ykcs11/yubico.h @@ -14,5 +14,7 @@ CK_RV YUBICO_get_token_flags(CK_FLAGS_PTR flags); CK_RV YUBICO_get_token_serial(CK_CHAR_PTR str, CK_ULONG len); CK_RV YUBICO_get_token_version(CK_UTF8CHAR_PTR v_str, CK_ULONG v_str_len, CK_VERSION_PTR version); CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num); +CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num); +CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info); #endif