2010-03-18 12:30:39 +00:00
|
|
|
/*
|
2011-03-20 12:18:55 +00:00
|
|
|
* Oberthur AWP extension for PKCS #15 initialization
|
2010-03-18 12:30:39 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Viktor Tarasov <viktor.tarasov@opentrust.com>
|
2010-03-18 17:51:06 +00:00
|
|
|
* Copyright (C) 2002 Juha Yrjola <juha.yrjola@iki.fi>
|
2012-04-02 21:40:05 +00:00
|
|
|
*
|
2010-03-18 12:30:39 +00:00
|
|
|
* 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
|
|
|
|
*
|
|
|
|
* best view with tabstop=4
|
2012-04-02 21:40:05 +00:00
|
|
|
*
|
2010-03-18 12:30:39 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include "config.h"
|
2016-01-06 14:40:59 +00:00
|
|
|
#include "pkcs15-oberthur.h"
|
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
#include "libopensc/opensc.h"
|
|
|
|
#include "libopensc/cardctl.h"
|
|
|
|
#include "libopensc/log.h"
|
|
|
|
#include "profile.h"
|
|
|
|
#include "pkcs15-init.h"
|
2010-04-02 12:23:21 +00:00
|
|
|
#include "libopensc/asn1.h"
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_OPENSSL
|
2019-06-29 18:52:02 +00:00
|
|
|
#include "libopensc/sc-ossl-compat.h"
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
struct awp_lv zero_lv = { 0, NULL };
|
|
|
|
struct awp_lv x30_lv = { 0x10, (unsigned char *)"0000000000000000" };
|
|
|
|
|
|
|
|
static unsigned char *
|
|
|
|
awp_get_commonName(X509 *x)
|
|
|
|
{
|
|
|
|
unsigned char *ret = NULL;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
r = X509_NAME_get_index_by_NID(X509_get_subject_name(x),
|
|
|
|
NID_commonName, -1);
|
|
|
|
if (r >= 0) {
|
|
|
|
X509_NAME_ENTRY *ne;
|
|
|
|
ASN1_STRING *a_str;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
if (!(ne = X509_NAME_get_entry(X509_get_subject_name(x), r)))
|
2010-03-18 12:30:39 +00:00
|
|
|
;
|
2012-04-02 21:40:05 +00:00
|
|
|
else if (!(a_str = X509_NAME_ENTRY_get_data(ne)))
|
2010-03-18 12:30:39 +00:00
|
|
|
;
|
|
|
|
else if (a_str->type == 0x0C) {
|
|
|
|
ret = malloc(a_str->length + 1);
|
|
|
|
if (ret) {
|
|
|
|
memcpy(ret, a_str->data, a_str->length);
|
|
|
|
*(ret + a_str->length) = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unsigned char *tmp = NULL;
|
|
|
|
|
|
|
|
r = ASN1_STRING_to_UTF8(&tmp, a_str);
|
|
|
|
if (r > 0) {
|
|
|
|
ret = malloc(r + 1);
|
|
|
|
if (ret) {
|
|
|
|
memcpy(ret, tmp, r);
|
|
|
|
*(ret + r) = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
OPENSSL_free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-04-18 14:51:44 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
static int
|
|
|
|
awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|
|
|
unsigned int type, unsigned int num,
|
|
|
|
struct sc_file **info_out, struct sc_file **obj_out)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *ifile=NULL, *ofile=NULL;
|
2010-03-28 11:53:44 +00:00
|
|
|
char name[NAME_MAX_LEN];
|
2011-02-05 20:53:08 +00:00
|
|
|
const char *itag=NULL, *otag=NULL;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "type 0x%X; num %i; info %p; obj %p", type, num, info_out, obj_out);
|
2010-03-18 12:30:39 +00:00
|
|
|
switch (type) {
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
itag = "certificate-info";
|
|
|
|
otag = "template-certificate";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
case COSM_TYPE_PRKEY_RSA:
|
|
|
|
itag = "private-key-info";
|
|
|
|
otag = "template-private-key";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
case COSM_TYPE_PUBKEY_RSA:
|
|
|
|
itag = "public-key-info";
|
|
|
|
otag = "template-public-key";
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
2010-03-22 14:17:27 +00:00
|
|
|
itag = "data-info";
|
|
|
|
otag = "template-data";
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
2010-04-18 14:51:44 +00:00
|
|
|
case COSM_TYPE_PRIVDATA_OBJECT:
|
|
|
|
itag = "privdata-info";
|
|
|
|
otag = "template-privdata";
|
|
|
|
break;
|
2010-03-18 12:30:39 +00:00
|
|
|
case SC_PKCS15_TYPE_AUTH_PIN:
|
2012-04-02 21:40:05 +00:00
|
|
|
case COSM_TOKENINFO :
|
2010-03-18 12:30:39 +00:00
|
|
|
itag = "token-info";
|
|
|
|
num = 0;
|
|
|
|
break;
|
|
|
|
case COSM_PUBLIC_LIST:
|
|
|
|
itag = "public-list";
|
|
|
|
num = 0;
|
|
|
|
break;
|
|
|
|
case COSM_PRIVATE_LIST:
|
|
|
|
itag = "private-list";
|
|
|
|
num = 0;
|
|
|
|
break;
|
|
|
|
case COSM_CONTAINER_LIST:
|
|
|
|
itag = "container-list";
|
|
|
|
num = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return SC_ERROR_INVALID_ARGUMENTS;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (itag) {
|
|
|
|
snprintf(name, sizeof(name),"%s-%s", COSM_TITLE, itag);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "info template %s",name);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (sc_profile_get_file(profile, name, &ifile) < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "profile does not defines template '%s'", name);
|
2010-03-18 12:30:39 +00:00
|
|
|
return SC_ERROR_INCONSISTENT_PROFILE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (otag) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "obj template %s",otag);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (sc_profile_get_file(profile, otag, &ofile) < 0) {
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(ifile);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "profile does not defines template '%s'", name);
|
2010-03-18 12:30:39 +00:00
|
|
|
return SC_ERROR_INCONSISTENT_PROFILE;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
ofile->id |= (num & 0xFF);
|
|
|
|
ofile->path.value[ofile->path.len-1] |= (num & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ifile) {
|
|
|
|
if(info_out) {
|
|
|
|
if (ofile) {
|
|
|
|
ifile->id = ofile->id | 0x100;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
ifile->path = ofile->path;
|
|
|
|
ifile->path.value[ifile->path.len-2] |= 0x01;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2019-01-14 09:35:00 +00:00
|
|
|
"info_file(id:%04X,size:%"SC_FORMAT_LEN_SIZE_T"u,rlen:%"SC_FORMAT_LEN_SIZE_T"u)",
|
2017-03-14 19:02:30 +00:00
|
|
|
ifile->id, ifile->size, ifile->record_length);
|
2010-03-18 12:30:39 +00:00
|
|
|
*info_out = ifile;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sc_file_free(ifile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ofile) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"obj file %04X; size %"SC_FORMAT_LEN_SIZE_T"u; ",
|
|
|
|
ofile->id, ofile->size);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (obj_out)
|
2010-03-18 12:30:39 +00:00
|
|
|
*obj_out = ofile;
|
2012-04-02 21:40:05 +00:00
|
|
|
else
|
|
|
|
sc_file_free(ofile);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
awp_update_blob(struct sc_context *ctx,
|
|
|
|
unsigned char **blob, int *blob_size,
|
|
|
|
struct awp_lv *lv, int type)
|
|
|
|
{
|
|
|
|
unsigned char *pp;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
switch (type) {
|
|
|
|
case TLV_TYPE_LLV :
|
|
|
|
if (!(pp = realloc(*blob, *blob_size + 2 + lv->len)))
|
2011-01-03 09:55:14 +00:00
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
*(pp + *blob_size) = (lv->len >> 8) & 0xFF;
|
|
|
|
*(pp + *blob_size + 1) = lv->len & 0xFF;
|
|
|
|
memcpy(pp + *blob_size + 2, lv->value, (lv->len & 0xFF));
|
|
|
|
*blob_size += 2 + lv->len;
|
|
|
|
break;
|
|
|
|
case TLV_TYPE_LV :
|
|
|
|
if (!(pp = realloc(*blob, *blob_size + 1 + lv->len)))
|
2011-01-03 09:55:14 +00:00
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
*(pp + *blob_size) = lv->len & 0xFF;
|
|
|
|
memcpy(pp + *blob_size + 1, lv->value, (lv->len & 0xFF));
|
|
|
|
*blob_size += 1 + lv->len;
|
|
|
|
break;
|
|
|
|
case TLV_TYPE_V :
|
2019-01-17 13:43:28 +00:00
|
|
|
if (0 == *blob_size + lv->len)
|
|
|
|
return SC_ERROR_INVALID_DATA;
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!(pp = realloc(*blob, *blob_size + lv->len)))
|
2011-01-03 09:55:14 +00:00
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(pp + *blob_size, lv->value, lv->len);
|
|
|
|
*blob_size += lv->len;
|
|
|
|
break;
|
|
|
|
default:
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "Invalid tlv type %i",type);
|
2010-03-18 12:30:39 +00:00
|
|
|
return SC_ERROR_INCORRECT_PARAMETERS;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
*blob = pp;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2019-01-14 09:35:00 +00:00
|
|
|
awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, size_t len)
|
2010-03-18 12:30:39 +00:00
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
2011-06-01 17:15:31 +00:00
|
|
|
int mm, rv = 0;
|
|
|
|
unsigned ii, marks[5] = {4,6,8,10,0};
|
2010-04-02 12:21:48 +00:00
|
|
|
unsigned char rand_buf[0x10];
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (len<0x34)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INCORRECT_PARAMETERS, "Invalid container update size");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2010-04-02 12:21:48 +00:00
|
|
|
rv = sc_get_challenge(p15card->card, rand_buf, sizeof(rand_buf));
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "Cannot get challenge");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
*(buff + 12) = 0x26;
|
|
|
|
*(buff + 13) = '{';
|
2010-04-02 12:21:48 +00:00
|
|
|
for (ii=0, mm = 0; ii<sizeof(rand_buf); ii++) {
|
2010-03-18 12:30:39 +00:00
|
|
|
if (ii==marks[mm]) {
|
|
|
|
*(buff + 14 + ii*2 + mm) = '-';
|
|
|
|
mm++;
|
|
|
|
}
|
2010-04-02 12:21:48 +00:00
|
|
|
sprintf((char *)(buff + 14 + ii*2 + mm),"%02X", rand_buf[ii]);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
*(buff + 14 + ii*2 + mm) = (unsigned char)'}';
|
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_file *list_file, struct awp_crypto_container *acc)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
int rv;
|
|
|
|
unsigned char *buff = NULL;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2019-01-14 09:35:00 +00:00
|
|
|
sc_log(ctx, "container file(file-id:%X,rlen:%"SC_FORMAT_LEN_SIZE_T"u,rcount:%"SC_FORMAT_LEN_SIZE_T"u)",
|
2010-03-18 12:30:39 +00:00
|
|
|
list_file->id, list_file->record_length, list_file->record_count);
|
|
|
|
|
|
|
|
buff = malloc(list_file->record_length);
|
|
|
|
if (!buff)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
memset(buff, 0, list_file->record_length);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_new_container_entry(p15card, buff, list_file->record_length);
|
2018-09-27 13:04:53 +00:00
|
|
|
if (rv < 0) {
|
2015-05-07 20:33:39 +00:00
|
|
|
free(buff);
|
2018-09-27 13:04:53 +00:00
|
|
|
sc_log(ctx, "Cannot create container");
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2015-05-07 20:33:39 +00:00
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
*(buff + 0) = (acc->pubkey_id >> 8) & 0xFF;
|
|
|
|
*(buff + 1) = acc->pubkey_id & 0xFF;
|
|
|
|
*(buff + 2) = (acc->prkey_id >> 8) & 0xFF;
|
|
|
|
*(buff + 3) = acc->prkey_id & 0xFF;
|
|
|
|
*(buff + 4) = (acc->cert_id >> 8) & 0xFF;
|
|
|
|
*(buff + 5) = acc->cert_id & 0xFF;
|
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &list_file->path, NULL);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (rv == SC_ERROR_FILE_NOT_FOUND)
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15init_create_file(profile, p15card, list_file);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
if (!rv)
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_append_record(p15card->card, buff, list_file->record_length, SC_RECORD_BY_REC_NR);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
free(buff);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, int type,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_lv *key_id, struct awp_crypto_container *acc)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *clist = NULL, *file = NULL;
|
2011-02-05 20:53:08 +00:00
|
|
|
int rv = 0;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "create container(%X:%X:%X)", acc->prkey_id, acc->cert_id, acc->pubkey_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "Create container failed");
|
2019-01-14 09:35:00 +00:00
|
|
|
sc_log(ctx, "contaner cfile(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", clist->record_count, clist->record_length);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &clist->path, &file);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "Create container failed: cannot select container's list");
|
2010-03-18 12:30:39 +00:00
|
|
|
file->record_length = clist->record_length;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2019-01-14 09:35:00 +00:00
|
|
|
sc_log(ctx, "contaner file(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", file->record_count, file->record_length);
|
|
|
|
sc_log(ctx, "Append new record %"SC_FORMAT_LEN_SIZE_T"u for private key", file->record_count + 1);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_create_container_record(p15card, profile, file, acc);
|
|
|
|
|
2015-01-22 19:29:33 +00:00
|
|
|
sc_file_free(file);
|
|
|
|
sc_file_free(clist);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|
|
|
struct sc_file *list_file, int type, int file_id,
|
2019-01-14 09:35:00 +00:00
|
|
|
size_t rec, int offs)
|
2010-03-18 12:30:39 +00:00
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
int rv;
|
|
|
|
unsigned char *buff = NULL;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2019-01-14 09:35:00 +00:00
|
|
|
"update container entry(type:%X,id %i,rec %"SC_FORMAT_LEN_SIZE_T"u,offs %i",
|
2017-03-14 19:02:30 +00:00
|
|
|
type, file_id, rec, offs);
|
2019-01-14 09:35:00 +00:00
|
|
|
sc_log(ctx, "container file(file-id:%X,rlen:%"SC_FORMAT_LEN_SIZE_T"u,rcount:%"SC_FORMAT_LEN_SIZE_T"u)",
|
2010-03-18 12:30:39 +00:00
|
|
|
list_file->id, list_file->record_length, list_file->record_count);
|
|
|
|
|
|
|
|
buff = malloc(list_file->record_length);
|
|
|
|
if (!buff)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
memset(buff, 0, list_file->record_length);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (rec > list_file->record_count) {
|
|
|
|
rv = awp_new_container_entry(p15card, buff, list_file->record_length);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = sc_select_file(p15card->card, &list_file->path, NULL);
|
2015-05-07 20:33:39 +00:00
|
|
|
if (!rv)
|
|
|
|
rv = sc_read_record(p15card->card, rec, buff, list_file->record_length, SC_RECORD_BY_REC_NR);
|
|
|
|
}
|
|
|
|
if (rv < 0) {
|
|
|
|
free(buff);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
switch (type) {
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
case COSM_TYPE_PUBKEY_RSA:
|
2012-04-02 21:40:05 +00:00
|
|
|
if (*(buff + offs + 4))
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "Insert public key to container that contains certificate %02X%02X",
|
2010-03-18 12:30:39 +00:00
|
|
|
*(buff + offs + 4), *(buff + offs + 5));
|
|
|
|
*(buff + offs + 0) = (file_id >> 8) & 0xFF;
|
|
|
|
*(buff + offs + 1) = file_id & 0xFF;
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
case COSM_TYPE_PRKEY_RSA:
|
2015-10-09 15:37:22 +00:00
|
|
|
if (*(buff + offs + 2)) {
|
|
|
|
free(buff);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_CARD, "private key exists already");
|
2015-10-09 15:37:22 +00:00
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
*(buff + offs + 2) = (file_id >> 8) & 0xFF;
|
|
|
|
*(buff + offs + 3) = file_id & 0xFF;
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509 :
|
|
|
|
*(buff + offs + 4) = (file_id >> 8) & 0xFF;
|
|
|
|
*(buff + offs + 5) = file_id & 0xFF;
|
|
|
|
break;
|
|
|
|
default:
|
2015-05-07 20:33:39 +00:00
|
|
|
free(buff);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_ERROR_INCORRECT_PARAMETERS);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rec > list_file->record_count) {
|
|
|
|
rv = sc_select_file(p15card->card, &list_file->path, NULL);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (rv == SC_ERROR_FILE_NOT_FOUND)
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15init_create_file(profile, p15card, list_file);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!rv)
|
|
|
|
rv = sc_append_record(p15card->card, buff, list_file->record_length, SC_RECORD_BY_REC_NR);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = sc_update_record(p15card->card, rec, buff, list_file->record_length, SC_RECORD_BY_REC_NR);
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
free(buff);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, int type,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_lv *key_id, unsigned obj_id, unsigned int *prkey_id)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *clist = NULL, *file = NULL;
|
|
|
|
struct sc_path private_path;
|
2019-01-14 09:35:00 +00:00
|
|
|
int rv = 0;
|
|
|
|
size_t rec, rec_offs;
|
2010-03-18 12:30:39 +00:00
|
|
|
unsigned char *list = NULL;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "update container(type:%X,obj_id:%X)", type, obj_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
if (prkey_id)
|
|
|
|
*prkey_id = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get path of the DF that contains private objects.
|
|
|
|
*/
|
|
|
|
rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_PRKEY_RSA, 1, NULL, &file);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
private_path = file->path;
|
|
|
|
sc_file_free(file), file=NULL;
|
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &clist->path, &file);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
file->record_length = clist->record_length;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (type == SC_PKCS15_TYPE_PRKEY_RSA || type == COSM_TYPE_PRKEY_RSA) {
|
|
|
|
rec_offs = 0;
|
|
|
|
rv = awp_update_container_entry(p15card, profile, file, type, obj_id, file->record_count + 1, rec_offs);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
list = malloc(AWP_CONTAINER_RECORD_LEN * file->record_count);
|
|
|
|
if (!list) {
|
2011-01-03 09:55:14 +00:00
|
|
|
rv = SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_READ);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
for (rec=0; rec < file->record_count; rec++) {
|
|
|
|
unsigned char tmp[256];
|
|
|
|
|
|
|
|
rv = sc_read_record(p15card->card, rec + 1, tmp, sizeof(tmp), SC_RECORD_BY_REC_NR);
|
|
|
|
if (rv >= AWP_CONTAINER_RECORD_LEN)
|
|
|
|
memcpy(list + rec*AWP_CONTAINER_RECORD_LEN, tmp, AWP_CONTAINER_RECORD_LEN);
|
|
|
|
else
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rec=0, rv=0; !rv && rec < file->record_count; rec++) {
|
|
|
|
for (rec_offs=0; !rv && rec_offs<12; rec_offs+=6) {
|
|
|
|
int offs;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2019-01-14 09:35:00 +00:00
|
|
|
sc_log(ctx, "rec %"SC_FORMAT_LEN_SIZE_T"u; rec_offs %"SC_FORMAT_LEN_SIZE_T"u", rec, rec_offs);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs = rec*AWP_CONTAINER_RECORD_LEN + rec_offs;
|
|
|
|
if (*(list + offs + 2)) {
|
|
|
|
unsigned char *buff = NULL;
|
|
|
|
int id_offs;
|
|
|
|
struct sc_path path = private_path;
|
|
|
|
struct sc_file *ff = NULL;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
path.value[path.len - 2] = *(list + offs + 2) | 0x01;
|
|
|
|
path.value[path.len - 1] = *(list + offs + 3);
|
|
|
|
rv = sc_select_file(p15card->card, &path, &ff);
|
|
|
|
if (rv)
|
|
|
|
continue;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, ff, SC_AC_OP_READ);
|
|
|
|
if (rv) {
|
2015-05-07 20:33:39 +00:00
|
|
|
sc_file_free(ff);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-05-07 20:33:39 +00:00
|
|
|
buff = malloc(ff->size);
|
|
|
|
if (!buff)
|
|
|
|
rv = SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
if (!rv) {
|
|
|
|
rv = sc_read_binary(p15card->card, 0, buff, ff->size, 0);
|
|
|
|
if ((unsigned)rv == ff->size) {
|
|
|
|
rv = 0;
|
|
|
|
id_offs = 5 + *(buff+3);
|
|
|
|
|
|
|
|
if (key_id->len == *(buff + id_offs) &&
|
|
|
|
!memcmp(key_id->value, buff + id_offs + 1, key_id->len)) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "found key file friend");
|
2015-05-07 20:33:39 +00:00
|
|
|
if (!rv)
|
|
|
|
rv = awp_update_container_entry(p15card, profile, file, type, obj_id, rec + 1, rec_offs);
|
|
|
|
|
|
|
|
if (rv >= 0 && prkey_id)
|
|
|
|
*prkey_id = *(list + offs + 2) * 0x100 + *(list + offs + 3);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
free(buff);
|
|
|
|
sc_file_free(ff);
|
2015-05-07 20:33:39 +00:00
|
|
|
|
|
|
|
if (rv)
|
|
|
|
break;
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
done:
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(clist);
|
|
|
|
sc_file_free(file);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (list) free(list);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *pinobj)
|
|
|
|
{
|
|
|
|
SC_FUNC_CALLED(p15card->card->ctx, 1);
|
|
|
|
/* No update DF when creating PIN objects */
|
|
|
|
SC_FUNC_RETURN(p15card->card->ctx, 1, SC_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_set_certificate_info (struct sc_pkcs15_card *p15card,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_profile *profile,
|
2012-04-02 21:40:05 +00:00
|
|
|
struct sc_file *file,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_cert_info *ci)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
int r = 0, blob_size;
|
|
|
|
unsigned char *blob;
|
|
|
|
const char *default_cert_label = "Certificate";
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
blob_size = 2;
|
|
|
|
if (!(blob = malloc(blob_size))) {
|
2011-01-03 09:55:14 +00:00
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2015-05-07 20:33:39 +00:00
|
|
|
goto done;
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
2010-03-22 14:17:27 +00:00
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
/* TODO: cert flags */
|
2010-03-18 12:30:39 +00:00
|
|
|
*blob = (COSM_TAG_CERT >> 8) & 0xFF;
|
|
|
|
*(blob + 1) = COSM_TAG_CERT & 0xFF;
|
|
|
|
|
2015-05-07 20:33:39 +00:00
|
|
|
if (ci->label.len && ci->label.len != strlen(default_cert_label)
|
|
|
|
&& memcmp(ci->label.value, default_cert_label, strlen(default_cert_label)))
|
2012-04-02 21:40:05 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->label, TLV_TYPE_LLV);
|
2010-03-18 12:30:39 +00:00
|
|
|
else
|
2012-04-02 21:40:05 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->cn, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->id, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
2015-05-07 20:33:39 +00:00
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->subject, TLV_TYPE_LLV);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (r)
|
2015-05-07 20:33:39 +00:00
|
|
|
goto done;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
if (ci->issuer.len != ci->subject.len ||
|
|
|
|
memcmp(ci->issuer.value, ci->subject.value, ci->subject.len)) {
|
2012-04-02 21:40:05 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->issuer, TLV_TYPE_LLV);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->serial, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &zero_lv, TLV_TYPE_LLV);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (r)
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &zero_lv, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
file->size = blob_size;
|
2010-03-18 12:30:39 +00:00
|
|
|
r = sc_pkcs15init_create_file(profile, p15card, file);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
r = sc_pkcs15init_update_file(profile, p15card, file, blob, blob_size);
|
|
|
|
if (r < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = 0;
|
2012-04-02 21:40:05 +00:00
|
|
|
done:
|
|
|
|
if (blob)
|
2010-03-18 12:30:39 +00:00
|
|
|
free(blob);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
unsigned int type, int num)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *obj_file = NULL, *lst_file = NULL;
|
|
|
|
struct sc_file *file = NULL;
|
|
|
|
char obj_name[NAME_MAX_LEN], lst_name[NAME_MAX_LEN];
|
|
|
|
unsigned char *buff = NULL;
|
2011-05-28 22:47:05 +00:00
|
|
|
int rv;
|
|
|
|
unsigned ii;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "type %i, num %i", type, num);
|
2010-03-18 12:30:39 +00:00
|
|
|
switch (type) {
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
snprintf(obj_name, NAME_MAX_LEN, "template-certificate");
|
2010-04-18 14:51:44 +00:00
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-public-list", COSM_TITLE);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
case COSM_TYPE_PUBKEY_RSA:
|
|
|
|
snprintf(obj_name, NAME_MAX_LEN, "template-public-key");
|
2010-04-18 14:51:44 +00:00
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-public-list", COSM_TITLE);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
2010-03-22 14:17:27 +00:00
|
|
|
snprintf(obj_name, NAME_MAX_LEN, "template-data");
|
2010-04-18 14:51:44 +00:00
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-public-list", COSM_TITLE);
|
|
|
|
break;
|
|
|
|
case COSM_TYPE_PRIVDATA_OBJECT:
|
|
|
|
snprintf(obj_name, NAME_MAX_LEN, "template-privdata");
|
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-private-list", COSM_TITLE);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
case COSM_TYPE_PRKEY_RSA:
|
|
|
|
snprintf(obj_name, NAME_MAX_LEN,"template-private-key");
|
2010-04-18 14:51:44 +00:00
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-private-list", COSM_TITLE);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
default:
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "Not supported file type %X", type);
|
2010-03-18 12:30:39 +00:00
|
|
|
return SC_ERROR_INVALID_ARGUMENTS;
|
|
|
|
}
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "obj_name %s; num 0x%X",obj_name, num);
|
|
|
|
sc_log(ctx, "lst_name %s",lst_name);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (sc_profile_get_file(profile, obj_name, &obj_file) < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "No profile template '%s'", obj_name);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = SC_ERROR_NOT_SUPPORTED;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
else if (sc_profile_get_file(profile, lst_name, &lst_file) < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "No profile template '%s'", lst_name);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = SC_ERROR_NOT_SUPPORTED;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj_file->id |= (num & 0xFF);
|
|
|
|
obj_file->path.value[obj_file->path.len-1] |= (num & 0xFF);
|
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &obj_file->path, &file);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (type == SC_PKCS15_TYPE_PUBKEY_RSA || type == COSM_TYPE_PUBKEY_RSA) {
|
|
|
|
if (file->size==PUBKEY_512_ASN1_SIZE)
|
|
|
|
file->size = 512;
|
|
|
|
else if (file->size==PUBKEY_1024_ASN1_SIZE)
|
|
|
|
file->size = 1024;
|
|
|
|
else if (file->size==PUBKEY_2048_ASN1_SIZE)
|
|
|
|
file->size = 2048;
|
|
|
|
}
|
|
|
|
|
|
|
|
buff = malloc(lst_file->size);
|
|
|
|
if (!buff) {
|
2011-01-03 09:55:14 +00:00
|
|
|
rv = SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, lst_file, SC_AC_OP_READ);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, lst_file, SC_AC_OP_UPDATE);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_select_file(p15card->card, &lst_file->path, NULL);
|
|
|
|
if (rv == SC_ERROR_FILE_NOT_FOUND)
|
|
|
|
rv = sc_pkcs15init_create_file(profile, p15card, lst_file);
|
|
|
|
if (rv < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_read_binary(p15card->card, 0, buff, lst_file->size, lst_file->ef_structure);
|
|
|
|
if (rv < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
for (ii=0; ii < lst_file->size; ii+=5)
|
|
|
|
if (*(buff + ii) != COSM_LIST_TAG)
|
|
|
|
break;
|
|
|
|
if (ii>=lst_file->size) {
|
|
|
|
rv = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
|
|
|
goto done;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"ii %i, rv %i; %X; %"SC_FORMAT_LEN_SIZE_T"u",
|
|
|
|
ii, rv, file->id, file->size);
|
2010-03-18 12:30:39 +00:00
|
|
|
*(buff + ii) = COSM_LIST_TAG;
|
|
|
|
*(buff + ii + 1) = (file->id >> 8) & 0xFF;
|
|
|
|
*(buff + ii + 2) = file->id & 0xFF;
|
|
|
|
*(buff + ii + 3) = (file->size >> 8) & 0xFF;
|
|
|
|
*(buff + ii + 4) = file->size & 0xFF;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_update_binary(p15card->card, ii, buff + ii, 5, 0);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "rv %i",rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (rv < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = 0;
|
|
|
|
done:
|
2012-04-02 21:40:05 +00:00
|
|
|
if (buff)
|
2010-03-18 12:30:39 +00:00
|
|
|
free(buff);
|
|
|
|
sc_file_free(lst_file);
|
|
|
|
sc_file_free(obj_file);
|
|
|
|
sc_file_free(file);
|
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj,
|
|
|
|
struct sc_pkcs15_pubkey_rsa *pubkey, struct awp_key_info *ki)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_pkcs15_prkey_info *key_info;
|
|
|
|
int r = 0;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2021-05-06 08:56:04 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_ERR_strings();
|
2021-05-06 08:56:04 +00:00
|
|
|
#endif
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_crypto_strings();
|
|
|
|
|
|
|
|
key_info = (struct sc_pkcs15_prkey_info *)obj->data;
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "object(%s,type:%X)", obj->label, obj->type);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (obj->type == SC_PKCS15_TYPE_PUBKEY_RSA || obj->type == COSM_TYPE_PUBKEY_RSA )
|
|
|
|
ki->flags = COSM_TAG_PUBKEY_RSA;
|
|
|
|
else if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA || obj->type == COSM_TYPE_PRKEY_RSA)
|
|
|
|
ki->flags = COSM_TAG_PRVKEY_RSA;
|
2012-04-02 21:40:05 +00:00
|
|
|
else
|
2010-03-18 12:30:39 +00:00
|
|
|
return SC_ERROR_INCORRECT_PARAMETERS;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (obj->type == COSM_TYPE_PUBKEY_RSA || obj->type == COSM_TYPE_PRKEY_RSA)
|
|
|
|
ki->flags |= COSM_GENERATED;
|
|
|
|
|
2015-01-28 06:39:35 +00:00
|
|
|
ki->label.value = (unsigned char *)strdup(obj->label);
|
|
|
|
ki->label.len = strlen(obj->label);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"cosm_encode_key_info() label(%u):%s",
|
|
|
|
ki->label.len, ki->label.value);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Oberthur saves modulus value without tag and length.
|
|
|
|
*/
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"pubkey->modulus.len %"SC_FORMAT_LEN_SIZE_T"u",
|
|
|
|
pubkey->modulus.len);
|
2010-03-18 12:30:39 +00:00
|
|
|
ki->modulus.value = malloc(pubkey->modulus.len);
|
|
|
|
if (!ki->modulus.value) {
|
2011-01-03 09:55:14 +00:00
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
memcpy(ki->modulus.value, pubkey->modulus.data, pubkey->modulus.len);
|
|
|
|
ki->modulus.len = pubkey->modulus.len;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Oberthur saves exponents as length and value, without tag.
|
|
|
|
*/
|
|
|
|
ki->exponent.value = malloc(pubkey->exponent.len);
|
|
|
|
if (!ki->exponent.value) {
|
2011-01-03 09:55:14 +00:00
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
memcpy(ki->exponent.value, pubkey->exponent.data, pubkey->exponent.len);
|
|
|
|
ki->exponent.len = pubkey->exponent.len;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
/*
|
2012-04-02 21:40:05 +00:00
|
|
|
* ID
|
2010-03-18 12:30:39 +00:00
|
|
|
*/
|
|
|
|
ki->id.value = calloc(1, key_info->id.len);
|
|
|
|
if (!ki->id.value)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: ID allocation error");
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(ki->id.value, key_info->id.value, key_info->id.len);
|
|
|
|
ki->id.len = key_info->id.len;
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "cosm_encode_key_info() label:%s",ki->label.value);
|
2010-03-18 12:30:39 +00:00
|
|
|
done:
|
2021-05-06 08:56:04 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_ERR_strings();
|
2021-05-06 08:56:04 +00:00
|
|
|
#endif
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_crypto_strings();
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static void
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_free_key_info(struct awp_key_info *ki)
|
|
|
|
{
|
2017-08-04 05:08:52 +00:00
|
|
|
free(ki->modulus.value);
|
|
|
|
free(ki->exponent.value);
|
|
|
|
free(ki->id.value);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_set_key_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_file *file,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_key_info *ki, struct awp_cert_info *ci)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
int r = 0, blob_size;
|
|
|
|
unsigned char *blob;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "file:%p, kinfo:%p, cinfo:%p", file, ki, ci);
|
2010-03-18 12:30:39 +00:00
|
|
|
blob_size = 2;
|
|
|
|
blob = malloc(blob_size);
|
|
|
|
if (!blob)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP set key info failed: blob allocation error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "label:%s",ki->label.value);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
*blob = (ki->flags >> 8) & 0xFF;
|
|
|
|
*(blob + 1) = ki->flags & 0xFF;
|
|
|
|
if (ci && ci->label.len)
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->label, TLV_TYPE_LLV);
|
|
|
|
else if (ci && !ci->label.len)
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ci->cn, TLV_TYPE_LLV);
|
2012-04-02 21:40:05 +00:00
|
|
|
else
|
2010-03-18 12:30:39 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ki->label, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ki->id, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &x30_lv, TLV_TYPE_V);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (ci)
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &(ci->subject), TLV_TYPE_LLV);
|
|
|
|
else
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &zero_lv, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if ((ki->flags & ~COSM_GENERATED) != COSM_TAG_PUBKEY_RSA) {
|
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ki->modulus, TLV_TYPE_V);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &ki->exponent, TLV_TYPE_LV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
file->size = blob_size;
|
|
|
|
r = sc_pkcs15init_create_file(profile, p15card, file);
|
|
|
|
if (r == SC_ERROR_FILE_ALREADY_EXISTS) {
|
|
|
|
r = cosm_delete_file(p15card, profile, file);
|
|
|
|
if (!r)
|
|
|
|
r = sc_pkcs15init_create_file(profile, p15card, file);
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (r<0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
r = sc_pkcs15init_update_file(profile, p15card, file, blob, blob_size);
|
|
|
|
if (r < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
r = 0;
|
2012-04-02 21:40:05 +00:00
|
|
|
done:
|
|
|
|
if (blob)
|
2010-03-18 12:30:39 +00:00
|
|
|
free(blob);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj,
|
|
|
|
struct awp_cert_info *ci)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_pkcs15_cert_info *cert_info;
|
|
|
|
struct sc_pkcs15_pubkey_rsa pubkey;
|
|
|
|
int r = 0;
|
|
|
|
unsigned char *buff = NULL, *ptr;
|
|
|
|
BIO *mem = NULL;
|
|
|
|
X509 *x = NULL;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2021-05-06 08:56:04 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_ERR_strings();
|
2021-05-06 08:56:04 +00:00
|
|
|
#endif
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_load_crypto_strings();
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!obj || !ci)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "AWP encode cert failed: invalid parameters");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
cert_info = (struct sc_pkcs15_cert_info *)obj->data;
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"Encode cert(%s,id:%s,der(%p,%"SC_FORMAT_LEN_SIZE_T"u))",
|
|
|
|
obj->label, sc_pkcs15_print_id(&cert_info->id),
|
|
|
|
obj->content.value, obj->content.len);
|
2010-03-18 12:30:39 +00:00
|
|
|
memset(&pubkey, 0, sizeof(pubkey));
|
|
|
|
|
2015-02-02 23:31:55 +00:00
|
|
|
ci->label.value = (unsigned char *)strdup(obj->label);
|
|
|
|
ci->label.len = strlen(obj->label);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
mem = BIO_new_mem_buf(obj->content.value, obj->content.len);
|
|
|
|
if (!mem)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: invalid data");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
x = d2i_X509_bio(mem, NULL);
|
|
|
|
if (!x)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: x509 parse error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE);
|
|
|
|
if (!buff)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: memory allocation error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
/*
|
|
|
|
* subject commonName.
|
|
|
|
*/
|
|
|
|
ptr = awp_get_commonName(x);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (!ptr) {
|
|
|
|
r = SC_ERROR_INTERNAL;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: cannot get CommonName");
|
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
ci->cn.value = ptr;
|
|
|
|
ci->cn.len = strlen((char *)ptr);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
/*
|
|
|
|
* subject DN
|
|
|
|
*/
|
|
|
|
ptr = buff;
|
|
|
|
r = i2d_X509_NAME(X509_get_subject_name(x),&ptr);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (r<=0) {
|
|
|
|
r = SC_ERROR_INTERNAL;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: cannot get SubjectName");
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
ci->subject.value = malloc(r);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (!ci->subject.value) {
|
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: subject allocation error");
|
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(ci->subject.value, buff, r);
|
|
|
|
ci->subject.len = r;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
/*
|
|
|
|
* issuer DN
|
|
|
|
*/
|
|
|
|
ptr = buff;
|
|
|
|
r = i2d_X509_NAME(X509_get_issuer_name(x),&ptr);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (r <= 0) {
|
|
|
|
r = SC_ERROR_INTERNAL;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: cannot get IssuerName");
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
ci->issuer.value = malloc(r);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (!ci->issuer.value) {
|
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: issuer allocation error");
|
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(ci->issuer.value, buff, r);
|
|
|
|
ci->issuer.len = r;
|
|
|
|
|
|
|
|
/*
|
2012-04-02 21:40:05 +00:00
|
|
|
* ID
|
2010-03-18 12:30:39 +00:00
|
|
|
*/
|
|
|
|
ci->id.value = calloc(1, cert_info->id.len);
|
2019-11-04 14:14:27 +00:00
|
|
|
if (!ci->id.value) {
|
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: ID allocation error");
|
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(ci->id.value, cert_info->id.value, cert_info->id.len);
|
|
|
|
ci->id.len = cert_info->id.len;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* serial number
|
|
|
|
*/
|
2016-01-06 14:40:59 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
|
|
|
|
|
|
/* TODO the der encoding of a ANS1_INTEGER is a TLV, the original code only as using the
|
|
|
|
* i2c_ASN1_INTEGER which is not in OpenSSL 1.1
|
|
|
|
* It was adding the tag V_ASN1_INTEGER and the one byte length back in in effect creating
|
|
|
|
* a DER encoded ASN1_INTEGER
|
2018-04-14 17:38:34 +00:00
|
|
|
* So we can simplify the code and make compatible with OpenSSL 1.1. This needs to be tested
|
2016-01-06 14:40:59 +00:00
|
|
|
*/
|
|
|
|
ci->serial.len = 0;
|
|
|
|
ci->serial.value = NULL;
|
|
|
|
/* get length */
|
|
|
|
ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL);
|
|
|
|
if (ci->serial.len > 0) {
|
|
|
|
if (!(ci->serial.value = malloc(ci->serial.len))) {
|
|
|
|
ci->serial.len = 0;
|
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2019-11-04 14:14:27 +00:00
|
|
|
goto err;
|
2016-01-06 14:40:59 +00:00
|
|
|
}
|
|
|
|
ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &ci->serial.value);
|
|
|
|
}
|
|
|
|
/* if len == 0, and value == NULL, then the cert did not have a serial number.*/
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "cert. serial encoded length %i", ci->serial.len);
|
2016-01-06 14:40:59 +00:00
|
|
|
|
|
|
|
#else
|
2010-03-18 12:30:39 +00:00
|
|
|
do {
|
|
|
|
int encoded_len;
|
|
|
|
unsigned char encoded[0x40], *encoded_ptr;
|
|
|
|
|
|
|
|
encoded_ptr = encoded;
|
|
|
|
encoded_len = i2c_ASN1_INTEGER(X509_get_serialNumber(x), &encoded_ptr);
|
|
|
|
|
|
|
|
if (!(ci->serial.value = malloc(encoded_len + 3))) {
|
2011-01-03 09:55:14 +00:00
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2019-11-04 14:14:27 +00:00
|
|
|
goto err;
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(ci->serial.value + 2, encoded, encoded_len);
|
|
|
|
*(ci->serial.value + 0) = V_ASN1_INTEGER;
|
|
|
|
*(ci->serial.value + 1) = encoded_len;
|
|
|
|
ci->serial.len = encoded_len + 2;
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "cert. serial encoded length %i", encoded_len);
|
2010-03-18 12:30:39 +00:00
|
|
|
} while (0);
|
2016-01-06 14:40:59 +00:00
|
|
|
#endif
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
ci->x509 = X509_dup(x);
|
2019-11-04 14:14:27 +00:00
|
|
|
err:
|
2010-03-18 12:30:39 +00:00
|
|
|
ERR_print_errors_fp(stderr);
|
|
|
|
ERR_clear_error();
|
|
|
|
ERR_free_strings();
|
|
|
|
if (pubkey.exponent.data) free(pubkey.exponent.data);
|
|
|
|
if (pubkey.modulus.data) free(pubkey.modulus.data);
|
|
|
|
if (x) X509_free(x);
|
|
|
|
if (mem) BIO_free(mem);
|
|
|
|
if (buff) OPENSSL_free(buff);
|
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static void
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_free_cert_info(struct awp_cert_info *ci)
|
|
|
|
{
|
2017-08-04 05:08:52 +00:00
|
|
|
if (ci) {
|
|
|
|
if (ci->cn.len && ci->cn.value)
|
|
|
|
free(ci->cn.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
if (ci->id.len && ci->id.value)
|
|
|
|
free(ci->id.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
if (ci->subject.len && ci->subject.value)
|
|
|
|
free(ci->subject.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
if (ci->issuer.len && ci->issuer.value)
|
|
|
|
free(ci->issuer.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
if (ci->x509)
|
|
|
|
X509_free(ci->x509);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
memset(ci,0,sizeof(struct awp_cert_info));
|
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-22 14:17:27 +00:00
|
|
|
awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj,
|
|
|
|
struct awp_data_info *di)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_pkcs15_data_info *data_info;
|
|
|
|
int r = 0;
|
|
|
|
unsigned char *buf = NULL;
|
|
|
|
size_t buflen;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
if (!obj || !di)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "AWP encode data failed: invalid parameters");
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
data_info = (struct sc_pkcs15_data_info *)obj->data;
|
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"Encode data(%s,id:%s,der(%p,%"SC_FORMAT_LEN_SIZE_T"u))",
|
|
|
|
obj->label, sc_pkcs15_print_id(&data_info->id),
|
|
|
|
obj->content.value, obj->content.len);
|
2010-03-22 14:17:27 +00:00
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
di->flags = 0x0000;
|
2010-03-22 14:17:27 +00:00
|
|
|
|
2015-01-28 06:39:35 +00:00
|
|
|
di->label.value = (unsigned char *)strdup(obj->label);
|
|
|
|
di->label.len = strlen(obj->label);
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
di->app.len = strlen(data_info->app_label);
|
|
|
|
if (di->app.len) {
|
2011-06-01 17:15:31 +00:00
|
|
|
di->app.value = (unsigned char *)strdup(data_info->app_label);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (!di->app.value)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
|
2010-03-22 14:17:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
r = sc_asn1_encode_object_id(&buf, &buflen, &data_info->app_oid);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, r, "AWP encode data failed: cannot encode OID");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
di->oid.len = buflen + 2;
|
|
|
|
di->oid.value = malloc(di->oid.len);
|
2015-10-09 15:37:22 +00:00
|
|
|
if (!di->oid.value) {
|
|
|
|
free(buf);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode data failed: cannot allocate OID");
|
2015-10-09 15:37:22 +00:00
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
*(di->oid.value + 0) = 0x06;
|
2012-04-02 21:40:05 +00:00
|
|
|
*(di->oid.value + 1) = buflen;
|
2010-03-22 14:17:27 +00:00
|
|
|
memcpy(di->oid.value + 2, buf, buflen);
|
|
|
|
|
|
|
|
free(buf);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-22 14:17:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static void
|
2010-03-22 14:17:27 +00:00
|
|
|
awp_free_data_info(struct awp_data_info *di)
|
|
|
|
{
|
|
|
|
if (di->label.len && di->label.value)
|
|
|
|
free(di->label.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
if (di->app.len && di->app.value)
|
|
|
|
free(di->app.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
if (di->oid.len && di->oid.value)
|
|
|
|
free(di->oid.value);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
memset(di, 0, sizeof(struct awp_data_info));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-22 14:17:27 +00:00
|
|
|
awp_set_data_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|
|
|
struct sc_file *file, struct awp_data_info *di)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
int r = 0, blob_size;
|
|
|
|
unsigned char *blob;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "Set 'DATA' info %p", di);
|
2010-03-22 14:17:27 +00:00
|
|
|
blob_size = 2;
|
|
|
|
if (!(blob = malloc(blob_size))) {
|
2011-01-03 09:55:14 +00:00
|
|
|
r = SC_ERROR_OUT_OF_MEMORY;
|
2010-03-22 14:17:27 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
*blob = (di->flags >> 8) & 0xFF;
|
|
|
|
*(blob + 1) = di->flags & 0xFF;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &di->label, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &di->app, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
r = awp_update_blob(ctx, &blob, &blob_size, &di->oid, TLV_TYPE_LLV);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
file->size = blob_size;
|
2010-03-22 14:17:27 +00:00
|
|
|
r = sc_pkcs15init_create_file(profile, p15card, file);
|
|
|
|
if (r)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
r = sc_pkcs15init_update_file(profile, p15card, file, blob, blob_size);
|
|
|
|
if (r < 0)
|
|
|
|
goto done;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
r = 0;
|
2012-04-02 21:40:05 +00:00
|
|
|
done:
|
|
|
|
if (blob)
|
2010-03-22 14:17:27 +00:00
|
|
|
free(blob);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, r);
|
2010-03-22 14:17:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_get_lv(struct sc_context *ctx, unsigned char *buf, size_t buf_len,
|
|
|
|
size_t offs, int len_len,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_lv *out)
|
|
|
|
{
|
|
|
|
int len = 0, ii;
|
|
|
|
|
|
|
|
if (buf_len - offs < 2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (len_len > 2) {
|
|
|
|
len = len_len;
|
|
|
|
len_len = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (len=0, ii=0; ii<len_len; ii++)
|
|
|
|
len = len * 0x100 + *(buf + offs + ii);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len && out) {
|
|
|
|
if (out->value)
|
|
|
|
free(out->value);
|
|
|
|
|
|
|
|
out->value = malloc(len);
|
|
|
|
if (!out->value)
|
2011-01-03 09:55:14 +00:00
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
2010-03-18 12:30:39 +00:00
|
|
|
memcpy(out->value, buf + offs + len_len, len);
|
|
|
|
out->len = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return len_len + len;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct awp_key_info *ikey)
|
|
|
|
{
|
|
|
|
size_t offs;
|
|
|
|
int len;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs = 0;
|
|
|
|
|
|
|
|
/* Flags */
|
|
|
|
if (buf_len - offs < 2)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
ikey->flags = *(buf + offs) * 0x100 + *(buf + offs + 1);
|
|
|
|
offs += 2;
|
|
|
|
|
|
|
|
/* Label */
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->label);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, len, "AWP parse key info failed: label");
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!len)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs += len;
|
|
|
|
|
|
|
|
/* Ignore Key ID */
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, len, "AWP parse key info failed: ID");
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!len)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs += len;
|
|
|
|
|
|
|
|
while (*(buf + offs) == '0')
|
|
|
|
offs++;
|
|
|
|
|
|
|
|
/* Subject */
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->subject);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, len, "AWP parse key info failed: subject");
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!len)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs += len;
|
|
|
|
|
|
|
|
/* Modulus */
|
|
|
|
if (buf_len - offs > 64 && buf_len - offs < 128)
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 64, &ikey->modulus);
|
|
|
|
else if (buf_len - offs > 128 && buf_len - offs < 256)
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 128, &ikey->modulus);
|
|
|
|
else
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 256, &ikey->modulus);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, len, "AWP parse key info failed: modulus");
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!len)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
offs += len;
|
|
|
|
|
|
|
|
/* Exponent */
|
|
|
|
len = awp_get_lv(ctx, buf, buf_len, offs, 1, &ikey->exponent);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, len, "AWP parse key info failed: exponent");
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!len)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|
|
|
unsigned prvkey_id, struct awp_cert_info *ci)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *key_file=NULL, *info_file=NULL, *file=NULL;
|
|
|
|
struct awp_key_info ikey;
|
|
|
|
int rv = 0;
|
|
|
|
unsigned char *buf;
|
|
|
|
size_t buf_len;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_PRKEY_RSA, prvkey_id & 0xFF, &info_file, &key_file);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update key info failed: instantiation error");
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "key id %X; info id%X", key_file->id, info_file->id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, info_file, SC_AC_OP_READ);
|
|
|
|
if (rv) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update key info failed: 'READ' authentication error");
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &info_file->path, &file);
|
|
|
|
if (rv) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update key info failed: cannot select info file");
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf = calloc(1,file->size);
|
|
|
|
if (!buf)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update key info failed: allocation error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_read_binary(p15card->card, 0, buf, file->size, 0);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update key info failed: read info file error");
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
buf_len = rv;
|
|
|
|
|
|
|
|
memset(&ikey, 0, sizeof(ikey));
|
|
|
|
rv = awp_parse_key_info(ctx, buf, buf_len, &ikey);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update key info failed: parse key info error");
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
rv = awp_set_key_info(p15card, profile, info_file, &ikey, ci);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update key info failed: set key info error");
|
2010-03-18 12:30:39 +00:00
|
|
|
done:
|
|
|
|
sc_file_free(file);
|
|
|
|
sc_file_free(key_file);
|
|
|
|
sc_file_free(info_file);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *info_file=NULL, *obj_file=NULL;
|
|
|
|
struct awp_cert_info icert;
|
|
|
|
struct sc_pkcs15_der der;
|
|
|
|
struct sc_path path;
|
|
|
|
unsigned prvkey_id, obj_id;
|
|
|
|
int rv;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
der = obj->content;
|
|
|
|
path = ((struct sc_pkcs15_cert_info *)obj->data)->path;
|
|
|
|
obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_CERT_X509, obj_id & 0xFF, &info_file, &obj_file);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "COSM new file error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
memset(&icert, 0, sizeof(icert));
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"Cert Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_encode_cert_info(p15card, obj, &icert);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot encode info");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_set_certificate_info(p15card, profile, info_file, &icert);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot set info");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_update_object_list(p15card, profile, SC_PKCS15_TYPE_CERT_X509, obj_id & 0xFF);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update list");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_update_container(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &icert.id, obj_id, &prvkey_id);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update container");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "PrvKeyID:%04X", prvkey_id);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
if (prvkey_id)
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_update_key_info(p15card, profile, prvkey_id, &icert);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update key info");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
awp_free_cert_info(&icert);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-06-21 12:21:05 +00:00
|
|
|
err:
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(info_file);
|
|
|
|
sc_file_free(obj_file);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *key_obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_pkcs15_pubkey pubkey;
|
|
|
|
struct sc_pkcs15_der der;
|
|
|
|
struct awp_key_info ikey;
|
|
|
|
struct awp_cert_info icert;
|
2015-10-09 15:37:22 +00:00
|
|
|
struct sc_file *info_file=NULL;
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_prkey_info *key_info;
|
|
|
|
struct sc_pkcs15_object *cert_obj = NULL, *pubkey_obj = NULL;
|
|
|
|
struct sc_path path;
|
|
|
|
struct awp_crypto_container cc;
|
2015-10-09 15:37:22 +00:00
|
|
|
struct sc_pkcs15_cert *p15cert = NULL;
|
2010-03-18 12:30:39 +00:00
|
|
|
int rv;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2015-10-09 15:37:22 +00:00
|
|
|
memset(&ikey, 0, sizeof(ikey));
|
2017-10-30 15:42:02 +00:00
|
|
|
memset(&icert, 0, sizeof(icert));
|
2015-10-09 15:37:22 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
key_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
|
|
|
|
der = key_obj->content;
|
|
|
|
|
|
|
|
memset(&cc, 0, sizeof(cc));
|
|
|
|
path = key_info->path;
|
|
|
|
cc.prkey_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
|
|
|
|
rv = sc_pkcs15_find_cert_by_id(p15card, &key_info->id, &cert_obj);
|
|
|
|
if (!rv) {
|
|
|
|
struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) cert_obj->data;
|
|
|
|
|
|
|
|
path = cert_info->path;
|
|
|
|
cc.cert_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
|
|
|
|
rv = sc_pkcs15_read_certificate(p15card, cert_info, &p15cert);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot get certificate");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2012-09-30 20:38:27 +00:00
|
|
|
rv = sc_pkcs15_allocate_object_content(ctx, cert_obj, p15cert->data.value, p15cert->data.len);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot allocate content");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_encode_cert_info(p15card, cert_obj, &icert);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot encode cert info");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
sc_pkcs15_free_certificate(p15cert);
|
2015-10-09 15:37:22 +00:00
|
|
|
p15cert = NULL;
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_pkcs15_find_pubkey_by_id(p15card, &key_info->id, &pubkey_obj);
|
|
|
|
if (!rv) {
|
|
|
|
path = ((struct sc_pkcs15_cert_info *)pubkey_obj->data)->path;
|
|
|
|
cc.pubkey_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
}
|
|
|
|
|
2015-10-09 15:37:22 +00:00
|
|
|
rv = awp_new_file(p15card, profile, key_obj->type, cc.prkey_id & 0xFF, &info_file, NULL);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "New private key info file error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
pubkey.algorithm = SC_ALGORITHM_RSA;
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: decode public key error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_encode_key_info(p15card, key_obj, &pubkey.u.rsa, &ikey);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: encode info error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_set_key_info(p15card, profile, info_file, &ikey, cert_obj ? &icert : NULL);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: set info error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_update_object_list(p15card, profile, key_obj->type, cc.prkey_id & 0xFF);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: update object list error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_create_container(p15card, profile, key_obj->type, &ikey.id, &cc);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: update container error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2015-10-09 15:37:22 +00:00
|
|
|
err:
|
|
|
|
if (p15cert)
|
|
|
|
sc_pkcs15_free_certificate(p15cert);
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(info_file);
|
2010-03-18 12:30:39 +00:00
|
|
|
if (cert_obj)
|
|
|
|
awp_free_cert_info(&icert);
|
|
|
|
awp_free_key_info(&ikey);
|
2017-08-04 05:08:52 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_pkcs15_pubkey pubkey;
|
|
|
|
struct sc_pkcs15_der der;
|
|
|
|
struct awp_key_info ikey;
|
2015-10-09 15:37:22 +00:00
|
|
|
struct sc_file *info_file=NULL;
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_path path;
|
|
|
|
unsigned obj_id;
|
|
|
|
int index, rv;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
path = ((struct sc_pkcs15_pubkey_info *)obj->data)->path;
|
|
|
|
der = obj->content;
|
|
|
|
index = path.value[path.len-1] & 0xFF;
|
|
|
|
obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
|
2017-08-04 05:08:52 +00:00
|
|
|
memset(&ikey, 0, sizeof(ikey));
|
|
|
|
|
2015-10-09 15:37:22 +00:00
|
|
|
rv = awp_new_file(p15card, profile, obj->type, index, &info_file, NULL);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "New public key info file error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
pubkey.algorithm = SC_ALGORITHM_RSA;
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx,
|
2017-03-14 19:02:30 +00:00
|
|
|
"PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: decode public key error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_encode_key_info(p15card, obj, &pubkey.u.rsa, &ikey);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: encode info error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_set_key_info(p15card, profile, info_file, &ikey, NULL);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: set info error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_update_object_list(p15card, profile, obj->type, index);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: update object list error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_update_container(p15card, profile, obj->type, &ikey.id, obj_id, NULL);
|
2018-11-23 07:12:53 +00:00
|
|
|
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: update container error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2015-10-09 15:37:22 +00:00
|
|
|
err:
|
2017-08-04 05:08:52 +00:00
|
|
|
awp_free_key_info(&ikey);
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(info_file);
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
2010-03-22 14:17:27 +00:00
|
|
|
struct sc_file *info_file=NULL, *obj_file=NULL;
|
|
|
|
struct awp_data_info idata;
|
|
|
|
struct sc_path path;
|
2010-04-18 14:51:44 +00:00
|
|
|
unsigned obj_id, obj_type = obj->auth_id.len ? COSM_TYPE_PRIVDATA_OBJECT : SC_PKCS15_TYPE_DATA_OBJECT;
|
2010-03-22 14:17:27 +00:00
|
|
|
int rv;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2019-01-25 00:15:01 +00:00
|
|
|
memset(&idata, 0, sizeof(idata));
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
path = ((struct sc_pkcs15_data_info *)obj->data)->path;
|
|
|
|
obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100;
|
|
|
|
|
2010-04-18 14:51:44 +00:00
|
|
|
rv = awp_new_file(p15card, profile, obj_type, obj_id & 0xFF, &info_file, &obj_file);
|
2019-01-25 00:15:01 +00:00
|
|
|
LOG_TEST_GOTO_ERR(ctx, rv, "COSM new file error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
rv = awp_encode_data_info(p15card, obj, &idata);
|
2019-01-25 00:15:01 +00:00
|
|
|
LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot encode info");
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
rv = awp_set_data_info(p15card, profile, info_file, &idata);
|
2019-01-25 00:15:01 +00:00
|
|
|
LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot set info");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-04-18 14:51:44 +00:00
|
|
|
rv = awp_update_object_list(p15card, profile, obj_type, obj_id & 0xFF);
|
2019-01-25 00:15:01 +00:00
|
|
|
LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot update list");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2019-01-25 00:15:01 +00:00
|
|
|
err:
|
2010-03-22 14:17:27 +00:00
|
|
|
awp_free_data_info(&idata);
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(info_file);
|
|
|
|
sc_file_free(obj_file);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_create(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *object)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
2014-02-25 08:07:09 +00:00
|
|
|
int rv = SC_ERROR_INTERNAL;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (!object)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
switch (object->type) {
|
|
|
|
case SC_PKCS15_TYPE_AUTH_PIN:
|
|
|
|
rv = awp_update_df_create_pin(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
rv = awp_update_df_create_cert(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
rv = awp_update_df_create_prvkey(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
rv = awp_update_df_create_pubkey(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
|
|
|
rv = awp_update_df_create_data(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
default:
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type");
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
|
|
|
awp_delete_from_container(struct sc_pkcs15_card *p15card,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_profile *profile, int type, int file_id)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *clist=NULL, *file=NULL;
|
|
|
|
unsigned rec, rec_len;
|
|
|
|
int rv = 0, ii;
|
|
|
|
unsigned char *buff=NULL;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "update container entry (type:%X,file-id:%X)", type, file_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot get allocate AWP file");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &clist->path, &file);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot select container list file");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
buff = malloc(file->record_length);
|
|
|
|
if (!buff)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update container entry: allocation error");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2011-05-28 22:47:05 +00:00
|
|
|
for (rec = 1; rec <= (unsigned)file->record_count; rec++) {
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_read_record(p15card->card, rec, buff, file->record_length, SC_RECORD_BY_REC_NR);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update contaner entry: read record error %i", rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
rec_len = rv;
|
2012-04-02 21:40:05 +00:00
|
|
|
|
|
|
|
for (ii=0; ii<12; ii+=2)
|
2010-03-18 12:30:39 +00:00
|
|
|
if (file_id == (*(buff+ii) * 0x100 + *(buff+ii+1)))
|
|
|
|
break;
|
|
|
|
if (ii==12)
|
|
|
|
continue;
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
if (type == SC_PKCS15_TYPE_PRKEY_RSA || type == COSM_TYPE_PRKEY_RSA)
|
2010-03-18 12:30:39 +00:00
|
|
|
memset(buff + ii/6*6, 0, 6);
|
|
|
|
else
|
|
|
|
memset(buff + ii, 0, 2);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (!memcmp(buff,"\0\0\0\0\0\0\0\0\0\0\0\0",12)) {
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_ERASE);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update contaner entry: 'erase' authentication error %i", rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_delete_record(p15card->card, rec);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update contaner entry: delete record error %i", rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update contaner entry: 'update' authentication error %i", rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_update_record(p15card->card, rec, buff, rec_len, SC_RECORD_BY_REC_NR);
|
|
|
|
if (rv < 0) {
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update contaner entry: update record error %i", rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv > 0)
|
|
|
|
rv = 0;
|
|
|
|
|
2017-01-05 19:21:44 +00:00
|
|
|
free(buff);
|
|
|
|
sc_file_free(clist);
|
2015-01-22 19:29:33 +00:00
|
|
|
sc_file_free(file);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-02 21:40:05 +00:00
|
|
|
static int
|
2010-03-18 12:30:39 +00:00
|
|
|
awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|
|
|
int type, unsigned int obj_id)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *lst_file=NULL, *lst=NULL;
|
2011-05-28 22:47:05 +00:00
|
|
|
int rv = 0;
|
|
|
|
unsigned ii;
|
2010-03-18 12:30:39 +00:00
|
|
|
char lst_name[NAME_MAX_LEN];
|
|
|
|
unsigned char *buff=NULL;
|
|
|
|
unsigned char id[2];
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "type %X; obj_id %X",type, obj_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
case COSM_TYPE_PRKEY_RSA:
|
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-private-list", COSM_TITLE);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
|
|
|
case COSM_TYPE_PUBKEY_RSA:
|
|
|
|
snprintf(lst_name, NAME_MAX_LEN,"%s-public-list", COSM_TITLE);
|
|
|
|
break;
|
|
|
|
default:
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INCORRECT_PARAMETERS, "AWP update object list: invalid type");
|
2012-04-02 21:40:05 +00:00
|
|
|
}
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "AWP update object list: select '%s' file", lst_name);
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = sc_profile_get_file(profile, lst_name, &lst_file);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update object list: cannot instantiate list file");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_select_file(p15card->card, &lst_file->path, &lst);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update object list: cannot select list file");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, lst, SC_AC_OP_READ);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP update object list: 'read' authentication failed");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
buff = malloc(lst->size);
|
|
|
|
if (!buff)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update object list: allocation error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = sc_read_binary(p15card->card, 0, buff, lst->size, 0);
|
2011-06-01 17:15:31 +00:00
|
|
|
if (rv != (int)lst->size)
|
2010-03-18 12:30:39 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
id[0] = (obj_id >> 8) & 0xFF;
|
|
|
|
id[1] = obj_id & 0xFF;
|
|
|
|
for (ii=0; ii<lst->size; ii+=5) {
|
|
|
|
if (*(buff+ii)==0xFF && *(buff+ii+1)==id[0] && *(buff+ii+2)==id[1]) {
|
|
|
|
rv = sc_pkcs15init_authenticate(profile, p15card, lst, SC_AC_OP_UPDATE);
|
|
|
|
if (rv)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
rv = sc_update_binary(p15card->card, ii, (unsigned char *)"\0", 1, 0);
|
|
|
|
if (rv && rv!=1)
|
|
|
|
rv = SC_ERROR_INVALID_CARD;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
if (rv > 0)
|
|
|
|
rv = 0;
|
|
|
|
done:
|
|
|
|
if (buff)
|
|
|
|
free(buff);
|
2015-01-22 19:29:33 +00:00
|
|
|
sc_file_free(lst);
|
2017-01-05 19:21:44 +00:00
|
|
|
sc_file_free(lst_file);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *info_file = NULL;
|
|
|
|
struct sc_path path;
|
2012-04-02 21:40:05 +00:00
|
|
|
int rv = SC_ERROR_NOT_SUPPORTED;
|
2010-03-18 12:30:39 +00:00
|
|
|
unsigned file_id;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
path = ((struct sc_pkcs15_cert_info *) obj->data)->path;
|
|
|
|
file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1];
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "file-id:%X", file_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot get allocate new AWP file");
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "info file-id:%X", info_file->id);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = cosm_delete_file(p15card, profile, info_file);
|
|
|
|
if (rv != SC_ERROR_FILE_NOT_FOUND)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: delete info file error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_delete_from_container(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot update container");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot remove object");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *info_file = NULL;
|
|
|
|
struct sc_path path;
|
2012-04-02 21:40:05 +00:00
|
|
|
int rv = SC_ERROR_NOT_SUPPORTED;
|
2010-03-18 12:30:39 +00:00
|
|
|
unsigned file_id;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
path = ((struct sc_pkcs15_prkey_info *) obj->data)->path;
|
|
|
|
file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1];
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "file-id:%X", file_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot get allocate new AWP file");
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "info file-id:%X", info_file->id);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = cosm_delete_file(p15card, profile, info_file);
|
|
|
|
if (rv != SC_ERROR_FILE_NOT_FOUND)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: delete info file error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_delete_from_container(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot update container");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot remove object");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
|
|
|
struct sc_file *info_file = NULL;
|
|
|
|
struct sc_path path;
|
2012-04-02 21:40:05 +00:00
|
|
|
int rv = SC_ERROR_NOT_SUPPORTED;
|
2010-03-18 12:30:39 +00:00
|
|
|
unsigned file_id;
|
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
path = ((struct sc_pkcs15_pubkey_info *) obj->data)->path;
|
|
|
|
file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1];
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "file-id:%X", file_id);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot get allocate new AWP file");
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "info file-id:%X", info_file->id);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = cosm_delete_file(p15card, profile, info_file);
|
|
|
|
if (rv != SC_ERROR_FILE_NOT_FOUND)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: delete info file error");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
rv = awp_delete_from_container(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot update container");
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot remove object");
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *obj)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
2010-03-22 14:17:27 +00:00
|
|
|
struct sc_file *info_file = NULL;
|
|
|
|
struct sc_path path;
|
2012-04-02 21:40:05 +00:00
|
|
|
int rv = SC_ERROR_NOT_SUPPORTED;
|
2010-03-22 14:17:27 +00:00
|
|
|
unsigned file_id;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
path = ((struct sc_pkcs15_data_info *) obj->data)->path;
|
|
|
|
file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1];
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "file-id:%X", file_id);
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: cannot get allocate new AWP file");
|
2018-11-22 08:31:29 +00:00
|
|
|
sc_log(ctx, "info file-id:%X", info_file->id);
|
2012-04-02 21:40:05 +00:00
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
rv = cosm_delete_file(p15card, profile, info_file);
|
|
|
|
if (rv != SC_ERROR_FILE_NOT_FOUND)
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: delete info file error");
|
2010-03-22 14:17:27 +00:00
|
|
|
|
|
|
|
rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id);
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: cannot remove object");
|
2010-03-22 14:17:27 +00:00
|
|
|
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, rv);
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
2010-03-22 14:17:27 +00:00
|
|
|
|
2010-03-18 12:30:39 +00:00
|
|
|
int
|
2012-04-02 21:40:05 +00:00
|
|
|
awp_update_df_delete(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
2010-03-18 12:30:39 +00:00
|
|
|
struct sc_pkcs15_object *object)
|
|
|
|
{
|
|
|
|
struct sc_context *ctx = p15card->card->ctx;
|
2014-02-25 08:07:09 +00:00
|
|
|
int rv = SC_ERROR_INTERNAL;
|
2010-03-18 12:30:39 +00:00
|
|
|
|
2018-11-22 08:14:50 +00:00
|
|
|
LOG_FUNC_CALLED(ctx);
|
2012-04-02 21:40:05 +00:00
|
|
|
if (!object)
|
2018-11-22 22:10:49 +00:00
|
|
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
2010-03-18 12:30:39 +00:00
|
|
|
|
|
|
|
switch (object->type) {
|
|
|
|
case SC_PKCS15_TYPE_CERT_X509:
|
|
|
|
rv = awp_update_df_delete_cert(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
rv = awp_update_df_delete_prvkey(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY_RSA:
|
|
|
|
rv = awp_update_df_delete_pubkey(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
|
|
|
rv = awp_update_df_delete_data(p15card, profile, object);
|
|
|
|
break;
|
|
|
|
default:
|
2018-11-23 20:54:14 +00:00
|
|
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type");
|
2010-03-18 12:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SC_FUNC_RETURN(ctx, 1, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* #ifdef ENABLE_OPENSSL */
|