sc-hsm: Added support for token label to be set via C_InitToken or sc-hsm-tool
This commit is contained in:
parent
abb48c8ba7
commit
d1ba6164ad
|
@ -45,6 +45,7 @@
|
|||
<para>Use <option>--pin</option> to define the initial user pin value.</para>
|
||||
<para>Use <option>--pin-retry</option> to define the maximum number of wrong user PIN presentations.</para>
|
||||
<para>Use with <option>--dkek-shares</option> to enable key wrap / unwrap.</para>
|
||||
<para>Use with <option>--label</option> to define a token label</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -180,6 +181,14 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--label</option> <replaceable>label</replaceable>,
|
||||
<option>-l</option> <replaceable>label</replaceable>
|
||||
</term>
|
||||
<listitem><para>Define the token label to be used in --initialize.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--reader</option> <replaceable>num</replaceable>,
|
||||
|
@ -217,7 +226,7 @@
|
|||
<para>Create a DKEK share with random password split up using a (3, 5) threshold scheme:</para>
|
||||
<para><command>sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5</command></para>
|
||||
<para>Initialize SmartCard-HSM to use a single DKEK share:</para>
|
||||
<para><command>sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1</command></para>
|
||||
<para><command>sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken</command></para>
|
||||
<para>Import DKEK share:</para>
|
||||
<para><command>sc-hsm-tool --import-dkek-share dkek-share-1.pbe</command></para>
|
||||
<para>Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:</para>
|
||||
|
|
|
@ -227,9 +227,9 @@ static int sc_hsm_read_binary(sc_card_t *card,
|
|||
|
||||
|
||||
|
||||
static int sc_hsm_update_binary(sc_card_t *card,
|
||||
unsigned int idx, const u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
static int sc_hsm_write_ef(sc_card_t *card,
|
||||
int fid,
|
||||
unsigned int idx, const u8 *buf, size_t count)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
sc_apdu_t apdu;
|
||||
|
@ -267,10 +267,11 @@ static int sc_hsm_update_binary(sc_card_t *card,
|
|||
len = 8;
|
||||
}
|
||||
|
||||
if (buf != NULL)
|
||||
memcpy(p, buf, count);
|
||||
len += count;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, 0x00, 0x00);
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF);
|
||||
apdu.data = cmdbuff;
|
||||
apdu.datalen = len;
|
||||
apdu.lc = len;
|
||||
|
@ -287,6 +288,15 @@ static int sc_hsm_update_binary(sc_card_t *card,
|
|||
|
||||
|
||||
|
||||
static int sc_hsm_update_binary(sc_card_t *card,
|
||||
unsigned int idx, const u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
{
|
||||
return sc_hsm_write_ef(card, 0, idx, buf, count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int sc_hsm_list_files(sc_card_t *card, u8 * buf, size_t buflen)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
|
@ -322,23 +332,12 @@ static int sc_hsm_list_files(sc_card_t *card, u8 * buf, size_t buflen)
|
|||
|
||||
static int sc_hsm_create_file(sc_card_t *card, sc_file_t *file)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
sc_apdu_t apdu;
|
||||
u8 cmdbuff[] = { 0x54, 0x02, 0x00, 0x00, 0x53, 0x00 };
|
||||
int r;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD7, file->id >> 8, file->id & 0xFF);
|
||||
apdu.data = cmdbuff;
|
||||
apdu.datalen = sizeof(cmdbuff);
|
||||
apdu.lc = sizeof(cmdbuff);
|
||||
r = sc_hsm_write_ef(card, file->id, 0, NULL, 0);
|
||||
LOG_TEST_RET(card->ctx, r, "Create file failed");
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(ctx, r, "APDU transmit failed");
|
||||
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(ctx, r, "Check SW error");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,7 +431,8 @@ static int sc_hsm_decode_ecdsa_signature(sc_card_t *card,
|
|||
const u8 * data, size_t datalen,
|
||||
u8 * out, size_t outlen) {
|
||||
|
||||
int fieldsizebytes, i, r;
|
||||
int i, r;
|
||||
size_t fieldsizebytes;
|
||||
const u8 *body, *tag;
|
||||
size_t bodylen, taglen;
|
||||
|
||||
|
@ -620,7 +620,10 @@ static int sc_hsm_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
|
|||
static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *params)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
sc_pkcs15_tokeninfo_t ti;
|
||||
struct sc_pin_cmd_data pincmd;
|
||||
int r;
|
||||
size_t tilen;
|
||||
sc_apdu_t apdu;
|
||||
u8 ibuff[50], *p;
|
||||
|
||||
|
@ -669,6 +672,29 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa
|
|||
|
||||
LOG_TEST_RET(ctx, r, "Check SW error");
|
||||
|
||||
if (params->label) {
|
||||
memset(&ti, 0, sizeof(ti));
|
||||
|
||||
ti.label = params->label;
|
||||
ti.flags = SC_PKCS15_TOKEN_PRN_GENERATION;
|
||||
|
||||
r = sc_pkcs15_encode_tokeninfo(ctx, &ti, &p, &tilen);
|
||||
LOG_TEST_RET(ctx, r, "Error encoding tokeninfo");
|
||||
|
||||
memset(&pincmd, 0, sizeof(pincmd));
|
||||
pincmd.cmd = SC_PIN_CMD_VERIFY;
|
||||
pincmd.pin_type = SC_AC_CHV;
|
||||
pincmd.pin_reference = 0x81;
|
||||
pincmd.pin1.data = params->user_pin;
|
||||
pincmd.pin1.len = params->user_pin_len;
|
||||
|
||||
r = (*iso_ops->pin_cmd)(card, &pincmd, NULL);
|
||||
LOG_TEST_RET(ctx, r, "Could not verify PIN");
|
||||
|
||||
r = sc_hsm_write_ef(card, 0x2F03, 0, p, tilen);
|
||||
LOG_TEST_RET(ctx, r, "Could not write EF.TokenInfo");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -784,32 +810,27 @@ static int sc_hsm_unwrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *p
|
|||
static int sc_hsm_init_token(sc_card_t *card, sc_cardctl_pkcs11_init_token_t *params)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
sc_cardctl_sc_hsm_init_param_t ip;
|
||||
int r, i;
|
||||
sc_apdu_t apdu;
|
||||
u8 ibuff[50], *p;
|
||||
u8 *p;
|
||||
char label[33],*cpo;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (params->so_pin_len != 16) {
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "SO PIN wrong length (!=16)");
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "SO PIN wrong length (!=16)");
|
||||
}
|
||||
|
||||
p = ibuff;
|
||||
*p++ = 0x80; // Options
|
||||
*p++ = 0x02;
|
||||
*p++ = 0x00;
|
||||
*p++ = 0x01;
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
ip.dkek_shares = -1;
|
||||
ip.options[0] = 0x00;
|
||||
ip.options[0] = 0x01;
|
||||
|
||||
*p++ = 0x81; // User PIN
|
||||
*p++ = 0x06; // Default value, later changed with C_InitPIN
|
||||
// We use only 6 of the 16 bytes init password for the initial user PIN
|
||||
memcpy(p, params->so_pin, 6);
|
||||
p += 6;
|
||||
ip.user_pin = (unsigned char *)params->so_pin; // Use the first 6 digits of the SO-PIN as initial User-PIN value
|
||||
ip.user_pin_len = 6;
|
||||
ip.user_pin_retry_counter = 3;
|
||||
|
||||
*p++ = 0x82; // Initialization code
|
||||
*p++ = 0x08;
|
||||
|
||||
memset(p, 0, 8);
|
||||
p = ip.init_code;
|
||||
for (i = 0; i < 16; i++) {
|
||||
*p <<= 4;
|
||||
*p |= params->so_pin[i] & 0xf;
|
||||
|
@ -817,28 +838,22 @@ static int sc_hsm_init_token(sc_card_t *card, sc_cardctl_pkcs11_init_token_t *pa
|
|||
p++;
|
||||
}
|
||||
|
||||
*p++ = 0x91; // User PIN retry counter
|
||||
*p++ = 0x01;
|
||||
*p++ = 0x03;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00);
|
||||
apdu.cla = 0x80;
|
||||
apdu.data = ibuff;
|
||||
apdu.datalen = p - ibuff;
|
||||
apdu.lc = apdu.datalen;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(ctx, r, "APDU transmit failed");
|
||||
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
||||
if (r == SC_ERROR_NOT_ALLOWED) {
|
||||
r = SC_ERROR_PIN_CODE_INCORRECT;
|
||||
if (params->label) {
|
||||
// Strip trailing spaces
|
||||
memcpy(label, params->label, 32);
|
||||
label[32] = 0;
|
||||
cpo = label + 31;
|
||||
while ((cpo >= label) && (*cpo == ' ')) {
|
||||
*cpo = 0;
|
||||
cpo--;
|
||||
}
|
||||
ip.label = label;
|
||||
}
|
||||
|
||||
r = sc_hsm_initialize(card, &ip);
|
||||
LOG_TEST_RET(ctx, r, "Check SW error");
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -938,8 +938,9 @@ typedef struct sc_cardctl_sc_hsm_init_param {
|
|||
u8 *user_pin; /* Initial user PIN */
|
||||
size_t user_pin_len; /* Length of user PIN */
|
||||
u8 user_pin_retry_counter; /* Retry counter default value */
|
||||
u8 options[2]; /* Initilization options */
|
||||
u8 options[2]; /* Initialization options */
|
||||
char dkek_shares; /* Number of DKEK shares, 0 for card generated, -1 for none */
|
||||
char *label; /* Token label to be set in EF.TokenInfo (2F03) */
|
||||
} sc_cardctl_sc_hsm_init_param_t;
|
||||
|
||||
typedef struct sc_cardctl_sc_hsm_dkek {
|
||||
|
|
|
@ -514,6 +514,33 @@ static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {
|
|||
|
||||
|
||||
|
||||
static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
sc_file_t *file = NULL;
|
||||
sc_path_t path;
|
||||
int r;
|
||||
u8 efbin[512];
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* Read token info */
|
||||
sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x03", 2, 0, 0);
|
||||
r = sc_select_file(card, &path, &file);
|
||||
LOG_TEST_RET(card->ctx, r, "Could not select EF.TokenInfo");
|
||||
sc_file_free(file);
|
||||
|
||||
r = sc_read_binary(p15card->card, 0, efbin, sizeof(efbin), 0);
|
||||
LOG_TEST_RET(card->ctx, r, "Could not read EF.TokenInfo");
|
||||
|
||||
r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, r);
|
||||
LOG_TEST_RET(card->ctx, r, "Could not decode EF.TokenInfo");
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Initialize PKCS#15 emulation with user PIN, private keys, certificate and data objects
|
||||
*
|
||||
|
@ -536,16 +563,12 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
|
|||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
p15card->tokeninfo->label = strdup("SmartCard-HSM");
|
||||
p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de");
|
||||
|
||||
appinfo = calloc(1, sizeof(struct sc_app_info));
|
||||
|
||||
if (appinfo == NULL) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
appinfo->label = strdup(p15card->tokeninfo->label);
|
||||
appinfo->aid = sc_hsm_aid;
|
||||
|
||||
appinfo->ddo.aid = sc_hsm_aid;
|
||||
|
@ -578,14 +601,36 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
|
|||
r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&ptr, &len, &devcert);
|
||||
LOG_TEST_RET(card->ctx, r, "Could not decode EF.C_DevAut");
|
||||
|
||||
sc_pkcs15emu_sc_hsm_read_tokeninfo(p15card);
|
||||
|
||||
if (p15card->tokeninfo->label == NULL) {
|
||||
p15card->tokeninfo->label = strdup("SmartCard-HSM");
|
||||
if (p15card->tokeninfo->label == NULL)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
if ((p15card->tokeninfo->manufacturer_id != NULL) && !strcmp("(unknown)", p15card->tokeninfo->manufacturer_id)) {
|
||||
free(p15card->tokeninfo->manufacturer_id);
|
||||
p15card->tokeninfo->manufacturer_id = NULL;
|
||||
}
|
||||
|
||||
if (p15card->tokeninfo->manufacturer_id == NULL) {
|
||||
p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de");
|
||||
if (p15card->tokeninfo->manufacturer_id == NULL)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
appinfo->label = strdup(p15card->tokeninfo->label);
|
||||
if (appinfo->label == NULL)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
len = strlen(devcert.chr); /* Strip last 5 digit sequence number from CHR */
|
||||
assert(len >= 8);
|
||||
len -= 5;
|
||||
|
||||
p15card->tokeninfo->serial_number = calloc(len + 1, 1);
|
||||
if (p15card->tokeninfo->serial_number == NULL) {
|
||||
if (p15card->tokeninfo->serial_number == NULL)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
memcpy(p15card->tokeninfo->serial_number, devcert.chr, len);
|
||||
*(p15card->tokeninfo->serial_number + len) = 0;
|
||||
|
@ -594,7 +639,6 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
|
|||
|
||||
sc_pkcs15emu_sc_hsm_free_cvc(&devcert);
|
||||
|
||||
|
||||
memset(&pin_info, 0, sizeof(pin_info));
|
||||
memset(&pin_obj, 0, sizeof(pin_obj));
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ static const char magic[] = "Salted__";
|
|||
static struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01 }, 11 };
|
||||
|
||||
static int opt_wait = 0;
|
||||
static char *opt_reader;
|
||||
static char *opt_reader = NULL;
|
||||
static char *opt_label = NULL;
|
||||
static int verbose = 0;
|
||||
|
||||
// Some reasonable maximums
|
||||
|
@ -84,6 +85,7 @@ static const struct option options[] = {
|
|||
{ "pwd-shares-threshold", 1, NULL, OPT_PASSWORD_SHARES_THRESHOLD },
|
||||
{ "pwd-shares-total", 1, NULL, OPT_PASSWORD_SHARES_TOTAL },
|
||||
{ "key-reference", 1, NULL, 'i' },
|
||||
{ "label", 1, NULL, 'l' },
|
||||
{ "force", 0, NULL, 'f' },
|
||||
{ "reader", 1, NULL, 'r' },
|
||||
{ "wait", 0, NULL, 'w' },
|
||||
|
@ -105,6 +107,7 @@ static const char *option_help[] = {
|
|||
"Define threshold for number of password shares required for reconstruction",
|
||||
"Define number of password shares",
|
||||
"Key reference for key wrap/unwrap",
|
||||
"Token label for --initialize",
|
||||
"Force replacement of key and certificate",
|
||||
"Uses reader number <arg> [0]",
|
||||
"Wait for a card to be inserted",
|
||||
|
@ -138,7 +141,7 @@ static sc_card_t *card = NULL;
|
|||
* @param rngSeed Seed value for CPRNG
|
||||
*
|
||||
*/
|
||||
static void generatePrime(BIGNUM *prime, const BIGNUM *s, const unsigned int n, char *rngSeed)
|
||||
static void generatePrime(BIGNUM *prime, const BIGNUM *s, const unsigned int n, unsigned char *rngSeed)
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
|
@ -490,7 +493,7 @@ static void print_info(sc_card_t *card, sc_file_t *file)
|
|||
|
||||
|
||||
|
||||
static void initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, int dkek_shares)
|
||||
static void initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, int dkek_shares, const char *label)
|
||||
{
|
||||
sc_cardctl_sc_hsm_init_param_t param;
|
||||
size_t len;
|
||||
|
@ -560,6 +563,7 @@ static void initialize(sc_card_t *card, const char *so_pin, const char *user_pin
|
|||
param.options[1] = 0x01;
|
||||
|
||||
param.dkek_shares = (char)dkek_shares;
|
||||
param.label = (char *)label;
|
||||
|
||||
r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_INITIALIZE, (void *)¶m);
|
||||
if (r < 0) {
|
||||
|
@ -816,7 +820,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
|
|||
*pwd = calloc(1, 8);
|
||||
*pwdlen = 8;
|
||||
|
||||
r = sc_get_challenge(card, *pwd, 8);
|
||||
r = sc_get_challenge(card, (unsigned char *)*pwd, 8);
|
||||
if (r < 0) {
|
||||
printf("Error generating random key failed with %s", sc_strerror(r));
|
||||
OPENSSL_cleanse(*pwd, *pwdlen);
|
||||
|
@ -834,7 +838,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
|
|||
/*
|
||||
* Encode the secret value
|
||||
*/
|
||||
BN_bin2bn(*pwd, *pwdlen, &secret);
|
||||
BN_bin2bn((unsigned char *)*pwd, *pwdlen, &secret);
|
||||
|
||||
/*
|
||||
* Generate seed and calculate a prime depending on the size of the secret
|
||||
|
@ -1007,7 +1011,7 @@ static int wrap_with_tag(u8 tag, u8 *indata, size_t inlen, u8 **outdata, size_t
|
|||
if (inlen > 127) {
|
||||
do {
|
||||
nlc++;
|
||||
} while (inlen >= (1 << (nlc << 3)));
|
||||
} while (inlen >= (unsigned)(1 << (nlc << 3)));
|
||||
}
|
||||
|
||||
*outlen = 2 + nlc + inlen;
|
||||
|
@ -1056,14 +1060,14 @@ static void wrap_key(sc_card_t *card, u8 keyid, const char *outf, const char *pi
|
|||
util_getpass(&lpin, NULL, stdin);
|
||||
printf("\n");
|
||||
} else {
|
||||
lpin = pin;
|
||||
lpin = (char *)pin;
|
||||
}
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.cmd = SC_PIN_CMD_VERIFY;
|
||||
data.pin_type = SC_AC_CHV;
|
||||
data.pin_reference = ID_USER_PIN;
|
||||
data.pin1.data = lpin;
|
||||
data.pin1.data = (unsigned char *)lpin;
|
||||
data.pin1.len = strlen(lpin);
|
||||
|
||||
r = sc_pin_cmd(card, &data, NULL);
|
||||
|
@ -1313,14 +1317,14 @@ static void unwrap_key(sc_card_t *card, u8 keyid, const char *inf, const char *p
|
|||
util_getpass(&lpin, NULL, stdin);
|
||||
printf("\n");
|
||||
} else {
|
||||
lpin = (u8 *)pin;
|
||||
lpin = (char *)pin;
|
||||
}
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.cmd = SC_PIN_CMD_VERIFY;
|
||||
data.pin_type = SC_AC_CHV;
|
||||
data.pin_reference = ID_USER_PIN;
|
||||
data.pin1.data = lpin;
|
||||
data.pin1.data = (u8 *)lpin;
|
||||
data.pin1.len = strlen(lpin);
|
||||
|
||||
r = sc_pin_cmd(card, &data, NULL);
|
||||
|
@ -1466,6 +1470,9 @@ int main(int argc, char * const argv[])
|
|||
case 'r':
|
||||
opt_reader = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
opt_label = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
@ -1509,7 +1516,7 @@ int main(int argc, char * const argv[])
|
|||
}
|
||||
|
||||
if (do_initialize) {
|
||||
initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares);
|
||||
initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares, opt_label);
|
||||
}
|
||||
|
||||
if (do_create_dkek_share) {
|
||||
|
|
Loading…
Reference in New Issue