Added PKCS#15 emulator for DIN 66291 profile
This commit is contained in:
parent
bc075d6639
commit
594e125f06
|
@ -52,7 +52,7 @@ libopensc_la_SOURCES_BASE = \
|
||||||
pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
|
pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
|
||||||
pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \
|
pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \
|
||||||
pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \
|
pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \
|
||||||
pkcs15-coolkey.c \
|
pkcs15-coolkey.c pkcs15-din-66291.c \
|
||||||
pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c \
|
pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c \
|
||||||
compression.c p15card-helper.c sm.c \
|
compression.c p15card-helper.c sm.c \
|
||||||
aux-data.c
|
aux-data.c
|
||||||
|
|
|
@ -32,7 +32,7 @@ OBJECTS = \
|
||||||
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
|
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
|
||||||
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
|
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
|
||||||
pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \
|
pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \
|
||||||
pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj \
|
pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \
|
||||||
pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \
|
pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \
|
||||||
pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \
|
pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \
|
||||||
compression.obj p15card-helper.obj sm.obj \
|
compression.obj p15card-helper.obj sm.obj \
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
/*
|
||||||
|
* PKCS15 emulation layer for DIN 66291–4 profile.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017, Frank Morgner
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/compat_strlcpy.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "pkcs15.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const unsigned char aid_CIA[] = {0xE8, 0x28, 0xBD, 0x08, 0x0F,
|
||||||
|
0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E};
|
||||||
|
static const unsigned char aid_ESIGN[] = {0xA0, 0x00, 0x00, 0x01, 0x67,
|
||||||
|
0x45, 0x53, 0x49, 0x47, 0x4E};
|
||||||
|
|
||||||
|
int din_66291_match_p15card(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
|
||||||
|
{
|
||||||
|
int ok = 0, r;
|
||||||
|
sc_path_t path;
|
||||||
|
unsigned char *tokeninfo_content = NULL;
|
||||||
|
struct sc_file *file_tokeninfo = NULL;
|
||||||
|
struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new();
|
||||||
|
|
||||||
|
if (!p15card || !tokeninfo
|
||||||
|
|| (aid && (aid->len != sizeof aid_CIA
|
||||||
|
|| 0 != memcmp(aid->value, aid_CIA, sizeof aid_CIA))))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (p15card->tokeninfo
|
||||||
|
&& p15card->tokeninfo->profile_indication.name
|
||||||
|
&& 0 == strcmp("DIN V 66291",
|
||||||
|
p15card->tokeninfo->profile_indication.name)) {
|
||||||
|
ok = 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it is possible that p15card->tokeninfo has not been touched yet */
|
||||||
|
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_CIA, sizeof aid_CIA, 0, 0);
|
||||||
|
if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
sc_format_path("5032", &path);
|
||||||
|
if (SC_SUCCESS != sc_select_file(p15card->card, &path, &file_tokeninfo))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
tokeninfo_content = malloc(file_tokeninfo->size);
|
||||||
|
if (!tokeninfo_content)
|
||||||
|
goto err;
|
||||||
|
r = sc_read_binary(p15card->card, 0, tokeninfo_content, file_tokeninfo->size, 0);
|
||||||
|
if (r < 0)
|
||||||
|
goto err;
|
||||||
|
r = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, tokeninfo, tokeninfo_content, r);
|
||||||
|
if (r != SC_SUCCESS)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (tokeninfo->profile_indication.name
|
||||||
|
&& 0 == strcmp("DIN V 66291",
|
||||||
|
tokeninfo->profile_indication.name)) {
|
||||||
|
ok = 1;
|
||||||
|
/* save tokeninfo and file_tokeninfo */
|
||||||
|
sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
|
||||||
|
sc_file_free(p15card->file_tokeninfo);
|
||||||
|
p15card->tokeninfo = tokeninfo;
|
||||||
|
p15card->file_tokeninfo = file_tokeninfo;
|
||||||
|
tokeninfo = NULL;
|
||||||
|
file_tokeninfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
sc_pkcs15_free_tokeninfo(tokeninfo);
|
||||||
|
sc_file_free(file_tokeninfo);
|
||||||
|
free(tokeninfo_content);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card)
|
||||||
|
{
|
||||||
|
/* EF.C.CH.AUT
|
||||||
|
* fileIdentifier ´C5 00´
|
||||||
|
* shortFileIdentifier ´01´= 1
|
||||||
|
* PrK.CH.AUT
|
||||||
|
* keyIdentifier ´02´ = 2
|
||||||
|
* privateKey …, Moduluslänge 2048 Bit
|
||||||
|
*
|
||||||
|
* EF.C.CH.ENC
|
||||||
|
* fileIdentifier ´C2 00´
|
||||||
|
* shortFileIdentifier ´02´= 2
|
||||||
|
* PrK.CH.ENC
|
||||||
|
* keyIdentifier ´03´ = 3
|
||||||
|
* privateKey …, Moduluslänge 2048 Bit
|
||||||
|
*/
|
||||||
|
sc_path_t path;
|
||||||
|
size_t i;
|
||||||
|
struct sc_pin_cmd_data data;
|
||||||
|
const unsigned char user_pin_ref = 0x02;
|
||||||
|
sc_serial_number_t serial;
|
||||||
|
|
||||||
|
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_ESIGN, sizeof aid_ESIGN, 0, 0);
|
||||||
|
if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL))
|
||||||
|
return SC_ERROR_WRONG_CARD;
|
||||||
|
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
data.cmd = SC_PIN_CMD_GET_INFO;
|
||||||
|
data.pin_type = SC_AC_CHV;
|
||||||
|
data.pin_reference = user_pin_ref;
|
||||||
|
|
||||||
|
if (SC_SUCCESS == sc_pin_cmd(p15card->card, &data, NULL)) {
|
||||||
|
const unsigned char user_pin_id = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
const char *pin_names[3] = { "PIN", "PUK" };
|
||||||
|
const int pin_min[] = {6, 10};
|
||||||
|
const int pin_max[] = {8, 8};
|
||||||
|
const unsigned char user_puk_id = 2;
|
||||||
|
const int pin_id[] = {user_pin_id, user_puk_id};
|
||||||
|
const int pin_flags[] = {SC_PKCS15_PIN_FLAG_INITIALIZED,
|
||||||
|
SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED};
|
||||||
|
const int max_tries[] = {3, 10};
|
||||||
|
struct sc_pkcs15_auth_info pin_info;
|
||||||
|
struct sc_pkcs15_object pin_obj;
|
||||||
|
|
||||||
|
memset(&pin_info, 0, sizeof(pin_info));
|
||||||
|
memset(&pin_obj, 0, sizeof(pin_obj));
|
||||||
|
|
||||||
|
pin_info.auth_id.value[0] = pin_id[i];
|
||||||
|
pin_info.auth_id.len = 1;
|
||||||
|
pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
|
||||||
|
pin_info.attrs.pin.flags = pin_flags[i];
|
||||||
|
pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
|
||||||
|
pin_info.attrs.pin.min_length = pin_min[i];
|
||||||
|
pin_info.attrs.pin.stored_length = pin_max[i];
|
||||||
|
pin_info.attrs.pin.max_length = pin_max[i];
|
||||||
|
pin_info.max_tries = max_tries[i];
|
||||||
|
|
||||||
|
strlcpy(pin_obj.label, pin_names[i], sizeof(pin_obj.label));
|
||||||
|
|
||||||
|
/* catch the differences between PIN and PUK */
|
||||||
|
if (pin_flags[i] & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) {
|
||||||
|
pin_info.tries_left = max_tries[i];
|
||||||
|
} else {
|
||||||
|
pin_info.attrs.pin.reference = user_pin_ref;
|
||||||
|
pin_info.tries_left = data.pin1.tries_left;
|
||||||
|
pin_info.logged_in = data.pin1.logged_in;
|
||||||
|
pin_obj.auth_id.value[0] = user_puk_id;
|
||||||
|
pin_obj.auth_id.len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 > sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info))
|
||||||
|
return SC_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
struct sc_aid aid;
|
||||||
|
const char *din_66291_cert_fids[] = { "C500", "C200"};
|
||||||
|
const char prk_id[] = { 0x10, 0x11,};
|
||||||
|
struct sc_pkcs15_cert_info cert_info;
|
||||||
|
struct sc_pkcs15_object cert_obj;
|
||||||
|
struct sc_pkcs15_prkey_info prkey_info;
|
||||||
|
struct sc_pkcs15_object prkey_obj;
|
||||||
|
const int prk_usage[2] = {
|
||||||
|
SC_PKCS15_PRKEY_USAGE_ENCRYPT
|
||||||
|
| SC_PKCS15_PRKEY_USAGE_DECRYPT
|
||||||
|
| SC_PKCS15_PRKEY_USAGE_SIGN,
|
||||||
|
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION};
|
||||||
|
|
||||||
|
memcpy(aid.value, aid_CIA, sizeof aid_CIA);
|
||||||
|
aid.len = sizeof aid_CIA;
|
||||||
|
|
||||||
|
memset(&prkey_info, 0, sizeof(prkey_info));
|
||||||
|
memset(&prkey_obj, 0, sizeof(prkey_obj));
|
||||||
|
memset(&cert_info, 0, sizeof(cert_info));
|
||||||
|
memset(&cert_obj, 0, sizeof(cert_obj));
|
||||||
|
|
||||||
|
|
||||||
|
sc_format_path(din_66291_cert_fids[i], &cert_info.path);
|
||||||
|
if (SC_SUCCESS != sc_select_file(p15card->card, &cert_info.path, NULL))
|
||||||
|
continue;
|
||||||
|
cert_info.path.aid = aid;
|
||||||
|
|
||||||
|
cert_info.id.value[0] = prk_id[i];
|
||||||
|
cert_info.id.len = 1;
|
||||||
|
|
||||||
|
if (0 > sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
sc_pkcs15_cert_t *cert;
|
||||||
|
if (SC_SUCCESS == sc_pkcs15_read_certificate(p15card, &cert_info, &cert)) {
|
||||||
|
static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }};
|
||||||
|
u8 *cn_name = NULL;
|
||||||
|
size_t cn_len = 0;
|
||||||
|
sc_pkcs15_get_name_from_dn(p15card->card->ctx, cert->subject,
|
||||||
|
cert->subject_len, &cn_oid, &cn_name, &cn_len);
|
||||||
|
if (cn_len > 0) {
|
||||||
|
char *token_name = malloc(cn_len+1);
|
||||||
|
if (token_name) {
|
||||||
|
memcpy(token_name, cn_name, cn_len);
|
||||||
|
token_name[cn_len] = '\0';
|
||||||
|
free(p15card->tokeninfo->label);
|
||||||
|
p15card->tokeninfo->label = token_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(cn_name);
|
||||||
|
sc_pkcs15_free_certificate(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&prkey_info, 0, sizeof(prkey_info));
|
||||||
|
memset(&prkey_obj, 0, sizeof(prkey_obj));
|
||||||
|
|
||||||
|
prkey_info.id.value[0] = prk_id[i];
|
||||||
|
prkey_info.id.len = 1;
|
||||||
|
prkey_info.usage = prk_usage[i];
|
||||||
|
prkey_info.native = 1;
|
||||||
|
prkey_info.key_reference = prk_id[i];
|
||||||
|
prkey_info.modulus_length = 2048;
|
||||||
|
prkey_obj.auth_id.value[0] = user_pin_id;
|
||||||
|
prkey_obj.auth_id.len = 1;
|
||||||
|
prkey_obj.user_consent = 0;
|
||||||
|
prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;
|
||||||
|
|
||||||
|
if (0 > sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the card serial number */
|
||||||
|
if (!p15card->tokeninfo->serial_number
|
||||||
|
&& SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) {
|
||||||
|
char serial_hex[SC_MAX_SERIALNR*2+2];
|
||||||
|
sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex - 1, 0);
|
||||||
|
p15card->tokeninfo->serial_number = strdup(serial_hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid,
|
||||||
|
sc_pkcs15emu_opt_t *opts)
|
||||||
|
{
|
||||||
|
if (!p15card || ! p15card->card)
|
||||||
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(p15card->card->ctx, 1);
|
||||||
|
|
||||||
|
/* Check card */
|
||||||
|
if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
|
||||||
|
if (!din_66291_match_p15card(p15card, aid))
|
||||||
|
return SC_ERROR_WRONG_CARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init card */
|
||||||
|
return sc_pkcs15emu_din_66291_init(p15card);
|
||||||
|
}
|
|
@ -59,6 +59,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = {
|
||||||
{ "iasecc", sc_pkcs15emu_iasecc_init_ex },
|
{ "iasecc", sc_pkcs15emu_iasecc_init_ex },
|
||||||
{ "jpki", sc_pkcs15emu_jpki_init_ex },
|
{ "jpki", sc_pkcs15emu_jpki_init_ex },
|
||||||
{ "coolkey", sc_pkcs15emu_coolkey_init_ex },
|
{ "coolkey", sc_pkcs15emu_coolkey_init_ex },
|
||||||
|
{ "din66291", sc_pkcs15emu_din_66291_init_ex },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_
|
||||||
int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||||
int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||||
int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||||
|
int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||||
|
|
||||||
struct sc_pkcs15_emulator_handler {
|
struct sc_pkcs15_emulator_handler {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
|
@ -738,40 +738,52 @@ sc_pkcs15_card_new(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_init_oid(&p15card->tokeninfo->profile_indication.oid);
|
|
||||||
|
|
||||||
p15card->magic = SC_PKCS15_CARD_MAGIC;
|
p15card->magic = SC_PKCS15_CARD_MAGIC;
|
||||||
return p15card;
|
return p15card;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
struct sc_pkcs15_tokeninfo *
|
||||||
sc_pkcs15_free_tokeninfo(struct sc_pkcs15_card *p15card)
|
sc_pkcs15_tokeninfo_new(void)
|
||||||
{
|
{
|
||||||
if (!p15card || !p15card->tokeninfo)
|
struct sc_pkcs15_tokeninfo *tokeninfo;
|
||||||
|
|
||||||
|
tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
|
||||||
|
if (tokeninfo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_init_oid(&tokeninfo->profile_indication.oid);
|
||||||
|
|
||||||
|
return tokeninfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
|
||||||
|
{
|
||||||
|
if (!tokeninfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (p15card->tokeninfo->label != NULL)
|
if (tokeninfo->label != NULL)
|
||||||
free(p15card->tokeninfo->label);
|
free(tokeninfo->label);
|
||||||
if (p15card->tokeninfo->serial_number != NULL)
|
if (tokeninfo->serial_number != NULL)
|
||||||
free(p15card->tokeninfo->serial_number);
|
free(tokeninfo->serial_number);
|
||||||
if (p15card->tokeninfo->manufacturer_id != NULL)
|
if (tokeninfo->manufacturer_id != NULL)
|
||||||
free(p15card->tokeninfo->manufacturer_id);
|
free(tokeninfo->manufacturer_id);
|
||||||
if (p15card->tokeninfo->last_update.gtime != NULL)
|
if (tokeninfo->last_update.gtime != NULL)
|
||||||
free(p15card->tokeninfo->last_update.gtime);
|
free(tokeninfo->last_update.gtime);
|
||||||
if (p15card->tokeninfo->preferred_language != NULL)
|
if (tokeninfo->preferred_language != NULL)
|
||||||
free(p15card->tokeninfo->preferred_language);
|
free(tokeninfo->preferred_language);
|
||||||
if (p15card->tokeninfo->profile_indication.name != NULL)
|
if (tokeninfo->profile_indication.name != NULL)
|
||||||
free(p15card->tokeninfo->profile_indication.name);
|
free(tokeninfo->profile_indication.name);
|
||||||
if (p15card->tokeninfo->seInfo != NULL) {
|
if (tokeninfo->seInfo != NULL) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < p15card->tokeninfo->num_seInfo; i++)
|
for (i = 0; i < tokeninfo->num_seInfo; i++)
|
||||||
free(p15card->tokeninfo->seInfo[i]);
|
free(tokeninfo->seInfo[i]);
|
||||||
free(p15card->tokeninfo->seInfo);
|
free(tokeninfo->seInfo);
|
||||||
}
|
}
|
||||||
free(p15card->tokeninfo);
|
free(tokeninfo);
|
||||||
|
|
||||||
p15card->tokeninfo = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -815,7 +827,7 @@ sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
|
||||||
sc_file_free(p15card->file_unusedspace);
|
sc_file_free(p15card->file_unusedspace);
|
||||||
|
|
||||||
p15card->magic = 0;
|
p15card->magic = 0;
|
||||||
sc_pkcs15_free_tokeninfo(p15card);
|
sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
|
||||||
sc_pkcs15_free_app(p15card);
|
sc_pkcs15_free_app(p15card);
|
||||||
free(p15card);
|
free(p15card);
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,6 +647,8 @@ int sc_pkcs15_find_object_by_id(struct sc_pkcs15_card *, unsigned int,
|
||||||
struct sc_pkcs15_card * sc_pkcs15_card_new(void);
|
struct sc_pkcs15_card * sc_pkcs15_card_new(void);
|
||||||
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card);
|
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card);
|
||||||
void sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card);
|
void sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card);
|
||||||
|
struct sc_pkcs15_tokeninfo * sc_pkcs15_tokeninfo_new(void);
|
||||||
|
void sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo);
|
||||||
|
|
||||||
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
||||||
const struct sc_pkcs15_object *prkey_obj,
|
const struct sc_pkcs15_object *prkey_obj,
|
||||||
|
|
Loading…
Reference in New Issue