p15: auxiliary data in prkey info data type
This commit is contained in:
parent
77898e6175
commit
47eb21175c
@ -11,7 +11,7 @@ noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.
|
||||
cardctl.h asn1.h log.h \
|
||||
errors.h types.h compression.h itacns.h iso7816.h \
|
||||
authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \
|
||||
pace.h cwa14890.h cwa-dnie.h card-gids.h
|
||||
pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h
|
||||
|
||||
AM_CPPFLAGS = -DOPENSC_CONF_PATH=\"$(sysconfdir)/opensc.conf\" \
|
||||
-I$(top_srcdir)/src
|
||||
@ -50,6 +50,7 @@ libopensc_la_SOURCES = \
|
||||
pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \
|
||||
pkcs15-dnie.c pkcs15-gids.c \
|
||||
compression.c p15card-helper.c sm.c \
|
||||
aux-data.c \
|
||||
libopensc.exports
|
||||
if WIN32
|
||||
libopensc_la_SOURCES += $(top_builddir)/win32/versioninfo.rc
|
||||
|
@ -33,6 +33,7 @@ OBJECTS = \
|
||||
pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \
|
||||
pkcs15-dnie.obj pkcs15-gids.obj \
|
||||
compression.obj p15card-helper.obj sm.obj \
|
||||
aux-data.obj \
|
||||
$(TOPDIR)\win32\versioninfo.res
|
||||
|
||||
all: $(TOPDIR)\win32\versioninfo.res $(TARGET)
|
||||
|
200
src/libopensc/aux-data.c
Normal file
200
src/libopensc/aux-data.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* aux-data.c: Auxiliary data help functions
|
||||
*
|
||||
* Copyright (C) 2016 Viktor Tarasov <viktor.tarasov@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/compat_strlcat.h"
|
||||
|
||||
#include <libopensc/errors.h>
|
||||
#include <libopensc/types.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <libopensc/aux-data.h>
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_allocate(struct sc_context *ctx, struct sc_auxiliary_data **dst, struct sc_auxiliary_data *src)
|
||||
{
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (!dst)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot allocate auxiliary data");
|
||||
|
||||
if (*dst == NULL) {
|
||||
*dst = calloc(1, sizeof(struct sc_auxiliary_data));
|
||||
if (*dst == NULL)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate aux. data");
|
||||
}
|
||||
|
||||
if ((src == NULL) || (src->type == SC_AUX_DATA_TYPE_NO_DATA))
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
switch(src->type) {
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
**dst = *src;
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", src->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_set_md_guid(struct sc_context *ctx, struct sc_auxiliary_data *aux_data, char *guid)
|
||||
{
|
||||
struct sc_md_cmap_record *rec;
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (!aux_data || !guid || strlen(guid) > SC_MD_MAX_CONTAINER_NAME_LEN)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot set guid for MD container");
|
||||
|
||||
switch(aux_data->type) {
|
||||
case SC_AUX_DATA_TYPE_NO_DATA:
|
||||
memset(aux_data, 0, sizeof(*aux_data));
|
||||
aux_data->type = SC_AUX_DATA_TYPE_MD_CMAP_RECORD;
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
rec = &aux_data->data.cmap_record;
|
||||
memcpy(rec->guid, guid, strlen(guid));
|
||||
rec->guid_len = strlen(guid);
|
||||
sc_log(ctx, "set MD container GUID '%s'", aux_data->data.cmap_record.guid);
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", aux_data->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_set_md_flags(struct sc_context *ctx, struct sc_auxiliary_data *aux_data, unsigned char flags)
|
||||
{
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (!aux_data)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot set flags of MD container");
|
||||
|
||||
switch(aux_data->type) {
|
||||
case SC_AUX_DATA_TYPE_NO_DATA:
|
||||
memset(aux_data, 0, sizeof(*aux_data));
|
||||
aux_data->type = SC_AUX_DATA_TYPE_MD_CMAP_RECORD;
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
aux_data->data.cmap_record.flags = flags;
|
||||
sc_log(ctx, "set MD container flags '0x%X'", flags);
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", aux_data->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_get_md_guid(struct sc_context *ctx, struct sc_auxiliary_data *aux_data,
|
||||
unsigned flags, unsigned char *out, size_t *out_size)
|
||||
{
|
||||
struct sc_md_cmap_record *cmap_record = NULL;
|
||||
char guid[SC_MD_MAX_CONTAINER_NAME_LEN + 3];
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!aux_data || !out || !out_size)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
cmap_record = &aux_data->data.cmap_record;
|
||||
|
||||
*guid = '\0';
|
||||
if (!flags)
|
||||
strcpy(guid, "{");
|
||||
strlcat(guid, (char *)cmap_record->guid, sizeof(guid)-1);
|
||||
if (!flags)
|
||||
strlcat(guid, "}", sizeof(guid));
|
||||
|
||||
if (*out_size < strlen(guid))
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);
|
||||
|
||||
memset(out, 0, *out_size);
|
||||
memcpy(out, guid, strlen(guid));
|
||||
*out_size = strlen(guid);
|
||||
|
||||
sc_log(ctx, "aux-data: returns guid '%s'", (char *)out);
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_get_md_flags(struct sc_context *ctx, struct sc_auxiliary_data *aux_data,
|
||||
unsigned char *flags)
|
||||
{
|
||||
struct sc_md_cmap_record *cmap_record = NULL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!aux_data || !flags)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
*flags = aux_data->data.cmap_record.flags;
|
||||
|
||||
sc_log(ctx, "aux-data: returns flags '0x%X'", *flags);
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sc_aux_data_free(struct sc_auxiliary_data **data)
|
||||
{
|
||||
if (data == NULL || *data == NULL)
|
||||
return;
|
||||
|
||||
switch((*data)->type) {
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
free(*data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*data = NULL;
|
||||
}
|
||||
|
85
src/libopensc/aux-data.h
Normal file
85
src/libopensc/aux-data.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* aux-data.h: Non PKCS#15, non ISO7816 data
|
||||
* Used to pass auxiliary data from non PKCS#15, non ISO7816 appliations (like minidriver)
|
||||
* to card specific part through the standard PKCS#15 and ISO7816 frameworks
|
||||
*
|
||||
* Copyright (C) 2016 Viktor Tarasov <viktor.tarasov@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _AUX_DATA_H
|
||||
#define _AUX_DATA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cardctl.h"
|
||||
#include "internal.h"
|
||||
#include "errors.h"
|
||||
#include "asn1.h"
|
||||
#include "types.h"
|
||||
|
||||
#define SC_AUX_DATA_TYPE_NO_DATA 0x00
|
||||
#define SC_AUX_DATA_TYPE_MD_CMAP_RECORD 0x01
|
||||
|
||||
/* From Windows Smart Card Minidriver Specification
|
||||
* Version 7.06
|
||||
*
|
||||
* #define MAX_CONTAINER_NAME_LEN 39
|
||||
* #define CONTAINER_MAP_VALID_CONTAINER 1
|
||||
* #define CONTAINER_MAP_DEFAULT_CONTAINER 2
|
||||
* typedef struct _CONTAINER_MAP_RECORD
|
||||
* {
|
||||
* WCHAR wszGuid [MAX_CONTAINER_NAME_LEN + 1];
|
||||
* BYTE bFlags;
|
||||
* BYTE bReserved;
|
||||
* WORD wSigKeySizeBits;
|
||||
* WORD wKeyExchangeKeySizeBits;
|
||||
* } CONTAINER_MAP_RECORD, *PCONTAINER_MAP_RECORD;
|
||||
*/
|
||||
#define SC_MD_MAX_CONTAINER_NAME_LEN 39
|
||||
#define SC_MD_CONTAINER_MAP_VALID_CONTAINER 0x01
|
||||
#define SC_MD_CONTAINER_MAP_DEFAULT_CONTAINER 0x02
|
||||
|
||||
struct sc_md_cmap_record {
|
||||
unsigned char guid[SC_MD_MAX_CONTAINER_NAME_LEN + 1];
|
||||
size_t guid_len;
|
||||
unsigned flags;
|
||||
unsigned keysize_sign;
|
||||
unsigned keysize_keyexchange;
|
||||
};
|
||||
|
||||
struct sc_auxiliary_data {
|
||||
unsigned type;
|
||||
union {
|
||||
struct sc_md_cmap_record cmap_record;
|
||||
} data;
|
||||
};
|
||||
|
||||
int sc_aux_data_set_md_flags(struct sc_context *, struct sc_auxiliary_data *, unsigned char);
|
||||
int sc_aux_data_allocate(struct sc_context *, struct sc_auxiliary_data **, struct sc_auxiliary_data *);
|
||||
int sc_aux_data_set_md_guid(struct sc_context *, struct sc_auxiliary_data *, char *);
|
||||
void sc_aux_data_free(struct sc_auxiliary_data **);
|
||||
int sc_aux_data_get_md_guid(struct sc_context *, struct sc_auxiliary_data *, unsigned,
|
||||
unsigned char *, size_t *);
|
||||
int sc_aux_data_get_md_flags(struct sc_context *, struct sc_auxiliary_data *, unsigned char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _AUX_DATA_H */
|
@ -53,6 +53,11 @@ sc_asn1_verify_tag
|
||||
sc_asn1_write_element
|
||||
sc_asn1_sig_value_sequence_to_rs
|
||||
sc_asn1_sig_value_rs_to_sequence
|
||||
sc_aux_data_set_md_flags
|
||||
sc_aux_data_allocate
|
||||
sc_aux_data_set_md_guid
|
||||
sc_aux_data_free
|
||||
sc_aux_data_get_md_guid
|
||||
sc_base64_decode
|
||||
sc_base64_encode
|
||||
sc_bin_to_hex
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "asn1.h"
|
||||
#include "pkcs15.h"
|
||||
#include "common/compat_strlcpy.h"
|
||||
#include "aux-data.h"
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
#include <openssl/x509.h>
|
||||
@ -597,6 +598,8 @@ void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key)
|
||||
|
||||
sc_pkcs15_free_key_params(&key->params);
|
||||
|
||||
sc_aux_data_free(&key->aux_data);
|
||||
|
||||
free(key);
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,11 @@ static const struct sc_asn1_entry c_asn1_tokeninfo[] = {
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *);
|
||||
static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *);
|
||||
static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *);
|
||||
static int sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
|
||||
unsigned, unsigned char *, size_t *);
|
||||
|
||||
int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
|
||||
sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen)
|
||||
@ -1206,8 +1208,8 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
|
||||
p15card->opts.pin_cache_ignore_user_consent);
|
||||
}
|
||||
sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d",
|
||||
p15card->opts.use_file_cache, p15card->opts.use_pin_cache,
|
||||
p15card->opts.pin_cache_counter, p15card->opts.pin_cache_ignore_user_consent);
|
||||
p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter,
|
||||
p15card->opts.pin_cache_ignore_user_consent);
|
||||
|
||||
r = sc_lock(card);
|
||||
if (r) {
|
||||
@ -1565,8 +1567,7 @@ sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, struct sc_pkcs15_search
|
||||
int
|
||||
sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type,
|
||||
int (* func)(struct sc_pkcs15_object *, void *),
|
||||
void *func_arg,
|
||||
struct sc_pkcs15_object **ret, size_t ret_size)
|
||||
void *func_arg, struct sc_pkcs15_object **ret, size_t ret_size)
|
||||
{
|
||||
return __sc_pkcs15_search_objects(p15card, 0, type,
|
||||
func, func_arg, ret, ret_size);
|
||||
@ -1789,8 +1790,7 @@ sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, const char *a
|
||||
|
||||
int
|
||||
sc_pkcs15_find_prkey_by_id_usage(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
|
||||
unsigned int usage,
|
||||
struct sc_pkcs15_object **out)
|
||||
unsigned int usage, struct sc_pkcs15_object **out)
|
||||
{
|
||||
struct sc_pkcs15_search_key sk;
|
||||
|
||||
@ -2721,6 +2721,12 @@ sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
rv = sc_pkcs15_aux_get_md_guid(p15card, obj, flags, out, out_size);
|
||||
if (rv == SC_SUCCESS)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
else if (rv != SC_ERROR_NOT_SUPPORTED)
|
||||
LOG_TEST_RET(ctx, rv, "Failed to get alternative object GUID");
|
||||
|
||||
memset(out, 0, *out_size);
|
||||
|
||||
rv = sc_pkcs15_get_object_id(obj, &id);
|
||||
@ -2775,6 +2781,31 @@ sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
|
||||
unsigned flags,
|
||||
unsigned char *out, size_t *out_size)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_prkey_info *prkey_info = NULL;
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!out || !out_size)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
prkey_info = (struct sc_pkcs15_prkey_info *)obj->data;
|
||||
if (!prkey_info->aux_data || prkey_info->aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
rv = sc_aux_data_get_md_guid(ctx, prkey_info->aux_data, flags, out, out_size);
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "libopensc/opensc.h"
|
||||
#include "libopensc/aux-data.h"
|
||||
|
||||
#define SC_PKCS15_CACHE_DIR ".eid"
|
||||
|
||||
@ -388,8 +389,8 @@ struct sc_pkcs15_prkey_info {
|
||||
|
||||
struct sc_path path;
|
||||
|
||||
/* Used by minidriver and its on-card support */
|
||||
/*struct sc_md_cmap_record cmap_record;*/
|
||||
/* Non-pkcs15 data, like MD CMAP record */
|
||||
struct sc_auxiliary_data *aux_data;
|
||||
};
|
||||
typedef struct sc_pkcs15_prkey_info sc_pkcs15_prkey_info_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user