Added ASN.1 helper for auxiliary data
This commit is contained in:
@@ -207,8 +207,8 @@ int npa_translate_apdus(sc_card_t *card, FILE *input)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(
|
static int add_to_ASN1_AUXILIARY_DATA(
|
||||||
CVC_DISCRETIONARY_DATA_TEMPLATES **templates,
|
ASN1_AUXILIARY_DATA **templates,
|
||||||
int nid, const unsigned char *data, size_t data_len)
|
int nid, const unsigned char *data, size_t data_len)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@@ -220,7 +220,7 @@ static int add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!*templates) {
|
if (!*templates) {
|
||||||
*templates = CVC_DISCRETIONARY_DATA_TEMPLATES_new();
|
*templates = ASN1_AUXILIARY_DATA_new();
|
||||||
if (!*templates) {
|
if (!*templates) {
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
@@ -298,7 +298,7 @@ main (int argc, char **argv)
|
|||||||
unsigned char *certs_chat = NULL;
|
unsigned char *certs_chat = NULL;
|
||||||
unsigned char *dg = NULL;
|
unsigned char *dg = NULL;
|
||||||
size_t dg_len = 0;
|
size_t dg_len = 0;
|
||||||
CVC_DISCRETIONARY_DATA_TEMPLATES *templates = NULL;
|
ASN1_AUXILIARY_DATA *templates = NULL;
|
||||||
|
|
||||||
struct gengetopt_args_info cmdline;
|
struct gengetopt_args_info cmdline;
|
||||||
|
|
||||||
@@ -577,7 +577,7 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cmdline.older_than_given) {
|
if (cmdline.older_than_given) {
|
||||||
r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates,
|
r = add_to_ASN1_AUXILIARY_DATA(&templates,
|
||||||
NID_id_DateOfBirth,
|
NID_id_DateOfBirth,
|
||||||
(unsigned char *) cmdline.older_than_arg,
|
(unsigned char *) cmdline.older_than_arg,
|
||||||
strlen(cmdline.older_than_arg));
|
strlen(cmdline.older_than_arg));
|
||||||
@@ -585,30 +585,32 @@ main (int argc, char **argv)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (cmdline.verify_validity_given) {
|
if (cmdline.verify_validity_given) {
|
||||||
r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates,
|
r = add_to_ASN1_AUXILIARY_DATA(&templates,
|
||||||
NID_id_DateOfExpiry, NULL, 0);
|
NID_id_DateOfExpiry, NULL, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (cmdline.verify_community_given) {
|
if (cmdline.verify_community_given) {
|
||||||
r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates,
|
r = add_to_ASN1_AUXILIARY_DATA(&templates,
|
||||||
NID_id_CommunityID,
|
NID_id_CommunityID,
|
||||||
(unsigned char *) cmdline.verify_community_arg,
|
(unsigned char *) cmdline.verify_community_arg,
|
||||||
strlen(cmdline.verify_community_arg));
|
strlen(cmdline.verify_community_arg));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
unsigned char *p = NULL;
|
if (templates) {
|
||||||
auxiliary_data_len = i2d_CVC_DISCRETIONARY_DATA_TEMPLATES(
|
unsigned char *p = NULL;
|
||||||
templates, &p);
|
auxiliary_data_len = i2d_ASN1_AUXILIARY_DATA(
|
||||||
if (0 >= (int) auxiliary_data_len
|
templates, &p);
|
||||||
|| auxiliary_data_len > sizeof auxiliary_data) {
|
if (0 > (int) auxiliary_data_len
|
||||||
|
|| auxiliary_data_len > sizeof auxiliary_data) {
|
||||||
|
free(p);
|
||||||
|
r = SC_ERROR_INTERNAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memcpy(auxiliary_data, p, auxiliary_data_len);
|
||||||
free(p);
|
free(p);
|
||||||
r = SC_ERROR_INTERNAL;
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
memcpy(auxiliary_data, p, auxiliary_data_len);
|
|
||||||
free(p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,7 +784,7 @@ err:
|
|||||||
free(privkey);
|
free(privkey);
|
||||||
free(dg);
|
free(dg);
|
||||||
if (templates)
|
if (templates)
|
||||||
CVC_DISCRETIONARY_DATA_TEMPLATES_free(templates);
|
ASN1_AUXILIARY_DATA_free(templates);
|
||||||
|
|
||||||
sm_stop(card);
|
sm_stop(card);
|
||||||
sc_reset(card, 1);
|
sc_reset(card, 1);
|
||||||
|
|||||||
@@ -44,6 +44,15 @@
|
|||||||
#define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type)
|
#define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type)
|
||||||
#define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type)
|
#define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type)
|
||||||
|
|
||||||
|
/* 0x67
|
||||||
|
* Auxiliary authenticated data */
|
||||||
|
ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) =
|
||||||
|
ASN1_EX_TEMPLATE_TYPE(
|
||||||
|
ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION,
|
||||||
|
7, ASN1_AUXILIARY_DATA, CVC_DISCRETIONARY_DATA_TEMPLATES)
|
||||||
|
ASN1_ITEM_TEMPLATE_END(ASN1_AUXILIARY_DATA)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MSE:Set AT
|
* MSE:Set AT
|
||||||
*/
|
*/
|
||||||
@@ -53,7 +62,7 @@ typedef struct npa_mse_cd_st {
|
|||||||
ASN1_OCTET_STRING *key_reference1;
|
ASN1_OCTET_STRING *key_reference1;
|
||||||
ASN1_OCTET_STRING *key_reference2;
|
ASN1_OCTET_STRING *key_reference2;
|
||||||
ASN1_OCTET_STRING *eph_pub_key;
|
ASN1_OCTET_STRING *eph_pub_key;
|
||||||
CVC_DISCRETIONARY_DATA_TEMPLATES *auxiliary_data;
|
ASN1_AUXILIARY_DATA *auxiliary_data;
|
||||||
CVC_CHAT *chat;
|
CVC_CHAT *chat;
|
||||||
} NPA_MSE_C;
|
} NPA_MSE_C;
|
||||||
ASN1_SEQUENCE(NPA_MSE_C) = {
|
ASN1_SEQUENCE(NPA_MSE_C) = {
|
||||||
@@ -71,8 +80,7 @@ ASN1_SEQUENCE(NPA_MSE_C) = {
|
|||||||
ASN1_IMP_OPT(NPA_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11),
|
ASN1_IMP_OPT(NPA_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11),
|
||||||
/* 0x67
|
/* 0x67
|
||||||
* Auxiliary authenticated data */
|
* Auxiliary authenticated data */
|
||||||
ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATES, 7),
|
ASN1_OPT(NPA_MSE_C, auxiliary_data, ASN1_AUXILIARY_DATA),
|
||||||
/*ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, ASN1_OCTET_STRING, 7),*/
|
|
||||||
/* Certificate Holder Authorization Template */
|
/* Certificate Holder Authorization Template */
|
||||||
ASN1_OPT(NPA_MSE_C, chat, CVC_CHAT),
|
ASN1_OPT(NPA_MSE_C, chat, CVC_CHAT),
|
||||||
} ASN1_SEQUENCE_END(NPA_MSE_C)
|
} ASN1_SEQUENCE_END(NPA_MSE_C)
|
||||||
@@ -516,9 +524,8 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auxiliary_data && auxiliary_data_len) {
|
if (auxiliary_data && auxiliary_data_len) {
|
||||||
bin_log(ctx, SC_LOG_DEBUG_NORMAL, "test", auxiliary_data, auxiliary_data_len);
|
if (!d2i_ASN1_AUXILIARY_DATA(&data->auxiliary_data, &auxiliary_data, auxiliary_data_len)) {
|
||||||
if (!d2i_CVC_DISCRETIONARY_DATA_TEMPLATES(&data->auxiliary_data, &auxiliary_data, auxiliary_data_len)) {
|
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting authenticated auxiliary data of MSE:Set AT data");
|
||||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting auxiliary authenticated data of MSE:Set AT data");
|
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1749,10 +1756,6 @@ int perform_terminal_authentication(sc_card_t *card,
|
|||||||
BUF_MEM_free(eacsmctx->auxiliary_data);
|
BUF_MEM_free(eacsmctx->auxiliary_data);
|
||||||
eacsmctx->auxiliary_data = BUF_MEM_create_init(auxiliary_data,
|
eacsmctx->auxiliary_data = BUF_MEM_create_init(auxiliary_data,
|
||||||
auxiliary_data_len);
|
auxiliary_data_len);
|
||||||
/* FIXME this is a workaround for fixing 0x30 tag of
|
|
||||||
* CVC_DISCRETIONARY_DATA_TEMPLATES. */
|
|
||||||
if (eacsmctx->auxiliary_data->data && eacsmctx->auxiliary_data->length)
|
|
||||||
eacsmctx->auxiliary_data->data[0] = 0x67;
|
|
||||||
signature = TA_STEP5_sign(eacsmctx->ctx, eacsmctx->eph_pub_key,
|
signature = TA_STEP5_sign(eacsmctx->ctx, eacsmctx->eph_pub_key,
|
||||||
eacsmctx->id_icc, eacsmctx->auxiliary_data);
|
eacsmctx->id_icc, eacsmctx->auxiliary_data);
|
||||||
if (!signature) {
|
if (!signature) {
|
||||||
@@ -2222,8 +2225,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx,
|
|||||||
int r;
|
int r;
|
||||||
CVC_CERT *cvc_cert = NULL;
|
CVC_CERT *cvc_cert = NULL;
|
||||||
unsigned char *cert = NULL;
|
unsigned char *cert = NULL;
|
||||||
int len, tag, class;
|
int len;
|
||||||
long int llen;
|
|
||||||
BUF_MEM *signature = NULL;
|
BUF_MEM *signature = NULL;
|
||||||
unsigned char *sequence = NULL, *templates = NULL;
|
unsigned char *sequence = NULL, *templates = NULL;
|
||||||
NPA_MSE_C *msesetat = NULL;
|
NPA_MSE_C *msesetat = NULL;
|
||||||
@@ -2333,31 +2335,15 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx,
|
|||||||
r = SC_ERROR_OUT_OF_MEMORY;
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* Note that we can not define CVC_DISCRETIONARY_DATA_TEMPLATES as
|
eacsmctx->auxiliary_data->length = i2d_ASN1_AUXILIARY_DATA(
|
||||||
* item template with the correct tag. Due to limitations of
|
msesetat->auxiliary_data,
|
||||||
* OpenSSL it is not possible to *encode* an optional item template
|
(unsigned char **) &eacsmctx->auxiliary_data->data);
|
||||||
* (such as APDU_DISCRETIONARY_DATA_TEMPLATES) in an other item
|
if ((int) eacsmctx->auxiliary_data->length < 0) {
|
||||||
* template (such as NPA_MSE_C). So what we have to do here
|
|
||||||
* is manually adding the correct tag to the saved
|
|
||||||
* CVC_DISCRETIONARY_DATA_TEMPLATES.
|
|
||||||
* See also openssl/crypto/asn1/tasn_dec.c:183
|
|
||||||
*/
|
|
||||||
len = i2d_CVC_DISCRETIONARY_DATA_TEMPLATES(msesetat->auxiliary_data, &templates);
|
|
||||||
p = templates;
|
|
||||||
if (len < 0 ||
|
|
||||||
(0x80 & ASN1_get_object(&p, &llen, &tag, &class, len))) {
|
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding auxiliary data.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding auxiliary data.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
eacsmctx->auxiliary_data->length = add_tag(
|
|
||||||
(unsigned char **) &eacsmctx->auxiliary_data->data, 1,
|
|
||||||
7, V_ASN1_APPLICATION, p, llen);
|
|
||||||
if ((int) eacsmctx->auxiliary_data->length < 0) {
|
|
||||||
r = SC_ERROR_OUT_OF_MEMORY;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
eacsmctx->auxiliary_data->max = eacsmctx->auxiliary_data->length;
|
eacsmctx->auxiliary_data->max = eacsmctx->auxiliary_data->length;
|
||||||
}
|
}
|
||||||
if (msesetat->eph_pub_key) {
|
if (msesetat->eph_pub_key) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#ifndef _CCID_NPA_H
|
#ifndef _CCID_NPA_H
|
||||||
#define _CCID_NPA_H
|
#define _CCID_NPA_H
|
||||||
|
|
||||||
|
#include <eac/cv_cert.h>
|
||||||
#include <eac/eac.h>
|
#include <eac/eac.h>
|
||||||
#include <eac/pace.h>
|
#include <eac/pace.h>
|
||||||
#include <libopensc/opensc.h>
|
#include <libopensc/opensc.h>
|
||||||
@@ -155,8 +156,8 @@ int perform_pace(sc_card_t *card,
|
|||||||
* @param[in] privkey The terminal's private key
|
* @param[in] privkey The terminal's private key
|
||||||
* @param[in] privkey_len length of \a privkey
|
* @param[in] privkey_len length of \a privkey
|
||||||
* @param[in] auxiliary_data auxiliary data for age/validity/community ID
|
* @param[in] auxiliary_data auxiliary data for age/validity/community ID
|
||||||
* verification. Should be formatted as buffer of
|
* verification. Should be an ASN1 object tagged
|
||||||
* \c CVC_DISCRETIONARY_DATA_TEMPLATES
|
* with \c 0x67
|
||||||
* @param[in] auxiliary_data_len length of \a auxiliary_data
|
* @param[in] auxiliary_data_len length of \a auxiliary_data
|
||||||
*
|
*
|
||||||
* @return \c SC_SUCCESS or error code if an error occurred
|
* @return \c SC_SUCCESS or error code if an error occurred
|
||||||
@@ -223,6 +224,10 @@ int npa_reset_retry_counter(sc_card_t *card,
|
|||||||
/** Use \c npa_default_flags to disable checks for EAC/SM */
|
/** Use \c npa_default_flags to disable checks for EAC/SM */
|
||||||
extern char npa_default_flags;
|
extern char npa_default_flags;
|
||||||
|
|
||||||
|
/** ASN.1 type for authenticated auxiliary data for terminal authentication */
|
||||||
|
typedef CVC_DISCRETIONARY_DATA_TEMPLATES ASN1_AUXILIARY_DATA;
|
||||||
|
DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user