static int muscle_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { sc_file_t *file; sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; int r; int type; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { type = SC_PKCS15INIT_SO_PIN; } else { type = SC_PKCS15INIT_USER_PIN; } if ((r = sc_select_file(card, &df->path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_WRITE)) < 0) return r; sc_keycache_set_pin_name(&df->path, pin_info->reference, type); pin_info->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; return 0; }
/* * Store a PIN */ static int jcop_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; unsigned char nulpin[16]; unsigned char padpin[16]; int r, type; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { type = SC_PKCS15INIT_SO_PIN; /* SO PIN reference must be 0 */ if (pin_info->reference != 3) return SC_ERROR_INVALID_ARGUMENTS; } else { type = SC_PKCS15INIT_USER_PIN; if (pin_info->reference >= 3) return SC_ERROR_TOO_MANY_OBJECTS; } if (puk != NULL && puk_len > 0) { return SC_ERROR_NOT_SUPPORTED; } r = sc_select_file(card, &df->path, NULL); if (r < 0) return r; /* Current PIN is 00:00:00:00:00:00:00:00... */ memset(nulpin, 0, sizeof(nulpin)); memset(padpin, 0, sizeof(padpin)); memcpy(padpin, pin, pin_len); r = sc_change_reference_data(card, SC_AC_CHV, pin_info->reference, nulpin, sizeof(nulpin), padpin, sizeof(padpin), NULL); if (r < 0) return r; sc_keycache_set_pin_name(&df->path, pin_info->reference, type); pin_info->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; return r; }
/* * Store a PIN */ static int gpk_create_pin(sc_profile_t *profile, sc_card_t *card, 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; u8 nulpin[8]; int r, type; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { type = SC_PKCS15INIT_SO_PIN; /* SO PIN reference must be 0 */ if (pin_info->reference != (GPK_PIN_SCOPE | 0)) return SC_ERROR_INVALID_ARGUMENTS; } else { type = SC_PKCS15INIT_USER_PIN; /* PIN references must be even numbers * (the odd numbered PIN entries contain the * PUKs). * Returning SC_ERROR_INVALID_PIN_REFERENCE will * tell the caller to pick a different value. */ if ((pin_info->reference & 1) || !(pin_info->reference & GPK_PIN_SCOPE)) return SC_ERROR_INVALID_PIN_REFERENCE; if (pin_info->reference >= (GPK_PIN_SCOPE + GPK_MAX_PINS)) return SC_ERROR_TOO_MANY_OBJECTS; } /* No PUK given, but the PIN file specifies an unblock * PIN for every PIN. * Use the same value for the PUK for now. * Alternatively, we could leave the unblock PIN at the default * value, but deliberately block it. */ if (puk == NULL || puk_len == 0) { puk = pin; puk_len = pin_len; } r = sc_select_file(card, &df->path, NULL); if (r < 0) return r; /* Current PIN is 00:00:00:00:00:00:00:00 */ memset(nulpin, 0, sizeof(nulpin)); r = sc_change_reference_data(card, SC_AC_CHV, pin_info->reference, nulpin, sizeof(nulpin), pin, pin_len, NULL); if (r < 0) return r; /* Current PUK is 00:00:00:00:00:00:00:00 */ r = sc_change_reference_data(card, SC_AC_CHV, pin_info->reference + 1, nulpin, sizeof(nulpin), puk, puk_len, NULL); if (r < 0) return r; sc_keycache_set_pin_name(&df->path, pin_info->reference, type); return r; }