switched to opensc.0.12.0. note that this has some issues when linking against both libnpa and the opensc libraries at the same time. readme information would be usefull for this...
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@385 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -1,17 +1,26 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src/pace -I$(top_builddir)/src/pace
|
||||
OPENSCVERSION = 0.12.0
|
||||
|
||||
EXTRA_DIST = opensc-$(OPENSCVERSION)
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src/pace -I$(top_srcdir)/src/opensc-$(OPENSCVERSION)/src
|
||||
|
||||
libpace_la_SOURCES = sm.c scutil.c pace.c pace_lib.c
|
||||
libpace_la_LIBADD = $(OPENSC_LIBS) $(OPENSSL_LIBS)
|
||||
libpace_la_CFLAGS = $(OPENSC_CFLAGS) $(OPENSSL_CFLAGS)
|
||||
libpace_la_LIBADD = $(OPENSSL_LIBS) libopensc.la
|
||||
libpace_la_CFLAGS = $(OPENSSL_CFLAGS)
|
||||
|
||||
pace_tool_SOURCES = pace-tool.c binutil.c
|
||||
pace_tool_LDADD = $(OPENSC_LIBS) $(OPENSSL_LIBS) libpace.la
|
||||
pace_tool_CFLAGS = $(OPENSC_CFLAGS) $(OPENSSL_CFLAGS)
|
||||
pace_tool_LDADD = $(OPENSSL_LIBS) libpace.la libopensc.la
|
||||
pace_tool_CFLAGS = $(OPENSSL_CFLAGS)
|
||||
noinst_HEADERS = \
|
||||
binutil.h
|
||||
|
||||
flaw:
|
||||
flawfinder -SQD *.h *.c
|
||||
opensc: opensc-$(OPENSCVERSION)
|
||||
cd $(top_builddir)/src && cp -r opensc-$(OPENSCVERSION) opensc
|
||||
|
||||
libopensc.la: opensc
|
||||
cd $(top_builddir)/src/opensc && ./configure
|
||||
$(MAKE) -C opensc
|
||||
cp $(top_builddir)/src/opensc/src/libopensc/.libs/libopensc* $(top_builddir)/src
|
||||
|
||||
bin_PROGRAMS = pace-tool
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "binutil.h"
|
||||
#include "pace.h"
|
||||
#include "scutil.h"
|
||||
#include <opensc/log.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <openssl/pace.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -130,7 +130,8 @@ int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card, FILE *input)
|
||||
if (linelen <= 1) {
|
||||
if (linelen < 0) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
sc_error(card->ctx, "Could not read line");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
|
||||
"Could not read line");
|
||||
} else {
|
||||
r = SC_SUCCESS;
|
||||
printf("Thanks for flying with ccid\n");
|
||||
@@ -141,7 +142,8 @@ int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card, FILE *input)
|
||||
|
||||
apdulen = sizeof buf;
|
||||
if (sc_hex_to_bin(read, buf, &apdulen) < 0) {
|
||||
sc_error(card->ctx, "Could not format binary string");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
|
||||
"Could not format binary string");
|
||||
continue;
|
||||
}
|
||||
if (input != stdin)
|
||||
@@ -149,7 +151,7 @@ int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card, FILE *input)
|
||||
|
||||
r = build_apdu(card->ctx, buf, apdulen, &apdu);
|
||||
if (r < 0) {
|
||||
bin_log(ctx, "Invalid C-APDU", buf, apdulen);
|
||||
bin_log(ctx, SC_LOG_DEBUG_NORMAL, "Invalid C-APDU", buf, apdulen);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -158,7 +160,8 @@ int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card, FILE *input)
|
||||
|
||||
r = sm_transmit_apdu(sctx, card, &apdu);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not send C-APDU: %s", sc_strerror(r));
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
|
||||
"Could not send C-APDU: %s", sc_strerror(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -312,14 +315,8 @@ main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < SC_MAX_SLOTS; i++) {
|
||||
if (sc_detect_card_presence(reader, 0) & SC_SLOT_CARD_PRESENT) {
|
||||
sc_connect_card(reader, i, &card);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == SC_MAX_SLOTS) {
|
||||
fprintf(stderr, "No card found\n");
|
||||
if (sc_connect_card(reader, &card) < 0) {
|
||||
fprintf(stderr, "Could not connect to card\n");
|
||||
sc_release_context(ctx);
|
||||
exit(1);
|
||||
}
|
||||
@@ -547,8 +544,8 @@ err:
|
||||
if (pace_output.id_pcd)
|
||||
free(pace_output.id_pcd);
|
||||
|
||||
sc_reset(card);
|
||||
sc_disconnect_card(card, 0);
|
||||
sc_reset(card, 1);
|
||||
sc_disconnect_card(card);
|
||||
sc_release_context(ctx);
|
||||
|
||||
return -i;
|
||||
|
||||
178
npa/src/pace.c
178
npa/src/pace.c
@@ -19,9 +19,9 @@
|
||||
#include "pace.h"
|
||||
#include "sm.h"
|
||||
#include "scutil.h"
|
||||
#include <opensc/asn1.h>
|
||||
#include <opensc/log.h>
|
||||
#include <opensc/opensc.h>
|
||||
#include <libopensc/asn1.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <libopensc/opensc.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
@@ -198,18 +198,18 @@ int get_ef_card_access(sc_card_t *card,
|
||||
memset(&path, 0, sizeof path);
|
||||
r = sc_append_file_id(&path, FID_EF_CARDACCESS);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not create path object.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create path object.");
|
||||
goto err;
|
||||
}
|
||||
r = sc_concatenate_path(&path, sc_get_mf_path(), &path);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not create path object.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create path object.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = sc_select_file(card, &path, &file);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not select EF.CardAccess.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select EF.CardAccess.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ int get_ef_card_access(sc_card_t *card,
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not read EF.CardAccess.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF.CardAccess.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ int get_ef_card_access(sc_card_t *card,
|
||||
/* test cards only return an empty FCI template,
|
||||
* so we can't determine any file proberties */
|
||||
if (*length_ef_cardaccess < file->size) {
|
||||
sc_error(card->ctx, "Actual filesize differs from the size in file "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Actual filesize differs from the size in file "
|
||||
"proberties (%u!=%u).", *length_ef_cardaccess, file->size);
|
||||
r = SC_ERROR_FILE_TOO_SMALL;
|
||||
goto err;
|
||||
@@ -298,7 +298,7 @@ static int pace_mse_set_at(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
}
|
||||
|
||||
if (!ASN1_INTEGER_set(data->key_reference1, secret_key)) {
|
||||
sc_error(card->ctx, "Error setting key reference 1 of MSE:Set AT data");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 1 of MSE:Set AT data");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -308,7 +308,7 @@ static int pace_mse_set_at(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
|
||||
r = i2d_PACE_MSE_SET_AT_C(data, &d);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Error encoding MSE:Set AT APDU data");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding MSE:Set AT APDU data");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -318,8 +318,7 @@ static int pace_mse_set_at(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
apdu.data = sc_asn1_find_tag(card->ctx, d, r, 0x30, &apdu.datalen);
|
||||
apdu.lc = apdu.datalen;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "MSE:Set AT command data", apdu.data, apdu.datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "MSE:Set AT command data", apdu.data, apdu.datalen);
|
||||
|
||||
if (oldpacectx)
|
||||
r = sm_transmit_apdu(oldpacectx, card, &apdu);
|
||||
@@ -329,7 +328,7 @@ static int pace_mse_set_at(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
goto err;
|
||||
|
||||
if (apdu.resplen) {
|
||||
sc_error(card->ctx, "MSE:Set AT response data should be empty "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "MSE:Set AT response data should be empty "
|
||||
"(contains %u bytes)", apdu.resplen);
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
goto err;
|
||||
@@ -343,19 +342,19 @@ static int pace_mse_set_at(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
tries = apdu.sw2 & 0x0f;
|
||||
if (tries <= 1) {
|
||||
/* this is only a warning... */
|
||||
sc_error(card->ctx, "Remaining tries: %d (%s must be %s)\n",
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Remaining tries: %d (%s must be %s)\n",
|
||||
tries, pace_secret_name(secret_key),
|
||||
tries ? "resumed" : "unblocked");
|
||||
}
|
||||
r = SC_SUCCESS;
|
||||
} else {
|
||||
sc_error(card->ctx, "Unknown status bytes: SW1=%02X, SW2=%02X\n",
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unknown status bytes: SW1=%02X, SW2=%02X\n",
|
||||
apdu.sw1, apdu.sw2);
|
||||
r = SC_ERROR_CARD_CMD_FAILED;
|
||||
goto err;
|
||||
}
|
||||
} else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x83) {
|
||||
sc_error(card->ctx, "Password is deactivated\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Password is deactivated\n");
|
||||
r = SC_ERROR_AUTH_METHOD_BLOCKED;
|
||||
goto err;
|
||||
} else {
|
||||
@@ -405,8 +404,7 @@ static int pace_gen_auth_1_encrypted_nonce(struct sm_ctx *oldpacectx,
|
||||
apdu.datalen = r;
|
||||
apdu.lc = r;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen);
|
||||
|
||||
apdu.resplen = maxresp;
|
||||
apdu.resp = malloc(apdu.resplen);
|
||||
@@ -421,12 +419,11 @@ static int pace_gen_auth_1_encrypted_nonce(struct sm_ctx *oldpacectx,
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen);
|
||||
|
||||
if (!d2i_PACE_GEN_AUTH_R(&r_data,
|
||||
(const unsigned char **) &apdu.resp, apdu.resplen)) {
|
||||
sc_error(card->ctx, "Could not parse general authenticate response data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data.");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -437,7 +434,7 @@ static int pace_gen_auth_1_encrypted_nonce(struct sm_ctx *oldpacectx,
|
||||
|| r_data->auth_token
|
||||
|| r_data->cur_car
|
||||
|| r_data->prev_car) {
|
||||
sc_error(card->ctx, "Response data of general authenticate for "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for "
|
||||
"step 1 should (only) contain the encrypted nonce.");
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
goto err;
|
||||
@@ -520,8 +517,7 @@ static int pace_gen_auth_2_map_nonce(struct sm_ctx *oldpacectx,
|
||||
apdu.datalen = r;
|
||||
apdu.lc = r;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen);
|
||||
|
||||
apdu.resplen = maxresp;
|
||||
apdu.resp = malloc(apdu.resplen);
|
||||
@@ -536,12 +532,11 @@ static int pace_gen_auth_2_map_nonce(struct sm_ctx *oldpacectx,
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen);
|
||||
|
||||
if (!d2i_PACE_GEN_AUTH_R(&r_data,
|
||||
(const unsigned char **) &apdu.resp, apdu.resplen)) {
|
||||
sc_error(card->ctx, "Could not parse general authenticate response data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data.");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -552,7 +547,7 @@ static int pace_gen_auth_2_map_nonce(struct sm_ctx *oldpacectx,
|
||||
|| r_data->auth_token
|
||||
|| r_data->cur_car
|
||||
|| r_data->prev_car) {
|
||||
sc_error(card->ctx, "Response data of general authenticate for "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for "
|
||||
"step 2 should (only) contain the mapping data.");
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
goto err;
|
||||
@@ -635,8 +630,7 @@ static int pace_gen_auth_3_perform_key_agreement(
|
||||
apdu.datalen = r;
|
||||
apdu.lc = r;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen);
|
||||
|
||||
apdu.resplen = maxresp;
|
||||
apdu.resp = malloc(apdu.resplen);
|
||||
@@ -651,12 +645,11 @@ static int pace_gen_auth_3_perform_key_agreement(
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen);
|
||||
|
||||
if (!d2i_PACE_GEN_AUTH_R(&r_data,
|
||||
(const unsigned char **) &apdu.resp, apdu.resplen)) {
|
||||
sc_error(card->ctx, "Could not parse general authenticate response data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data.");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -667,7 +660,7 @@ static int pace_gen_auth_3_perform_key_agreement(
|
||||
|| r_data->auth_token
|
||||
|| r_data->cur_car
|
||||
|| r_data->prev_car) {
|
||||
sc_error(card->ctx, "Response data of general authenticate for "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for "
|
||||
"step 3 should (only) contain the ephemeral public key.");
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
goto err;
|
||||
@@ -753,8 +746,7 @@ static int pace_gen_auth_4_mutual_authentication(
|
||||
apdu.datalen = r;
|
||||
apdu.lc = r;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen);
|
||||
|
||||
apdu.resplen = maxresp;
|
||||
apdu.resp = malloc(apdu.resplen);
|
||||
@@ -769,12 +761,11 @@ static int pace_gen_auth_4_mutual_authentication(
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen);
|
||||
|
||||
if (!d2i_PACE_GEN_AUTH_R(&r_data,
|
||||
(const unsigned char **) &apdu.resp, apdu.resplen)) {
|
||||
sc_error(card->ctx, "Could not parse general authenticate response data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data.");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
@@ -783,7 +774,7 @@ static int pace_gen_auth_4_mutual_authentication(
|
||||
|| r_data->mapping_data
|
||||
|| r_data->eph_pub_key
|
||||
|| !r_data->auth_token) {
|
||||
sc_error(card->ctx, "Response data of general authenticate for "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for "
|
||||
"step 4 should (only) contain the authentication token.");
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
goto err;
|
||||
@@ -792,7 +783,7 @@ static int pace_gen_auth_4_mutual_authentication(
|
||||
l = r_data->auth_token->length;
|
||||
/* XXX CAR sould be returned as result in some way */
|
||||
if (r_data->cur_car) {
|
||||
bin_log(card->ctx, "Most recent Certificate Authority Reference",
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Most recent Certificate Authority Reference",
|
||||
r_data->cur_car->data, r_data->cur_car->length);
|
||||
*recent_car = malloc(r_data->cur_car->length);
|
||||
if (!*recent_car) {
|
||||
@@ -805,7 +796,7 @@ static int pace_gen_auth_4_mutual_authentication(
|
||||
} else
|
||||
*recent_car_len = 0;
|
||||
if (r_data->prev_car) {
|
||||
bin_log(card->ctx, "Previous Certificate Authority Reference",
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Previous Certificate Authority Reference",
|
||||
r_data->prev_car->data, r_data->prev_car->length);
|
||||
*prev_car = malloc(r_data->prev_car->length);
|
||||
if (!*prev_car) {
|
||||
@@ -869,13 +860,13 @@ pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card,
|
||||
if (ask_for_secret && (!new || !new_len)) {
|
||||
p = malloc(MAX_PIN_LEN+1);
|
||||
if (!p) {
|
||||
sc_error(card->ctx, "Not enough memory for new PIN.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for new PIN.\n");
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (0 > EVP_read_pw_string_min(p,
|
||||
MIN_PIN_LEN, MAX_PIN_LEN+1,
|
||||
"Please enter your new PIN: ", 0)) {
|
||||
sc_error(card->ctx, "Could not read new PIN.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n");
|
||||
free(p);
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
@@ -921,17 +912,17 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id
|
||||
if (!length_pin || !pin) {
|
||||
if (0 > snprintf(buf, sizeof buf, "Please enter your %s: ",
|
||||
pace_secret_name(pin_id))) {
|
||||
sc_error(card->ctx, "Could not create password prompt.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create password prompt.\n");
|
||||
return NULL;
|
||||
}
|
||||
p = malloc(MAX_MRZ_LEN);
|
||||
if (!p) {
|
||||
sc_error(card->ctx, "Not enough memory for %s.\n",
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for %s.\n",
|
||||
pace_secret_name(pin_id));
|
||||
return NULL;
|
||||
}
|
||||
if (0 > EVP_read_pw_string_min(p, 0, MAX_MRZ_LEN, buf, 0)) {
|
||||
sc_error(card->ctx, "Could not read %s.\n",
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s.\n",
|
||||
pace_secret_name(pin_id));
|
||||
return NULL;
|
||||
}
|
||||
@@ -953,7 +944,7 @@ void ssl_error(sc_context_t *ctx) {
|
||||
unsigned long r;
|
||||
ERR_load_crypto_strings();
|
||||
for (r = ERR_get_error(); r; r = ERR_get_error()) {
|
||||
sc_error(ctx, ERR_error_string(r, NULL));
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, ERR_error_string(r, NULL));
|
||||
}
|
||||
ERR_free_strings();
|
||||
}
|
||||
@@ -989,7 +980,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
if (!bio_stdout)
|
||||
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
if (!bio_stdout) {
|
||||
sc_error(card->ctx, "Could not create output buffer.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create output buffer.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1000,24 +991,24 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
pace_input.certificate_description,
|
||||
pace_input.certificate_description_length, "\t")) {
|
||||
case -1:
|
||||
sc_error(card->ctx, "Could not print certificate description.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print certificate description.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
sc_error(card->ctx, "Certificate description in "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
|
||||
"HTML format can not (yet) be handled.");
|
||||
r = SC_ERROR_NOT_SUPPORTED;
|
||||
goto err;
|
||||
case 2:
|
||||
sc_error(card->ctx, "Certificate description in "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
|
||||
"PDF format can not (yet) be handled.");
|
||||
r = SC_ERROR_NOT_SUPPORTED;
|
||||
goto err;
|
||||
default:
|
||||
sc_error(card->ctx, "Certificate description in "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
|
||||
"unknown format can not (yet) be handled.");
|
||||
r = SC_ERROR_NOT_SUPPORTED;
|
||||
goto err;
|
||||
@@ -1027,7 +1018,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
pace_input.certificate_description,
|
||||
pace_input.certificate_description_length);
|
||||
if (!hash_cert_desc) {
|
||||
sc_error(card->ctx, "Could not hash certificate description.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not hash certificate description.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1035,7 +1026,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
|
||||
p = realloc(pace_output->hash_cert_desc, hash_cert_desc->length);
|
||||
if (!p) {
|
||||
sc_error(card->ctx, "Not enough memory for hash of certificate description.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for hash of certificate description.\n");
|
||||
r = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
@@ -1050,7 +1041,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
if (!bio_stdout)
|
||||
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
if (!bio_stdout) {
|
||||
sc_error(card->ctx, "Could not create output buffer.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create output buffer.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1058,14 +1049,14 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
|
||||
if (!d2i_CVC_CHAT(&chat, (const unsigned char **) &pace_input.chat,
|
||||
pace_input.chat_length)) {
|
||||
sc_error(card->ctx, "Could not parse card holder authorization template (CHAT).");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse card holder authorization template (CHAT).");
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("Card holder authorization template (CHAT)\n");
|
||||
if (!cvc_chat_print(bio_stdout, chat, "\t")) {
|
||||
sc_error(card->ctx, "Could not print card holder authorization template (CHAT).");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print card holder authorization template (CHAT).");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1076,16 +1067,16 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
r = get_ef_card_access(card, &pace_output->ef_cardaccess,
|
||||
&pace_output->ef_cardaccess_length);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not get EF.CardAccess.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get EF.CardAccess.");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
bin_log(card->ctx, "EF.CardAccess", pace_output->ef_cardaccess,
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "EF.CardAccess", pace_output->ef_cardaccess,
|
||||
pace_output->ef_cardaccess_length);
|
||||
|
||||
if (!parse_ef_card_access(pace_output->ef_cardaccess,
|
||||
pace_output->ef_cardaccess_length, &info, &static_dp)) {
|
||||
sc_error(card->ctx, "Could not parse EF.CardAccess.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse EF.CardAccess.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1093,7 +1084,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
|
||||
pctx = PACE_CTX_new();
|
||||
if (!pctx || !PACE_init(pctx, &static_dp, info)) {
|
||||
sc_error(card->ctx, "Could not initialize PACE parameters.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize PACE parameters.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1103,7 +1094,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
r = pace_mse_set_at(oldpacectx, card, info->protocol, pace_input.pin_id,
|
||||
chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not select protocol proberties "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
|
||||
"(MSE: Set AT failed).");
|
||||
goto err;
|
||||
}
|
||||
@@ -1115,18 +1106,17 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
r = pace_gen_auth_1_encrypted_nonce(oldpacectx, card, (u8 **) &enc_nonce->data,
|
||||
&enc_nonce->length);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not get encrypted nonce from card "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get encrypted nonce from card "
|
||||
"(General Authenticate step 1 failed).");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug >= SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length);
|
||||
enc_nonce->max = enc_nonce->length;
|
||||
|
||||
sec = get_psec(card, (char *) pace_input.pin, pace_input.pin_length,
|
||||
pace_input.pin_id);
|
||||
if (!sec) {
|
||||
sc_error(card->ctx, "Could not encode PACE secret.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encode PACE secret.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1137,7 +1127,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
mdata_opp = BUF_MEM_new();
|
||||
mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx);
|
||||
if (!nonce || !mdata || !mdata_opp) {
|
||||
sc_error(card->ctx, "Could not generate mapping data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate mapping data.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1145,19 +1135,18 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
r = pace_gen_auth_2_map_nonce(oldpacectx, card, (u8 *) mdata->data, mdata->length,
|
||||
(u8 **) &mdata_opp->data, &mdata_opp->length);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not exchange mapping data with card "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange mapping data with card "
|
||||
"(General Authenticate step 2 failed).");
|
||||
goto err;
|
||||
}
|
||||
mdata_opp->max = mdata_opp->length;
|
||||
if (card->ctx->debug >= SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length);
|
||||
|
||||
eph_dp = PACE_STEP3A_map_dp(static_dp, pctx, nonce, mdata_opp);
|
||||
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
|
||||
pub_opp = BUF_MEM_new();
|
||||
if (!eph_dp || !pub || !pub_opp) {
|
||||
sc_error(card->ctx, "Could not generate ephemeral domain parameter or "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate ephemeral domain parameter or "
|
||||
"ephemeral key pair.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
@@ -1166,18 +1155,17 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
r = pace_gen_auth_3_perform_key_agreement(oldpacectx, card, (u8 *) pub->data, pub->length,
|
||||
(u8 **) &pub_opp->data, &pub_opp->length);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not exchange ephemeral public key with card "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange ephemeral public key with card "
|
||||
"(General Authenticate step 3 failed).");
|
||||
goto err;
|
||||
}
|
||||
pub_opp->max = pub_opp->length;
|
||||
if (card->ctx->debug >= SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length);
|
||||
|
||||
key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp);
|
||||
if (!key ||
|
||||
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
|
||||
sc_error(card->ctx, "Could not compute ephemeral shared secret or "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute ephemeral shared secret or "
|
||||
"derive keys for encryption and authentication.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
@@ -1187,7 +1175,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
eph_dp, info, pub_opp, k_mac);
|
||||
token_opp = BUF_MEM_new();
|
||||
if (!token || !token_opp) {
|
||||
sc_error(card->ctx, "Could not compute authentication token.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute authentication token.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1198,7 +1186,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
&pace_output->previous_car, &pace_output->previous_car_length);
|
||||
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not exchange authentication token with card "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange authentication token with card "
|
||||
"(General Authenticate step 4 failed).");
|
||||
goto err;
|
||||
}
|
||||
@@ -1206,7 +1194,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
|
||||
if (!PACE_STEP3D_verify_authentication_token(pctx,
|
||||
eph_dp, info, k_mac, token_opp)) {
|
||||
sc_error(card->ctx, "Could not verify authentication token.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify authentication token.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1216,32 +1204,32 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||
comp_pub = PACE_Comp(eph_dp, pctx, pub);
|
||||
comp_pub_opp = PACE_Comp(eph_dp, pctx, pub_opp);
|
||||
if (!comp_pub || !comp_pub_opp) {
|
||||
sc_error(card->ctx, "Could not compress public keys for identification.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compress public keys for identification.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
p = realloc(pace_output->id_icc, comp_pub_opp->length);
|
||||
if (!p) {
|
||||
sc_error(card->ctx, "Not enough memory for ID ICC.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for ID ICC.\n");
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
pace_output->id_icc = p;
|
||||
pace_output->id_icc_length = comp_pub_opp->length;
|
||||
/* Flawfinder: ignore */
|
||||
memcpy(pace_output->id_icc, comp_pub_opp->data, comp_pub_opp->length);
|
||||
bin_log(card->ctx, "ID ICC", pace_output->id_icc,
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ID ICC", pace_output->id_icc,
|
||||
pace_output->id_icc_length);
|
||||
p = realloc(pace_output->id_pcd, comp_pub->length);
|
||||
if (!p) {
|
||||
sc_error(card->ctx, "Not enough memory for ID PCD.\n");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for ID PCD.\n");
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
pace_output->id_pcd = p;
|
||||
pace_output->id_pcd_length = comp_pub->length;
|
||||
/* Flawfinder: ignore */
|
||||
memcpy(pace_output->id_pcd, comp_pub->data, comp_pub->length);
|
||||
bin_log(card->ctx, "ID PCD", pace_output->id_pcd,
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd,
|
||||
pace_output->id_pcd_length);
|
||||
|
||||
sctx->authentication_ctx = pace_sm_ctx_create(k_mac,
|
||||
@@ -1392,7 +1380,7 @@ pace_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
databuf = BUF_MEM_create_init(data, datalen);
|
||||
encbuf = PACE_encrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, databuf);
|
||||
if (!databuf || !encbuf) {
|
||||
sc_error(card->ctx, "Could not encrypt data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt data.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1436,7 +1424,7 @@ pace_sm_decrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
encbuf = BUF_MEM_create_init(enc, enclen);
|
||||
databuf = PACE_decrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, encbuf);
|
||||
if (!encbuf || !databuf) {
|
||||
sc_error(card->ctx, "Could not decrypt data.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt data.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1480,8 +1468,8 @@ pace_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
macbuf = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
||||
data, datalen);
|
||||
if (!macbuf) {
|
||||
sc_error(card->ctx, "Could not compute message authentication code "
|
||||
"(MAC).");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
||||
"Could not compute message authentication code (MAC).");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1524,8 +1512,8 @@ pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
my_mac = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
||||
macdata, macdatalen);
|
||||
if (!my_mac) {
|
||||
sc_error(card->ctx, "Could not compute message authentication code "
|
||||
"(MAC) for verification.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
||||
"Could not compute message authentication code (MAC) for verification.");
|
||||
ssl_error(card->ctx);
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
@@ -1534,12 +1522,12 @@ pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
if (my_mac->length != maclen ||
|
||||
memcmp(my_mac->data, mac, maclen) != 0) {
|
||||
r = SC_ERROR_OBJECT_NOT_VALID;
|
||||
sc_error(card->ctx, "Authentication data not verified");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
||||
"Authentication data not verified");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
sc_debug(card->ctx, "Authentication data verified");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Authentication data verified");
|
||||
|
||||
r = SC_SUCCESS;
|
||||
|
||||
@@ -1554,13 +1542,13 @@ static int
|
||||
pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
sc_apdu_t *apdu)
|
||||
{
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG,
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,
|
||||
increment_ssc(ctx->cipher_ctx));
|
||||
}
|
||||
|
||||
static int pace_sm_post_transmit(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
sc_apdu_t *sm_apdu)
|
||||
{
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG,
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,
|
||||
increment_ssc(ctx->cipher_ctx));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <pace/pace_lib.h>
|
||||
#include <pace/sm.h>
|
||||
#include <opensc/opensc.h>
|
||||
#include <libopensc/opensc.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/pace.h>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef _CCID_SCUTIL_H
|
||||
#define _CCID_SCUTIL_H
|
||||
|
||||
#include <opensc/opensc.h>
|
||||
#include <libopensc/opensc.h>
|
||||
|
||||
/**
|
||||
* @brief Initializes smart card context and reader
|
||||
@@ -68,8 +68,8 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu);
|
||||
* @param[in] data Binary data
|
||||
* @param[in] len Length of \a data
|
||||
*/
|
||||
#define bin_log(ctx, label, data, len) \
|
||||
_bin_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, label, data, len, NULL)
|
||||
#define bin_log(ctx, level, label, data, len) \
|
||||
_bin_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, label, data, len, NULL)
|
||||
/**
|
||||
* @brief Log binary data
|
||||
*
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef _CCID_SM_H
|
||||
#define _CCID_SM_H
|
||||
|
||||
#include <opensc/opensc.h>
|
||||
#include <libopensc/opensc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "scutil.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <opensc/log.h>
|
||||
#include <libopensc/log.h>
|
||||
|
||||
int initialize(int reader_id, const char *cdriver, int verbose,
|
||||
sc_context_t **ctx, sc_reader_t **reader)
|
||||
@@ -38,7 +38,7 @@ int initialize(int reader_id, const char *cdriver, int verbose,
|
||||
if (cdriver != NULL) {
|
||||
r = sc_set_card_driver(*ctx, cdriver);
|
||||
if (r < 0) {
|
||||
sc_error(*ctx, "Card driver '%s' not found!\n", cdriver);
|
||||
sc_debug(*ctx, SC_LOG_DEBUG_VERBOSE, "Card driver '%s' not found!\n", cdriver);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -54,14 +54,14 @@ int initialize(int reader_id, const char *cdriver, int verbose,
|
||||
/* Automatically try to skip to a reader with a card if reader not specified */
|
||||
for (i = 0; i < reader_count; i++) {
|
||||
*reader = sc_ctx_get_reader(*ctx, i);
|
||||
if (sc_detect_card_presence(*reader, 0) & SC_SLOT_CARD_PRESENT) {
|
||||
if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) {
|
||||
reader_id = i;
|
||||
sc_debug(*ctx, "Using the first reader with a card: %s", (*reader)->name);
|
||||
sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader with a card: %s", (*reader)->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (reader_id >= reader_count) {
|
||||
sc_debug(*ctx, "No card found, using the first reader.");
|
||||
sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader.");
|
||||
reader_id = 0;
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
|
||||
len0 = len;
|
||||
if (len < 4) {
|
||||
sc_error(ctx, "APDU too short (must be at least 4 bytes)");
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too short (must be at least 4 bytes)");
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
apdu->lc += *p++;
|
||||
len -= 3;
|
||||
if (len < apdu->lc) {
|
||||
sc_error(ctx, "APDU too short (need %lu more bytes)\n",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too short (need %lu more bytes)\n",
|
||||
(unsigned long) apdu->lc - len);
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
} else {
|
||||
/* at this point the apdu has a Lc, so Le is on 2 bytes */
|
||||
if (len < 2) {
|
||||
sc_error(ctx, "APDU too short (need 2 more bytes)\n");
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too short (need 2 more bytes)\n");
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
apdu->le = (*p++)<<8;
|
||||
@@ -151,7 +151,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
apdu->lc = *p++;
|
||||
len--;
|
||||
if (len < apdu->lc) {
|
||||
sc_error(ctx, "APDU too short (need %lu more bytes)\n",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too short (need %lu more bytes)\n",
|
||||
(unsigned long) apdu->lc - len);
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
}
|
||||
}
|
||||
if (len) {
|
||||
sc_error(ctx, "APDU too long (%lu bytes extra)\n",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too long (%lu bytes extra)\n",
|
||||
(unsigned long) len);
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
@@ -180,7 +180,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||
|
||||
apdu->flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
|
||||
|
||||
sc_debug(ctx, "Case %d %s APDU, %lu bytes:\tins=%02x p1=%02x p2=%02x lc=%04x le=%04x",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Case %d %s APDU, %lu bytes:\tins=%02x p1=%02x p2=%02x lc=%04x le=%04x",
|
||||
apdu->cse & SC_APDU_SHORT_MASK,
|
||||
(apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
|
||||
(unsigned long) len0, apdu->ins, apdu->p1, apdu->p2, apdu->lc, apdu->le);
|
||||
@@ -197,7 +197,7 @@ void _bin_log(sc_context_t *ctx, int type, const char *file, int line,
|
||||
char buf[1800];
|
||||
|
||||
if (data)
|
||||
sc_hex_dump(ctx, data, len, buf, sizeof buf);
|
||||
sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, data, len, buf, sizeof buf);
|
||||
else
|
||||
buf[0] = 0;
|
||||
if (!f) {
|
||||
|
||||
121
npa/src/sm.c
121
npa/src/sm.c
@@ -19,8 +19,8 @@
|
||||
#include "scutil.h"
|
||||
#include "sm.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <opensc/asn1.h>
|
||||
#include <opensc/log.h>
|
||||
#include <libopensc/asn1.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -201,25 +201,23 @@ static int format_data(sc_card_t *card, const struct sm_ctx *ctx,
|
||||
|
||||
r = add_padding(ctx, data, datalen, &pad_data);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not add padding to data: %s",
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not add padding to data: %s",
|
||||
sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
pad_data_len = r;
|
||||
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Data to encrypt", pad_data, pad_data_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to encrypt", pad_data, pad_data_len);
|
||||
r = ctx->encrypt(card, ctx, pad_data, pad_data_len, formatted_data);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not encrypt the data");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt the data");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Cryptogram", *formatted_data, r);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptogram", *formatted_data, r);
|
||||
|
||||
r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not prepend padding indicator to formatted "
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not prepend padding indicator to formatted "
|
||||
"data: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
@@ -267,20 +265,19 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
size_t sm_data_len, fdata_len, mac_data_len, asn1_len, mac_len, le_len;
|
||||
int r;
|
||||
|
||||
if (!apdu || !ctx || !card || !card->slot || !sm_apdu) {
|
||||
if (!apdu || !ctx || !card || !card->reader || !sm_apdu) {
|
||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((apdu->cla & 0x0C) == 0x0C) {
|
||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||
sc_error(card->ctx, "Given APDU is already protected with some secure messaging");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging");
|
||||
goto err;
|
||||
}
|
||||
|
||||
sc_copy_asn1_entry(c_sm_capdu, sm_capdu);
|
||||
|
||||
sm_apdu->sensitive = 0;
|
||||
sm_apdu->control = apdu->control;
|
||||
sm_apdu->flags = apdu->flags;
|
||||
sm_apdu->cla = apdu->cla|0x0C;
|
||||
@@ -289,7 +286,7 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
sm_apdu->p2 = apdu->p2;
|
||||
r = format_head(ctx, sm_apdu, &mac_data);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format header of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format header of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
mac_data_len = r;
|
||||
@@ -302,19 +299,18 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
le_len = 1;
|
||||
r = format_le(apdu->le, sm_capdu + 1, &le, &le_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format Le of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Protected Le (plain)", le, le_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len);
|
||||
break;
|
||||
case SC_APDU_CASE_2_EXT:
|
||||
if (card->slot->active_protocol == SC_PROTO_T0) {
|
||||
if (card->reader->active_protocol == SC_PROTO_T0) {
|
||||
/* T0 extended APDUs look just like short APDUs */
|
||||
le_len = 1;
|
||||
r = format_le(apdu->le, sm_capdu + 1, &le, &le_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format Le of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
@@ -322,50 +318,46 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
le_len = 3;
|
||||
r = format_le(apdu->le, sm_capdu + 1, &le, &le_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format Le of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Protected Le (plain)", le, le_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len);
|
||||
break;
|
||||
case SC_APDU_CASE_3_SHORT:
|
||||
case SC_APDU_CASE_3_EXT:
|
||||
r = format_data(card, ctx, apdu->data, apdu->datalen,
|
||||
sm_capdu + 0, &fdata, &fdata_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format data of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
break;
|
||||
case SC_APDU_CASE_4_SHORT:
|
||||
/* in case of T0 no Le byte is added */
|
||||
if (card->slot->active_protocol != SC_PROTO_T0) {
|
||||
if (card->reader->active_protocol != SC_PROTO_T0) {
|
||||
le_len = 1;
|
||||
r = format_le(apdu->le, sm_capdu + 1, &le, &le_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format Le of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Protected Le (plain)", le, le_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len);
|
||||
}
|
||||
|
||||
r = format_data(card, ctx, apdu->data, apdu->datalen,
|
||||
sm_capdu + 0, &fdata, &fdata_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format data of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
break;
|
||||
case SC_APDU_CASE_4_EXT:
|
||||
if (card->slot->active_protocol == SC_PROTO_T0) {
|
||||
if (card->reader->active_protocol == SC_PROTO_T0) {
|
||||
/* again a T0 extended case 4 APDU looks just
|
||||
* like a short APDU, the additional data is
|
||||
* transferred using ENVELOPE and GET RESPONSE */
|
||||
@@ -375,25 +367,23 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
le_len = 2;
|
||||
r = format_le(apdu->le, sm_capdu + 1, &le, &le_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format Le of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Protected Le (plain)", le, le_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len);
|
||||
}
|
||||
|
||||
r = format_data(card, ctx, apdu->data, apdu->datalen,
|
||||
sm_capdu + 0, &fdata, &fdata_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not format data of SM apdu");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
|
||||
goto err;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)",
|
||||
fdata, fdata_len);
|
||||
break;
|
||||
default:
|
||||
sc_error(card->ctx, "Unhandled apdu case");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unhandled apdu case");
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
}
|
||||
@@ -419,20 +409,18 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
}
|
||||
mac_data_len = r;
|
||||
}
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Data to authenticate", mac_data, mac_data_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to authenticate", mac_data, mac_data_len);
|
||||
|
||||
r = ctx->authenticate(card, ctx, mac_data, mac_data_len,
|
||||
&mac);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not get authentication code");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get authentication code");
|
||||
goto err;
|
||||
}
|
||||
mac_len = r;
|
||||
sc_format_asn1_entry(sm_capdu + 2, mac, &mac_len,
|
||||
SC_ASN1_PRESENT);
|
||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "Cryptographic Checksum (plain)", mac, mac_len);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptographic Checksum (plain)", mac, mac_len);
|
||||
|
||||
|
||||
/* format SM apdu */
|
||||
@@ -440,7 +428,7 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
if (r < 0)
|
||||
goto err;
|
||||
if (sm_apdu->datalen < sm_data_len) {
|
||||
sc_error(card->ctx, "Data for SM APDU too long");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Data for SM APDU too long");
|
||||
r = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
@@ -450,8 +438,7 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
sm_apdu->lc = sm_apdu->datalen;
|
||||
sm_apdu->le = 0;
|
||||
sm_apdu->cse = SC_APDU_CASE_4;
|
||||
if (card->ctx->debug >= SC_LOG_TYPE_DEBUG)
|
||||
bin_log(card->ctx, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen);
|
||||
|
||||
err:
|
||||
if (fdata)
|
||||
@@ -515,7 +502,7 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
if (r < 0)
|
||||
goto err;
|
||||
} else {
|
||||
sc_error(card->ctx, "Cryptographic Checksum missing");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Cryptographic Checksum missing");
|
||||
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
@@ -533,12 +520,12 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
|
||||
r = no_padding(ctx->padding_indicator, data, buf_len);
|
||||
if (r < 0) {
|
||||
sc_error(card->ctx, "Could not remove padding");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not remove padding");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (apdu->resplen < r) {
|
||||
sc_error(card->ctx, "Response of SM APDU too long");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response of SM APDU too long");
|
||||
r = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
@@ -551,24 +538,22 @@ static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||
|
||||
if (sm_rapdu[1].flags & SC_ASN1_PRESENT) {
|
||||
if (sw_len != 2) {
|
||||
sc_error(card->ctx, "Length of processing status bytes must be 2");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Length of processing status bytes must be 2");
|
||||
r = SC_ERROR_ASN1_END_OF_CONTENTS;
|
||||
goto err;
|
||||
}
|
||||
apdu->sw1 = sw[0];
|
||||
apdu->sw2 = sw[1];
|
||||
} else {
|
||||
sc_error(card->ctx, "Authenticated status bytes are missing");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Authenticated status bytes are missing");
|
||||
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (card->ctx->debug >= SC_LOG_TYPE_DEBUG) {
|
||||
sc_debug(card->ctx, "Decrypted APDU sw1=%02x sw2=%02x",
|
||||
apdu->sw1, apdu->sw2);
|
||||
bin_log(card->ctx, "Decrypted APDU response data",
|
||||
apdu->resp, apdu->resplen);
|
||||
}
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Decrypted APDU sw1=%02x sw2=%02x",
|
||||
apdu->sw1, apdu->sw2);
|
||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Decrypted APDU response data",
|
||||
apdu->resp, apdu->resplen);
|
||||
|
||||
r = SC_SUCCESS;
|
||||
|
||||
@@ -595,27 +580,27 @@ int sm_transmit_apdu(struct sm_ctx *sctx, sc_card_t *card,
|
||||
sm_apdu.resplen = sizeof rbuf;
|
||||
|
||||
if (!sctx || !sctx->active) {
|
||||
sc_debug(card->ctx, "Secure messaging disabled.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Secure messaging disabled.");
|
||||
return sc_transmit_apdu(card, apdu);
|
||||
}
|
||||
|
||||
if ((apdu->cla & 0x0C) == 0x0C) {
|
||||
sc_debug(card->ctx, "Given APDU is already protected with some secure messaging. Deactivating own SM context.");
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging. Deactivating own SM context.");
|
||||
sctx->active = 0;
|
||||
return sc_transmit_apdu(card, apdu);
|
||||
}
|
||||
|
||||
if (sctx->pre_transmit)
|
||||
SC_TEST_RET(card->ctx, sctx->pre_transmit(card, sctx, apdu),
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->pre_transmit(card, sctx, apdu),
|
||||
"Could not complete SM specific pre transmit routine");
|
||||
SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu),
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sm_encrypt(sctx, card, apdu, &sm_apdu),
|
||||
"Could not encrypt APDU");
|
||||
SC_TEST_RET(card->ctx, sc_transmit_apdu(card, &sm_apdu),
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_transmit_apdu(card, &sm_apdu),
|
||||
"Could not transmit SM APDU");
|
||||
if (sctx->post_transmit)
|
||||
SC_TEST_RET(card->ctx, sctx->post_transmit(card, sctx, &sm_apdu),
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->post_transmit(card, sctx, &sm_apdu),
|
||||
"Could not complete SM specific post transmit routine");
|
||||
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
||||
"Could not decrypt APDU");
|
||||
|
||||
return SC_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user