/* * Create a new PIN */ static int myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_file *df, struct sc_pkcs15_object *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; unsigned char data[20]; struct sc_cardctl_myeid_data_obj data_obj; struct sc_pkcs15_pin_info *pin_info = (struct sc_pkcs15_pin_info *)pin_obj->data; struct sc_pkcs15_pin_info puk_info; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN('%s',ref:%i,flags:0x%X,pin_len:%d,puk_len:%d)\n", pin_obj->label, pin_info->reference, pin_info->flags, pin_len, puk_len); if (pin_info->reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; sc_profile_get_pin_info(profile, (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, &puk_info); memset(data, 0, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 0x01; data_obj.P2 = pin_info->reference; /* myeid pin number */ memset(data, pin_info->pad_char, 8); memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin */ memset(&data[8], puk_info.pad_char, 8); memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ if(pin_info->tries_left > 0 && pin_info->tries_left < 15) data[16] = pin_info->tries_left; else data[16] = 5; /* default value */ if(puk_info.tries_left > 0 && puk_info.tries_left < 15) data[17] = puk_info.tries_left; else data[17] = 5; /* default value */ data[18] = 0x00; data_obj.Data = data; data_obj.DataLen = 19; r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Initialize PIN failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int setcos_puk_retries(sc_profile_t *profile, int pin_ref) { sc_pkcs15_auth_info_t auth_info; auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; auth_info.attrs.pin.reference = 1; /* Default SO PIN ref. */ sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info); /* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */ sc_profile_get_pin_info(profile, pin_ref == auth_info.attrs.pin.reference ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, &auth_info); if ((auth_info.tries_left < 0) || (auth_info.tries_left > 15)) return 3; /* Little extra safety */ return auth_info.tries_left; }
static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info) { sc_pkcs15_pin_info_t puk_info; sc_profile_get_pin_info(profile, (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, &puk_info); if ((puk_info.tries_left < 0) || (puk_info.tries_left >= 15)) return -1; return puk_info.tries_left; }
/* * Create new PIN */ static int miocos_create_pin(struct sc_profile *profile, sc_pkcs15_card_t *p15card, struct sc_file *df, struct sc_pkcs15_object *pin_obj, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin; struct sc_pkcs15_auth_info tmpinfo; struct sc_cardctl_miocos_ac_info ac_info; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); /* Ignore SOPIN */ if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) return SC_SUCCESS; auth_info->path = profile->df_info->file->path; r = sc_select_file(p15card->card, &auth_info->path, NULL); if (r) return r; memset(&ac_info, 0, sizeof(ac_info)); ac_info.ref = pin_attrs->reference; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &tmpinfo); ac_info.max_tries = tmpinfo.tries_left; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &tmpinfo); ac_info.max_unblock_tries = tmpinfo.tries_left; if (pin_len > 8) pin_len = 8; memcpy(ac_info.key_value, pin, pin_len); if (puk_len > 8) puk_len = 8; strncpy((char *) ac_info.unblock_value, (const char *) puk, puk_len); r = sc_card_ctl(p15card->card, SC_CARDCTL_MIOCOS_CREATE_AC, &ac_info); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Miocos create AC failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); }
/* * Select the PIN reference */ static int setcos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_auth_info_t *auth_info) { sc_pkcs15_auth_info_t auth_info_prof; auth_info_prof.attrs.pin.reference = 1; /* Default SO PIN ref. */ auth_info_prof.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info_prof); /* For the SO pin, we take the first available pin reference = 1 */ if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference; /* sc_pkcs15init_create_pin() starts checking if -1 is an acceptable * pin reference, which isn't for the SetCOS cards. And since the * value 1 has been assigned to the SO pin, we'll jump to 2. */ else if (auth_info->attrs.pin.reference <= 0) auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference + 1; return 0; }
/* * Store a PIN */ static int incrypto34_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; unsigned int puk_id = INCRYPTO34_AC_NEVER; int r; if (!pin || !pin_len) return SC_ERROR_INVALID_ARGUMENTS; if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; r = sc_select_file(p15card->card, &df->path, NULL); if (r < 0) return r; if (puk && puk_len) { struct sc_pkcs15_auth_info puk_ainfo; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &puk_ainfo); puk_ainfo.attrs.pin.reference = puk_id = auth_info->attrs.pin.reference + 1; r = incrypto34_store_pin(profile, p15card->card, &puk_ainfo, INCRYPTO34_AC_NEVER, puk, puk_len); } if (r >= 0) { r = incrypto34_store_pin(profile, p15card->card, auth_info, puk_id, pin, pin_len); } return r; }
/* * Store a PIN */ static int cardos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; struct sc_card *card = p15card->card; unsigned int puk_id = CARDOS_AC_NEVER; int r; if (!pin || !pin_len) return SC_ERROR_INVALID_ARGUMENTS; r = sc_select_file(card, &df->path, NULL); if (r < 0) return r; if (puk && puk_len) { struct sc_pkcs15_pin_info puk_info; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &puk_info); puk_info.reference = puk_id = pin_info->reference + 1; r = cardos_store_pin(profile, card, &puk_info, CARDOS_AC_NEVER, puk, puk_len); } if (r >= 0) { r = cardos_store_pin(profile, card, pin_info, puk_id, pin, pin_len); } return r; }